Compare commits
22 Commits
2.91.1
...
configurab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a4cfde4e2 | ||
|
|
c853d197e3 | ||
|
|
bf7ae3e4d3 | ||
|
|
2b21f1d48c | ||
|
|
4c91e05b86 | ||
|
|
bc91c328f3 | ||
|
|
5bbbac65d6 | ||
|
|
a0a0fc14d7 | ||
|
|
cc9efe1289 | ||
|
|
8825ded1ca | ||
|
|
b823ef0007 | ||
|
|
a846434bcf | ||
|
|
825fc2c0c8 | ||
|
|
4fbe547f16 | ||
|
|
fc2ba0afbe | ||
|
|
3e7d2df6f3 | ||
|
|
02e709e89e | ||
|
|
1114e5effa | ||
|
|
c40fab214d | ||
|
|
441c050808 | ||
|
|
85425f64a5 | ||
|
|
b445ee3763 |
40
configure.in
40
configure.in
@@ -2,7 +2,7 @@ AC_PREREQ(2.50)
|
||||
|
||||
m4_define([mutter_major_version], [2])
|
||||
m4_define([mutter_minor_version], [91])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_micro_version], [2])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -127,35 +127,11 @@ if test "$enable_compile_warnings" != no ; then
|
||||
fi
|
||||
changequote([,])dnl
|
||||
|
||||
AC_MSG_CHECKING([which gtk+ version to compile against])
|
||||
AC_ARG_WITH([gtk],
|
||||
AC_HELP_STRING([--with-gtk=3.0|2.0],
|
||||
[which gtk+ version to compile against (default: 3.0)]),
|
||||
[case "$with_gtk" in
|
||||
2.0|3.0) ;;
|
||||
*) AC_MSG_ERROR([invalid gtk+ version specified]);;
|
||||
esac],
|
||||
[with_gtk=3.0])
|
||||
AC_MSG_RESULT([$with_gtk])
|
||||
GTK_MIN_VERSION=2.90.7
|
||||
CANBERRA_GTK=libcanberra-gtk3
|
||||
CANBERRA_GTK_VERSION=0.26
|
||||
|
||||
case "$with_gtk" in
|
||||
2.0) GTK_API_VERSION=2.0
|
||||
GTK_MIN_VERSION=2.18
|
||||
CANBERRA_GTK=libcanberra-gtk
|
||||
CANBERRA_GTK_VERSION=0.24
|
||||
;;
|
||||
3.0) GTK_API_VERSION=3.0
|
||||
GTK_MIN_VERSION=2.90.7
|
||||
CANBERRA_GTK=libcanberra-gtk3
|
||||
CANBERRA_GTK_VERSION=0.26
|
||||
AC_DEFINE(USE_CAIRO_REGION, 1, [Use cairo_region_t instead of GdkRegion])
|
||||
;;
|
||||
esac
|
||||
|
||||
AM_CONDITIONAL(INSTALL_LIBMUTTER_PRIVATE, test "$with_gtk" = "3.0")
|
||||
|
||||
MUTTER_PC_MODULES="gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION pango >= 1.2.0 cairo >= 1.10.0"
|
||||
AC_SUBST(GTK_API_VERSION)
|
||||
MUTTER_PC_MODULES="gtk+-3.0 >= $GTK_MIN_VERSION pango >= 1.2.0 cairo >= 1.10.0"
|
||||
|
||||
AC_ARG_ENABLE(gconf,
|
||||
AC_HELP_STRING([--disable-gconf],
|
||||
@@ -215,8 +191,8 @@ AM_GLIB_GNU_GETTEXT
|
||||
# GRegex requires Glib-2.14.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
# gtk_window_set_icon_name requires gtk2+-2.6.0
|
||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0 >= $GTK_MIN_VERSION)
|
||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0 >= $GTK_MIN_VERSION)
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -574,7 +550,7 @@ fi
|
||||
|
||||
dnl ==========================================================================
|
||||
echo "
|
||||
mutter-$VERSION (using gtk+-${GTK_API_VERSION}):
|
||||
mutter-$VERSION
|
||||
|
||||
prefix: ${prefix}
|
||||
source code location: ${srcdir}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
|
||||
.AUTOPARALLEL:
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
lib_LTLIBRARIES = libmutter-private.la
|
||||
else
|
||||
noinst_LTLIBRARIES = libmutter-private.la
|
||||
endif
|
||||
|
||||
SUBDIRS=wm-tester tools compositor/plugins
|
||||
|
||||
@@ -32,6 +28,8 @@ mutter_SOURCES= \
|
||||
compositor/meta-plugin.c \
|
||||
compositor/meta-plugin-manager.c \
|
||||
compositor/meta-plugin-manager.h \
|
||||
compositor/meta-shadow-factory.c \
|
||||
compositor/meta-shadow-factory-private.h \
|
||||
compositor/meta-shaped-texture.c \
|
||||
compositor/meta-shaped-texture.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -40,16 +38,13 @@ mutter_SOURCES= \
|
||||
compositor/meta-window-actor-private.h \
|
||||
compositor/meta-window-group.c \
|
||||
compositor/meta-window-group.h \
|
||||
compositor/shadow.c \
|
||||
compositor/shadow.h \
|
||||
compositor/tidy/tidy-texture-frame.c \
|
||||
compositor/tidy/tidy-texture-frame.h \
|
||||
gdk-compat.h \
|
||||
gtk-compat.h \
|
||||
gdk2-drawing-utils.c \
|
||||
gdk2-drawing-utils.h \
|
||||
compositor/meta-window-shape.c \
|
||||
compositor/meta-window-shape.h \
|
||||
compositor/region-utils.c \
|
||||
compositor/region-utils.h \
|
||||
include/compositor.h \
|
||||
include/meta-plugin.h \
|
||||
include/meta-shadow-factory.h \
|
||||
include/meta-window-actor.h \
|
||||
include/compositor-mutter.h \
|
||||
core/constraints.c \
|
||||
@@ -147,8 +142,6 @@ libmutter_private_la_SOURCES= \
|
||||
include/common.h \
|
||||
ui/preview-widget.c \
|
||||
ui/preview-widget.h \
|
||||
gdk2-drawing-utils.c \
|
||||
gdk2-drawing-utils.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme.c \
|
||||
ui/theme.h
|
||||
@@ -177,6 +170,7 @@ libmutterinclude_base_headers = \
|
||||
include/group.h \
|
||||
include/keybindings.h \
|
||||
include/meta-plugin.h \
|
||||
include/meta-shadow-factory.h \
|
||||
include/meta-window-actor.h
|
||||
|
||||
# Excluded from scanning for introspection but installed
|
||||
@@ -186,17 +180,11 @@ libmutterinclude_extra_headers = \
|
||||
ui/preview-widget.h \
|
||||
include/atomnames.h
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
libmutterincludedir = $(includedir)/mutter/mutter-private
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
else
|
||||
noinst_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
endif
|
||||
|
||||
mutter_theme_viewer_SOURCES= \
|
||||
ui/theme-viewer.c
|
||||
@@ -226,11 +214,11 @@ Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mu
|
||||
--warn-all \
|
||||
--warn-error \
|
||||
--include=GObject-2.0 \
|
||||
--include=Gdk-@GTK_API_VERSION@ \
|
||||
--include=Gtk-@GTK_API_VERSION@ \
|
||||
--include=Gdk-3.0 \
|
||||
--include=Gtk-3.0 \
|
||||
--include=Clutter-1.0 \
|
||||
--pkg=clutter-1.0 \
|
||||
--pkg=gtk+-@GTK_API_VERSION@ \
|
||||
--pkg=gtk+-3.0 \
|
||||
--include=xlib-2.0 \
|
||||
--include=xfixes-4.0 \
|
||||
--program=$$pwd/mutter \
|
||||
@@ -305,11 +293,9 @@ CLEANFILES = \
|
||||
inlinepixbufs.h: $(IMAGES)
|
||||
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
||||
|
||||
if INSTALL_LIBMUTTER_PRIVATE
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
|
||||
endif
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_files) \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "compositor-mutter.h"
|
||||
#include "xprops.h"
|
||||
#include "prefs.h"
|
||||
#include "meta-shadow-factory.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "../core/window-private.h" /* to check window->hidden */
|
||||
@@ -444,7 +445,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
XCompositeRedirectSubwindows (xdisplay, xroot, CompositeRedirectManual);
|
||||
XSync (xdisplay, FALSE);
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE))
|
||||
if (meta_error_trap_pop_with_return (display))
|
||||
{
|
||||
g_warning ("Another compositing manager is running on screen %i",
|
||||
screen_number);
|
||||
@@ -568,7 +569,7 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
||||
|
||||
add_win (window);
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1017,6 +1018,26 @@ meta_repaint_func (gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_shadow_factory_changed (MetaShadowFactory *factory,
|
||||
MetaCompositor *compositor)
|
||||
{
|
||||
GSList *screens = meta_display_get_screens (compositor->display);
|
||||
GList *l;
|
||||
GSList *sl;
|
||||
|
||||
for (sl = screens; sl; sl = sl->next)
|
||||
{
|
||||
MetaScreen *screen = sl->data;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
if (!info)
|
||||
continue;
|
||||
|
||||
for (l = info->windows; l; l = l->next)
|
||||
meta_window_actor_invalidate_shadow (l->data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_compositor_new: (skip)
|
||||
*
|
||||
@@ -1047,6 +1068,11 @@ meta_compositor_new (MetaDisplay *display)
|
||||
XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
|
||||
g_signal_connect (meta_shadow_factory_get_default (),
|
||||
"changed",
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->atom_x_root_pixmap = atoms[0];
|
||||
compositor->atom_x_set_root = atoms[1];
|
||||
compositor->atom_net_wm_window_opacity = atoms[2];
|
||||
|
||||
65
src/compositor/meta-shadow-factory-private.h
Normal file
65
src/compositor/meta-shadow-factory-private.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MetaShadowFactory:
|
||||
*
|
||||
* Create and cache shadow textures for arbitrary window shapes
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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_SHADOW_FACTORY_PRIVATE_H__
|
||||
#define __META_SHADOW_FACTORY_PRIVATE_H__
|
||||
|
||||
#include <cairo.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "meta-window-shape.h"
|
||||
#include "meta-shadow-factory.h"
|
||||
|
||||
/**
|
||||
* MetaShadow:
|
||||
* #MetaShadow holds a shadow texture along with information about how to
|
||||
* apply that texture to draw a window texture. (E.g., it knows how big the
|
||||
* unscaled borders are on each side of the shadow texture.)
|
||||
*/
|
||||
typedef struct _MetaShadow MetaShadow;
|
||||
|
||||
MetaShadow *meta_shadow_ref (MetaShadow *shadow);
|
||||
void meta_shadow_unref (MetaShadow *shadow);
|
||||
CoglHandle meta_shadow_get_texture (MetaShadow *shadow);
|
||||
void meta_shadow_paint (MetaShadow *shadow,
|
||||
int window_x,
|
||||
int window_y,
|
||||
int window_width,
|
||||
int window_height,
|
||||
guint8 opacity,
|
||||
cairo_region_t *clip);
|
||||
void meta_shadow_get_bounds (MetaShadow *shadow,
|
||||
int window_x,
|
||||
int window_y,
|
||||
int window_width,
|
||||
int window_height,
|
||||
cairo_rectangle_int_t *bounds);
|
||||
|
||||
MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
||||
MetaWindowShape *shape,
|
||||
int width,
|
||||
int height,
|
||||
const char *class_name,
|
||||
gboolean focused);
|
||||
|
||||
#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */
|
||||
1032
src/compositor/meta-shadow-factory.c
Normal file
1032
src/compositor/meta-shadow-factory.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@ void meta_window_actor_process_damage (MetaWindowActor *self,
|
||||
XDamageNotifyEvent *event);
|
||||
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
|
||||
|
||||
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
|
||||
void meta_window_actor_sync_actor_position (MetaWindowActor *self);
|
||||
void meta_window_actor_sync_visibility (MetaWindowActor *self);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <gdk/gdk.h> /* for gdk_rectangle_union() */
|
||||
|
||||
#include "display.h"
|
||||
#include "errors.h"
|
||||
@@ -17,10 +18,9 @@
|
||||
#include "xprops.h"
|
||||
|
||||
#include "compositor-private.h"
|
||||
#include "meta-shadow-factory-private.h"
|
||||
#include "meta-shaped-texture.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "shadow.h"
|
||||
#include "tidy/tidy-texture-frame.h"
|
||||
|
||||
struct _MetaWindowActorPrivate
|
||||
{
|
||||
@@ -31,12 +31,27 @@ struct _MetaWindowActorPrivate
|
||||
MetaScreen *screen;
|
||||
|
||||
ClutterActor *actor;
|
||||
ClutterActor *shadow;
|
||||
|
||||
/* MetaShadowFactory only caches shadows that are actually in use;
|
||||
* to avoid unnecessary recomputation we do two things: 1) we store
|
||||
* both a focused and unfocused shadow for the window. If the window
|
||||
* doesn't have different focused and unfocused shadow parameters,
|
||||
* these will be the same. 2) when the shadow potentially changes we
|
||||
* don't immediately unreference the old shadow, we just flag it as
|
||||
* dirty and recompute it when we next need it (recompute_focused_shadow,
|
||||
* recompute_unfocused_shadow.) Because of the our extraction of
|
||||
* size-invariant window shape, we'll often find that the new shadow
|
||||
* is the same as the old shadow.
|
||||
*/
|
||||
MetaShadow *focused_shadow;
|
||||
MetaShadow *unfocused_shadow;
|
||||
|
||||
Pixmap back_pixmap;
|
||||
|
||||
Damage damage;
|
||||
|
||||
guint8 opacity;
|
||||
guint8 shadow_opacity;
|
||||
|
||||
gchar * desc;
|
||||
|
||||
@@ -45,9 +60,16 @@ struct _MetaWindowActorPrivate
|
||||
/* A rectangular region with the unshaped extends of the window
|
||||
* texture */
|
||||
cairo_region_t *bounding_region;
|
||||
/* The region we should clip to when painting the shadow */
|
||||
cairo_region_t *shadow_clip;
|
||||
|
||||
/* Extracted size-invariant shape used for shadows */
|
||||
MetaWindowShape *shadow_shape;
|
||||
|
||||
gint freeze_count;
|
||||
|
||||
char * shadow_class;
|
||||
|
||||
/*
|
||||
* These need to be counters rather than flags, since more plugins
|
||||
* can implement same effect; the practicality of stacking effects
|
||||
@@ -70,7 +92,9 @@ struct _MetaWindowActorPrivate
|
||||
guint received_damage : 1;
|
||||
|
||||
guint needs_pixmap : 1;
|
||||
guint needs_reshape : 1;
|
||||
guint needs_reshape : 1;
|
||||
guint recompute_focused_shadow : 1;
|
||||
guint recompute_unfocused_shadow : 1;
|
||||
guint size_changed : 1;
|
||||
|
||||
guint needs_destroy : 1;
|
||||
@@ -87,8 +111,13 @@ enum
|
||||
PROP_X_WINDOW,
|
||||
PROP_X_WINDOW_ATTRIBUTES,
|
||||
PROP_NO_SHADOW,
|
||||
PROP_SHADOW_CLASS
|
||||
};
|
||||
|
||||
#define DEFAULT_SHADOW_RADIUS 12
|
||||
#define DEFAULT_SHADOW_X_OFFSET 0
|
||||
#define DEFAULT_SHADOW_Y_OFFSET 8
|
||||
|
||||
static void meta_window_actor_dispose (GObject *object);
|
||||
static void meta_window_actor_finalize (GObject *object);
|
||||
static void meta_window_actor_constructed (GObject *object);
|
||||
@@ -101,11 +130,18 @@ static void meta_window_actor_get_property (GObject *object,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void meta_window_actor_paint (ClutterActor *actor);
|
||||
#if CLUTTER_CHECK_VERSION(1, 5, 2)
|
||||
static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume);
|
||||
#endif
|
||||
|
||||
static void meta_window_actor_detach (MetaWindowActor *self);
|
||||
static gboolean meta_window_actor_has_shadow (MetaWindowActor *self);
|
||||
|
||||
static void meta_window_actor_clear_shape_region (MetaWindowActor *self);
|
||||
static void meta_window_actor_clear_bounding_region (MetaWindowActor *self);
|
||||
static void meta_window_actor_clear_shadow_clip (MetaWindowActor *self);
|
||||
|
||||
static gboolean is_shaped (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
@@ -161,6 +197,7 @@ static void
|
||||
meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaWindowActorPrivate));
|
||||
@@ -171,6 +208,11 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
object_class->get_property = meta_window_actor_get_property;
|
||||
object_class->constructed = meta_window_actor_constructed;
|
||||
|
||||
actor_class->paint = meta_window_actor_paint;
|
||||
#if CLUTTER_CHECK_VERSION(1, 5, 2)
|
||||
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
||||
#endif
|
||||
|
||||
pspec = g_param_spec_object ("meta-window",
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
@@ -216,11 +258,21 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
"No shadow",
|
||||
"Do not add shaddow to this window",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NO_SHADOW,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_string ("shadow-class",
|
||||
"Name of the shadow class for this window.",
|
||||
"NULL means to use the default shadow class for this window type",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SHADOW_CLASS,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -232,6 +284,7 @@ meta_window_actor_init (MetaWindowActor *self)
|
||||
META_TYPE_WINDOW_ACTOR,
|
||||
MetaWindowActorPrivate);
|
||||
priv->opacity = 0xff;
|
||||
priv->shadow_class = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -272,7 +325,7 @@ window_decorated_notify (MetaWindow *mw,
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XDamageDestroy (xdisplay, priv->damage);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
priv->damage = None;
|
||||
}
|
||||
|
||||
@@ -291,18 +344,6 @@ window_decorated_notify (MetaWindow *mw,
|
||||
|
||||
g_object_set (self, "x-window-attributes", &attrs, NULL);
|
||||
|
||||
if (priv->shadow)
|
||||
{
|
||||
ClutterActor *p = clutter_actor_get_parent (priv->shadow);
|
||||
|
||||
if (CLUTTER_IS_CONTAINER (p))
|
||||
clutter_container_remove_actor (CLUTTER_CONTAINER (p), priv->shadow);
|
||||
else
|
||||
clutter_actor_unparent (priv->shadow);
|
||||
|
||||
priv->shadow = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recreate the contents.
|
||||
*/
|
||||
@@ -344,13 +385,6 @@ meta_window_actor_constructed (GObject *object)
|
||||
|
||||
meta_window_actor_update_opacity (self);
|
||||
|
||||
if (meta_window_actor_has_shadow (self))
|
||||
{
|
||||
priv->shadow = meta_create_shadow_frame (compositor);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->shadow);
|
||||
}
|
||||
|
||||
if (!priv->actor)
|
||||
{
|
||||
priv->actor = meta_shaped_texture_new ();
|
||||
@@ -406,12 +440,37 @@ meta_window_actor_dispose (GObject *object)
|
||||
|
||||
meta_window_actor_clear_shape_region (self);
|
||||
meta_window_actor_clear_bounding_region (self);
|
||||
meta_window_actor_clear_shadow_clip (self);
|
||||
|
||||
if (priv->shadow_class != NULL)
|
||||
{
|
||||
g_free (priv->shadow_class);
|
||||
priv->shadow_class = NULL;
|
||||
}
|
||||
|
||||
if (priv->focused_shadow != NULL)
|
||||
{
|
||||
meta_shadow_unref (priv->focused_shadow);
|
||||
priv->focused_shadow = NULL;
|
||||
}
|
||||
|
||||
if (priv->unfocused_shadow != NULL)
|
||||
{
|
||||
meta_shadow_unref (priv->unfocused_shadow);
|
||||
priv->unfocused_shadow = NULL;
|
||||
}
|
||||
|
||||
if (priv->shadow_shape != NULL)
|
||||
{
|
||||
meta_window_shape_unref (priv->shadow_shape);
|
||||
priv->shadow_shape = NULL;
|
||||
}
|
||||
|
||||
if (priv->damage != None)
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XDamageDestroy (xdisplay, priv->damage);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
priv->damage = None;
|
||||
}
|
||||
@@ -463,36 +522,27 @@ meta_window_actor_set_property (GObject *object,
|
||||
break;
|
||||
case PROP_NO_SHADOW:
|
||||
{
|
||||
gboolean oldv = priv->no_shadow ? TRUE : FALSE;
|
||||
gboolean newv = g_value_get_boolean (value);
|
||||
|
||||
if (oldv == newv)
|
||||
if (newv == priv->no_shadow)
|
||||
return;
|
||||
|
||||
priv->no_shadow = newv;
|
||||
|
||||
if (newv && priv->shadow)
|
||||
{
|
||||
clutter_container_remove_actor (CLUTTER_CONTAINER (object),
|
||||
priv->shadow);
|
||||
priv->shadow = NULL;
|
||||
}
|
||||
else if (!newv && !priv->shadow && meta_window_actor_has_shadow (self))
|
||||
{
|
||||
gfloat w, h;
|
||||
MetaDisplay *display = meta_screen_get_display (priv->screen);
|
||||
MetaCompositor *compositor;
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
break;
|
||||
case PROP_SHADOW_CLASS:
|
||||
{
|
||||
const char *newv = g_value_get_string (value);
|
||||
|
||||
compositor = meta_display_get_compositor (display);
|
||||
if (g_strcmp0 (newv, priv->shadow_class) == 0)
|
||||
return;
|
||||
|
||||
clutter_actor_get_size (CLUTTER_ACTOR (self), &w, &h);
|
||||
g_free (priv->shadow_class);
|
||||
priv->shadow_class = g_strdup (newv);
|
||||
|
||||
priv->shadow = meta_create_shadow_frame (compositor);
|
||||
|
||||
clutter_actor_set_size (priv->shadow, w, h);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->shadow);
|
||||
}
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -526,12 +576,164 @@ meta_window_actor_get_property (GObject *object,
|
||||
case PROP_NO_SHADOW:
|
||||
g_value_set_boolean (value, priv->no_shadow);
|
||||
break;
|
||||
case PROP_SHADOW_CLASS:
|
||||
g_value_set_string (value, priv->shadow_class);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
meta_window_actor_get_shadow_class (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->shadow_class != NULL)
|
||||
return priv->shadow_class;
|
||||
else
|
||||
{
|
||||
MetaWindowType window_type = meta_window_get_window_type (priv->window);
|
||||
|
||||
switch (window_type)
|
||||
{
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
return "dropdown-menu";
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
return "popup-menu";
|
||||
default:
|
||||
{
|
||||
MetaFrameType frame_type = meta_window_get_frame_type (priv->window);
|
||||
return meta_frame_type_to_string (frame_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_get_shadow_params (MetaWindowActor *self,
|
||||
gboolean appears_focused,
|
||||
MetaShadowParams *params)
|
||||
{
|
||||
const char *shadow_class = meta_window_actor_get_shadow_class (self);
|
||||
|
||||
meta_shadow_factory_get_params (meta_shadow_factory_get_default (),
|
||||
shadow_class, appears_focused,
|
||||
params);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
cairo_rectangle_int_t *bounds)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
/* We need to be defensive here because there are corner cases
|
||||
* where getting the shape fails on a window being destroyed
|
||||
* and similar.
|
||||
*/
|
||||
if (priv->shaped && priv->shape_region)
|
||||
cairo_region_get_extents (priv->shape_region, bounds);
|
||||
else if (priv->bounding_region)
|
||||
cairo_region_get_extents (priv->bounding_region, bounds);
|
||||
else
|
||||
bounds->x = bounds->y = bounds->width = bounds->height = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_get_shadow_bounds (MetaWindowActor *self,
|
||||
gboolean appears_focused,
|
||||
cairo_rectangle_int_t *bounds)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow;
|
||||
cairo_rectangle_int_t shape_bounds;
|
||||
MetaShadowParams params;
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||
|
||||
meta_shadow_get_bounds (shadow,
|
||||
params.x_offset + shape_bounds.x,
|
||||
params.y_offset + shape_bounds.y,
|
||||
shape_bounds.width,
|
||||
shape_bounds.height,
|
||||
bounds);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_paint (ClutterActor *actor)
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow;
|
||||
|
||||
if (shadow != NULL)
|
||||
{
|
||||
MetaShadowParams params;
|
||||
cairo_rectangle_int_t shape_bounds;
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||
|
||||
meta_shadow_paint (shadow,
|
||||
params.x_offset + shape_bounds.x,
|
||||
params.y_offset + shape_bounds.y,
|
||||
shape_bounds.width,
|
||||
shape_bounds.height,
|
||||
(clutter_actor_get_paint_opacity (actor) * params.opacity) / 255,
|
||||
priv->shadow_clip);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
|
||||
}
|
||||
|
||||
#if CLUTTER_CHECK_VERSION(1, 5, 2)
|
||||
static gboolean
|
||||
meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t bounds;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
ClutterVertex origin;
|
||||
|
||||
/* The paint volume is computed before paint functions are called
|
||||
* so our bounds might not be updated yet. Force an update. */
|
||||
meta_window_actor_pre_paint (self);
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &bounds);
|
||||
|
||||
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
|
||||
{
|
||||
cairo_rectangle_int_t shadow_bounds;
|
||||
|
||||
/* We could compute an full clip region as we do for the window
|
||||
* texture, but the shadow is relatively cheap to draw, and
|
||||
* a little more complex to clip, so we just catch the case where
|
||||
* the shadow is completely obscured and doesn't need to be drawn
|
||||
* at all.
|
||||
*/
|
||||
|
||||
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
|
||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||
}
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
origin.z = 0.0f;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
|
||||
clutter_paint_volume_set_width (volume, bounds.width);
|
||||
clutter_paint_volume_set_height (volume, bounds.height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* CLUTTER_CHECK_VERSION */
|
||||
|
||||
static gboolean
|
||||
is_shaped (MetaDisplay *display, Window xwindow)
|
||||
{
|
||||
@@ -560,10 +762,16 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
if (priv->no_shadow)
|
||||
return FALSE;
|
||||
|
||||
/* Leaving out shadows for maximized and fullscreen windows is an effeciency
|
||||
* win and also prevents the unsightly effect of the shadow of maximized
|
||||
* window appearing on an adjacent window */
|
||||
if ((meta_window_get_maximized (priv->window) == (META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL)) ||
|
||||
meta_window_is_fullscreen (priv->window))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Always put a shadow around windows with a frame - This should override
|
||||
* the restriction about not putting a shadow around shaped windows
|
||||
* as the frame might be the reason the window is shaped
|
||||
* the restriction about not putting a shadow around ARGB windows.
|
||||
*/
|
||||
if (priv->window)
|
||||
{
|
||||
@@ -576,7 +784,8 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not add shadows to ARGB windows (since they are probably transparent)
|
||||
* Do not add shadows to ARGB windows; eventually we should generate a
|
||||
* shadow from the input shape for such windows.
|
||||
*/
|
||||
if (priv->argb32 || priv->opacity != 0xff)
|
||||
{
|
||||
@@ -585,19 +794,8 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Never put a shadow around shaped windows
|
||||
*/
|
||||
if (priv->shaped)
|
||||
{
|
||||
meta_verbose ("Window 0x%x has no shadow as it is shaped\n",
|
||||
(guint)priv->xwindow);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add shadows to override redirect windows (e.g., Gtk menus).
|
||||
* This must have lower priority than window shape test.
|
||||
*/
|
||||
if (priv->attrs.override_redirect)
|
||||
{
|
||||
@@ -1358,6 +1556,18 @@ meta_window_actor_clear_bounding_region (MetaWindowActor *self)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_clear_shadow_clip (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->shadow_clip)
|
||||
{
|
||||
cairo_region_destroy (priv->shadow_clip);
|
||||
priv->shadow_clip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_update_bounding_region (MetaWindowActor *self,
|
||||
int width,
|
||||
@@ -1366,9 +1576,26 @@ meta_window_actor_update_bounding_region (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t bounding_rectangle = { 0, 0, width, height };
|
||||
|
||||
if (priv->bounding_region != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t old_bounding_rectangle;
|
||||
cairo_region_get_extents (priv->bounding_region, &old_bounding_rectangle);
|
||||
|
||||
if (old_bounding_rectangle.width == width && old_bounding_rectangle.height == height)
|
||||
return;
|
||||
}
|
||||
|
||||
meta_window_actor_clear_bounding_region (self);
|
||||
|
||||
priv->bounding_region = cairo_region_create_rectangle (&bounding_rectangle);
|
||||
|
||||
/* When we're shaped, we use the shape region to generate the shadow; the shape
|
||||
* region only changes when we get ShapeNotify event; but for unshaped windows
|
||||
* we generate the shadow from the bounding region, so we need to recompute
|
||||
* the shadow when the size changes.
|
||||
*/
|
||||
if (!priv->shaped)
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1497,30 +1724,12 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
|
||||
if (priv->shadow)
|
||||
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
|
||||
{
|
||||
cairo_rectangle_int_t shadow_rect;
|
||||
ClutterActorBox box;
|
||||
cairo_region_overlap_t overlap;
|
||||
|
||||
/* We could compute an full clip region as we do for the window
|
||||
* texture, but the shadow is relatively cheap to draw, and
|
||||
* a little more complex to clip, so we just catch the case where
|
||||
* the shadow is completely obscured and doesn't need to be drawn
|
||||
* at all.
|
||||
*/
|
||||
clutter_actor_get_allocation_box (priv->shadow, &box);
|
||||
|
||||
shadow_rect.x = roundf (box.x1);
|
||||
shadow_rect.y = roundf (box.y1);
|
||||
shadow_rect.width = roundf (box.x2 - box.x1);
|
||||
shadow_rect.height = roundf (box.y2 - box.y1);
|
||||
|
||||
overlap = cairo_region_contains_rectangle (beneath_region, &shadow_rect);
|
||||
|
||||
tidy_texture_frame_set_needs_paint (TIDY_TEXTURE_FRAME (priv->shadow),
|
||||
overlap != CAIRO_REGION_OVERLAP_OUT);
|
||||
meta_window_actor_clear_shadow_clip (self);
|
||||
priv->shadow_clip = cairo_region_copy (beneath_region);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1538,8 +1747,7 @@ meta_window_actor_reset_visible_regions (MetaWindowActor *self)
|
||||
|
||||
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
||||
NULL);
|
||||
if (priv->shadow)
|
||||
tidy_texture_frame_set_needs_paint (TIDY_TEXTURE_FRAME (priv->shadow), TRUE);
|
||||
meta_window_actor_clear_shadow_clip (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1582,7 +1790,7 @@ check_needs_pixmap (MetaWindowActor *self)
|
||||
|
||||
priv->back_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
/* Probably a BadMatch if the window isn't viewable; we could
|
||||
* GrabServer/GetWindowAttributes/NameWindowPixmap/UngrabServer/Sync
|
||||
@@ -1622,19 +1830,87 @@ check_needs_pixmap (MetaWindowActor *self)
|
||||
"pixmap-height", &pxm_height,
|
||||
NULL);
|
||||
|
||||
if (priv->shadow)
|
||||
clutter_actor_set_size (priv->shadow, pxm_width, pxm_height);
|
||||
|
||||
meta_window_actor_update_bounding_region (self, pxm_width, pxm_height);
|
||||
|
||||
full = TRUE;
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
priv->needs_pixmap = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
check_needs_shadow (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaShadow *old_shadow = NULL;
|
||||
MetaShadow **shadow_location;
|
||||
gboolean recompute_shadow;
|
||||
gboolean should_have_shadow;
|
||||
gboolean appears_focused;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
/* Calling meta_window_actor_has_shadow() here at every pre-paint is cheap
|
||||
* and avoids the need to explicitly handle window type changes, which
|
||||
* we would do if tried to keep track of when we might be adding or removing
|
||||
* a shadow more explicitly. We only keep track of changes to the *shape* of
|
||||
* the shadow with priv->recompute_shadow.
|
||||
*/
|
||||
|
||||
should_have_shadow = meta_window_actor_has_shadow (self);
|
||||
appears_focused = meta_window_appears_focused (priv->window);
|
||||
|
||||
if (appears_focused)
|
||||
{
|
||||
recompute_shadow = priv->recompute_focused_shadow;
|
||||
priv->recompute_focused_shadow = FALSE;
|
||||
shadow_location = &priv->focused_shadow;
|
||||
}
|
||||
else
|
||||
{
|
||||
recompute_shadow = priv->recompute_unfocused_shadow;
|
||||
priv->recompute_unfocused_shadow = FALSE;
|
||||
shadow_location = &priv->unfocused_shadow;
|
||||
}
|
||||
|
||||
if (!should_have_shadow || recompute_shadow)
|
||||
{
|
||||
if (*shadow_location != NULL)
|
||||
{
|
||||
old_shadow = *shadow_location;
|
||||
*shadow_location = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (*shadow_location == NULL && should_have_shadow)
|
||||
{
|
||||
MetaShadowFactory *factory = meta_shadow_factory_get_default ();
|
||||
const char *shadow_class = meta_window_actor_get_shadow_class (self);
|
||||
cairo_rectangle_int_t shape_bounds;
|
||||
|
||||
if (priv->shadow_shape == NULL)
|
||||
{
|
||||
if (priv->shaped)
|
||||
priv->shadow_shape = meta_window_shape_new (priv->shape_region);
|
||||
else
|
||||
priv->shadow_shape = meta_window_shape_new (priv->bounding_region);
|
||||
}
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||
|
||||
*shadow_location = meta_shadow_factory_get_shadow (factory,
|
||||
priv->shadow_shape,
|
||||
shape_bounds.width, shape_bounds.height,
|
||||
shadow_class, appears_focused);
|
||||
}
|
||||
|
||||
if (old_shadow != NULL)
|
||||
meta_shadow_unref (old_shadow);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_frozen (MetaWindowActor *self)
|
||||
{
|
||||
@@ -1718,7 +1994,7 @@ check_needs_reshape (MetaWindowActor *self)
|
||||
ShapeBounding,
|
||||
&n_rects,
|
||||
&ordering);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (rects)
|
||||
{
|
||||
@@ -1733,6 +2009,7 @@ check_needs_reshape (MetaWindowActor *self)
|
||||
#endif
|
||||
|
||||
priv->needs_reshape = FALSE;
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1743,6 +2020,11 @@ meta_window_actor_update_shape (MetaWindowActor *self,
|
||||
|
||||
priv->shaped = shaped;
|
||||
priv->needs_reshape = TRUE;
|
||||
if (priv->shadow_shape != NULL)
|
||||
{
|
||||
meta_window_shape_unref (priv->shadow_shape);
|
||||
priv->shadow_shape = NULL;
|
||||
}
|
||||
|
||||
clutter_actor_queue_redraw (priv->actor);
|
||||
}
|
||||
@@ -1766,12 +2048,23 @@ meta_window_actor_pre_paint (MetaWindowActor *self)
|
||||
{
|
||||
meta_error_trap_push (display);
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
check_needs_reshape (self);
|
||||
check_needs_pixmap (self);
|
||||
check_needs_reshape (self);
|
||||
check_needs_shadow (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_invalidate_shadow (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
priv->recompute_focused_shadow = TRUE;
|
||||
priv->recompute_unfocused_shadow = TRUE;
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
253
src/compositor/meta-window-shape.c
Normal file
253
src/compositor/meta-window-shape.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MetaWindowShape
|
||||
*
|
||||
* Extracted invariant window shape
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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 <string.h>
|
||||
|
||||
#include "meta-window-shape.h"
|
||||
#include "region-utils.h"
|
||||
|
||||
struct _MetaWindowShape
|
||||
{
|
||||
guint ref_count;
|
||||
|
||||
int top, right, bottom, left;
|
||||
int n_rectangles;
|
||||
cairo_rectangle_int_t *rectangles;
|
||||
guint hash;
|
||||
};
|
||||
|
||||
MetaWindowShape *
|
||||
meta_window_shape_new (cairo_region_t *region)
|
||||
{
|
||||
MetaWindowShape *shape;
|
||||
MetaRegionIterator iter;
|
||||
cairo_rectangle_int_t extents;
|
||||
int max_yspan_y1 = 0;
|
||||
int max_yspan_y2 = 0;
|
||||
int max_xspan_x1 = -1;
|
||||
int max_xspan_x2 = -1;
|
||||
guint hash;
|
||||
|
||||
shape = g_slice_new0 (MetaWindowShape);
|
||||
shape->ref_count = 1;
|
||||
|
||||
cairo_region_get_extents (region, &extents);
|
||||
|
||||
shape->n_rectangles = cairo_region_num_rectangles (region);
|
||||
|
||||
if (shape->n_rectangles == 0)
|
||||
{
|
||||
shape->rectangles = NULL;
|
||||
shape->top = shape->right = shape->bottom = shape->left = 0;
|
||||
shape->hash = 0;
|
||||
return shape;
|
||||
}
|
||||
|
||||
for (meta_region_iterator_init (&iter, region);
|
||||
!meta_region_iterator_at_end (&iter);
|
||||
meta_region_iterator_next (&iter))
|
||||
{
|
||||
int max_line_xspan_x1 = -1;
|
||||
int max_line_xspan_x2 = -1;
|
||||
|
||||
if (iter.rectangle.width > max_line_xspan_x2 - max_line_xspan_x1)
|
||||
{
|
||||
max_line_xspan_x1 = iter.rectangle.x;
|
||||
max_line_xspan_x2 = iter.rectangle.x + iter.rectangle.width;
|
||||
}
|
||||
|
||||
if (iter.line_end)
|
||||
{
|
||||
if (iter.rectangle.height > max_yspan_y2 - max_yspan_y1)
|
||||
{
|
||||
max_yspan_y1 = iter.rectangle.y;
|
||||
max_yspan_y2 = iter.rectangle.y + iter.rectangle.height;
|
||||
}
|
||||
|
||||
if (max_xspan_x1 < 0) /* First line */
|
||||
{
|
||||
max_xspan_x1 = max_line_xspan_x1;
|
||||
max_xspan_x2 = max_line_xspan_x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_xspan_x1 = MAX (max_xspan_x1, max_line_xspan_x1);
|
||||
max_xspan_x2 = MIN (max_xspan_x2, max_line_xspan_x2);
|
||||
|
||||
if (max_xspan_x2 < max_xspan_x1)
|
||||
max_xspan_x2 = max_xspan_x1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
g_print ("xspan: %d -> %d, yspan: %d -> %d\n",
|
||||
max_xspan_x1, max_xspan_x2,
|
||||
max_yspan_y1, max_yspan_y2);
|
||||
#endif
|
||||
|
||||
shape->top = max_yspan_y1 - extents.y;
|
||||
shape->right = extents.x + extents.width - max_xspan_x2;
|
||||
shape->bottom = extents.y + extents.height - max_yspan_y2;
|
||||
shape->left = max_xspan_x1 - extents.x;
|
||||
|
||||
shape->rectangles = g_new (cairo_rectangle_int_t, shape->n_rectangles);
|
||||
|
||||
hash = 0;
|
||||
for (meta_region_iterator_init (&iter, region);
|
||||
!meta_region_iterator_at_end (&iter);
|
||||
meta_region_iterator_next (&iter))
|
||||
{
|
||||
int x1, x2, y1, y2;
|
||||
|
||||
x1 = iter.rectangle.x;
|
||||
x2 = iter.rectangle.x + iter.rectangle.width;
|
||||
y1 = iter.rectangle.y;
|
||||
y2 = iter.rectangle.y + iter.rectangle.height;
|
||||
|
||||
if (x1 > max_xspan_x1)
|
||||
x1 -= MIN (x1, max_xspan_x2 - 1) - max_xspan_x1;
|
||||
if (x2 > max_xspan_x1)
|
||||
x2 -= MIN (x2, max_xspan_x2 - 1) - max_xspan_x1;
|
||||
if (y1 > max_yspan_y1)
|
||||
y1 -= MIN (y1, max_yspan_y2 - 1) - max_yspan_y1;
|
||||
if (y2 > max_yspan_y1)
|
||||
y2 -= MIN (y2, max_yspan_y2 - 1) - max_yspan_y1;
|
||||
|
||||
shape->rectangles[iter.i].x = x1 - extents.x;
|
||||
shape->rectangles[iter.i].y = y1 - extents.y;
|
||||
shape->rectangles[iter.i].width = x2 - x1;
|
||||
shape->rectangles[iter.i].height = y2 - y1;
|
||||
|
||||
#if 0
|
||||
g_print ("%d: +%d+%dx%dx%d => +%d+%dx%dx%d\n",
|
||||
i, iter.rectangle.x, iter.rectangle.y, iter.rectangle.width, iter.rectangle.height,
|
||||
shape->rectangles[i].x, shape->rectangles[i].y, shape->rectangles[i].width, shape->rectangles[i].height);
|
||||
#endif
|
||||
|
||||
hash = hash * 31 + x1 * 17 + x2 * 27 + y1 * 37 + y2 * 43;
|
||||
}
|
||||
|
||||
shape->hash = hash;
|
||||
|
||||
#if 0
|
||||
g_print ("%d %d %d %d: %#x\n\n", shape->top, shape->right, shape->bottom, shape->left, shape->hash);
|
||||
#endif
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
MetaWindowShape *
|
||||
meta_window_shape_ref (MetaWindowShape *shape)
|
||||
{
|
||||
shape->ref_count++;
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_shape_unref (MetaWindowShape *shape)
|
||||
{
|
||||
shape->ref_count--;
|
||||
if (shape->ref_count == 0)
|
||||
{
|
||||
g_free (shape->rectangles);
|
||||
g_slice_free (MetaWindowShape, shape);
|
||||
}
|
||||
}
|
||||
|
||||
guint
|
||||
meta_window_shape_hash (MetaWindowShape *shape)
|
||||
{
|
||||
return shape->hash;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_shape_equal (MetaWindowShape *shape_a,
|
||||
MetaWindowShape *shape_b)
|
||||
{
|
||||
if (shape_a->n_rectangles != shape_b->n_rectangles)
|
||||
return FALSE;
|
||||
|
||||
return memcmp (shape_a->rectangles, shape_b->rectangles,
|
||||
sizeof (cairo_rectangle_int_t) * shape_a->n_rectangles) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_shape_get_borders (MetaWindowShape *shape,
|
||||
int *border_top,
|
||||
int *border_right,
|
||||
int *border_bottom,
|
||||
int *border_left)
|
||||
{
|
||||
if (border_top)
|
||||
*border_top = shape->top;
|
||||
if (border_right)
|
||||
*border_right = shape->right;
|
||||
if (border_bottom)
|
||||
*border_bottom = shape->bottom;
|
||||
if (border_left)
|
||||
*border_left = shape->left;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_shape_to_region:
|
||||
* @shape: a #MetaWindowShape
|
||||
* @center_width: size of the central region horizontally
|
||||
* @center_height: size of the central region vertically
|
||||
*
|
||||
* Converts the shape to to a cairo_region_t using the given width
|
||||
* and height for the central scaled region.
|
||||
*
|
||||
* Return value: a newly created region
|
||||
*/
|
||||
cairo_region_t *
|
||||
meta_window_shape_to_region (MetaWindowShape *shape,
|
||||
int center_width,
|
||||
int center_height)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
int i;
|
||||
|
||||
region = cairo_region_create ();
|
||||
|
||||
for (i = 0; i < shape->n_rectangles; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect = shape->rectangles[i];
|
||||
|
||||
if (rect.x <= shape->left && rect.x + rect.width >= shape->left + 1)
|
||||
rect.width += center_width;
|
||||
else if (rect.x >= shape->left + 1)
|
||||
rect.x += center_width;
|
||||
|
||||
if (rect.y <= shape->top && rect.y + rect.height >= shape->top + 1)
|
||||
rect.height += center_height;
|
||||
else if (rect.y >= shape->top + 1)
|
||||
rect.y += center_height;
|
||||
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
60
src/compositor/meta-window-shape.h
Normal file
60
src/compositor/meta-window-shape.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MetaWindowShape
|
||||
*
|
||||
* Extracted invariant window shape
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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_WINDOW_SHAPE_H__
|
||||
#define __META_WINDOW_SHAPE_H__
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* MetaWindowShape:
|
||||
* #MetaWindowShape represents a 9-sliced region with borders on all sides that
|
||||
* are unscaled, and a constant central region that is scaled. For example,
|
||||
* if you the regions representing two windows that around rounded rectangles,
|
||||
* with the same corner regions, but different sizes, they have the
|
||||
* same MetaWindowShape.
|
||||
*
|
||||
* #MetaWindowShape is designed to be used as part of a hash table key, so has
|
||||
* efficient hash and equal functions.
|
||||
*/
|
||||
typedef struct _MetaWindowShape MetaWindowShape;
|
||||
|
||||
MetaWindowShape * meta_window_shape_new (cairo_region_t *region);
|
||||
MetaWindowShape * meta_window_shape_ref (MetaWindowShape *shape);
|
||||
void meta_window_shape_unref (MetaWindowShape *shape);
|
||||
guint meta_window_shape_hash (MetaWindowShape *shape);
|
||||
gboolean meta_window_shape_equal (MetaWindowShape *shape_a,
|
||||
MetaWindowShape *shape_b);
|
||||
void meta_window_shape_get_borders (MetaWindowShape *shape,
|
||||
int *border_top,
|
||||
int *border_right,
|
||||
int *border_bottom,
|
||||
int *border_left);
|
||||
cairo_region_t *meta_window_shape_to_region (MetaWindowShape *shape,
|
||||
int center_width,
|
||||
int center_height);
|
||||
|
||||
#endif /* __META_WINDOW_SHAPE_H __*/
|
||||
|
||||
334
src/compositor/region-utils.c
Normal file
334
src/compositor/region-utils.c
Normal file
@@ -0,0 +1,334 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for region manipulation
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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 "region-utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* MetaRegionBuilder */
|
||||
|
||||
/* Various algorithms in this file require unioning together a set of rectangles
|
||||
* that are unsorted or overlap; unioning such a set of rectangles 1-by-1
|
||||
* using cairo_region_union_rectangle() produces O(N^2) behavior (if the union
|
||||
* adds or removes rectangles in the middle of the region, then it has to
|
||||
* move all the rectangles after that.) To avoid this behavior, MetaRegionBuilder
|
||||
* creates regions for small groups of rectangles and merges them together in
|
||||
* a binary tree.
|
||||
*
|
||||
* Possible improvement: From a glance at the code, accumulating all the rectangles
|
||||
* into a flat array and then calling the (not usefully documented)
|
||||
* cairo_region_create_rectangles() would have the same behavior and would be
|
||||
* simpler and a bit more efficient.
|
||||
*/
|
||||
|
||||
/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
|
||||
* But using 8 may be more robust to systems with slow malloc(). */
|
||||
#define MAX_CHUNK_RECTANGLES 8
|
||||
#define MAX_LEVELS 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* To merge regions in a binary tree, we need to keep track of The way these are filled is in the pattern:
|
||||
*
|
||||
* |a |
|
||||
* |b |a |
|
||||
* |c | |ab |
|
||||
* |d |c |ab |
|
||||
* |e | | |abcd|
|
||||
*/
|
||||
cairo_region_t *levels[MAX_LEVELS];
|
||||
int n_levels;
|
||||
} MetaRegionBuilder;
|
||||
|
||||
static void
|
||||
meta_region_builder_init (MetaRegionBuilder *builder)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_LEVELS; i++)
|
||||
builder->levels[i] = NULL;
|
||||
builder->n_levels = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int i;
|
||||
|
||||
if (builder->levels[0] == NULL)
|
||||
builder->levels[0] = cairo_region_create ();
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
cairo_region_union_rectangle (builder->levels[0], &rect);
|
||||
if (cairo_region_num_rectangles (builder->levels[0]) >= MAX_CHUNK_RECTANGLES)
|
||||
{
|
||||
for (i = 1; i < builder->n_levels + 1; i++)
|
||||
{
|
||||
if (builder->levels[i] == NULL)
|
||||
{
|
||||
if (i < MAX_LEVELS)
|
||||
{
|
||||
builder->levels[i] = builder->levels[i - 1];
|
||||
builder->levels[i - 1] = NULL;
|
||||
if (i == builder->n_levels)
|
||||
builder->n_levels++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_region_union (builder->levels[i], builder->levels[i - 1]);
|
||||
cairo_region_destroy (builder->levels[i - 1]);
|
||||
builder->levels[i - 1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
meta_region_builder_finish (MetaRegionBuilder *builder)
|
||||
{
|
||||
cairo_region_t *result = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < builder->n_levels; i++)
|
||||
{
|
||||
if (builder->levels[i])
|
||||
{
|
||||
if (result == NULL)
|
||||
result = builder->levels[i];
|
||||
else
|
||||
{
|
||||
cairo_region_union(result, builder->levels[i]);
|
||||
cairo_region_destroy (builder->levels[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
result = cairo_region_create ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* MetaRegionIterator */
|
||||
|
||||
void
|
||||
meta_region_iterator_init (MetaRegionIterator *iter,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
iter->region = region;
|
||||
iter->i = 0;
|
||||
iter->n_rectangles = cairo_region_num_rectangles (region);
|
||||
iter->line_start = TRUE;
|
||||
|
||||
if (iter->n_rectangles > 1)
|
||||
{
|
||||
cairo_region_get_rectangle (region, 0, &iter->rectangle);
|
||||
cairo_region_get_rectangle (region, 1, &iter->next_rectangle);
|
||||
|
||||
iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
|
||||
}
|
||||
else if (iter->n_rectangles > 0)
|
||||
{
|
||||
cairo_region_get_rectangle (region, 0, &iter->rectangle);
|
||||
iter->line_end = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_region_iterator_at_end (MetaRegionIterator *iter)
|
||||
{
|
||||
return iter->i >= iter->n_rectangles;
|
||||
}
|
||||
|
||||
void
|
||||
meta_region_iterator_next (MetaRegionIterator *iter)
|
||||
{
|
||||
iter->i++;
|
||||
iter->rectangle = iter->next_rectangle;
|
||||
iter->line_start = iter->line_end;
|
||||
|
||||
if (iter->i < iter->n_rectangles)
|
||||
{
|
||||
cairo_region_get_rectangle (iter->region, iter->i + 1, &iter->next_rectangle);
|
||||
iter->line_end = iter->next_rectangle.y != iter->rectangle.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->line_end = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_expanded_rect (MetaRegionBuilder *builder,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
int x_amount,
|
||||
int y_amount,
|
||||
gboolean flip)
|
||||
{
|
||||
if (flip)
|
||||
meta_region_builder_add_rectangle (builder,
|
||||
y - y_amount, x - x_amount,
|
||||
height + 2 * y_amount, width + 2 * x_amount);
|
||||
else
|
||||
meta_region_builder_add_rectangle (builder,
|
||||
x - x_amount, y - y_amount,
|
||||
width + 2 * x_amount, height + 2 * y_amount);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
expand_region (cairo_region_t *region,
|
||||
int x_amount,
|
||||
int y_amount,
|
||||
gboolean flip)
|
||||
{
|
||||
MetaRegionBuilder builder;
|
||||
int n;
|
||||
int i;
|
||||
|
||||
meta_region_builder_init (&builder);
|
||||
|
||||
n = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
add_expanded_rect (&builder,
|
||||
rect.x, rect.y, rect.width, rect.height,
|
||||
x_amount, y_amount, flip);
|
||||
}
|
||||
|
||||
return meta_region_builder_finish (&builder);
|
||||
}
|
||||
|
||||
/* This computes a (clipped version) of the inverse of the region
|
||||
* and expands it by the given amount */
|
||||
static cairo_region_t *
|
||||
expand_region_inverse (cairo_region_t *region,
|
||||
int x_amount,
|
||||
int y_amount,
|
||||
gboolean flip)
|
||||
{
|
||||
MetaRegionBuilder builder;
|
||||
MetaRegionIterator iter;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_region_t *chunk;
|
||||
|
||||
int last_x;
|
||||
|
||||
meta_region_builder_init (&builder);
|
||||
|
||||
cairo_region_get_extents (region, &extents);
|
||||
add_expanded_rect (&builder,
|
||||
extents.x, extents.y - 1, extents.width, 1,
|
||||
x_amount, y_amount, flip);
|
||||
add_expanded_rect (&builder,
|
||||
extents.x - 1, extents.y, 1, extents.height,
|
||||
x_amount, y_amount, flip);
|
||||
add_expanded_rect (&builder,
|
||||
extents.x + extents.width, extents.y, 1, extents.height,
|
||||
x_amount, y_amount, flip);
|
||||
add_expanded_rect (&builder,
|
||||
extents.x, extents.y + extents.height, extents.width, 1,
|
||||
x_amount, y_amount, flip);
|
||||
|
||||
chunk = NULL;
|
||||
|
||||
last_x = extents.x;
|
||||
for (meta_region_iterator_init (&iter, region);
|
||||
!meta_region_iterator_at_end (&iter);
|
||||
meta_region_iterator_next (&iter))
|
||||
{
|
||||
if (chunk == NULL)
|
||||
chunk = cairo_region_create ();
|
||||
|
||||
if (iter.rectangle.x > last_x)
|
||||
add_expanded_rect (&builder,
|
||||
last_x, iter.rectangle.y,
|
||||
iter.rectangle.x - last_x, iter.rectangle.height,
|
||||
x_amount, y_amount, flip);
|
||||
|
||||
if (iter.line_end)
|
||||
{
|
||||
if (extents.x + extents.width > iter.rectangle.x + iter.rectangle.width)
|
||||
add_expanded_rect (&builder,
|
||||
iter.rectangle.x + iter.rectangle.width, iter.rectangle.y,
|
||||
(extents.x + extents.width) - (iter.rectangle.x + iter.rectangle.width), iter.rectangle.height,
|
||||
x_amount, y_amount, flip);
|
||||
last_x = extents.x;
|
||||
}
|
||||
else
|
||||
last_x = iter.rectangle.x + iter.rectangle.width;
|
||||
}
|
||||
|
||||
return meta_region_builder_finish (&builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_make_border_region:
|
||||
* @region: a #cairo_region_t
|
||||
* @x_amount: distance from the border to extend horizontally
|
||||
* @y_amount: distance from the border to extend vertically
|
||||
* @flip: if true, the result is computed with x and y interchanged
|
||||
*
|
||||
* Computes the "border region" of a given region, which is roughly
|
||||
* speaking the set of points near the boundary of the region. If we
|
||||
* define the operation of growing a region as computing the set of
|
||||
* points within a given manhattan distance of the region, then the
|
||||
* border is 'grow(region) intersect grow(inverse(region))'.
|
||||
*
|
||||
* If we create an image by filling the region with a solid color,
|
||||
* the border is the region affected by blurring the region.
|
||||
*
|
||||
* Return value: a new region which is the border of the given region
|
||||
*/
|
||||
cairo_region_t *
|
||||
meta_make_border_region (cairo_region_t *region,
|
||||
int x_amount,
|
||||
int y_amount,
|
||||
gboolean flip)
|
||||
{
|
||||
cairo_region_t *border_region;
|
||||
cairo_region_t *inverse_region;
|
||||
|
||||
border_region = expand_region (region, x_amount, y_amount, flip);
|
||||
inverse_region = expand_region_inverse (region, x_amount, y_amount, flip);
|
||||
cairo_region_intersect (border_region, inverse_region);
|
||||
cairo_region_destroy (inverse_region);
|
||||
|
||||
return border_region;
|
||||
}
|
||||
76
src/compositor/region-utils.h
Normal file
76
src/compositor/region-utils.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Utilities for region manipulation
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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_REGION_UTILS_H__
|
||||
#define __META_REGION_UTILS_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* MetaRegionIterator:
|
||||
* @region: region being iterated
|
||||
* @rectangle: current rectangle
|
||||
* @line_start: whether the current rectangle starts a horizontal band
|
||||
* @line_end: whether the current rectangle ends a horizontal band
|
||||
*
|
||||
* cairo_region_t is a yx banded region; sometimes its useful to iterate through
|
||||
* such a region treating the start and end of each horizontal band in a distinct
|
||||
* fashion.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* MetaRegionIterator iter;
|
||||
* for (meta_region_iterator_init (&iter, region);
|
||||
* !meta_region_iterator_at_end (&iter);
|
||||
* meta_region_iterator_next (&iter))
|
||||
* {
|
||||
* [ Use iter.rectangle, iter.line_start, iter.line_end ]
|
||||
* }
|
||||
*/
|
||||
typedef struct _MetaRegionIterator MetaRegionIterator;
|
||||
|
||||
struct _MetaRegionIterator {
|
||||
cairo_region_t *region;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
gboolean line_start;
|
||||
gboolean line_end;
|
||||
int i;
|
||||
|
||||
/*< private >*/
|
||||
int n_rectangles;
|
||||
cairo_rectangle_int_t next_rectangle;
|
||||
};
|
||||
|
||||
void meta_region_iterator_init (MetaRegionIterator *iter,
|
||||
cairo_region_t *region);
|
||||
gboolean meta_region_iterator_at_end (MetaRegionIterator *iter);
|
||||
void meta_region_iterator_next (MetaRegionIterator *iter);
|
||||
|
||||
cairo_region_t *meta_make_border_region (cairo_region_t *region,
|
||||
int x_amount,
|
||||
int y_amount,
|
||||
gboolean flip);
|
||||
|
||||
#endif /* __META_REGION_UTILS_H__ */
|
||||
@@ -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 *
|
||||
meta_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;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef SHADOW_H
|
||||
#define SHADOW_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include "compositor.h"
|
||||
|
||||
ClutterActor *meta_create_shadow_frame (MetaCompositor *compositor);
|
||||
|
||||
#endif /* SHADOW_H */
|
||||
@@ -1,641 +0,0 @@
|
||||
/* tidy-texture-frame.h: Expandible texture actor
|
||||
*
|
||||
* Copyright (C) 2007 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:tidy-texture-frame
|
||||
* @short_description: Stretch a texture to fit the entire allocation
|
||||
*
|
||||
* #TidyTextureFrame
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "tidy-texture-frame.h"
|
||||
|
||||
#define TIDY_PARAM_READABLE \
|
||||
(G_PARAM_READABLE | \
|
||||
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||
|
||||
#define TIDY_PARAM_READWRITE \
|
||||
(G_PARAM_READABLE | G_PARAM_WRITABLE | \
|
||||
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_PARENT_TEXTURE,
|
||||
|
||||
PROP_LEFT,
|
||||
PROP_TOP,
|
||||
PROP_RIGHT,
|
||||
PROP_BOTTOM
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (TidyTextureFrame, tidy_texture_frame, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate))
|
||||
|
||||
struct _TidyTextureFramePrivate
|
||||
{
|
||||
ClutterTexture *parent_texture;
|
||||
|
||||
gfloat left;
|
||||
gfloat top;
|
||||
gfloat right;
|
||||
gfloat bottom;
|
||||
|
||||
CoglHandle material;
|
||||
|
||||
guint needs_paint : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (G_UNLIKELY (priv->parent_texture == NULL))
|
||||
{
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
/* by directly querying the parent texture's class implementation
|
||||
* we are going around any override mechanism the parent texture
|
||||
* might have in place, and we ask directly for the original
|
||||
* preferred width
|
||||
*/
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
|
||||
klass->get_preferred_width (CLUTTER_ACTOR (priv->parent_texture),
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (G_UNLIKELY (priv->parent_texture == NULL))
|
||||
{
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
/* by directly querying the parent texture's class implementation
|
||||
* we are going around any override mechanism the parent texture
|
||||
* might have in place, and we ask directly for the original
|
||||
* preferred height
|
||||
*/
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
|
||||
klass->get_preferred_height (CLUTTER_ACTOR (priv->parent_texture),
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_realize (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
priv->material = cogl_material_new ();
|
||||
|
||||
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_unrealize (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (priv->material == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
cogl_handle_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
|
||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_paint (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
CoglHandle cogl_texture = COGL_INVALID_HANDLE;
|
||||
ClutterActorBox box = { 0, };
|
||||
gfloat width, height;
|
||||
gfloat tex_width, tex_height;
|
||||
gfloat ex, ey;
|
||||
gfloat tx1, ty1, tx2, ty2;
|
||||
guint8 opacity;
|
||||
|
||||
/* no need to paint stuff if we don't have a texture */
|
||||
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
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture));
|
||||
|
||||
cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
|
||||
if (cogl_texture == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
tex_width = cogl_texture_get_width (cogl_texture);
|
||||
tex_height = cogl_texture_get_height (cogl_texture);
|
||||
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
width = box.x2 - box.x1;
|
||||
height = box.y2 - box.y1;
|
||||
|
||||
tx1 = priv->left / tex_width;
|
||||
tx2 = (tex_width - priv->right) / tex_width;
|
||||
ty1 = priv->top / tex_height;
|
||||
ty2 = (tex_height - priv->bottom) / tex_height;
|
||||
|
||||
ex = width - priv->right;
|
||||
if (ex < 0)
|
||||
ex = priv->right; /* FIXME ? */
|
||||
|
||||
ey = height - priv->bottom;
|
||||
if (ey < 0)
|
||||
ey = priv->bottom; /* FIXME ? */
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (self);
|
||||
|
||||
g_assert (priv->material != COGL_INVALID_HANDLE);
|
||||
|
||||
/* set the source material using the parent texture's COGL handle */
|
||||
cogl_material_set_color4ub (priv->material, opacity, opacity, opacity, opacity);
|
||||
cogl_material_set_layer (priv->material, 0, cogl_texture);
|
||||
cogl_set_source (priv->material);
|
||||
|
||||
/* top left corner */
|
||||
cogl_rectangle_with_texture_coords (0, 0, priv->left, priv->top,
|
||||
0.0, 0.0,
|
||||
tx1, ty1);
|
||||
|
||||
/* top middle */
|
||||
cogl_rectangle_with_texture_coords (priv->left, 0, ex, priv->top,
|
||||
tx1, 0.0,
|
||||
tx2, ty1);
|
||||
|
||||
/* top right */
|
||||
cogl_rectangle_with_texture_coords (ex, 0, width, priv->top,
|
||||
tx2, 0.0,
|
||||
1.0, ty1);
|
||||
|
||||
/* mid left */
|
||||
cogl_rectangle_with_texture_coords (0, priv->top, priv->left, ey,
|
||||
0.0, ty1,
|
||||
tx1, ty2);
|
||||
|
||||
/* center */
|
||||
cogl_rectangle_with_texture_coords (priv->left, priv->top, ex, ey,
|
||||
tx1, ty1,
|
||||
tx2, ty2);
|
||||
|
||||
/* mid right */
|
||||
cogl_rectangle_with_texture_coords (ex, priv->top, width, ey,
|
||||
tx2, ty1,
|
||||
1.0, ty2);
|
||||
|
||||
/* bottom left */
|
||||
cogl_rectangle_with_texture_coords (0, ey, priv->left, height,
|
||||
0.0, ty2,
|
||||
tx1, 1.0);
|
||||
|
||||
/* bottom center */
|
||||
cogl_rectangle_with_texture_coords (priv->left, ey, ex, height,
|
||||
tx1, ty2,
|
||||
tx2, 1.0);
|
||||
|
||||
/* bottom right */
|
||||
cogl_rectangle_with_texture_coords (ex, ey, width, height,
|
||||
tx2, ty2,
|
||||
1.0, 1.0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tidy_texture_frame_set_frame_internal (TidyTextureFrame *frame,
|
||||
gfloat left,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = frame->priv;
|
||||
GObject *gobject = G_OBJECT (frame);
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_object_freeze_notify (gobject);
|
||||
|
||||
if (priv->top != top)
|
||||
{
|
||||
priv->top = top;
|
||||
g_object_notify (gobject, "top");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->right != right)
|
||||
{
|
||||
priv->right = right;
|
||||
g_object_notify (gobject, "right");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->bottom != bottom)
|
||||
{
|
||||
priv->bottom = bottom;
|
||||
g_object_notify (gobject, "bottom");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->left != left)
|
||||
{
|
||||
priv->left = left;
|
||||
g_object_notify (gobject, "left");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed && CLUTTER_ACTOR_IS_VISIBLE (frame))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (frame));
|
||||
|
||||
g_object_thaw_notify (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TidyTextureFrame *frame = TIDY_TEXTURE_FRAME (gobject);
|
||||
TidyTextureFramePrivate *priv = frame->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PARENT_TEXTURE:
|
||||
tidy_texture_frame_set_parent_texture (frame,
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_TOP:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->left,
|
||||
g_value_get_float (value),
|
||||
priv->right,
|
||||
priv->bottom);
|
||||
break;
|
||||
|
||||
case PROP_RIGHT:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
g_value_get_float (value),
|
||||
priv->bottom,
|
||||
priv->left);
|
||||
break;
|
||||
|
||||
case PROP_BOTTOM:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
priv->right,
|
||||
g_value_get_float (value),
|
||||
priv->left);
|
||||
break;
|
||||
|
||||
case PROP_LEFT:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
priv->right,
|
||||
priv->bottom,
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PARENT_TEXTURE:
|
||||
g_value_set_object (value, priv->parent_texture);
|
||||
break;
|
||||
|
||||
case PROP_LEFT:
|
||||
g_value_set_float (value, priv->left);
|
||||
break;
|
||||
|
||||
case PROP_TOP:
|
||||
g_value_set_float (value, priv->top);
|
||||
break;
|
||||
|
||||
case PROP_RIGHT:
|
||||
g_value_set_float (value, priv->right);
|
||||
break;
|
||||
|
||||
case PROP_BOTTOM:
|
||||
g_value_set_float (value, priv->bottom);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_dispose (GObject *gobject)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv;
|
||||
|
||||
if (priv->parent_texture)
|
||||
{
|
||||
g_object_unref (priv->parent_texture);
|
||||
priv->parent_texture = NULL;
|
||||
}
|
||||
|
||||
if (priv->material)
|
||||
{
|
||||
cogl_handle_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (tidy_texture_frame_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_class_init (TidyTextureFrameClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate));
|
||||
|
||||
actor_class->get_preferred_width =
|
||||
tidy_texture_frame_get_preferred_width;
|
||||
actor_class->get_preferred_height =
|
||||
tidy_texture_frame_get_preferred_height;
|
||||
actor_class->realize = tidy_texture_frame_realize;
|
||||
actor_class->unrealize = tidy_texture_frame_unrealize;
|
||||
actor_class->paint = tidy_texture_frame_paint;
|
||||
|
||||
gobject_class->set_property = tidy_texture_frame_set_property;
|
||||
gobject_class->get_property = tidy_texture_frame_get_property;
|
||||
gobject_class->dispose = tidy_texture_frame_dispose;
|
||||
|
||||
pspec = g_param_spec_object ("parent-texture",
|
||||
"Parent Texture",
|
||||
"The parent ClutterTexture",
|
||||
CLUTTER_TYPE_TEXTURE,
|
||||
TIDY_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_PARENT_TEXTURE, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("left",
|
||||
"Left",
|
||||
"Left offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LEFT, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("top",
|
||||
"Top",
|
||||
"Top offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TOP, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("bottom",
|
||||
"Bottom",
|
||||
"Bottom offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_BOTTOM, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("right",
|
||||
"Right",
|
||||
"Right offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_RIGHT, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_init (TidyTextureFrame *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
|
||||
self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self);
|
||||
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* tidy_texture_frame_new:
|
||||
* @texture: a #ClutterTexture or %NULL
|
||||
* @left: left margin preserving its content
|
||||
* @top: top margin preserving its content
|
||||
* @right: right margin preserving its content
|
||||
* @bottom: bottom margin preserving its content
|
||||
*
|
||||
* A #TidyTextureFrame is a specialized texture that efficiently clones
|
||||
* an area of the given @texture while keeping preserving portions of the
|
||||
* same texture.
|
||||
*
|
||||
* A #TidyTextureFrame can be used to make a rectangular texture fit a
|
||||
* given size without stretching its borders.
|
||||
*
|
||||
* Return value: the newly created #TidyTextureFrame
|
||||
*/
|
||||
ClutterActor*
|
||||
tidy_texture_frame_new (ClutterTexture *texture,
|
||||
gfloat left,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom)
|
||||
{
|
||||
g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL);
|
||||
|
||||
return g_object_new (TIDY_TYPE_TEXTURE_FRAME,
|
||||
"parent-texture", texture,
|
||||
"left", left,
|
||||
"top", top,
|
||||
"right", right,
|
||||
"bottom", bottom,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ClutterTexture *
|
||||
tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame)
|
||||
{
|
||||
g_return_val_if_fail (TIDY_IS_TEXTURE_FRAME (frame), NULL);
|
||||
|
||||
return frame->priv->parent_texture;
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame,
|
||||
ClutterTexture *texture)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
gboolean was_visible;
|
||||
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
g_return_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture));
|
||||
|
||||
priv = frame->priv;
|
||||
|
||||
was_visible = CLUTTER_ACTOR_IS_VISIBLE (frame);
|
||||
|
||||
if (priv->parent_texture == texture)
|
||||
return;
|
||||
|
||||
if (priv->parent_texture)
|
||||
{
|
||||
g_object_unref (priv->parent_texture);
|
||||
priv->parent_texture = NULL;
|
||||
|
||||
if (was_visible)
|
||||
clutter_actor_hide (CLUTTER_ACTOR (frame));
|
||||
}
|
||||
|
||||
if (texture)
|
||||
{
|
||||
priv->parent_texture = g_object_ref (texture);
|
||||
|
||||
if (was_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture))
|
||||
clutter_actor_show (CLUTTER_ACTOR (frame));
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
|
||||
|
||||
g_object_notify (G_OBJECT (frame), "parent-texture");
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_set_frame (TidyTextureFrame *frame,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left)
|
||||
{
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
|
||||
tidy_texture_frame_set_frame_internal (frame, top, right, bottom, left);
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_get_frame (TidyTextureFrame *frame,
|
||||
gfloat *top,
|
||||
gfloat *right,
|
||||
gfloat *bottom,
|
||||
gfloat *left)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
|
||||
priv = frame->priv;
|
||||
|
||||
if (top)
|
||||
*top = priv->top;
|
||||
|
||||
if (right)
|
||||
*right = priv->right;
|
||||
|
||||
if (bottom)
|
||||
*bottom = priv->bottom;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/* tidy-texture-frame.h: Expandible texture actor
|
||||
*
|
||||
* Copyright (C) 2007, 2008 OpenedHand Ltd
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_TIDY_TEXTURE_FRAME_H
|
||||
#define _HAVE_TIDY_TEXTURE_FRAME_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TIDY_TYPE_TEXTURE_FRAME (tidy_texture_frame_get_type ())
|
||||
#define TIDY_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrame))
|
||||
#define TIDY_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass))
|
||||
#define TIDY_IS_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_TEXTURE_FRAME))
|
||||
#define TIDY_IS_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_TEXTURE_FRAME))
|
||||
#define TIDY_TEXTURE_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass))
|
||||
|
||||
typedef struct _TidyTextureFrame TidyTextureFrame;
|
||||
typedef struct _TidyTextureFramePrivate TidyTextureFramePrivate;
|
||||
typedef struct _TidyTextureFrameClass TidyTextureFrameClass;
|
||||
|
||||
struct _TidyTextureFrame
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActor parent_instance;
|
||||
|
||||
TidyTextureFramePrivate *priv;
|
||||
};
|
||||
|
||||
struct _TidyTextureFrameClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_clutter_box_1) (void);
|
||||
void (*_clutter_box_2) (void);
|
||||
void (*_clutter_box_3) (void);
|
||||
void (*_clutter_box_4) (void);
|
||||
};
|
||||
|
||||
GType tidy_texture_frame_get_type (void) G_GNUC_CONST;
|
||||
ClutterActor * tidy_texture_frame_new (ClutterTexture *texture,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left);
|
||||
void tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame,
|
||||
ClutterTexture *texture);
|
||||
ClutterTexture *tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame);
|
||||
void tidy_texture_frame_set_frame (TidyTextureFrame *frame,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left);
|
||||
void tidy_texture_frame_get_frame (TidyTextureFrame *frame,
|
||||
gfloat *top,
|
||||
gfloat *right,
|
||||
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 */
|
||||
@@ -117,65 +117,8 @@ meta_core_get (Display *xdisplay,
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
{
|
||||
MetaFrameType base_type = META_FRAME_TYPE_LAST;
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
case META_WINDOW_NORMAL:
|
||||
base_type = META_FRAME_TYPE_NORMAL;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DIALOG:
|
||||
base_type = META_FRAME_TYPE_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
base_type = META_FRAME_TYPE_MODAL_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MENU:
|
||||
base_type = META_FRAME_TYPE_MENU;
|
||||
break;
|
||||
|
||||
case META_WINDOW_UTILITY:
|
||||
base_type = META_FRAME_TYPE_UTILITY;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
/* No frame */
|
||||
base_type = META_FRAME_TYPE_LAST;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (base_type == META_FRAME_TYPE_LAST)
|
||||
{
|
||||
/* can't add border if undecorated */
|
||||
*((MetaFrameType*)answer) = META_FRAME_TYPE_LAST;
|
||||
}
|
||||
else if (window->border_only)
|
||||
{
|
||||
/* override base frame type */
|
||||
*((MetaFrameType*)answer) = META_FRAME_TYPE_BORDER;
|
||||
}
|
||||
else
|
||||
{
|
||||
*((MetaFrameType*)answer) = base_type;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
@@ -348,7 +291,7 @@ meta_core_lower_beneath_focus_window (Display *xdisplay,
|
||||
xwindow,
|
||||
CWSibling | CWStackMode,
|
||||
&changes);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -136,7 +136,7 @@ meta_window_delete (MetaWindow *window,
|
||||
window->desc);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
}
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_display_ping_window (window->display,
|
||||
window,
|
||||
@@ -200,7 +200,7 @@ meta_window_kill (MetaWindow *window)
|
||||
window->desc);
|
||||
meta_error_trap_push (window->display);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -347,7 +347,7 @@ sn_error_trap_pop (SnDisplay *sn_display,
|
||||
MetaDisplay *display;
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
if (display != NULL)
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -890,7 +890,7 @@ meta_display_open (void)
|
||||
timestamp);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (the_display, FALSE);
|
||||
meta_error_trap_pop (the_display);
|
||||
}
|
||||
|
||||
meta_display_ungrab (the_display);
|
||||
@@ -1099,7 +1099,7 @@ meta_display_screen_for_xwindow (MetaDisplay *display,
|
||||
meta_error_trap_push (display);
|
||||
attr.screen = NULL;
|
||||
result = XGetWindowAttributes (display->xdisplay, xwindow, &attr);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
/* Note, XGetWindowAttributes is on all kinds of crack
|
||||
* and returns 1 on success 0 on failure, rather than Success
|
||||
@@ -1492,7 +1492,7 @@ window_raise_with_delay_callback (void *data)
|
||||
window->xwindow,
|
||||
&root, &child,
|
||||
&root_x, &root_y, &x, &y, &mask);
|
||||
meta_error_trap_pop (window->display, TRUE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
point_in_window =
|
||||
(window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) ||
|
||||
@@ -2208,7 +2208,7 @@ event_callback (XEvent *event,
|
||||
window->frame->xwindow);
|
||||
meta_error_trap_push (display);
|
||||
meta_window_destroy_frame (window->frame->window);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2377,7 +2377,7 @@ event_callback (XEvent *event,
|
||||
meta_error_trap_push (display);
|
||||
XConfigureWindow (display->xdisplay, event->xconfigurerequest.window,
|
||||
xwcm, &xwc);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3148,7 +3148,7 @@ meta_spew_event (MetaDisplay *display,
|
||||
meta_error_trap_push (display);
|
||||
str = XGetAtomName (display->xdisplay,
|
||||
event->xproperty.atom);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (event->xproperty.state == PropertyNewValue)
|
||||
state = "PropertyNewValue";
|
||||
@@ -3182,7 +3182,7 @@ meta_spew_event (MetaDisplay *display,
|
||||
meta_error_trap_push (display);
|
||||
str = XGetAtomName (display->xdisplay,
|
||||
event->xclient.message_type);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
extra = g_strdup_printf ("type: %s format: %d\n",
|
||||
str ? str : "(unknown atom)",
|
||||
event->xclient.format);
|
||||
@@ -3460,7 +3460,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Changed pointer with XChangeActivePointerGrab()\n");
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Error trapped from XChangeActivePointerGrab()\n");
|
||||
@@ -3493,7 +3493,7 @@ meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
"XGrabPointer() failed time %u\n",
|
||||
timestamp);
|
||||
}
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
#undef GRAB_MASK
|
||||
@@ -3669,7 +3669,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
XSyncCAEvents,
|
||||
&values);
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
display->grab_sync_request_alarm = None;
|
||||
|
||||
meta_topic (META_DEBUG_RESIZING,
|
||||
@@ -3888,7 +3888,7 @@ meta_change_button_grab (MetaDisplay *display,
|
||||
{
|
||||
int result;
|
||||
|
||||
result = meta_error_trap_pop_with_return (display, FALSE);
|
||||
result = meta_error_trap_pop_with_return (display);
|
||||
|
||||
if (result != Success)
|
||||
meta_verbose ("Failed to %s button %d with mask 0x%x for window 0x%lx error code %d\n",
|
||||
@@ -3899,7 +3899,7 @@ meta_change_button_grab (MetaDisplay *display,
|
||||
++ignored_mask;
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4083,7 +4083,7 @@ meta_display_update_active_window_hint (MetaDisplay *display)
|
||||
XA_WINDOW,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -4363,7 +4363,7 @@ process_request_frame_extents (MetaDisplay *display,
|
||||
display->atom__NET_FRAME_EXTENTS,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 4);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
meta_XFree (hints);
|
||||
}
|
||||
@@ -4841,11 +4841,11 @@ convert_property (MetaDisplay *display,
|
||||
(unsigned char *)icccm_version, 2);
|
||||
else
|
||||
{
|
||||
meta_error_trap_pop_with_return (display, FALSE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
return FALSE;
|
||||
|
||||
/* Be sure the PropertyNotify has arrived so we
|
||||
@@ -4877,7 +4877,7 @@ process_selection_request (MetaDisplay *display,
|
||||
meta_error_trap_push (display);
|
||||
str = XGetAtomName (display->xdisplay,
|
||||
event->xselectionrequest.selection);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
meta_verbose ("Selection request with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
|
||||
str ? str : "(bad atom)", event->xselectionrequest.owner);
|
||||
@@ -4911,11 +4911,11 @@ process_selection_request (MetaDisplay *display,
|
||||
display->atom_ATOM_PAIR,
|
||||
&type, &format, &num, &rest, &data) != Success)
|
||||
{
|
||||
meta_error_trap_pop_with_return (display, TRUE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, TRUE) == Success)
|
||||
if (meta_error_trap_pop_with_return (display) == Success)
|
||||
{
|
||||
/* FIXME: to be 100% correct, should deal with rest > 0,
|
||||
* but since we have 4 possible targets, we will hardly ever
|
||||
@@ -4938,7 +4938,7 @@ process_selection_request (MetaDisplay *display,
|
||||
event->xselectionrequest.property,
|
||||
display->atom_ATOM_PAIR,
|
||||
32, PropModeReplace, data, num);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_XFree (data);
|
||||
}
|
||||
}
|
||||
@@ -4994,7 +4994,7 @@ process_selection_clear (MetaDisplay *display,
|
||||
meta_error_trap_push (display);
|
||||
str = XGetAtomName (display->xdisplay,
|
||||
event->xselectionclear.selection);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
meta_verbose ("Selection clear with selection %s window 0x%lx not a WM_Sn selection we recognize\n",
|
||||
str ? str : "(bad atom)", event->xselectionclear.window);
|
||||
@@ -5366,7 +5366,7 @@ meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
focus_frame ? window->frame->xwindow : window->xwindow,
|
||||
RevertToPointerRoot,
|
||||
timestamp);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
display->expected_focus_window = window;
|
||||
display->last_focus_time = timestamp;
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtk.h> /* Only for GTK_CHECK_VERSION */
|
||||
|
||||
/* In GTK+-3.0, the error trapping code was significantly rewritten. The new code
|
||||
* has some neat features (like knowing automatically if a sync is needed or not
|
||||
@@ -41,26 +40,6 @@
|
||||
* use the GTK+ handling straight-up.
|
||||
* (See https://bugzilla.gnome.org/show_bug.cgi?id=630216 for restoring logging.)
|
||||
*/
|
||||
#if GTK_CHECK_VERSION(2, 90, 0)
|
||||
#define USE_GDK_ERROR_HANDLERS 1
|
||||
#endif
|
||||
|
||||
#ifndef USE_GDK_ERROR_HANDLERS
|
||||
static int x_error_handler (Display *display,
|
||||
XErrorEvent *error);
|
||||
static int x_io_error_handler (Display *display);
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_errors_init (void)
|
||||
{
|
||||
#ifndef USE_GDK_ERROR_HANDLERS
|
||||
XSetErrorHandler (x_error_handler);
|
||||
XSetIOErrorHandler (x_io_error_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_GDK_ERROR_HANDLERS
|
||||
|
||||
void
|
||||
meta_error_trap_push (MetaDisplay *display)
|
||||
@@ -69,8 +48,7 @@ meta_error_trap_push (MetaDisplay *display)
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
meta_error_trap_pop (MetaDisplay *display)
|
||||
{
|
||||
gdk_error_trap_pop_ignored ();
|
||||
}
|
||||
@@ -82,220 +60,7 @@ meta_error_trap_push_with_return (MetaDisplay *display)
|
||||
}
|
||||
|
||||
int
|
||||
meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
meta_error_trap_pop_with_return (MetaDisplay *display)
|
||||
{
|
||||
return gdk_error_trap_pop ();
|
||||
}
|
||||
|
||||
#else /* !USE_GDK_ERROR_HANDLERS */
|
||||
|
||||
static void
|
||||
meta_error_trap_push_internal (MetaDisplay *display,
|
||||
gboolean need_sync)
|
||||
{
|
||||
/* GDK resets the error handler on each push */
|
||||
int (* old_error_handler) (Display *,
|
||||
XErrorEvent *);
|
||||
|
||||
if (need_sync)
|
||||
{
|
||||
XSync (display->xdisplay, False);
|
||||
}
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
/* old_error_handler will just be equal to x_error_handler
|
||||
* for nested traps
|
||||
*/
|
||||
old_error_handler = XSetErrorHandler (x_error_handler);
|
||||
|
||||
/* Replace GDK handler, but save it so we can chain up */
|
||||
if (display->error_trap_handler == NULL)
|
||||
{
|
||||
g_assert (display->error_traps == 0);
|
||||
display->error_trap_handler = old_error_handler;
|
||||
g_assert (display->error_trap_handler != x_error_handler);
|
||||
}
|
||||
|
||||
display->error_traps += 1;
|
||||
|
||||
meta_topic (META_DEBUG_ERRORS, "%d traps remain\n", display->error_traps);
|
||||
}
|
||||
|
||||
static int
|
||||
meta_error_trap_pop_internal (MetaDisplay *display,
|
||||
gboolean need_sync)
|
||||
{
|
||||
int result;
|
||||
|
||||
g_assert (display->error_traps > 0);
|
||||
|
||||
if (need_sync)
|
||||
{
|
||||
XSync (display->xdisplay, False);
|
||||
}
|
||||
|
||||
result = gdk_error_trap_pop ();
|
||||
|
||||
display->error_traps -= 1;
|
||||
|
||||
if (display->error_traps == 0)
|
||||
{
|
||||
/* check that GDK put our handler back; this
|
||||
* assumes that there are no pending GDK traps from GDK itself
|
||||
*/
|
||||
|
||||
int (* restored_error_handler) (Display *,
|
||||
XErrorEvent *);
|
||||
|
||||
restored_error_handler = XSetErrorHandler (x_error_handler);
|
||||
|
||||
/* remove this */
|
||||
display->error_trap_handler = NULL;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_ERRORS, "%d traps\n", display->error_traps);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push (MetaDisplay *display)
|
||||
{
|
||||
meta_error_trap_push_internal (display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
gboolean need_sync;
|
||||
|
||||
/* we only have to sync when popping the outermost trap */
|
||||
need_sync = (display->error_traps == 1 && !last_request_was_roundtrip);
|
||||
|
||||
if (need_sync)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop, traps = %d, roundtrip = %d\n",
|
||||
display->error_traps, last_request_was_roundtrip);
|
||||
|
||||
display->error_trap_synced_at_last_pop = need_sync || last_request_was_roundtrip;
|
||||
|
||||
meta_error_trap_pop_internal (display, need_sync);
|
||||
}
|
||||
|
||||
void
|
||||
meta_error_trap_push_with_return (MetaDisplay *display)
|
||||
{
|
||||
gboolean need_sync;
|
||||
|
||||
/* We don't sync on push_with_return if there are no traps
|
||||
* currently, because we assume that any errors were either covered
|
||||
* by a previous pop, or were fatal.
|
||||
*
|
||||
* More generally, we don't sync if we were synchronized last time
|
||||
* we popped. This is known to be the case if there are no traps,
|
||||
* but we also keep a flag so we know whether it's the case otherwise.
|
||||
*/
|
||||
|
||||
if (!display->error_trap_synced_at_last_pop)
|
||||
need_sync = TRUE;
|
||||
else
|
||||
need_sync = FALSE;
|
||||
|
||||
if (need_sync)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_push_with_return, traps = %d\n",
|
||||
display->error_traps);
|
||||
|
||||
meta_error_trap_push_internal (display, FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip)
|
||||
{
|
||||
if (!last_request_was_roundtrip)
|
||||
meta_topic (META_DEBUG_SYNC, "Syncing on error_trap_pop_with_return, traps = %d, roundtrip = %d\n",
|
||||
display->error_traps, last_request_was_roundtrip);
|
||||
|
||||
display->error_trap_synced_at_last_pop = TRUE;
|
||||
|
||||
return meta_error_trap_pop_internal (display,
|
||||
!last_request_was_roundtrip);
|
||||
}
|
||||
|
||||
static int
|
||||
x_error_handler (Display *xdisplay,
|
||||
XErrorEvent *error)
|
||||
{
|
||||
int retval;
|
||||
gchar buf[64];
|
||||
MetaDisplay *display;
|
||||
|
||||
XGetErrorText (xdisplay, error->error_code, buf, 63);
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
/* Display can be NULL here Xlib only has one global error handler; and
|
||||
* there might be other displays open in the process.
|
||||
*/
|
||||
if (display && display->error_traps > 0)
|
||||
{
|
||||
/* we're in an error trap, chain to the trap handler
|
||||
* saved from GDK
|
||||
*/
|
||||
meta_verbose ("X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
|
||||
buf,
|
||||
error->serial,
|
||||
error->error_code,
|
||||
error->request_code,
|
||||
error->minor_code);
|
||||
|
||||
g_assert (display->error_trap_handler != NULL);
|
||||
g_assert (display->error_trap_handler != x_error_handler);
|
||||
|
||||
retval = (* display->error_trap_handler) (xdisplay, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_bug ("Unexpected X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
|
||||
buf,
|
||||
error->serial,
|
||||
error->error_code,
|
||||
error->request_code,
|
||||
error->minor_code);
|
||||
|
||||
retval = 1; /* compiler warning */
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
x_io_error_handler (Display *xdisplay)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
if (errno == EPIPE)
|
||||
{
|
||||
meta_warning (_("Lost connection to the display '%s';\n"
|
||||
"most likely the X server was shut down or you killed/destroyed\n"
|
||||
"the window manager.\n"),
|
||||
display ? display->name : DisplayString (xdisplay));
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning (_("Fatal IO error %d (%s) on display '%s'.\n"),
|
||||
errno, g_strerror (errno),
|
||||
display ? display->name : DisplayString (xdisplay));
|
||||
}
|
||||
|
||||
/* Xlib would force an exit anyhow */
|
||||
exit (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_GDK_ERROR_HANDLERS */
|
||||
|
||||
@@ -153,7 +153,7 @@ meta_window_ensure_frame (MetaWindow *window)
|
||||
window->rect.x,
|
||||
window->rect.y);
|
||||
/* FIXME handle this error */
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
/* stick frame to the window */
|
||||
window->frame = frame;
|
||||
@@ -217,7 +217,7 @@ meta_window_destroy_frame (MetaWindow *window)
|
||||
*/
|
||||
window->frame->rect.x,
|
||||
window->frame->rect.y);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_ui_destroy_frame_window (window->screen->ui, frame->xwindow);
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ read_rgb_icon (MetaDisplay *display,
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, &data);
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
err = meta_error_trap_pop_with_return (display);
|
||||
|
||||
if (err != Success ||
|
||||
result != Success)
|
||||
@@ -406,7 +406,7 @@ try_pixmap_and_mask (MetaDisplay *display,
|
||||
w, h);
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
@@ -482,7 +482,7 @@ get_kwm_win_icon (MetaDisplay *display,
|
||||
&bytes_after, &data);
|
||||
icons = (Pixmap *)data;
|
||||
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
err = meta_error_trap_pop_with_return (display);
|
||||
if (err != Success ||
|
||||
result != Success)
|
||||
return;
|
||||
|
||||
@@ -470,7 +470,7 @@ regrab_key_bindings (MetaDisplay *display)
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
@@ -700,7 +700,7 @@ meta_change_keygrab (MetaDisplay *display,
|
||||
{
|
||||
int result;
|
||||
|
||||
result = meta_error_trap_pop_with_return (display, FALSE);
|
||||
result = meta_error_trap_pop_with_return (display);
|
||||
|
||||
if (grab && result != Success)
|
||||
{
|
||||
@@ -716,7 +716,7 @@ meta_change_keygrab (MetaDisplay *display,
|
||||
++ignored_mask;
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -758,7 +758,7 @@ grab_keys (MetaKeyBinding *bindings,
|
||||
++i;
|
||||
}
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -777,14 +777,14 @@ ungrab_all_keys (MetaDisplay *display,
|
||||
{
|
||||
int result;
|
||||
|
||||
result = meta_error_trap_pop_with_return (display, FALSE);
|
||||
result = meta_error_trap_pop_with_return (display);
|
||||
|
||||
if (result != Success)
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Ungrabbing all keys on 0x%lx failed\n", xwindow);
|
||||
}
|
||||
else
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -916,7 +916,7 @@ grab_keyboard (MetaDisplay *display,
|
||||
|
||||
if (grab_status != GrabSuccess)
|
||||
{
|
||||
meta_error_trap_pop_with_return (display, TRUE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"XGrabKeyboard() returned failure status %s time %u\n",
|
||||
grab_status_to_string (grab_status),
|
||||
@@ -925,7 +925,7 @@ grab_keyboard (MetaDisplay *display,
|
||||
}
|
||||
else
|
||||
{
|
||||
result = meta_error_trap_pop_with_return (display, TRUE);
|
||||
result = meta_error_trap_pop_with_return (display);
|
||||
if (result != Success)
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
@@ -948,7 +948,7 @@ ungrab_keyboard (MetaDisplay *display, guint32 timestamp)
|
||||
"Ungrabbing keyboard with timestamp %u\n",
|
||||
timestamp);
|
||||
XUngrabKeyboard (display->xdisplay, timestamp);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -1373,8 +1373,7 @@ meta_display_process_key_event (MetaDisplay *display,
|
||||
return FALSE; /* event window is destroyed */
|
||||
|
||||
/* ignore key events on popup menus and such. */
|
||||
if (window == NULL &&
|
||||
meta_ui_window_is_widget (screen->ui, event->xany.window))
|
||||
if (meta_ui_window_is_widget (screen->ui, event->xany.window))
|
||||
return FALSE;
|
||||
|
||||
/* window may be NULL */
|
||||
@@ -2899,7 +2898,7 @@ handle_panel (MetaDisplay *display,
|
||||
StructureNotifyMask,
|
||||
(XEvent*) &ev);
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -623,9 +623,6 @@ main (int argc, char **argv)
|
||||
|
||||
g_option_context_free (ctx);
|
||||
|
||||
/* must be after UI init so we can override GDK handlers */
|
||||
meta_errors_init ();
|
||||
|
||||
/* Load prefs */
|
||||
meta_prefs_init ();
|
||||
meta_prefs_add_listener (prefs_changed_callback, NULL);
|
||||
|
||||
@@ -601,7 +601,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
attrs.event_mask = StructureNotifyMask;
|
||||
XChangeWindowAttributes (xdisplay,
|
||||
current_wm_sn_owner, CWEventMask, &attrs);
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
current_wm_sn_owner = None; /* don't wait for it to die later on */
|
||||
}
|
||||
|
||||
@@ -670,7 +670,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
FocusChangeMask | StructureNotifyMask |
|
||||
ExposureMask | attr.your_event_mask);
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_warning (_("Screen %d on display \"%s\" already has a window manager\n"),
|
||||
number, display->name);
|
||||
@@ -856,7 +856,7 @@ meta_screen_free (MetaScreen *screen,
|
||||
|
||||
meta_error_trap_push_with_return (screen->display);
|
||||
XSelectInput (screen->display->xdisplay, screen->xroot, 0);
|
||||
if (meta_error_trap_pop_with_return (screen->display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (screen->display) != Success)
|
||||
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
|
||||
screen->number, screen->display->name);
|
||||
|
||||
@@ -913,7 +913,7 @@ list_windows (MetaScreen *screen)
|
||||
XGetWindowAttributes (screen->display->xdisplay,
|
||||
children[i], &info->attrs);
|
||||
|
||||
if (meta_error_trap_pop_with_return (screen->display, TRUE))
|
||||
if (meta_error_trap_pop_with_return (screen->display))
|
||||
{
|
||||
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
||||
children[i]);
|
||||
@@ -1220,7 +1220,7 @@ set_number_of_spaces_hint (MetaScreen *screen,
|
||||
screen->display->atom__NET_NUMBER_OF_DESKTOPS,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1241,7 +1241,7 @@ set_desktop_geometry_hint (MetaScreen *screen)
|
||||
screen->display->atom__NET_DESKTOP_GEOMETRY,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 2);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1265,7 +1265,7 @@ set_desktop_viewport_hint (MetaScreen *screen)
|
||||
screen->display->atom__NET_DESKTOP_VIEWPORT,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 2);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1839,7 +1839,7 @@ meta_screen_get_mouse_window (MetaScreen *screen,
|
||||
&win_x_return,
|
||||
&win_y_return,
|
||||
&mask_return);
|
||||
meta_error_trap_pop (screen->display, TRUE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
|
||||
window = meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||
screen->active_workspace,
|
||||
@@ -2242,7 +2242,7 @@ set_workspace_names (MetaScreen *screen)
|
||||
screen->display->atom_UTF8_STRING,
|
||||
8, PropModeReplace,
|
||||
(unsigned char *)flattened->str, flattened->len);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
|
||||
g_string_free (flattened, TRUE);
|
||||
}
|
||||
@@ -2346,7 +2346,7 @@ set_work_area_hint (MetaScreen *screen)
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar*) data, num_workspaces*4);
|
||||
g_free (data);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
|
||||
g_signal_emit (screen, screen_signals[WORKAREAS_CHANGED], 0);
|
||||
}
|
||||
@@ -2721,7 +2721,7 @@ meta_screen_update_showing_desktop_hint (MetaScreen *screen)
|
||||
screen->display->atom__NET_SHOWING_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -1026,7 +1026,7 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
||||
xwindow,
|
||||
CWSibling | CWStackMode,
|
||||
&changes);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1046,7 +1046,7 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
|
||||
XNextRequest (screen->display->xdisplay));
|
||||
XLowerWindow (screen->display->xdisplay,
|
||||
xwindow);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1267,7 +1267,7 @@ stack_sync_to_server (MetaStack *stack)
|
||||
all_hidden->len);
|
||||
g_array_free (all_hidden, TRUE);
|
||||
|
||||
meta_error_trap_pop (stack->screen->display, FALSE);
|
||||
meta_error_trap_pop (stack->screen->display);
|
||||
/* on error, a window was destroyed; it should eventually
|
||||
* get removed from the stacking list when we unmanage it
|
||||
* and we'll fix stacking at that time.
|
||||
|
||||
@@ -461,8 +461,6 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
gboolean meta_window_appears_focused (MetaWindow *window);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
gboolean user_op,
|
||||
|
||||
@@ -442,7 +442,7 @@ set_title_text (MetaWindow *window,
|
||||
XDeleteProperty (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
atom);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
return modified;
|
||||
|
||||
@@ -484,11 +484,11 @@ meta_window_new (MetaDisplay *display,
|
||||
|
||||
if (XGetWindowAttributes (display->xdisplay,xwindow, &attrs))
|
||||
{
|
||||
if(meta_error_trap_pop_with_return (display, TRUE) != Success)
|
||||
if(meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
||||
xwindow);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_display_ungrab (display);
|
||||
return NULL;
|
||||
}
|
||||
@@ -499,16 +499,16 @@ meta_window_new (MetaDisplay *display,
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_error_trap_pop_with_return (display, TRUE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
meta_verbose ("Failed to get attributes for window 0x%lx\n",
|
||||
xwindow);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_display_ungrab (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_display_ungrab (display);
|
||||
|
||||
return window;
|
||||
@@ -607,7 +607,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
(state == IconicState || state == NormalState)))
|
||||
{
|
||||
meta_verbose ("Deciding not to manage unmapped or unviewable window 0x%lx\n", xwindow);
|
||||
meta_error_trap_pop (display, TRUE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_display_ungrab (display);
|
||||
return NULL;
|
||||
}
|
||||
@@ -629,7 +629,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
*/
|
||||
meta_error_trap_push_with_return (display);
|
||||
XAddToSaveSet (display->xdisplay, xwindow);
|
||||
meta_error_trap_pop_with_return (display, FALSE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
|
||||
event_mask =
|
||||
PropertyChangeMask | EnterWindowMask | LeaveWindowMask |
|
||||
@@ -685,11 +685,11 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
&set_attrs);
|
||||
}
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_verbose ("Window 0x%lx disappeared just as we tried to manage it\n",
|
||||
xwindow);
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
meta_display_ungrab (display);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1162,7 +1162,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
||||
!window->initially_iconic)
|
||||
unminimize_window_and_all_transient_parents (window);
|
||||
|
||||
meta_error_trap_pop (display, FALSE); /* pop the XSync()-reducing trap */
|
||||
meta_error_trap_pop (display); /* pop the XSync()-reducing trap */
|
||||
meta_display_ungrab (display);
|
||||
|
||||
window->constructing = FALSE;
|
||||
@@ -1482,7 +1482,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
window->xwindow,
|
||||
window->display->atom__NET_WM_FULLSCREEN_MONITORS);
|
||||
set_wm_state (window, WithdrawnState);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1493,7 +1493,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
set_wm_state (window, NormalState);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
/* And we need to be sure the window is mapped so other WMs
|
||||
@@ -1502,7 +1502,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
meta_error_trap_push (window->display);
|
||||
XMapWindow (window->display->xdisplay,
|
||||
window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
meta_window_ungrab_keys (window);
|
||||
@@ -1550,7 +1550,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
XShapeSelectInput (window->display->xdisplay, window->xwindow, NoEventMask);
|
||||
#endif
|
||||
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
g_signal_emit (window, window_signals[UNMANAGED], 0);
|
||||
|
||||
@@ -1577,7 +1577,7 @@ set_wm_state (MetaWindow *window,
|
||||
window->display->atom_WM_STATE,
|
||||
window->display->atom_WM_STATE,
|
||||
32, PropModeReplace, (guchar*) data, 2);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1655,7 +1655,7 @@ set_net_wm_state (MetaWindow *window)
|
||||
window->display->atom__NET_WM_STATE,
|
||||
XA_ATOM,
|
||||
32, PropModeReplace, (guchar*) data, i);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
if (window->fullscreen)
|
||||
{
|
||||
@@ -1671,7 +1671,7 @@ set_net_wm_state (MetaWindow *window)
|
||||
window->display->atom__NET_WM_FULLSCREEN_MONITORS,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(guchar*) data, 4);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2414,7 +2414,7 @@ map_client_window (MetaWindow *window)
|
||||
window->mapped = TRUE;
|
||||
meta_error_trap_push (window->display);
|
||||
XMapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2438,7 +2438,7 @@ unmap_client_window (MetaWindow *window,
|
||||
window->unmaps_pending += 1;
|
||||
meta_error_trap_push (window->display);
|
||||
XUnmapWindow (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -3158,6 +3158,32 @@ meta_window_maximize (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_maximized:
|
||||
*
|
||||
* Gets the current maximization state of the window, as combination
|
||||
* of the %META_MAXIMIZE_HORIZONTAL and %META_MAXIMIZE_VERTICAL flags;
|
||||
*
|
||||
* Return value: current maximization state
|
||||
*/
|
||||
MetaMaximizeFlags
|
||||
meta_window_get_maximized (MetaWindow *window)
|
||||
{
|
||||
return ((window->maximized_horizontally ? META_MAXIMIZE_HORIZONTAL : 0) |
|
||||
(window->maximized_vertically ? META_MAXIMIZE_VERTICAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_is_fullscreen:
|
||||
*
|
||||
* Return value: %TRUE if the window is currently fullscreen
|
||||
*/
|
||||
gboolean
|
||||
meta_window_is_fullscreen (MetaWindow *window)
|
||||
{
|
||||
return window->fullscreen;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_tile (MetaWindow *window)
|
||||
{
|
||||
@@ -4323,7 +4349,7 @@ meta_window_move_resize_internal (MetaWindow *window,
|
||||
mask,
|
||||
&values);
|
||||
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
if (!configure_frame_first && window->frame)
|
||||
@@ -5026,7 +5052,7 @@ update_net_frame_extents (MetaWindow *window)
|
||||
window->display->atom__NET_FRAME_EXTENTS,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 4);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5053,7 +5079,7 @@ meta_window_set_current_workspace_hint (MetaWindow *window)
|
||||
window->display->atom__NET_WM_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -5178,7 +5204,7 @@ meta_window_send_icccm_message (MetaWindow *window,
|
||||
meta_error_trap_push (window->display);
|
||||
XSendEvent (window->display->xdisplay,
|
||||
window->xwindow, False, 0, (XEvent*) &ev);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5583,12 +5609,12 @@ meta_window_client_message (MetaWindow *window,
|
||||
|
||||
meta_error_trap_push_with_return (display);
|
||||
str1 = XGetAtomName (display->xdisplay, first);
|
||||
if (meta_error_trap_pop_with_return (display, TRUE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
str1 = NULL;
|
||||
|
||||
meta_error_trap_push_with_return (display);
|
||||
str2 = XGetAtomName (display->xdisplay, second);
|
||||
if (meta_error_trap_pop_with_return (display, TRUE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
str2 = NULL;
|
||||
|
||||
meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
|
||||
@@ -5876,7 +5902,7 @@ meta_window_client_message (MetaWindow *window,
|
||||
&query_root_x, &query_root_y,
|
||||
&x, &y,
|
||||
&mask);
|
||||
meta_error_trap_pop (window->display, TRUE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
if (mask & Button1Mask)
|
||||
button = 1;
|
||||
@@ -6112,7 +6138,7 @@ meta_window_notify_focus (MetaWindow *window,
|
||||
meta_error_trap_push (window->display);
|
||||
XInstallColormap (window->display->xdisplay,
|
||||
window->colormap);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
/* move into FOCUSED_WINDOW layer */
|
||||
meta_window_update_layer (window);
|
||||
@@ -6175,7 +6201,7 @@ meta_window_notify_focus (MetaWindow *window,
|
||||
meta_error_trap_push (window->display);
|
||||
XUninstallColormap (window->display->xdisplay,
|
||||
window->colormap);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
/* move out of FOCUSED_WINDOW layer */
|
||||
meta_window_update_layer (window);
|
||||
@@ -6266,7 +6292,7 @@ send_configure_notify (MetaWindow *window)
|
||||
XSendEvent (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
False, StructureNotifyMask, &event);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
/* FIXME: @rect should be marked (out), but gjs doesn't currently support
|
||||
@@ -6502,7 +6528,7 @@ meta_window_update_net_wm_type (MetaWindow *window)
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
str = XGetAtomName (window->display->xdisplay, window->type_atom);
|
||||
meta_error_trap_pop (window->display, TRUE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
meta_verbose ("Window %s type atom %s\n", window->desc,
|
||||
@@ -6863,7 +6889,7 @@ recalc_window_type (MetaWindow *window)
|
||||
meta_error_trap_push (window->display);
|
||||
atom_name = XGetAtomName (window->display->xdisplay,
|
||||
window->type_atom);
|
||||
meta_error_trap_pop (window->display, TRUE);
|
||||
meta_error_trap_pop (window->display);
|
||||
|
||||
meta_warning ("Unrecognized type atom [%s] set for %s \n",
|
||||
atom_name ? atom_name : "unknown",
|
||||
@@ -7021,7 +7047,7 @@ set_allowed_actions_hint (MetaWindow *window)
|
||||
window->display->atom__NET_WM_ALLOWED_ACTIONS,
|
||||
XA_ATOM,
|
||||
32, PropModeReplace, (guchar*) data, i);
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
#undef MAX_N_ACTIONS
|
||||
}
|
||||
|
||||
@@ -8493,7 +8519,7 @@ meta_window_set_gravity (MetaWindow *window,
|
||||
CWWinGravity,
|
||||
&attrs);
|
||||
|
||||
meta_error_trap_pop (window->display, FALSE);
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8937,7 +8963,7 @@ warp_grab_pointer (MetaWindow *window,
|
||||
0, 0, 0, 0,
|
||||
*x, *y);
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, FALSE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
meta_verbose ("Failed to warp pointer for window %s\n",
|
||||
window->desc);
|
||||
@@ -9275,9 +9301,22 @@ transient_has_focus (MetaWindow *window,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_appears_focused:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Determines if the window should be drawn with a focused appearance. This is
|
||||
* true for focused windows but also true for windows with a focused modal
|
||||
* dialog attached.
|
||||
*
|
||||
* Return value: %TRUE if the window should be drawn with a focused frame
|
||||
*/
|
||||
gboolean
|
||||
meta_window_appears_focused (MetaWindow *window)
|
||||
{
|
||||
/* FIXME: meta_window_foreach_transient() iterates over all windows; we
|
||||
* should eat the complexity to cache a bit for this.
|
||||
*/
|
||||
if (!window->has_focus && meta_prefs_get_attach_modal_dialogs ())
|
||||
{
|
||||
gboolean focus = FALSE;
|
||||
@@ -9655,3 +9694,74 @@ meta_window_get_mutter_hints (MetaWindow *window)
|
||||
|
||||
return window->mutter_hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_frame_type:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Gets the type of window decorations that should be used for this window.
|
||||
*
|
||||
* Return value: the frame type
|
||||
*/
|
||||
MetaFrameType
|
||||
meta_window_get_frame_type (MetaWindow *window)
|
||||
{
|
||||
MetaFrameType base_type = META_FRAME_TYPE_LAST;
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
case META_WINDOW_NORMAL:
|
||||
base_type = META_FRAME_TYPE_NORMAL;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DIALOG:
|
||||
base_type = META_FRAME_TYPE_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
if (meta_prefs_get_attach_modal_dialogs () &&
|
||||
meta_window_get_transient_for (window) != NULL)
|
||||
base_type = META_FRAME_TYPE_ATTACHED;
|
||||
else
|
||||
base_type = META_FRAME_TYPE_MODAL_DIALOG;
|
||||
break;
|
||||
|
||||
case META_WINDOW_MENU:
|
||||
base_type = META_FRAME_TYPE_MENU;
|
||||
break;
|
||||
|
||||
case META_WINDOW_UTILITY:
|
||||
base_type = META_FRAME_TYPE_UTILITY;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
/* No frame */
|
||||
base_type = META_FRAME_TYPE_LAST;
|
||||
break;
|
||||
}
|
||||
|
||||
if (base_type == META_FRAME_TYPE_LAST)
|
||||
{
|
||||
/* can't add border if undecorated */
|
||||
return META_FRAME_TYPE_LAST;
|
||||
}
|
||||
else if (window->border_only && base_type != META_FRAME_TYPE_ATTACHED)
|
||||
{
|
||||
/* override base frame type */
|
||||
return META_FRAME_TYPE_BORDER;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base_type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ set_active_space_hint (MetaScreen *screen)
|
||||
screen->display->atom__NET_CURRENT_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) data, 1);
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
meta_error_trap_pop (screen->display);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -126,7 +126,7 @@ validate_or_free_results (GetPropertyResults *results,
|
||||
type_name = XGetAtomName (results->display->xdisplay, results->type);
|
||||
expected_name = XGetAtomName (results->display->xdisplay, expected_type);
|
||||
prop_name = XGetAtomName (results->display->xdisplay, results->xatom);
|
||||
meta_error_trap_pop (results->display, TRUE);
|
||||
meta_error_trap_pop (results->display);
|
||||
|
||||
w = meta_display_lookup_x_window (results->display, results->xwindow);
|
||||
|
||||
@@ -204,11 +204,11 @@ get_property (MetaDisplay *display,
|
||||
{
|
||||
if (results->prop)
|
||||
XFree (results->prop);
|
||||
meta_error_trap_pop_with_return (display, TRUE);
|
||||
meta_error_trap_pop_with_return (display);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (meta_error_trap_pop_with_return (display, TRUE) != Success)
|
||||
if (meta_error_trap_pop_with_return (display) != Success)
|
||||
{
|
||||
if (results->prop)
|
||||
XFree (results->prop);
|
||||
@@ -490,7 +490,7 @@ utf8_list_from_results (GetPropertyResults *results,
|
||||
|
||||
meta_error_trap_push (results->display);
|
||||
name = XGetAtomName (results->display->xdisplay, results->xatom);
|
||||
meta_error_trap_pop (results->display, TRUE);
|
||||
meta_error_trap_pop (results->display);
|
||||
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"),
|
||||
name, results->xwindow, i);
|
||||
meta_XFree (name);
|
||||
@@ -547,7 +547,7 @@ meta_prop_set_utf8_string_hint (MetaDisplay *display,
|
||||
xwindow, atom,
|
||||
display->atom_UTF8_STRING,
|
||||
8, PropModeReplace, (guchar*) val, strlen (val));
|
||||
meta_error_trap_pop (display, FALSE);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef __GDK_COMPAT_H__
|
||||
#define __GDK_COMPAT_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Provide a compatibility layer for accessor function introduced
|
||||
* in GTK+ 2.22 which we need to build without deprecated GDK symbols.
|
||||
* That way it is still possible to build with GTK+ 2.18 when not
|
||||
* using GDK_DISABLE_DEPRECATED.
|
||||
*/
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 21, 1)
|
||||
|
||||
#define gdk_visual_get_depth(v) GDK_VISUAL(v)->depth
|
||||
|
||||
#endif /* GTK_CHECK_VERSION (2, 21, 1) */
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 90, 8)
|
||||
|
||||
#define gdk_window_get_screen gdk_drawable_get_screen
|
||||
#define gdk_pixbuf_get_from_window(window, src_x, src_y, width, height) \
|
||||
gdk_pixbuf_get_from_drawable(NULL, window, NULL, src_x, src_y, 0, 0, width, height)
|
||||
|
||||
static inline int
|
||||
gdk_window_get_width (GdkWindow *window)
|
||||
{
|
||||
int width;
|
||||
|
||||
gdk_drawable_get_size (window, &width, NULL);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static inline int
|
||||
gdk_window_get_height (GdkWindow *window)
|
||||
{
|
||||
int height;
|
||||
|
||||
gdk_drawable_get_size (window, NULL, &height);
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
static inline gboolean
|
||||
gdk_cairo_get_clip_rectangle (cairo_t *cr,
|
||||
GdkRectangle *rect)
|
||||
{
|
||||
double x1, y1, x2, y2;
|
||||
gboolean clip_exists;
|
||||
|
||||
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
|
||||
|
||||
clip_exists = x1 < x2 && y1 < y2;
|
||||
|
||||
if (rect)
|
||||
{
|
||||
x1 = floor (x1);
|
||||
y1 = floor (y1);
|
||||
x2 = ceil (x2);
|
||||
y2 = ceil (y2);
|
||||
|
||||
rect->x = CLAMP (x1, G_MININT, G_MAXINT);
|
||||
rect->y = CLAMP (y1, G_MININT, G_MAXINT);
|
||||
rect->width = CLAMP (x2 - x1, G_MININT, G_MAXINT);
|
||||
rect->height = CLAMP (y2 - y1, G_MININT, G_MAXINT);
|
||||
}
|
||||
|
||||
return clip_exists;
|
||||
}
|
||||
|
||||
#endif /* GTK_CHECK_VERSION (2, 90, 8) */
|
||||
|
||||
/* Compatibility with old GDK key symbols */
|
||||
#ifndef GDK_KEY_Escape
|
||||
#define GDK_KEY_Escape GDK_Escape
|
||||
#endif /* GDK_KEY_Escape */
|
||||
|
||||
#endif /* __GDK_COMPAT_H__ */
|
||||
@@ -1,177 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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 "gdk2-drawing-utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gdk-compat.h"
|
||||
|
||||
#ifndef USE_GTK3
|
||||
|
||||
static const cairo_user_data_key_t context_key;
|
||||
|
||||
cairo_t *
|
||||
meta_cairo_create (GdkDrawable *drawable)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_cairo_create (drawable);
|
||||
cairo_set_user_data (cr, &context_key, drawable, NULL);
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
extract_window (cairo_t *cr,
|
||||
int *dx,
|
||||
int *dy,
|
||||
GdkRectangle *clip_area)
|
||||
{
|
||||
GdkWindow *window = cairo_get_user_data (cr, &context_key);
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
g_assert (dx != NULL);
|
||||
g_assert (dy != NULL);
|
||||
g_assert (clip_area != NULL);
|
||||
|
||||
/* lots of stuff that mustn't happen because we can't cope with it. */
|
||||
if (window == NULL)
|
||||
{
|
||||
g_error ("Could not get the GdkWindow from the cairo context passed to\n"
|
||||
"theme drawing functions. A GdkWindow must be set on all cairo\n"
|
||||
"context passed to theme drawing functions when using GTK2.\n"
|
||||
"Please use meta_cairo_create() to create the Cairo context.\n");
|
||||
}
|
||||
cairo_get_matrix (cr, &matrix);
|
||||
if (matrix.xx != 1.0 || matrix.yy != 1.0 ||
|
||||
matrix.xy != 0.0 || matrix.yx != 0.0 ||
|
||||
floor (matrix.x0) != matrix.x0 ||
|
||||
floor (matrix.y0) != matrix.y0)
|
||||
{
|
||||
g_error ("GTK2 drawing requires that the matrix set on the cairo context\n"
|
||||
"is an integer translation, however that is not the case.\n");
|
||||
}
|
||||
|
||||
gdk_cairo_get_clip_rectangle (cr, clip_area);
|
||||
clip_area->x += matrix.x0;
|
||||
clip_area->y += matrix.y0;
|
||||
|
||||
*dx = matrix.x0;
|
||||
*dy = matrix.y0;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_vline (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint y1_,
|
||||
gint y2_,
|
||||
gint x)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_vline (style, window, state_type, &area,
|
||||
widget, detail, y1_ + dy, y2_ + dy, x + dx);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_arrow (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
GtkArrowType arrow_type,
|
||||
gboolean fill,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_arrow (style, window, state_type, shadow_type,
|
||||
&area, widget, detail, arrow_type,
|
||||
fill, x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_box (style, window, state_type, shadow_type,
|
||||
&area, widget, detail,
|
||||
x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
meta_paint_flat_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
int dx, dy;
|
||||
GdkWindow *window;
|
||||
GdkRectangle area;
|
||||
|
||||
window = extract_window (cr, &dx, &dy, &area);
|
||||
|
||||
gtk_paint_flat_box (style, window, state_type, shadow_type,
|
||||
&area, widget, detail,
|
||||
x + dx, y + dy, width, height);
|
||||
}
|
||||
|
||||
#endif /* USE_GTK3 */
|
||||
@@ -1,100 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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 __GTK3_COMPAT_H__
|
||||
#define __GTK3_COMPAT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 90, 8)
|
||||
|
||||
#define USE_GTK3 1
|
||||
|
||||
#define MetaPixmap cairo_surface_t
|
||||
|
||||
#define meta_pixmap_new(window, w, h) gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR, w, h)
|
||||
#define meta_pixmap_free(pixmap) cairo_surface_destroy (pixmap)
|
||||
#define meta_pixmap_cairo_create(pixmap) cairo_create (pixmap)
|
||||
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) cairo_set_source_surface (cr, pixmap, x, y)
|
||||
|
||||
#define meta_paint_vline gtk_paint_vline
|
||||
#define meta_paint_box gtk_paint_box
|
||||
#define meta_paint_arrow gtk_paint_arrow
|
||||
#define meta_paint_flat_box gtk_paint_flat_box
|
||||
|
||||
#else /* GTK_VERSION < 2.90.8 */
|
||||
|
||||
#undef USE_GTK3
|
||||
|
||||
#define MetaPixmap GdkPixmap
|
||||
|
||||
#define meta_pixmap_new(window, w, h) gdk_pixmap_new (window, w, h, -1)
|
||||
#define meta_pixmap_free(pixmap) g_object_unref (pixmap)
|
||||
#define meta_pixmap_cairo_create(pixmap) meta_cairo_create (pixmap)
|
||||
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) gdk_cairo_set_source_pixmap (cr, pixmap, x, y)
|
||||
|
||||
/* This function only exists for GTK2 code. */
|
||||
cairo_t * meta_cairo_create (GdkDrawable *drawable);
|
||||
|
||||
void meta_paint_vline (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint y1_,
|
||||
gint y2_,
|
||||
gint x);
|
||||
void meta_paint_arrow (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
GtkArrowType arrow_type,
|
||||
gboolean fill,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
void meta_paint_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
void meta_paint_flat_box (GtkStyle *style,
|
||||
cairo_t *cr,
|
||||
GtkStateType state_type,
|
||||
GtkShadowType shadow_type,
|
||||
GtkWidget *widget,
|
||||
const gchar *detail,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
#endif /* GTK_VERSION < 2.90.8 */
|
||||
|
||||
#endif /* __GTK3_COMPAT_H__ */
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef __GTK_COMPAT_H__
|
||||
#define __GTK_COMPAT_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Provide a compatibility layer for accessor function introduces
|
||||
* in GTK+ 2.20 which we need to build with GSEAL_ENABLE.
|
||||
* That way it is still possible to build with GTK+ 2.18 when not
|
||||
* using GSEAL_ENABLE
|
||||
*/
|
||||
|
||||
#if !GTK_CHECK_VERSION (2, 20, 0)
|
||||
|
||||
#define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED (w)
|
||||
#define gtk_widget_get_requisition(w,r) (*r = GTK_WIDGET (w)->requisition)
|
||||
#define gtk_widget_set_mapped(w,m) \
|
||||
G_STMT_START { \
|
||||
if (m) \
|
||||
GTK_WIDGET_SET_FLAGS (w, GTK_MAPPED); \
|
||||
else \
|
||||
GTK_WIDGET_UNSET_FLAGS (w, GTK_MAPPED); \
|
||||
} G_STMT_END
|
||||
|
||||
#endif /* GTK_CHECK_VERSION */
|
||||
|
||||
#endif /* __GTK_COMPAT_H__ */
|
||||
@@ -195,6 +195,7 @@ typedef enum
|
||||
META_FRAME_TYPE_UTILITY,
|
||||
META_FRAME_TYPE_MENU,
|
||||
META_FRAME_TYPE_BORDER,
|
||||
META_FRAME_TYPE_ATTACHED,
|
||||
META_FRAME_TYPE_LAST
|
||||
} MetaFrameType;
|
||||
|
||||
|
||||
@@ -29,16 +29,12 @@
|
||||
#include "util.h"
|
||||
#include "display.h"
|
||||
|
||||
void meta_errors_init (void);
|
||||
|
||||
void meta_error_trap_push (MetaDisplay *display);
|
||||
void meta_error_trap_pop (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip);
|
||||
void meta_error_trap_pop (MetaDisplay *display);
|
||||
|
||||
void meta_error_trap_push_with_return (MetaDisplay *display);
|
||||
/* returns X error code, or 0 for no error */
|
||||
int meta_error_trap_pop_with_return (MetaDisplay *display,
|
||||
gboolean last_request_was_roundtrip);
|
||||
int meta_error_trap_pop_with_return (MetaDisplay *display);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
86
src/include/meta-shadow-factory.h
Normal file
86
src/include/meta-shadow-factory.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* MetaShadowFactory:
|
||||
*
|
||||
* Create and cache shadow textures for arbitrary window shapes
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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_SHADOW_FACTORY_H__
|
||||
#define __META_SHADOW_FACTORY_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
/**
|
||||
* MetaShadowParams:
|
||||
* The #MetaShadowParams structure holds information about how to draw
|
||||
* a particular style of shadow.
|
||||
* @radius: the radius (gaussian standard deviation) of the shadow
|
||||
* @top_fade: if >= 0, the shadow doesn't extend above the top
|
||||
* of the shape, and fades out over the given number of pixels
|
||||
* @x_offset: horizontal offset of the shadow with respect to the
|
||||
* shape being shadowed, in pixels
|
||||
* @y_offset: vertical offset of the shadow with respect to the
|
||||
* shape being shadowed, in pixels
|
||||
* @opacity: opacity of the shadow, from 0 to 255
|
||||
*/
|
||||
|
||||
typedef struct _MetaShadowParams MetaShadowParams;
|
||||
|
||||
struct _MetaShadowParams
|
||||
{
|
||||
int radius;
|
||||
int top_fade;
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
guint8 opacity;
|
||||
};
|
||||
|
||||
#define META_TYPE_SHADOW_FACTORY (meta_shadow_factory_get_type ())
|
||||
#define META_SHADOW_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SHADOW_FACTORY, MetaShadowFactory))
|
||||
#define META_SHADOW_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SHADOW_FACTORY, MetaShadowFactoryClass))
|
||||
#define META_IS_SHADOW_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_SHADOW_FACTORY))
|
||||
#define META_IS_SHADOW_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_SHADOW_FACTORY))
|
||||
#define META_SHADOW_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_SHADOW_FACTORY, MetaShadowFactoryClass))
|
||||
|
||||
/**
|
||||
* MetaShadowFactory:
|
||||
* #MetaShadowFactory is used to create window shadows. It caches shadows internally
|
||||
* so that multiple shadows created for the same shape with the same radius will
|
||||
* share the same MetaShadow.
|
||||
*/
|
||||
typedef struct _MetaShadowFactory MetaShadowFactory;
|
||||
typedef struct _MetaShadowFactoryClass MetaShadowFactoryClass;
|
||||
|
||||
MetaShadowFactory *meta_shadow_factory_get_default (void);
|
||||
|
||||
GType meta_shadow_factory_get_type (void);
|
||||
|
||||
MetaShadowFactory *meta_shadow_factory_new (void);
|
||||
|
||||
void meta_shadow_factory_set_params (MetaShadowFactory *factory,
|
||||
const char *class_name,
|
||||
gboolean focused,
|
||||
MetaShadowParams *params);
|
||||
void meta_shadow_factory_get_params (MetaShadowFactory *factory,
|
||||
const char *class_name,
|
||||
gboolean focused,
|
||||
MetaShadowParams *params);
|
||||
|
||||
#endif /* __META_SHADOW_FACTORY_H__ */
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
gboolean meta_is_verbose (void);
|
||||
void meta_set_verbose (gboolean setting);
|
||||
gboolean meta_is_debugging (void);
|
||||
@@ -91,6 +93,7 @@ guint meta_unsigned_long_hash (gconstpointer v);
|
||||
|
||||
void meta_print_backtrace (void);
|
||||
|
||||
const char* meta_frame_type_to_string (MetaFrameType type);
|
||||
const char* meta_gravity_to_string (int gravity);
|
||||
|
||||
#include <libintl.h>
|
||||
|
||||
@@ -69,6 +69,7 @@ GType meta_window_get_type (void);
|
||||
|
||||
MetaFrame *meta_window_get_frame (MetaWindow *window);
|
||||
gboolean meta_window_has_focus (MetaWindow *window);
|
||||
gboolean meta_window_appears_focused (MetaWindow *window);
|
||||
gboolean meta_window_is_shaded (MetaWindow *window);
|
||||
gboolean meta_window_is_override_redirect (MetaWindow *window);
|
||||
gboolean meta_window_is_skip_taskbar (MetaWindow *window);
|
||||
@@ -119,6 +120,9 @@ void meta_window_foreach_ancestor (MetaWindow *window,
|
||||
MetaWindowForeachFunc func,
|
||||
void *user_data);
|
||||
|
||||
MetaMaximizeFlags meta_window_get_maximized (MetaWindow *window);
|
||||
gboolean meta_window_is_fullscreen (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_toplevel_is_mapped (MetaWindow *window);
|
||||
gboolean meta_window_get_icon_geometry (MetaWindow *window,
|
||||
@@ -143,4 +147,7 @@ const char *meta_window_get_client_machine (MetaWindow *window);
|
||||
gboolean meta_window_is_remote (MetaWindow *window);
|
||||
gboolean meta_window_is_modal (MetaWindow *window);
|
||||
const char *meta_window_get_mutter_hints (MetaWindow *window);
|
||||
|
||||
MetaFrameType meta_window_get_frame_type (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@ libgnome_serverdir=@libexecdir@
|
||||
|
||||
Name: libmutter-private
|
||||
Description: Mutter internals shared
|
||||
Requires: gtk+-@GTK_API_VERSION@
|
||||
Requires: gtk+-3.0
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lmutter-private
|
||||
Cflags: -I${includedir}/mutter
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gdk-compat.h"
|
||||
|
||||
static GtkWidget *grab_widget = NULL;
|
||||
static GtkWidget *display_window = NULL;
|
||||
static int last_grab_x = 0;
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gtk-compat.h"
|
||||
|
||||
static GtkWidget* do_appwindow (void);
|
||||
|
||||
static gboolean aspect_on;
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "fixedtip.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
/**
|
||||
* The floating rectangle. This is a GtkWindow, and it contains
|
||||
* the "label" widget, below.
|
||||
@@ -52,7 +50,6 @@ static int screen_right_edge = 0;
|
||||
*/
|
||||
static int screen_bottom_edge = 0;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
draw_handler (GtkWidget *tooltips,
|
||||
cairo_t *cr,
|
||||
@@ -68,21 +65,6 @@ draw_handler (GtkWidget *tooltips,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#else /* !USE_GTK3 */
|
||||
static gint
|
||||
expose_handler (GtkWidget *tooltips,
|
||||
GdkEventExpose *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_paint_flat_box (gtk_widget_get_style (tip),
|
||||
gtk_widget_get_window (tip),
|
||||
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
|
||||
NULL, tip, "tooltip",
|
||||
0, 0, -1, -1);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* !USE_GTK3 */
|
||||
|
||||
void
|
||||
meta_fixed_tip_show (Display *xdisplay, int screen_number,
|
||||
@@ -116,13 +98,8 @@ meta_fixed_tip_show (Display *xdisplay, int screen_number,
|
||||
gtk_widget_set_name (tip, "gtk-tooltips");
|
||||
gtk_container_set_border_width (GTK_CONTAINER (tip), 4);
|
||||
|
||||
#ifdef USE_GTK3
|
||||
g_signal_connect (tip, "draw",
|
||||
G_CALLBACK (draw_handler), NULL);
|
||||
#else
|
||||
g_signal_connect (tip, "expose_event",
|
||||
G_CALLBACK (expose_handler), NULL);
|
||||
#endif
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
|
||||
166
src/ui/frames.c
166
src/ui/frames.c
@@ -35,10 +35,6 @@
|
||||
#include "prefs.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "gdk2-drawing-utils.h"
|
||||
#include "gtk-compat.h"
|
||||
#include "gdk-compat.h"
|
||||
|
||||
#include <cairo-xlib.h>
|
||||
|
||||
#ifdef HAVE_SHAPE
|
||||
@@ -47,11 +43,7 @@
|
||||
|
||||
#define DEFAULT_INNER_BUTTON_BORDER 3
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static void meta_frames_destroy (GtkWidget *object);
|
||||
#else
|
||||
static void meta_frames_destroy (GtkObject *object);
|
||||
#endif
|
||||
static void meta_frames_finalize (GObject *object);
|
||||
static void meta_frames_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style);
|
||||
@@ -69,13 +61,8 @@ static gboolean meta_frames_motion_notify_event (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
static gboolean meta_frames_destroy_event (GtkWidget *widget,
|
||||
GdkEventAny *event);
|
||||
#ifdef USE_GTK3
|
||||
static gboolean meta_frames_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
#else
|
||||
static gboolean meta_frames_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
#endif
|
||||
static gboolean meta_frames_enter_notify_event (GtkWidget *widget,
|
||||
GdkEventCrossing *event);
|
||||
static gboolean meta_frames_leave_notify_event (GtkWidget *widget,
|
||||
@@ -148,22 +135,14 @@ meta_frames_class_init (MetaFramesClass *class)
|
||||
gobject_class->constructor = meta_frames_constructor;
|
||||
gobject_class->finalize = meta_frames_finalize;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
widget_class->destroy = meta_frames_destroy;
|
||||
#else
|
||||
GTK_OBJECT_CLASS (class)->destroy = meta_frames_destroy;
|
||||
#endif
|
||||
|
||||
widget_class->style_set = meta_frames_style_set;
|
||||
|
||||
widget_class->map = meta_frames_map;
|
||||
widget_class->unmap = meta_frames_unmap;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
widget_class->draw = meta_frames_draw;
|
||||
#else
|
||||
widget_class->expose_event = meta_frames_expose_event;
|
||||
#endif
|
||||
widget_class->destroy_event = meta_frames_destroy_event;
|
||||
widget_class->button_press_event = meta_frames_button_press_event;
|
||||
widget_class->button_release_event = meta_frames_button_release_event;
|
||||
@@ -238,13 +217,8 @@ listify_func (gpointer key, gpointer value, gpointer data)
|
||||
*listp = g_slist_prepend (*listp, value);
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static void
|
||||
meta_frames_destroy (GtkWidget *object)
|
||||
#else
|
||||
static void
|
||||
meta_frames_destroy (GtkObject *object)
|
||||
#endif
|
||||
{
|
||||
GSList *winlist;
|
||||
GSList *tmp;
|
||||
@@ -268,11 +242,7 @@ meta_frames_destroy (GtkObject *object)
|
||||
}
|
||||
g_slist_free (winlist);
|
||||
|
||||
#ifdef USE_GTK3
|
||||
GTK_WIDGET_CLASS (meta_frames_parent_class)->destroy (object);
|
||||
#else
|
||||
GTK_OBJECT_CLASS (meta_frames_parent_class)->destroy (object);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -300,7 +270,7 @@ meta_frames_finalize (GObject *object)
|
||||
typedef struct
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
MetaPixmap *pixmap;
|
||||
cairo_surface_t *pixmap;
|
||||
} CachedFramePiece;
|
||||
|
||||
typedef struct
|
||||
@@ -337,7 +307,7 @@ invalidate_cache (MetaFrames *frames,
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (pixels->piece[i].pixmap)
|
||||
meta_pixmap_free (pixels->piece[i].pixmap);
|
||||
cairo_surface_destroy (pixels->piece[i].pixmap);
|
||||
|
||||
g_free (pixels);
|
||||
g_hash_table_remove (frames->cache, frame);
|
||||
@@ -2036,53 +2006,6 @@ meta_frames_destroy_event (GtkWidget *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if !GTK_CHECK_VERSION(2,21,6)
|
||||
/* Copied from GDK */
|
||||
static cairo_surface_t *
|
||||
_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
|
||||
|
||||
return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable);
|
||||
}
|
||||
|
||||
static cairo_pattern_t *
|
||||
gdk_window_get_background_pattern (GdkWindow *window)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject *) window;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
|
||||
|
||||
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG)
|
||||
pattern = NULL;
|
||||
else if (private->bg_pixmap != GDK_NO_BG &&
|
||||
private->bg_pixmap != NULL)
|
||||
{
|
||||
static cairo_user_data_key_t key;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap);
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
|
||||
cairo_pattern_set_user_data (pattern,
|
||||
&key,
|
||||
g_object_ref (private->bg_pixmap),
|
||||
g_object_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern =
|
||||
cairo_pattern_create_rgb (private->bg_color.red / 65535.,
|
||||
private->bg_color.green / 65535.,
|
||||
private->bg_color.blue / 65535.);
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
setup_bg_cr (cairo_t *cr, GdkWindow *window, int x_offset, int y_offset)
|
||||
@@ -2109,22 +2032,23 @@ setup_bg_cr (cairo_t *cr, GdkWindow *window, int x_offset, int y_offset)
|
||||
/* Returns a pixmap with a piece of the windows frame painted on it.
|
||||
*/
|
||||
|
||||
static MetaPixmap *
|
||||
static cairo_surface_t *
|
||||
generate_pixmap (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
MetaPixmap *result;
|
||||
cairo_surface_t *result;
|
||||
cairo_t *cr;
|
||||
|
||||
/* do not create a pixmap for nonexisting areas */
|
||||
if (rect->width <= 0 || rect->height <= 0)
|
||||
return NULL;
|
||||
|
||||
result = meta_pixmap_new (frame->window,
|
||||
rect->width, rect->height);
|
||||
result = gdk_window_create_similar_surface (frame->window,
|
||||
CAIRO_CONTENT_COLOR,
|
||||
rect->width, rect->height);
|
||||
|
||||
cr = meta_pixmap_cairo_create (result);
|
||||
cr = cairo_create (result);
|
||||
cairo_translate (cr, -rect->x, -rect->y);
|
||||
|
||||
setup_bg_cr (cr, frame->window, 0, 0);
|
||||
@@ -2295,8 +2219,8 @@ cached_pixels_draw (CachedPixels *pixels,
|
||||
|
||||
if (piece->pixmap)
|
||||
{
|
||||
meta_cairo_set_source_pixmap (cr, piece->pixmap,
|
||||
piece->rect.x, piece->rect.y);
|
||||
cairo_set_source_surface (cr, piece->pixmap,
|
||||
piece->rect.x, piece->rect.y);
|
||||
cairo_paint (cr);
|
||||
|
||||
region_piece = cairo_region_create_rectangle (&piece->rect);
|
||||
@@ -2306,7 +2230,6 @@ cached_pixels_draw (CachedPixels *pixels,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
meta_frames_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@@ -2373,75 +2296,6 @@ meta_frames_draw (GtkWidget *widget,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else /* !USE_GTK3 */
|
||||
static gboolean
|
||||
meta_frames_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
MetaUIFrame *frame;
|
||||
MetaFrames *frames;
|
||||
CachedPixels *pixels;
|
||||
cairo_region_t *region;
|
||||
int i, n_areas;
|
||||
GdkRectangle *event_rectangles;
|
||||
int n_event_rectangles;
|
||||
cairo_t *cr;
|
||||
|
||||
frames = META_FRAMES (widget);
|
||||
|
||||
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
|
||||
if (frame == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (frames->expose_delay_count > 0)
|
||||
{
|
||||
/* Redraw this entire frame later */
|
||||
frame->expose_delayed = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
populate_cache (frames, frame);
|
||||
|
||||
/* Count on GdkRectangle and cairo_rectangle_int_t being identical */
|
||||
gdk_region_get_rectangles (event->region, &event_rectangles, &n_event_rectangles);
|
||||
region = cairo_region_create_rectangles ((cairo_rectangle_int_t *)event_rectangles,
|
||||
n_event_rectangles);
|
||||
g_free (event_rectangles);
|
||||
|
||||
pixels = get_cache (frames, frame);
|
||||
|
||||
cr = gdk_cairo_create (event->window);
|
||||
cached_pixels_draw (pixels, cr, region);
|
||||
cairo_destroy (cr);
|
||||
|
||||
clip_to_screen (region, frame);
|
||||
subtract_client_area (region, frame);
|
||||
|
||||
n_areas = cairo_region_num_rectangles (region);
|
||||
|
||||
for (i = 0; i < n_areas; i++)
|
||||
{
|
||||
GdkRectangle area;
|
||||
|
||||
/* Count on GdkRectangle and cairo_rectangle_int_t being identical */
|
||||
cairo_region_get_rectangle (region, i, (cairo_rectangle_int_t *)&area);
|
||||
|
||||
gdk_window_begin_paint_rect (event->window, &area);
|
||||
cr = gdk_cairo_create (event->window);
|
||||
/* no need to clip, begin_paint_region ensures the pixmap
|
||||
* is only as big as the rect we use. */
|
||||
|
||||
meta_frames_paint (frames, frame, cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
gdk_window_end_paint (event->window);
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* !USE_GTK3 */
|
||||
|
||||
static void
|
||||
meta_frames_paint (MetaFrames *frames,
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
#include "metaaccellabel.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "gdk-compat.h"
|
||||
|
||||
typedef struct _MenuItem MenuItem;
|
||||
typedef struct _MenuData MenuData;
|
||||
|
||||
|
||||
@@ -37,24 +37,16 @@
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
#include "gtk-compat.h"
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static void meta_accel_label_destroy (GtkWidget *object);
|
||||
#else
|
||||
static void meta_accel_label_destroy (GtkObject *object);
|
||||
#endif
|
||||
static void meta_accel_label_finalize (GObject *object);
|
||||
static void meta_accel_label_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
#ifdef USE_GTK3
|
||||
static void meta_accel_label_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void meta_accel_label_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static gboolean meta_accel_label_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
#else
|
||||
static gboolean meta_accel_label_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
#endif
|
||||
|
||||
static void meta_accel_label_update (MetaAccelLabel *accel_label);
|
||||
static int meta_accel_label_get_accel_width (MetaAccelLabel *accel_label);
|
||||
@@ -69,18 +61,11 @@ meta_accel_label_class_init (MetaAccelLabelClass *class)
|
||||
|
||||
gobject_class->finalize = meta_accel_label_finalize;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
widget_class->destroy = meta_accel_label_destroy;
|
||||
#else
|
||||
GTK_OBJECT_CLASS (class)->destroy = meta_accel_label_destroy;
|
||||
#endif
|
||||
|
||||
widget_class->size_request = meta_accel_label_size_request;
|
||||
#ifdef USE_GTK3
|
||||
widget_class->get_preferred_width = meta_accel_label_get_preferred_width;
|
||||
widget_class->get_preferred_height = meta_accel_label_get_preferred_height;
|
||||
widget_class->draw = meta_accel_label_draw;
|
||||
#else
|
||||
widget_class->expose_event = meta_accel_label_expose_event;
|
||||
#endif
|
||||
|
||||
class->signal_quote1 = g_strdup ("<:");
|
||||
class->signal_quote2 = g_strdup (":>");
|
||||
@@ -173,13 +158,8 @@ meta_accel_label_new_with_mnemonic (const gchar *string)
|
||||
return GTK_WIDGET (accel_label);
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static void
|
||||
meta_accel_label_destroy (GtkWidget *object)
|
||||
#else
|
||||
static void
|
||||
meta_accel_label_destroy (GtkObject *object)
|
||||
#endif
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (object);
|
||||
|
||||
@@ -190,11 +170,7 @@ meta_accel_label_destroy (GtkObject *object)
|
||||
accel_label->accel_mods = 0;
|
||||
accel_label->accel_key = 0;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->destroy (object);
|
||||
#else
|
||||
GTK_OBJECT_CLASS (meta_accel_label_parent_class)->destroy (object);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -234,15 +210,15 @@ meta_accel_label_get_accel_width (MetaAccelLabel *accel_label)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_accel_label_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition)
|
||||
meta_accel_label_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
|
||||
PangoLayout *layout;
|
||||
gint width;
|
||||
|
||||
if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->size_request)
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->size_request (widget, requisition);
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->get_preferred_width (widget, minimum, natural);
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
|
||||
pango_layout_get_pixel_size (layout, &width, NULL);
|
||||
@@ -251,7 +227,14 @@ meta_accel_label_size_request (GtkWidget *widget,
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static void
|
||||
meta_accel_label_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->get_preferred_height (widget, minimum, natural);
|
||||
}
|
||||
|
||||
/* Mostly taken from GTK3. */
|
||||
static gboolean
|
||||
meta_accel_label_draw (GtkWidget *widget,
|
||||
@@ -338,89 +321,6 @@ meta_accel_label_draw (GtkWidget *widget,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#else /* !USE_GTK3 */
|
||||
static gboolean
|
||||
meta_accel_label_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
MetaAccelLabel *accel_label = META_ACCEL_LABEL (widget);
|
||||
GtkMisc *misc = GTK_MISC (accel_label);
|
||||
PangoLayout *layout;
|
||||
|
||||
if (gtk_widget_is_drawable (GTK_WIDGET (accel_label)))
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
GtkRequisition requisition;
|
||||
int ac_width;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
gtk_widget_get_requisition (widget, &requisition);
|
||||
ac_width = meta_accel_label_get_accel_width (accel_label);
|
||||
|
||||
if (allocation.width >= requisition.width + ac_width)
|
||||
{
|
||||
GtkTextDirection direction = gtk_widget_get_direction (widget);
|
||||
gfloat xalign, yalign;
|
||||
gint x, y;
|
||||
gint xpad, ypad;
|
||||
|
||||
gtk_misc_get_padding (misc, &xpad, &ypad);
|
||||
gtk_misc_get_alignment (misc, &xalign, &yalign);
|
||||
|
||||
if (direction == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
allocation.x += ac_width;
|
||||
}
|
||||
allocation.width -= ac_width;
|
||||
gtk_widget_set_allocation (widget, &allocation);
|
||||
|
||||
if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->expose_event)
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->expose_event (widget, event);
|
||||
|
||||
if (direction == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
allocation.x -= ac_width;
|
||||
}
|
||||
allocation.width += ac_width;
|
||||
gtk_widget_set_allocation (widget, &allocation);
|
||||
|
||||
if (direction == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
x = allocation.x + xpad;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = allocation.x + allocation.width - xpad - ac_width;
|
||||
}
|
||||
|
||||
y = (allocation.y * (1.0 - yalign) +
|
||||
(allocation.y + allocation.height -
|
||||
(requisition.height - ypad * 2)) * yalign) + 1.5;
|
||||
|
||||
layout = gtk_widget_create_pango_layout (widget, accel_label->accel_string);
|
||||
|
||||
gtk_paint_layout (gtk_widget_get_style (widget),
|
||||
gtk_widget_get_window (widget),
|
||||
gtk_widget_get_state (widget),
|
||||
FALSE,
|
||||
&event->area,
|
||||
widget,
|
||||
"accellabel",
|
||||
x, y,
|
||||
layout);
|
||||
|
||||
g_object_unref (G_OBJECT (layout));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GTK_WIDGET_CLASS (meta_accel_label_parent_class)->expose_event)
|
||||
GTK_WIDGET_CLASS (meta_accel_label_parent_class)->expose_event (widget, event);
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* !USE_GTK3 */
|
||||
|
||||
static void
|
||||
meta_accel_label_update (MetaAccelLabel *accel_label)
|
||||
|
||||
@@ -28,19 +28,16 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include "preview-widget.h"
|
||||
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
static void meta_preview_size_request (GtkWidget *widget,
|
||||
GtkRequisition *req);
|
||||
static void meta_preview_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void meta_preview_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void meta_preview_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
#ifdef USE_GTK3
|
||||
static gboolean meta_preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
#else
|
||||
static gboolean meta_preview_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
#endif
|
||||
static void meta_preview_finalize (GObject *object);
|
||||
|
||||
G_DEFINE_TYPE (MetaPreview, meta_preview, GTK_TYPE_BIN);
|
||||
@@ -55,13 +52,12 @@ meta_preview_class_init (MetaPreviewClass *class)
|
||||
|
||||
gobject_class->finalize = meta_preview_finalize;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
widget_class->draw = meta_preview_draw;
|
||||
#else
|
||||
widget_class->expose_event = meta_preview_expose;
|
||||
#endif
|
||||
widget_class->size_request = meta_preview_size_request;
|
||||
widget_class->get_preferred_width = meta_preview_get_preferred_width;
|
||||
widget_class->get_preferred_height = meta_preview_get_preferred_height;
|
||||
widget_class->size_allocate = meta_preview_size_allocate;
|
||||
|
||||
gtk_container_class_handle_border_width (GTK_CONTAINER_CLASS (class));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -194,7 +190,6 @@ ensure_info (MetaPreview *preview)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
meta_preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@@ -203,25 +198,9 @@ meta_preview_draw (GtkWidget *widget,
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
#else
|
||||
static gboolean
|
||||
meta_preview_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
cairo_t *cr = meta_cairo_create (gtk_widget_get_window (widget));
|
||||
MetaPreview *preview = META_PREVIEW (widget);
|
||||
GtkAllocation allocation;
|
||||
|
||||
gdk_cairo_region (cr, event->region);
|
||||
cairo_clip (cr);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
cairo_translate (cr, allocation.x, allocation.y);
|
||||
#endif
|
||||
|
||||
if (preview->theme)
|
||||
{
|
||||
int border_width;
|
||||
int client_width;
|
||||
int client_height;
|
||||
MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
|
||||
@@ -235,11 +214,8 @@ meta_preview_expose (GtkWidget *widget,
|
||||
ensure_info (preview);
|
||||
cairo_save (cr);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
cairo_translate (cr, border_width, border_width);
|
||||
|
||||
client_width = allocation.width - preview->left_width - preview->right_width - border_width * 2;
|
||||
client_height = allocation.height - preview->top_height - preview->bottom_height - border_width * 2;
|
||||
client_width = allocation.width - preview->left_width - preview->right_width;
|
||||
client_height = allocation.height - preview->top_height - preview->bottom_height;
|
||||
|
||||
if (client_width < 0)
|
||||
client_width = 1;
|
||||
@@ -262,53 +238,73 @@ meta_preview_expose (GtkWidget *widget,
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
/* draw child */
|
||||
return GTK_WIDGET_CLASS (meta_preview_parent_class)->draw (widget, cr);
|
||||
#else
|
||||
cairo_destroy (cr);
|
||||
|
||||
/* draw child */
|
||||
return GTK_WIDGET_CLASS (meta_preview_parent_class)->expose_event (widget, event);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NO_CHILD_WIDTH 80
|
||||
#define NO_CHILD_HEIGHT 20
|
||||
|
||||
static void
|
||||
meta_preview_size_request (GtkWidget *widget,
|
||||
GtkRequisition *req)
|
||||
meta_preview_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
MetaPreview *preview;
|
||||
GtkWidget *child;
|
||||
guint border_width;
|
||||
|
||||
preview = META_PREVIEW (widget);
|
||||
|
||||
ensure_info (preview);
|
||||
|
||||
req->width = preview->left_width + preview->right_width;
|
||||
req->height = preview->top_height + preview->bottom_height;
|
||||
*minimum = *natural = preview->left_width + preview->right_width;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (preview));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
GtkRequisition child_requisition;
|
||||
gint child_min, child_nat;
|
||||
|
||||
gtk_widget_size_request (child, &child_requisition);
|
||||
gtk_widget_get_preferred_width (child, &child_min, &child_nat);
|
||||
|
||||
req->width += child_requisition.width;
|
||||
req->height += child_requisition.height;
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
}
|
||||
else
|
||||
{
|
||||
#define NO_CHILD_WIDTH 80
|
||||
#define NO_CHILD_HEIGHT 20
|
||||
req->width += NO_CHILD_WIDTH;
|
||||
req->height += NO_CHILD_HEIGHT;
|
||||
*minimum += NO_CHILD_WIDTH;
|
||||
*natural += NO_CHILD_WIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
req->width += border_width * 2;
|
||||
req->height += border_width * 2;
|
||||
static void
|
||||
meta_preview_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
MetaPreview *preview;
|
||||
GtkWidget *child;
|
||||
|
||||
preview = META_PREVIEW (widget);
|
||||
|
||||
ensure_info (preview);
|
||||
|
||||
*minimum = *natural = preview->top_height + preview->bottom_height;
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (preview));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gint child_min, child_nat;
|
||||
|
||||
gtk_widget_get_preferred_height (child, &child_min, &child_nat);
|
||||
|
||||
*minimum += child_min;
|
||||
*natural += child_nat;
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum += NO_CHILD_HEIGHT;
|
||||
*natural += NO_CHILD_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -318,7 +314,6 @@ meta_preview_size_allocate (GtkWidget *widget,
|
||||
MetaPreview *preview;
|
||||
GtkAllocation widget_allocation, child_allocation;
|
||||
GtkWidget *child;
|
||||
guint border_width;
|
||||
|
||||
preview = META_PREVIEW (widget);
|
||||
|
||||
@@ -326,17 +321,15 @@ meta_preview_size_allocate (GtkWidget *widget,
|
||||
|
||||
gtk_widget_set_allocation (widget, allocation);
|
||||
|
||||
border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
||||
if (child && gtk_widget_get_visible (child))
|
||||
{
|
||||
gtk_widget_get_allocation (widget, &widget_allocation);
|
||||
child_allocation.x = widget_allocation.x + border_width + preview->left_width;
|
||||
child_allocation.y = widget_allocation.y + border_width + preview->top_height;
|
||||
child_allocation.x = widget_allocation.x + preview->left_width;
|
||||
child_allocation.y = widget_allocation.y + preview->top_height;
|
||||
|
||||
child_allocation.width = MAX (1, widget_allocation.width - border_width * 2 - preview->left_width - preview->right_width);
|
||||
child_allocation.height = MAX (1, widget_allocation.height - border_width * 2 - preview->top_height - preview->bottom_height);
|
||||
child_allocation.width = MAX (1, widget_allocation.width - preview->left_width - preview->right_width);
|
||||
child_allocation.height = MAX (1, widget_allocation.height - preview->top_height - preview->bottom_height);
|
||||
|
||||
gtk_widget_size_allocate (child, &child_allocation);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "util.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include "gtk-compat.h"
|
||||
|
||||
struct _MetaResizePopup
|
||||
{
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gtk-compat.h"
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
#define OUTSIDE_SELECT_RECT 2
|
||||
#define INSIDE_SELECT_RECT 2
|
||||
|
||||
@@ -74,21 +71,11 @@ static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
|
||||
static void select_workspace (GtkWidget *widget);
|
||||
static void unselect_workspace (GtkWidget *widget);
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
outline_window_draw (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
gpointer data)
|
||||
{
|
||||
#else /* !USE_GTK3 */
|
||||
static gboolean
|
||||
outline_window_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
cairo_t *cr = gdk_cairo_create (event->window);
|
||||
#endif /* !USE_GTK3 */
|
||||
|
||||
MetaTabPopup *popup;
|
||||
TabEntry *te;
|
||||
GtkStyle *style;
|
||||
@@ -116,10 +103,6 @@ outline_window_expose (GtkWidget *widget,
|
||||
te->inner_rect.height + 1);
|
||||
cairo_stroke (cr);
|
||||
|
||||
#ifndef USE_GTK3
|
||||
cairo_destroy (cr);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -260,13 +243,8 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries,
|
||||
gtk_widget_set_app_paintable (popup->outline_window, TRUE);
|
||||
gtk_widget_realize (popup->outline_window);
|
||||
|
||||
#ifdef USE_GTK3
|
||||
g_signal_connect (G_OBJECT (popup->outline_window), "draw",
|
||||
G_CALLBACK (outline_window_draw), popup);
|
||||
#else
|
||||
g_signal_connect (G_OBJECT (popup->outline_window), "expose_event",
|
||||
G_CALLBACK (outline_window_expose), popup);
|
||||
#endif
|
||||
|
||||
popup->window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
|
||||
@@ -499,6 +477,9 @@ display_entry (MetaTabPopup *popup,
|
||||
|
||||
if (popup->outline)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
cairo_region_t *inner_region;
|
||||
|
||||
window = gtk_widget_get_window (popup->outline_window);
|
||||
|
||||
/* Do stuff behind gtk's back */
|
||||
@@ -516,40 +497,20 @@ display_entry (MetaTabPopup *popup,
|
||||
|
||||
gdk_window_set_background (window,
|
||||
>k_widget_get_style (popup->outline_window)->black);
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 90, 8) /* gtk3 */
|
||||
{
|
||||
cairo_region_t *region;
|
||||
cairo_region_t *inner_region;
|
||||
|
||||
region = cairo_region_create_rectangle (&rect);
|
||||
inner_region = cairo_region_create_rectangle (&te->inner_rect);
|
||||
cairo_region_subtract (region, inner_region);
|
||||
cairo_region_destroy (inner_region);
|
||||
|
||||
gdk_window_shape_combine_region (window,
|
||||
region,
|
||||
0, 0);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
#else /* gtk2 */
|
||||
{
|
||||
GdkRegion *region;
|
||||
GdkRegion *inner_region;
|
||||
region = cairo_region_create_rectangle (&rect);
|
||||
inner_region = cairo_region_create_rectangle (&te->inner_rect);
|
||||
cairo_region_subtract (region, inner_region);
|
||||
cairo_region_destroy (inner_region);
|
||||
|
||||
region = gdk_region_rectangle (&rect);
|
||||
inner_region = gdk_region_rectangle (&te->inner_rect);
|
||||
gdk_region_subtract (region, inner_region);
|
||||
gdk_region_destroy (inner_region);
|
||||
gdk_window_shape_combine_region (window,
|
||||
region,
|
||||
0, 0);
|
||||
|
||||
gdk_window_shape_combine_region (window,
|
||||
region,
|
||||
0, 0);
|
||||
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
#endif /* gtk2 */
|
||||
cairo_region_destroy (region);
|
||||
|
||||
|
||||
/* This should piss off gtk a bit, but we don't want to raise
|
||||
* above the tab popup. So, instead of calling gtk_widget_show,
|
||||
@@ -693,13 +654,8 @@ unselect_image (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void meta_select_image_class_init (MetaSelectImageClass *klass);
|
||||
#if USE_GTK3
|
||||
static gboolean meta_select_image_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
#else
|
||||
static gboolean meta_select_image_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
#endif
|
||||
|
||||
static GtkImageClass *parent_class;
|
||||
|
||||
@@ -738,14 +694,9 @@ meta_select_image_class_init (MetaSelectImageClass *klass)
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
#if USE_GTK3
|
||||
widget_class->draw = meta_select_image_draw;
|
||||
#else
|
||||
widget_class->expose_event = meta_select_image_expose_event;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_GTK3
|
||||
static gboolean
|
||||
meta_select_image_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@@ -753,19 +704,6 @@ meta_select_image_draw (GtkWidget *widget,
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
#else /* !USE_GTK3 */
|
||||
static gboolean
|
||||
meta_select_image_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
cairo_t *cr = gdk_cairo_create (event->window);
|
||||
|
||||
gdk_cairo_region (cr, event->region);
|
||||
cairo_clip (cr);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
cairo_translate (cr, allocation.x, allocation.y);
|
||||
#endif
|
||||
|
||||
if (META_SELECT_IMAGE (widget)->selected)
|
||||
{
|
||||
@@ -806,13 +744,7 @@ meta_select_image_expose_event (GtkWidget *widget,
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
|
||||
#else
|
||||
cairo_destroy (cr);
|
||||
|
||||
return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
|
||||
#endif /* !USE_GTK3 */
|
||||
}
|
||||
|
||||
#define META_TYPE_SELECT_WORKSPACE (meta_select_workspace_get_type ())
|
||||
@@ -876,13 +808,8 @@ unselect_workspace (GtkWidget *widget)
|
||||
|
||||
static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
|
||||
|
||||
#if USE_GTK3
|
||||
static gboolean meta_select_workspace_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
#else
|
||||
static gboolean meta_select_workspace_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
#endif
|
||||
|
||||
GType
|
||||
meta_select_workspace_get_type (void)
|
||||
@@ -920,11 +847,7 @@ meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
#if USE_GTK3
|
||||
widget_class->draw = meta_select_workspace_draw;
|
||||
#else
|
||||
widget_class->expose_event = meta_select_workspace_expose_event;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -961,18 +884,10 @@ meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
meta_select_workspace_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
#else /* !USE_GTK3 */
|
||||
static gboolean
|
||||
meta_select_workspace_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
cairo_t *cr = gdk_cairo_create (event->window);
|
||||
#endif /* !USE_GTK3 */
|
||||
MetaWorkspace *workspace;
|
||||
WnckWindowDisplayInfo *windows;
|
||||
GtkAllocation allocation;
|
||||
@@ -1047,9 +962,5 @@ meta_select_workspace_expose_event (GtkWidget *widget,
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
#ifndef USE_GTK3
|
||||
cairo_destroy (cr);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
* look out for.
|
||||
*/
|
||||
#define THEME_MAJOR_VERSION 3
|
||||
#define THEME_MINOR_VERSION 1
|
||||
#define THEME_MINOR_VERSION 2
|
||||
#define THEME_VERSION (1000 * THEME_MAJOR_VERSION + THEME_MINOR_VERSION)
|
||||
|
||||
#define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml"
|
||||
@@ -1257,7 +1257,8 @@ parse_toplevel_element (GMarkupParseContext *context,
|
||||
|
||||
type = meta_frame_type_from_string (type_name);
|
||||
|
||||
if (type == META_FRAME_TYPE_LAST)
|
||||
if (type == META_FRAME_TYPE_LAST ||
|
||||
(type == META_FRAME_TYPE_ATTACHED && peek_required_version (info) < 3002))
|
||||
{
|
||||
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
|
||||
_("Unknown type \"%s\" on <%s> element"),
|
||||
|
||||
@@ -1189,7 +1189,6 @@ const char* meta_frame_resize_to_string (MetaFrameResize r
|
||||
MetaFrameFocus meta_frame_focus_from_string (const char *str);
|
||||
const char* meta_frame_focus_to_string (MetaFrameFocus focus);
|
||||
MetaFrameType meta_frame_type_from_string (const char *str);
|
||||
const char* meta_frame_type_to_string (MetaFrameType type);
|
||||
MetaGradientType meta_gradient_type_from_string (const char *str);
|
||||
const char* meta_gradient_type_to_string (MetaGradientType type);
|
||||
GtkStateType meta_gtk_state_from_string (const char *str);
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
#define N_(x) x
|
||||
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
/* We need to compute all different button arrangements
|
||||
* in terms of button location. We don't care about
|
||||
* different arrangements in terms of button function.
|
||||
@@ -409,6 +407,10 @@ get_window_contents (MetaFrameType type,
|
||||
case META_FRAME_TYPE_BORDER:
|
||||
*title = _("Border");
|
||||
return border_only_contents ();
|
||||
|
||||
case META_FRAME_TYPE_ATTACHED:
|
||||
*title = _("Attached Modal Dialog");
|
||||
return dialog_contents ();
|
||||
|
||||
case META_FRAME_TYPE_LAST:
|
||||
g_assert_not_reached ();
|
||||
@@ -456,6 +458,9 @@ get_window_flags (MetaFrameType type)
|
||||
|
||||
case META_FRAME_TYPE_BORDER:
|
||||
break;
|
||||
|
||||
case META_FRAME_TYPE_ATTACHED:
|
||||
break;
|
||||
|
||||
case META_FRAME_TYPE_LAST:
|
||||
g_assert_not_reached ();
|
||||
@@ -942,7 +947,7 @@ static void
|
||||
run_theme_benchmark (void)
|
||||
{
|
||||
GtkWidget* widget;
|
||||
MetaPixmap *pixmap;
|
||||
cairo_surface_t *pixmap;
|
||||
int top_height, bottom_height, left_width, right_width;
|
||||
MetaButtonState button_states[META_BUTTON_TYPE_LAST] =
|
||||
{
|
||||
@@ -1006,11 +1011,12 @@ run_theme_benchmark (void)
|
||||
/* Creating the pixmap in the loop is right, since
|
||||
* GDK does the same with its double buffering.
|
||||
*/
|
||||
pixmap = meta_pixmap_new (gtk_widget_get_window (widget),
|
||||
client_width + left_width + right_width,
|
||||
client_height + top_height + bottom_height);
|
||||
pixmap = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
|
||||
CAIRO_CONTENT_COLOR,
|
||||
client_width + left_width + right_width,
|
||||
client_height + top_height + bottom_height);
|
||||
|
||||
cr = meta_pixmap_cairo_create (pixmap);
|
||||
cr = cairo_create (pixmap);
|
||||
|
||||
meta_theme_draw_frame (global_theme,
|
||||
widget,
|
||||
@@ -1026,7 +1032,7 @@ run_theme_benchmark (void)
|
||||
meta_preview_get_icon ());
|
||||
|
||||
cairo_destroy (cr);
|
||||
meta_pixmap_free (pixmap);
|
||||
cairo_surface_destroy (pixmap);
|
||||
|
||||
++i;
|
||||
client_width += inc;
|
||||
|
||||
@@ -61,10 +61,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gtk-compat.h"
|
||||
#include "gdk-compat.h"
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
#define GDK_COLOR_RGBA(color) \
|
||||
((guint32) (0xff | \
|
||||
(((color).red / 256) << 24) | \
|
||||
@@ -3712,7 +3708,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
rwidth = parse_size_unchecked (op->data.gtk_arrow.width, env);
|
||||
rheight = parse_size_unchecked (op->data.gtk_arrow.height, env);
|
||||
|
||||
meta_paint_arrow (style_gtk,
|
||||
gtk_paint_arrow (style_gtk,
|
||||
cr,
|
||||
op->data.gtk_arrow.state,
|
||||
op->data.gtk_arrow.shadow,
|
||||
@@ -3733,7 +3729,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
rwidth = parse_size_unchecked (op->data.gtk_box.width, env);
|
||||
rheight = parse_size_unchecked (op->data.gtk_box.height, env);
|
||||
|
||||
meta_paint_box (style_gtk,
|
||||
gtk_paint_box (style_gtk,
|
||||
cr,
|
||||
op->data.gtk_box.state,
|
||||
op->data.gtk_box.shadow,
|
||||
@@ -3751,7 +3747,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
|
||||
ry1 = parse_y_position_unchecked (op->data.gtk_vline.y1, env);
|
||||
ry2 = parse_y_position_unchecked (op->data.gtk_vline.y2, env);
|
||||
|
||||
meta_paint_vline (style_gtk,
|
||||
gtk_paint_vline (style_gtk,
|
||||
cr,
|
||||
op->data.gtk_vline.state,
|
||||
widget,
|
||||
@@ -4996,7 +4992,7 @@ meta_theme_validate (MetaTheme *theme,
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)META_FRAME_TYPE_LAST; i++)
|
||||
if (theme->style_sets_by_type[i] == NULL)
|
||||
if (i != (int)META_FRAME_TYPE_ATTACHED && theme->style_sets_by_type[i] == NULL)
|
||||
{
|
||||
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
||||
_("No frame style set for window type \"%s\" in theme \"%s\", add a <window type=\"%s\" style_set=\"whatever\"/> element"),
|
||||
@@ -5078,7 +5074,10 @@ theme_get_style (MetaTheme *theme,
|
||||
|
||||
style_set = theme->style_sets_by_type[type];
|
||||
|
||||
/* Right now the parser forces a style set for all types,
|
||||
if (style_set == NULL && type == META_FRAME_TYPE_ATTACHED)
|
||||
style_set = theme->style_sets_by_type[META_FRAME_TYPE_BORDER];
|
||||
|
||||
/* Right now the parser forces a style set for all other types,
|
||||
* but this fallback code is here in case I take that out.
|
||||
*/
|
||||
if (style_set == NULL)
|
||||
@@ -6008,6 +6007,8 @@ meta_frame_type_from_string (const char *str)
|
||||
return META_FRAME_TYPE_MENU;
|
||||
else if (strcmp ("border", str) == 0)
|
||||
return META_FRAME_TYPE_BORDER;
|
||||
else if (strcmp ("attached", str) == 0)
|
||||
return META_FRAME_TYPE_ATTACHED;
|
||||
#if 0
|
||||
else if (strcmp ("toolbar", str) == 0)
|
||||
return META_FRAME_TYPE_TOOLBAR;
|
||||
@@ -6016,6 +6017,14 @@ meta_frame_type_from_string (const char *str)
|
||||
return META_FRAME_TYPE_LAST;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_frame_type_to_string:
|
||||
*
|
||||
* Converts a frame type enum value to the name string that would
|
||||
* appear in the theme definition file.
|
||||
*
|
||||
* Return value: the string value
|
||||
*/
|
||||
const char*
|
||||
meta_frame_type_to_string (MetaFrameType type)
|
||||
{
|
||||
@@ -6033,6 +6042,8 @@ meta_frame_type_to_string (MetaFrameType type)
|
||||
return "menu";
|
||||
case META_FRAME_TYPE_BORDER:
|
||||
return "border";
|
||||
case META_FRAME_TYPE_ATTACHED:
|
||||
return "attached";
|
||||
#if 0
|
||||
case META_FRAME_TYPE_TOOLBAR:
|
||||
return "toolbar";
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#include "tile-preview.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
#define OUTLINE_WIDTH 5 /* frame width in non-composite case */
|
||||
|
||||
|
||||
@@ -46,20 +44,11 @@ struct _MetaTilePreview {
|
||||
gboolean has_alpha: 1;
|
||||
};
|
||||
|
||||
#ifdef USE_GTK3
|
||||
static gboolean
|
||||
meta_tile_preview_draw (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
gpointer user_data)
|
||||
{
|
||||
#else
|
||||
static gboolean
|
||||
meta_tile_preview_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
cairo_t *cr = gdk_cairo_create (event->window);
|
||||
#endif
|
||||
MetaTilePreview *preview = user_data;
|
||||
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
@@ -98,10 +87,6 @@ meta_tile_preview_expose (GtkWidget *widget,
|
||||
preview->tile_rect.height - 1);
|
||||
cairo_stroke (cr);
|
||||
|
||||
#ifndef USE_GTK3
|
||||
cairo_destroy (cr);
|
||||
#endif
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -163,13 +148,8 @@ meta_tile_preview_new (int screen_number,
|
||||
|
||||
if (preview->has_alpha)
|
||||
{
|
||||
#ifdef USE_GTK3
|
||||
gtk_widget_set_visual (preview->preview_window,
|
||||
gdk_screen_get_rgba_visual (screen));
|
||||
#else
|
||||
gtk_widget_set_colormap (preview->preview_window,
|
||||
gdk_screen_get_rgba_colormap (screen));
|
||||
#endif
|
||||
|
||||
g_signal_connect (preview->preview_window, "style-set",
|
||||
G_CALLBACK (on_preview_window_style_set), preview);
|
||||
@@ -181,15 +161,8 @@ meta_tile_preview_new (int screen_number,
|
||||
*/
|
||||
preview->create_serial = XNextRequest (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
||||
gtk_widget_realize (preview->preview_window);
|
||||
#ifdef USE_GTK3
|
||||
g_signal_connect (preview->preview_window, "draw",
|
||||
G_CALLBACK (meta_tile_preview_draw), preview);
|
||||
#else
|
||||
gdk_window_set_back_pixmap (gtk_widget_get_window (preview->preview_window),
|
||||
NULL, FALSE);
|
||||
g_signal_connect (preview->preview_window, "expose-event",
|
||||
G_CALLBACK (meta_tile_preview_expose), preview);
|
||||
#endif
|
||||
|
||||
return preview;
|
||||
}
|
||||
@@ -239,6 +212,7 @@ meta_tile_preview_show (MetaTilePreview *preview,
|
||||
|
||||
if (!preview->has_alpha)
|
||||
{
|
||||
cairo_region_t *outer_region, *inner_region;
|
||||
GdkRectangle outer_rect, inner_rect;
|
||||
GdkColor black;
|
||||
|
||||
@@ -254,33 +228,14 @@ meta_tile_preview_show (MetaTilePreview *preview,
|
||||
inner_rect.width = outer_rect.width - 2 * OUTLINE_WIDTH;
|
||||
inner_rect.height = outer_rect.height - 2 * OUTLINE_WIDTH;
|
||||
|
||||
#if GTK_CHECK_VERSION (2, 90, 8) /* gtk3 */
|
||||
{
|
||||
cairo_region_t *outer_region, *inner_region;
|
||||
outer_region = cairo_region_create_rectangle (&outer_rect);
|
||||
inner_region = cairo_region_create_rectangle (&inner_rect);
|
||||
|
||||
outer_region = cairo_region_create_rectangle (&outer_rect);
|
||||
inner_region = cairo_region_create_rectangle (&inner_rect);
|
||||
cairo_region_subtract (outer_region, inner_region);
|
||||
cairo_region_destroy (inner_region);
|
||||
|
||||
cairo_region_subtract (outer_region, inner_region);
|
||||
cairo_region_destroy (inner_region);
|
||||
|
||||
gdk_window_shape_combine_region (window, outer_region, 0, 0);
|
||||
cairo_region_destroy (outer_region);
|
||||
}
|
||||
#else /* gtk2 */
|
||||
{
|
||||
GdkRegion *outer_region, *inner_region;
|
||||
|
||||
outer_region = gdk_region_rectangle (&outer_rect);
|
||||
inner_region = gdk_region_rectangle (&inner_rect);
|
||||
|
||||
gdk_region_subtract (outer_region, inner_region);
|
||||
gdk_region_destroy (inner_region);
|
||||
|
||||
gdk_window_shape_combine_region (window, outer_region, 0, 0);
|
||||
gdk_region_destroy (outer_region);
|
||||
}
|
||||
#endif /* gtk2 */
|
||||
gdk_window_shape_combine_region (window, outer_region, 0, 0);
|
||||
cairo_region_destroy (outer_region);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
251
src/ui/ui.c
251
src/ui/ui.c
@@ -32,8 +32,6 @@
|
||||
#include "theme-private.h"
|
||||
|
||||
#include "inlinepixbufs.h"
|
||||
#include "gdk-compat.h"
|
||||
#include "gdk2-drawing-utils.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -50,6 +48,13 @@ struct _MetaUI
|
||||
Display *xdisplay;
|
||||
Screen *xscreen;
|
||||
MetaFrames *frames;
|
||||
|
||||
/* For double-click tracking */
|
||||
guint button_click_number;
|
||||
Window button_click_window;
|
||||
int button_click_x;
|
||||
int button_click_y;
|
||||
guint32 button_click_time;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -67,6 +72,137 @@ meta_ui_get_display (void)
|
||||
return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
}
|
||||
|
||||
/* We do some of our event handling in frames.c, which expects
|
||||
* GDK events delivered by GTK+. However, since the transition to
|
||||
* client side windows, we can't let GDK see button events, since the
|
||||
* client-side tracking of implicit and explicit grabs it does will
|
||||
* get confused by our direct use of X grabs in the core code.
|
||||
*
|
||||
* So we do a very minimal GDK => GTK event conversion here and send on the
|
||||
* events we care about, and then filter them out so they don't go
|
||||
* through the normal GDK event handling.
|
||||
*
|
||||
* To reduce the amount of code, the only events fields filled out
|
||||
* below are the ones that frames.c uses. If frames.c is modified to
|
||||
* use more fields, more fields need to be filled out below.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
maybe_redirect_mouse_event (XEvent *xevent)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
MetaUI *ui;
|
||||
GdkEvent *gevent;
|
||||
GdkWindow *gdk_window;
|
||||
Window window;
|
||||
|
||||
switch (xevent->type)
|
||||
{
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
window = xevent->xbutton.window;
|
||||
break;
|
||||
case MotionNotify:
|
||||
window = xevent->xmotion.window;
|
||||
break;
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
window = xevent->xcrossing.window;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xevent->xany.display);
|
||||
ui = g_object_get_data (G_OBJECT (gdisplay), "meta-ui");
|
||||
if (!ui)
|
||||
return FALSE;
|
||||
|
||||
gdk_window = gdk_window_lookup_for_display (gdisplay, window);
|
||||
if (gdk_window == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* If GDK already thinks it has a grab, we better let it see events; this
|
||||
* is the menu-navigation case and events need to get sent to the appropriate
|
||||
* (client-side) subwindow for individual menu items.
|
||||
*/
|
||||
if (gdk_display_pointer_is_grabbed (gdisplay))
|
||||
return FALSE;
|
||||
|
||||
switch (xevent->type)
|
||||
{
|
||||
case ButtonPress:
|
||||
case ButtonRelease:
|
||||
if (xevent->type == ButtonPress)
|
||||
{
|
||||
GtkSettings *settings = gtk_settings_get_default ();
|
||||
int double_click_time;
|
||||
int double_click_distance;
|
||||
|
||||
g_object_get (settings,
|
||||
"gtk-double-click-time", &double_click_time,
|
||||
"gtk-double-click-distance", &double_click_distance,
|
||||
NULL);
|
||||
|
||||
if (xevent->xbutton.button == ui->button_click_number &&
|
||||
xevent->xbutton.window == ui->button_click_window &&
|
||||
xevent->xbutton.time < ui->button_click_time + double_click_time &&
|
||||
ABS (xevent->xbutton.x - ui->button_click_x) <= double_click_distance &&
|
||||
ABS (xevent->xbutton.y - ui->button_click_y) <= double_click_distance)
|
||||
{
|
||||
gevent = gdk_event_new (GDK_2BUTTON_PRESS);
|
||||
|
||||
ui->button_click_number = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_PRESS);
|
||||
ui->button_click_number = xevent->xbutton.button;
|
||||
ui->button_click_window = xevent->xbutton.window;
|
||||
ui->button_click_time = xevent->xbutton.time;
|
||||
ui->button_click_x = xevent->xbutton.x;
|
||||
ui->button_click_y = xevent->xbutton.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gevent = gdk_event_new (GDK_BUTTON_RELEASE);
|
||||
}
|
||||
|
||||
gevent->button.window = g_object_ref (gdk_window);
|
||||
gevent->button.button = xevent->xbutton.button;
|
||||
gevent->button.time = xevent->xbutton.time;
|
||||
gevent->button.x = xevent->xbutton.x;
|
||||
gevent->button.y = xevent->xbutton.y;
|
||||
gevent->button.x_root = xevent->xbutton.x_root;
|
||||
gevent->button.y_root = xevent->xbutton.y_root;
|
||||
|
||||
break;
|
||||
case MotionNotify:
|
||||
gevent = gdk_event_new (GDK_MOTION_NOTIFY);
|
||||
gevent->motion.type = GDK_MOTION_NOTIFY;
|
||||
gevent->motion.window = g_object_ref (gdk_window);
|
||||
break;
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
gevent = gdk_event_new (xevent->type == EnterNotify ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY);
|
||||
gevent->crossing.window = g_object_ref (gdk_window);
|
||||
gevent->crossing.x = xevent->xcrossing.x;
|
||||
gevent->crossing.y = xevent->xcrossing.y;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've gotten here, we've created the gdk_event and should send it on */
|
||||
gdk_event_set_device (gevent, gdk_display_get_core_pointer (gdisplay));
|
||||
gtk_main_do_event (gevent);
|
||||
gdk_event_free (gevent);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _EventFunc EventFunc;
|
||||
|
||||
struct _EventFunc
|
||||
@@ -84,7 +220,8 @@ filter_func (GdkXEvent *xevent,
|
||||
{
|
||||
g_return_val_if_fail (ef != NULL, GDK_FILTER_CONTINUE);
|
||||
|
||||
if ((* ef->func) (xevent, ef->data))
|
||||
if ((* ef->func) (xevent, ef->data) ||
|
||||
maybe_redirect_mouse_event (xevent))
|
||||
return GDK_FILTER_REMOVE;
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
@@ -122,27 +259,37 @@ MetaUI*
|
||||
meta_ui_new (Display *xdisplay,
|
||||
Screen *screen)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
MetaUI *ui;
|
||||
|
||||
ui = g_new (MetaUI, 1);
|
||||
ui = g_new0 (MetaUI, 1);
|
||||
ui->xdisplay = xdisplay;
|
||||
ui->xscreen = screen;
|
||||
|
||||
g_assert (xdisplay == GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
|
||||
gdisplay = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
g_assert (gdisplay == gdk_display_get_default ());
|
||||
|
||||
ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
|
||||
/* This does not actually show any widget. MetaFrames has been hacked so
|
||||
* that showing it doesn't actually do anything. But we need the flags
|
||||
* set for GTK to deliver events properly. */
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_free (MetaUI *ui)
|
||||
{
|
||||
GdkDisplay *gdisplay;
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (ui->frames));
|
||||
|
||||
gdisplay = gdk_x11_lookup_xdisplay (ui->xdisplay);
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", NULL);
|
||||
|
||||
g_free (ui);
|
||||
}
|
||||
|
||||
@@ -174,9 +321,6 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
gint attributes_mask;
|
||||
GdkWindow *window;
|
||||
GdkVisual *visual;
|
||||
#ifndef USE_GTK3
|
||||
GdkColormap *cmap = gdk_screen_get_default_colormap (screen);
|
||||
#endif
|
||||
|
||||
/* Default depth/visual handles clients with weird visuals; they can
|
||||
* always be children of the root depth/visual obviously, but
|
||||
@@ -189,9 +333,6 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
{
|
||||
visual = gdk_x11_screen_lookup_visual (screen,
|
||||
XVisualIDFromVisual (xvisual));
|
||||
#ifndef USE_GTK3
|
||||
cmap = gdk_colormap_new (visual, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
attrs.title = NULL;
|
||||
@@ -207,9 +348,6 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
attrs.y = y;
|
||||
attrs.wclass = GDK_INPUT_OUTPUT;
|
||||
attrs.visual = visual;
|
||||
#ifndef USE_GTK3
|
||||
attrs.colormap = cmap;
|
||||
#endif
|
||||
attrs.window_type = GDK_WINDOW_CHILD;
|
||||
attrs.cursor = NULL;
|
||||
attrs.wmclass_name = NULL;
|
||||
@@ -219,11 +357,7 @@ meta_ui_create_frame_window (MetaUI *ui,
|
||||
attrs.width = width;
|
||||
attrs.height = height;
|
||||
|
||||
#ifdef USE_GTK3
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
|
||||
#else
|
||||
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
|
||||
#endif
|
||||
|
||||
/* We make an assumption that gdk_window_new() is going to call
|
||||
* XCreateWindow as it's first operation; this seems to be true currently
|
||||
@@ -370,7 +504,6 @@ meta_ui_window_menu_free (MetaWindowMenu *menu)
|
||||
meta_window_menu_free (menu);
|
||||
}
|
||||
|
||||
#ifdef USE_GTK3
|
||||
GdkPixbuf*
|
||||
meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
@@ -420,84 +553,6 @@ meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
|
||||
return retval;
|
||||
}
|
||||
#else /* !USE_GTK3 */
|
||||
static GdkColormap*
|
||||
get_cmap (GdkPixmap *pixmap)
|
||||
{
|
||||
GdkColormap *cmap;
|
||||
|
||||
cmap = gdk_drawable_get_colormap (pixmap);
|
||||
if (cmap)
|
||||
g_object_ref (G_OBJECT (cmap));
|
||||
|
||||
if (cmap == NULL)
|
||||
{
|
||||
if (gdk_drawable_get_depth (pixmap) == 1)
|
||||
{
|
||||
meta_verbose ("Using NULL colormap for snapshotting bitmap\n");
|
||||
cmap = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_verbose ("Using system cmap to snapshot pixmap\n");
|
||||
cmap = gdk_screen_get_system_colormap (gdk_drawable_get_screen (pixmap));
|
||||
|
||||
g_object_ref (G_OBJECT (cmap));
|
||||
}
|
||||
}
|
||||
|
||||
/* Be sure we aren't going to blow up due to visual mismatch */
|
||||
if (cmap &&
|
||||
(gdk_visual_get_depth (gdk_colormap_get_visual (cmap)) !=
|
||||
gdk_drawable_get_depth (pixmap)))
|
||||
{
|
||||
cmap = NULL;
|
||||
meta_verbose ("Switching back to NULL cmap because of depth mismatch\n");
|
||||
}
|
||||
|
||||
return cmap;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkDrawable *drawable;
|
||||
GdkPixbuf *retval;
|
||||
GdkColormap *cmap;
|
||||
|
||||
retval = NULL;
|
||||
cmap = NULL;
|
||||
|
||||
drawable = gdk_xid_table_lookup (xpixmap);
|
||||
|
||||
if (drawable)
|
||||
g_object_ref (G_OBJECT (drawable));
|
||||
else
|
||||
drawable = gdk_pixmap_foreign_new (xpixmap);
|
||||
|
||||
if (drawable)
|
||||
{
|
||||
cmap = get_cmap (drawable);
|
||||
|
||||
retval = gdk_pixbuf_get_from_drawable (NULL,
|
||||
drawable,
|
||||
cmap,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
width, height);
|
||||
}
|
||||
if (cmap)
|
||||
g_object_unref (G_OBJECT (cmap));
|
||||
if (drawable)
|
||||
g_object_unref (G_OBJECT (drawable));
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif /* !USE_GTK3 */
|
||||
|
||||
void
|
||||
meta_ui_push_delay_exposes (MetaUI *ui)
|
||||
|
||||
Reference in New Issue
Block a user