Make window shadows globally configurable
Instead of setting shadow parameters on individual windows, add the idea of a "shadow class". Windows have default shadow classes based on their frame and window type, which can be overriden by setting the shadow-class property. Each shadow class has separably configurable parameters for the focused and unfocused state. New shadow classes can be defined with arbitrary names. https://bugzilla.gnome.org/show_bug.cgi?id=592382
This commit is contained in:
parent
7952feb48b
commit
1bbaec81ce
@ -11,6 +11,7 @@
|
|||||||
#include "compositor-mutter.h"
|
#include "compositor-mutter.h"
|
||||||
#include "xprops.h"
|
#include "xprops.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
|
#include "meta-shadow-factory.h"
|
||||||
#include "meta-window-actor-private.h"
|
#include "meta-window-actor-private.h"
|
||||||
#include "meta-window-group.h"
|
#include "meta-window-group.h"
|
||||||
#include "../core/window-private.h" /* to check window->hidden */
|
#include "../core/window-private.h" /* to check window->hidden */
|
||||||
@ -1017,6 +1018,26 @@ meta_repaint_func (gpointer data)
|
|||||||
return TRUE;
|
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)
|
* meta_compositor_new: (skip)
|
||||||
*
|
*
|
||||||
@ -1047,6 +1068,11 @@ meta_compositor_new (MetaDisplay *display)
|
|||||||
XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||||
False, atoms);
|
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_root_pixmap = atoms[0];
|
||||||
compositor->atom_x_set_root = atoms[1];
|
compositor->atom_x_set_root = atoms[1];
|
||||||
compositor->atom_net_wm_window_opacity = atoms[2];
|
compositor->atom_net_wm_window_opacity = atoms[2];
|
||||||
|
@ -60,7 +60,7 @@ MetaShadow * meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
MetaWindowShape *shape,
|
MetaWindowShape *shape,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int radius,
|
const char *class_name,
|
||||||
int top_fade);
|
gboolean focused);
|
||||||
|
|
||||||
#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */
|
#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _MetaShadowCacheKey MetaShadowCacheKey;
|
typedef struct _MetaShadowCacheKey MetaShadowCacheKey;
|
||||||
|
typedef struct _MetaShadowClassInfo MetaShadowClassInfo;
|
||||||
|
|
||||||
struct _MetaShadowCacheKey
|
struct _MetaShadowCacheKey
|
||||||
{
|
{
|
||||||
@ -82,6 +83,13 @@ struct _MetaShadow
|
|||||||
guint scale_height : 1;
|
guint scale_height : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _MetaShadowClassInfo
|
||||||
|
{
|
||||||
|
const char *name; /* const so we can reuse for static definitions */
|
||||||
|
MetaShadowParams focused;
|
||||||
|
MetaShadowParams unfocused;
|
||||||
|
};
|
||||||
|
|
||||||
struct _MetaShadowFactory
|
struct _MetaShadowFactory
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
@ -89,6 +97,9 @@ struct _MetaShadowFactory
|
|||||||
/* MetaShadowCacheKey => MetaShadow; the shadows are not referenced
|
/* MetaShadowCacheKey => MetaShadow; the shadows are not referenced
|
||||||
* by the factory, they are simply removed from the table when freed */
|
* by the factory, they are simply removed from the table when freed */
|
||||||
GHashTable *shadows;
|
GHashTable *shadows;
|
||||||
|
|
||||||
|
/* class name => MetaShadowClassInfo */
|
||||||
|
GHashTable *shadow_classes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaShadowFactoryClass
|
struct _MetaShadowFactoryClass
|
||||||
@ -96,6 +107,31 @@ struct _MetaShadowFactoryClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHANGED,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
|
/* The first element in this array also defines the default parameters
|
||||||
|
* for newly created classes */
|
||||||
|
MetaShadowClassInfo default_shadow_classes[] = {
|
||||||
|
{ "normal", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
{ "dialog", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
{ "modal_dialog", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
{ "utility", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
{ "border", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
{ "menu", { 12, -1, 0, 8, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
|
||||||
|
{ "popup-menu", { 6, -1, 0, 4, 255 }, { 6, -1, 0, 4, 255 } },
|
||||||
|
|
||||||
|
{ "dropdown-menu", { 6, 25, 0, 4, 255 }, { 6, 100, 0, 4, 255 } },
|
||||||
|
{ "attached", { 6, 25, 0, 4, 255 }, { 6, 100, 0, 4, 255 } }
|
||||||
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static guint
|
static guint
|
||||||
@ -262,11 +298,36 @@ meta_shadow_get_bounds (MetaShadow *shadow,
|
|||||||
bounds->height = window_height + shadow->outer_border_top + shadow->outer_border_bottom;
|
bounds->height = window_height + shadow->outer_border_top + shadow->outer_border_bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_shadow_class_info_free (MetaShadowClassInfo *class_info)
|
||||||
|
{
|
||||||
|
g_free ((char *)class_info->name);
|
||||||
|
g_slice_free (MetaShadowClassInfo, class_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_shadow_factory_init (MetaShadowFactory *factory)
|
meta_shadow_factory_init (MetaShadowFactory *factory)
|
||||||
{
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
factory->shadows = g_hash_table_new (meta_shadow_cache_key_hash,
|
factory->shadows = g_hash_table_new (meta_shadow_cache_key_hash,
|
||||||
meta_shadow_cache_key_equal);
|
meta_shadow_cache_key_equal);
|
||||||
|
|
||||||
|
factory->shadow_classes = g_hash_table_new_full (g_str_hash,
|
||||||
|
g_str_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify)meta_shadow_class_info_free);
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (default_shadow_classes); i++)
|
||||||
|
{
|
||||||
|
MetaShadowClassInfo *class_info = g_slice_new (MetaShadowClassInfo);
|
||||||
|
|
||||||
|
*class_info = default_shadow_classes[i];
|
||||||
|
class_info->name = g_strdup (class_info->name);
|
||||||
|
|
||||||
|
g_hash_table_insert (factory->shadow_classes,
|
||||||
|
(char *)class_info->name, class_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -286,6 +347,7 @@ meta_shadow_factory_finalize (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_destroy (factory->shadows);
|
g_hash_table_destroy (factory->shadows);
|
||||||
|
g_hash_table_destroy (factory->shadow_classes);
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_shadow_factory_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_shadow_factory_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -296,6 +358,15 @@ meta_shadow_factory_class_init (MetaShadowFactoryClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = meta_shadow_factory_finalize;
|
object_class->finalize = meta_shadow_factory_finalize;
|
||||||
|
|
||||||
|
signals[CHANGED] =
|
||||||
|
g_signal_new ("changed",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaShadowFactory *
|
MetaShadowFactory *
|
||||||
@ -657,15 +728,45 @@ make_shadow (MetaShadow *shadow,
|
|||||||
cogl_material_set_layer (shadow->material, 0, shadow->texture);
|
cogl_material_set_layer (shadow->material, 0, shadow->texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaShadowParams *
|
||||||
|
get_shadow_params (MetaShadowFactory *factory,
|
||||||
|
const char *class_name,
|
||||||
|
gboolean focused,
|
||||||
|
gboolean create)
|
||||||
|
{
|
||||||
|
MetaShadowClassInfo *class_info = g_hash_table_lookup (factory->shadow_classes,
|
||||||
|
class_name);
|
||||||
|
if (class_info == NULL)
|
||||||
|
{
|
||||||
|
if (create)
|
||||||
|
{
|
||||||
|
class_info = g_slice_new0 (MetaShadowClassInfo);
|
||||||
|
*class_info = default_shadow_classes[0];
|
||||||
|
class_info->name = g_strdup (class_info->name);
|
||||||
|
|
||||||
|
g_hash_table_insert (factory->shadow_classes,
|
||||||
|
(char *)class_info->name, class_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
class_info = &default_shadow_classes[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focused)
|
||||||
|
return &class_info->focused;
|
||||||
|
else
|
||||||
|
return &class_info->unfocused;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_shadow_factory_get_shadow:
|
* meta_shadow_factory_get_shadow:
|
||||||
* @factory: a #MetaShadowFactory
|
* @factory: a #MetaShadowFactory
|
||||||
* @shape: the size-invariant shape of the window's region
|
* @shape: the size-invariant shape of the window's region
|
||||||
* @width: the actual width of the window's region
|
* @width: the actual width of the window's region
|
||||||
* @width: the actual height of the window's region
|
* @height: the actual height of the window's region
|
||||||
* @radius: the radius (gaussian standard deviation) of the shadow
|
* @class_name: name of the class of window shadows
|
||||||
* @top_fade: if >= 0, the shadow doesn't extend above the top
|
* @focused: whether the shadow is for a focused window
|
||||||
* of the shape, and fades out over the given number of pixels
|
|
||||||
*
|
*
|
||||||
* Gets the appropriate shadow object for drawing shadows for the
|
* Gets the appropriate shadow object for drawing shadows for the
|
||||||
* specified window shape. The region that we are shadowing is specified
|
* specified window shape. The region that we are shadowing is specified
|
||||||
@ -681,9 +782,10 @@ meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
MetaWindowShape *shape,
|
MetaWindowShape *shape,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int radius,
|
const char *class_name,
|
||||||
int top_fade)
|
gboolean focused)
|
||||||
{
|
{
|
||||||
|
MetaShadowParams *params;
|
||||||
MetaShadowCacheKey key;
|
MetaShadowCacheKey key;
|
||||||
MetaShadow *shadow;
|
MetaShadow *shadow;
|
||||||
cairo_region_t *region;
|
cairo_region_t *region;
|
||||||
@ -721,15 +823,18 @@ meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
* In the case where we are fading a the top, that also has to fit
|
* In the case where we are fading a the top, that also has to fit
|
||||||
* within the top unscaled border.
|
* within the top unscaled border.
|
||||||
*/
|
*/
|
||||||
spread = get_shadow_spread (radius);
|
|
||||||
|
params = get_shadow_params (factory, class_name, focused, FALSE);
|
||||||
|
|
||||||
|
spread = get_shadow_spread (params->radius);
|
||||||
meta_window_shape_get_borders (shape,
|
meta_window_shape_get_borders (shape,
|
||||||
&shape_border_top,
|
&shape_border_top,
|
||||||
&shape_border_right,
|
&shape_border_right,
|
||||||
&shape_border_bottom,
|
&shape_border_bottom,
|
||||||
&shape_border_left);
|
&shape_border_left);
|
||||||
|
|
||||||
inner_border_top = MAX (shape_border_top + spread, top_fade);
|
inner_border_top = MAX (shape_border_top + spread, params->top_fade);
|
||||||
outer_border_top = top_fade >= 0 ? 0 : spread;
|
outer_border_top = params->top_fade >= 0 ? 0 : spread;
|
||||||
inner_border_right = shape_border_right + spread;
|
inner_border_right = shape_border_right + spread;
|
||||||
outer_border_right = spread;
|
outer_border_right = spread;
|
||||||
inner_border_bottom = shape_border_bottom + spread;
|
inner_border_bottom = shape_border_bottom + spread;
|
||||||
@ -744,8 +849,8 @@ meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
if (cacheable)
|
if (cacheable)
|
||||||
{
|
{
|
||||||
key.shape = shape;
|
key.shape = shape;
|
||||||
key.radius = radius;
|
key.radius = params->radius;
|
||||||
key.top_fade = top_fade;
|
key.top_fade = params->top_fade;
|
||||||
|
|
||||||
shadow = g_hash_table_lookup (factory->shadows, &key);
|
shadow = g_hash_table_lookup (factory->shadows, &key);
|
||||||
if (shadow)
|
if (shadow)
|
||||||
@ -757,8 +862,8 @@ meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
shadow->ref_count = 1;
|
shadow->ref_count = 1;
|
||||||
shadow->factory = factory;
|
shadow->factory = factory;
|
||||||
shadow->key.shape = meta_window_shape_ref (shape);
|
shadow->key.shape = meta_window_shape_ref (shape);
|
||||||
shadow->key.radius = radius;
|
shadow->key.radius = params->radius;
|
||||||
shadow->key.top_fade = top_fade;
|
shadow->key.top_fade = params->top_fade;
|
||||||
|
|
||||||
shadow->outer_border_top = outer_border_top;
|
shadow->outer_border_top = outer_border_top;
|
||||||
shadow->inner_border_top = inner_border_top;
|
shadow->inner_border_top = inner_border_top;
|
||||||
@ -793,3 +898,69 @@ meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
|
|||||||
|
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_shadow_factory_set_params:
|
||||||
|
* @factory: a #MetaShadowFactory
|
||||||
|
* @class_name: name of the class of shadow to set the params for.
|
||||||
|
* the default shadow classes are the names of the different
|
||||||
|
* theme frame types (normal, dialog, modal_dialog, utility,
|
||||||
|
* border, menu, attached) and in addition, popup-menu
|
||||||
|
* and dropdown-menu.
|
||||||
|
* @focused: whether the shadow is for a focused window
|
||||||
|
* @params: new parameter values
|
||||||
|
*
|
||||||
|
* Updates the shadow parameters for a particular class of shadows
|
||||||
|
* for either the focused or unfocused state. If the class name
|
||||||
|
* does not name an existing class, a new class will be created
|
||||||
|
* (the other focus state for that class will have default values
|
||||||
|
* assigned to it.)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_shadow_factory_set_params (MetaShadowFactory *factory,
|
||||||
|
const char *class_name,
|
||||||
|
gboolean focused,
|
||||||
|
MetaShadowParams *params)
|
||||||
|
{
|
||||||
|
MetaShadowParams *stored_params;
|
||||||
|
|
||||||
|
g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
|
||||||
|
g_return_if_fail (class_name != NULL);
|
||||||
|
g_return_if_fail (params != NULL);
|
||||||
|
g_return_if_fail (params->radius >= 0);
|
||||||
|
|
||||||
|
stored_params = get_shadow_params (factory, class_name, focused, TRUE);
|
||||||
|
|
||||||
|
*stored_params = *params;
|
||||||
|
|
||||||
|
g_signal_emit (factory, signals[CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta_shadow_factory_get_params:
|
||||||
|
* @factory: a #MetaShadowFactory
|
||||||
|
* @class_name: name of the class of shadow to get the params for
|
||||||
|
* @focused: whether the shadow is for a focused window
|
||||||
|
* @params: (out caller-allocates): location to store the current parameter values
|
||||||
|
*
|
||||||
|
* Gets the shadow parameters for a particular class of shadows
|
||||||
|
* for either the focused or unfocused state. If the class name
|
||||||
|
* does not name an existing class, default values will be returned
|
||||||
|
* without printing an error.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
meta_shadow_factory_get_params (MetaShadowFactory *factory,
|
||||||
|
const char *class_name,
|
||||||
|
gboolean focused,
|
||||||
|
MetaShadowParams *params)
|
||||||
|
{
|
||||||
|
MetaShadowParams *stored_params;
|
||||||
|
|
||||||
|
g_return_if_fail (META_IS_SHADOW_FACTORY (factory));
|
||||||
|
g_return_if_fail (class_name != NULL);
|
||||||
|
|
||||||
|
stored_params = get_shadow_params (factory, class_name, focused, FALSE);
|
||||||
|
|
||||||
|
if (params)
|
||||||
|
*params = *stored_params;
|
||||||
|
}
|
||||||
|
@ -28,6 +28,8 @@ void meta_window_actor_process_damage (MetaWindowActor *self,
|
|||||||
XDamageNotifyEvent *event);
|
XDamageNotifyEvent *event);
|
||||||
void meta_window_actor_pre_paint (MetaWindowActor *self);
|
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);
|
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
|
||||||
void meta_window_actor_sync_actor_position (MetaWindowActor *self);
|
void meta_window_actor_sync_actor_position (MetaWindowActor *self);
|
||||||
void meta_window_actor_sync_visibility (MetaWindowActor *self);
|
void meta_window_actor_sync_visibility (MetaWindowActor *self);
|
||||||
|
@ -30,7 +30,21 @@ struct _MetaWindowActorPrivate
|
|||||||
MetaScreen *screen;
|
MetaScreen *screen;
|
||||||
|
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
MetaShadow *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 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;
|
Pixmap back_pixmap;
|
||||||
|
|
||||||
Damage damage;
|
Damage damage;
|
||||||
@ -51,10 +65,7 @@ struct _MetaWindowActorPrivate
|
|||||||
|
|
||||||
gint freeze_count;
|
gint freeze_count;
|
||||||
|
|
||||||
gint shadow_radius;
|
char * shadow_class;
|
||||||
gint shadow_top_fade;
|
|
||||||
gint shadow_x_offset;
|
|
||||||
gint shadow_y_offset;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These need to be counters rather than flags, since more plugins
|
* These need to be counters rather than flags, since more plugins
|
||||||
@ -79,7 +90,8 @@ struct _MetaWindowActorPrivate
|
|||||||
|
|
||||||
guint needs_pixmap : 1;
|
guint needs_pixmap : 1;
|
||||||
guint needs_reshape : 1;
|
guint needs_reshape : 1;
|
||||||
guint recompute_shadow : 1;
|
guint recompute_focused_shadow : 1;
|
||||||
|
guint recompute_unfocused_shadow : 1;
|
||||||
guint paint_shadow : 1;
|
guint paint_shadow : 1;
|
||||||
guint size_changed : 1;
|
guint size_changed : 1;
|
||||||
|
|
||||||
@ -97,11 +109,7 @@ enum
|
|||||||
PROP_X_WINDOW,
|
PROP_X_WINDOW,
|
||||||
PROP_X_WINDOW_ATTRIBUTES,
|
PROP_X_WINDOW_ATTRIBUTES,
|
||||||
PROP_NO_SHADOW,
|
PROP_NO_SHADOW,
|
||||||
PROP_SHADOW_RADIUS,
|
PROP_SHADOW_CLASS
|
||||||
PROP_SHADOW_TOP_FADE,
|
|
||||||
PROP_SHADOW_X_OFFSET,
|
|
||||||
PROP_SHADOW_Y_OFFSET,
|
|
||||||
PROP_SHADOW_OPACITY
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_SHADOW_RADIUS 12
|
#define DEFAULT_SHADOW_RADIUS 12
|
||||||
@ -246,56 +254,14 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||||||
PROP_NO_SHADOW,
|
PROP_NO_SHADOW,
|
||||||
pspec);
|
pspec);
|
||||||
|
|
||||||
pspec = g_param_spec_int ("shadow-radius",
|
pspec = g_param_spec_string ("shadow-class",
|
||||||
"Shadow Radius",
|
"Name of the shadow class for this window.",
|
||||||
"Radius (standard deviation of gaussian blur) of window's shadow",
|
"NULL means to use the default shadow class for this window type",
|
||||||
0, 128, DEFAULT_SHADOW_RADIUS,
|
NULL,
|
||||||
G_PARAM_READWRITE);
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
g_object_class_install_property (object_class,
|
||||||
PROP_SHADOW_RADIUS,
|
PROP_SHADOW_CLASS,
|
||||||
pspec);
|
|
||||||
|
|
||||||
pspec = g_param_spec_int ("shadow-top-fade",
|
|
||||||
"Shadow Top Fade",
|
|
||||||
"If >= 0, the shadow doesn't extend above the top "
|
|
||||||
"of the window, and fades out over the given number of pixels",
|
|
||||||
-1, G_MAXINT, -1,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_SHADOW_TOP_FADE,
|
|
||||||
pspec);
|
|
||||||
|
|
||||||
pspec = g_param_spec_int ("shadow-x-offset",
|
|
||||||
"Shadow X Offset",
|
|
||||||
"Distance shadow is offset in the horizontal direction in pixels",
|
|
||||||
G_MININT, G_MAXINT, DEFAULT_SHADOW_X_OFFSET,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_SHADOW_X_OFFSET,
|
|
||||||
pspec);
|
|
||||||
|
|
||||||
pspec = g_param_spec_int ("shadow-y-offset",
|
|
||||||
"Shadow Y Offset",
|
|
||||||
"Distance shadow is offset in the vertical direction in piyels",
|
|
||||||
G_MININT, G_MAXINT, DEFAULT_SHADOW_Y_OFFSET,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_SHADOW_Y_OFFSET,
|
|
||||||
pspec);
|
|
||||||
|
|
||||||
pspec = g_param_spec_uint ("shadow-opacity",
|
|
||||||
"Shadow Opacity",
|
|
||||||
"Opacity of the window's shadow",
|
|
||||||
0, 255,
|
|
||||||
255,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
|
||||||
PROP_SHADOW_OPACITY,
|
|
||||||
pspec);
|
pspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,11 +274,7 @@ meta_window_actor_init (MetaWindowActor *self)
|
|||||||
META_TYPE_WINDOW_ACTOR,
|
META_TYPE_WINDOW_ACTOR,
|
||||||
MetaWindowActorPrivate);
|
MetaWindowActorPrivate);
|
||||||
priv->opacity = 0xff;
|
priv->opacity = 0xff;
|
||||||
priv->shadow_radius = DEFAULT_SHADOW_RADIUS;
|
priv->shadow_class = NULL;
|
||||||
priv->shadow_top_fade = -1;
|
|
||||||
priv->shadow_x_offset = DEFAULT_SHADOW_X_OFFSET;
|
|
||||||
priv->shadow_y_offset = DEFAULT_SHADOW_Y_OFFSET;
|
|
||||||
priv->shadow_opacity = 0xff;
|
|
||||||
priv->paint_shadow = TRUE;
|
priv->paint_shadow = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,10 +432,22 @@ meta_window_actor_dispose (GObject *object)
|
|||||||
meta_window_actor_clear_shape_region (self);
|
meta_window_actor_clear_shape_region (self);
|
||||||
meta_window_actor_clear_bounding_region (self);
|
meta_window_actor_clear_bounding_region (self);
|
||||||
|
|
||||||
if (priv->shadow != NULL)
|
if (priv->shadow_class != NULL)
|
||||||
{
|
{
|
||||||
meta_shadow_unref (priv->shadow);
|
g_free (priv->shadow_class);
|
||||||
priv->shadow = NULL;
|
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)
|
if (priv->shadow_shape != NULL)
|
||||||
@ -545,65 +519,20 @@ meta_window_actor_set_property (GObject *object,
|
|||||||
|
|
||||||
priv->no_shadow = newv;
|
priv->no_shadow = newv;
|
||||||
|
|
||||||
priv->recompute_shadow = TRUE;
|
meta_window_actor_invalidate_shadow (self);
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_SHADOW_RADIUS:
|
case PROP_SHADOW_CLASS:
|
||||||
{
|
{
|
||||||
gint newv = g_value_get_int (value);
|
const char *newv = g_value_get_string (value);
|
||||||
|
|
||||||
if (newv == priv->shadow_radius)
|
if (g_strcmp0 (newv, priv->shadow_class) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
priv->shadow_radius = newv;
|
g_free (priv->shadow_class);
|
||||||
priv->recompute_shadow = TRUE;
|
priv->shadow_class = g_strdup (newv);
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_TOP_FADE:
|
|
||||||
{
|
|
||||||
gint newv = g_value_get_int (value);
|
|
||||||
|
|
||||||
if (newv == priv->shadow_top_fade)
|
meta_window_actor_invalidate_shadow (self);
|
||||||
return;
|
|
||||||
|
|
||||||
priv->shadow_top_fade = newv;
|
|
||||||
priv->recompute_shadow = TRUE;
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_X_OFFSET:
|
|
||||||
{
|
|
||||||
gint newv = g_value_get_int (value);
|
|
||||||
|
|
||||||
if (newv == priv->shadow_x_offset)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->shadow_x_offset = newv;
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_Y_OFFSET:
|
|
||||||
{
|
|
||||||
gint newv = g_value_get_int (value);
|
|
||||||
|
|
||||||
if (newv == priv->shadow_y_offset)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->shadow_y_offset = newv;
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_OPACITY:
|
|
||||||
{
|
|
||||||
guint newv = g_value_get_uint (value);
|
|
||||||
|
|
||||||
if (newv == priv->shadow_opacity)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv->shadow_opacity = newv;
|
|
||||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -637,26 +566,53 @@ meta_window_actor_get_property (GObject *object,
|
|||||||
case PROP_NO_SHADOW:
|
case PROP_NO_SHADOW:
|
||||||
g_value_set_boolean (value, priv->no_shadow);
|
g_value_set_boolean (value, priv->no_shadow);
|
||||||
break;
|
break;
|
||||||
case PROP_SHADOW_RADIUS:
|
case PROP_SHADOW_CLASS:
|
||||||
g_value_set_int (value, priv->shadow_radius);
|
g_value_set_string (value, priv->shadow_class);
|
||||||
break;
|
break;
|
||||||
case PROP_SHADOW_TOP_FADE:
|
|
||||||
g_value_set_int (value, priv->shadow_top_fade);
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_X_OFFSET:
|
|
||||||
g_value_set_int (value, priv->shadow_x_offset);
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_Y_OFFSET:
|
|
||||||
g_value_set_int (value, priv->shadow_y_offset);
|
|
||||||
break;
|
|
||||||
case PROP_SHADOW_OPACITY:
|
|
||||||
g_value_set_uint (value, priv->shadow_opacity);
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
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
|
static void
|
||||||
meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||||
cairo_rectangle_int_t *bounds)
|
cairo_rectangle_int_t *bounds)
|
||||||
@ -675,17 +631,26 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
if (priv->shadow != NULL && priv->paint_shadow)
|
if (priv->paint_shadow)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t shape_bounds;
|
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow;
|
||||||
|
|
||||||
meta_shadow_paint (priv->shadow,
|
if (shadow != NULL)
|
||||||
priv->shadow_x_offset + shape_bounds.x,
|
{
|
||||||
priv->shadow_y_offset + shape_bounds.y,
|
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.width,
|
||||||
shape_bounds.height,
|
shape_bounds.height,
|
||||||
(clutter_actor_get_paint_opacity (actor) * priv->shadow_opacity) / 255);
|
(clutter_actor_get_paint_opacity (actor) * params.opacity) / 255);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
|
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
|
||||||
@ -719,9 +684,6 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
|||||||
if (priv->no_shadow)
|
if (priv->no_shadow)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (priv->shadow_radius == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always put a shadow around windows with a frame - This should override
|
* Always put a shadow around windows with a frame - This should override
|
||||||
* the restriction about not putting a shadow around ARGB windows.
|
* the restriction about not putting a shadow around ARGB windows.
|
||||||
@ -1536,7 +1498,7 @@ meta_window_actor_update_bounding_region (MetaWindowActor *self,
|
|||||||
* the shadow when the size changes.
|
* the shadow when the size changes.
|
||||||
*/
|
*/
|
||||||
if (!priv->shaped)
|
if (!priv->shaped)
|
||||||
priv->recompute_shadow = TRUE;
|
meta_window_actor_invalidate_shadow (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1666,8 +1628,10 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
|||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
if (priv->shadow)
|
if (priv->focused_shadow)
|
||||||
{
|
{
|
||||||
|
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||||
|
MetaShadowParams params;
|
||||||
cairo_rectangle_int_t shape_bounds;
|
cairo_rectangle_int_t shape_bounds;
|
||||||
cairo_rectangle_int_t shadow_bounds;
|
cairo_rectangle_int_t shadow_bounds;
|
||||||
cairo_region_overlap_t overlap;
|
cairo_region_overlap_t overlap;
|
||||||
@ -1679,10 +1643,11 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
|||||||
* at all.
|
* at all.
|
||||||
*/
|
*/
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||||
|
meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
|
||||||
|
|
||||||
meta_shadow_get_bounds (priv->shadow,
|
meta_shadow_get_bounds (appears_focused ? priv->focused_shadow : priv->unfocused_shadow,
|
||||||
priv->shadow_x_offset + shape_bounds.x,
|
params.x_offset + shape_bounds.x,
|
||||||
priv->shadow_y_offset + shape_bounds.y,
|
params.y_offset + shape_bounds.y,
|
||||||
shape_bounds.width,
|
shape_bounds.width,
|
||||||
shape_bounds.height,
|
shape_bounds.height,
|
||||||
&shadow_bounds);
|
&shadow_bounds);
|
||||||
@ -1804,7 +1769,10 @@ check_needs_shadow (MetaWindowActor *self)
|
|||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
MetaShadow *old_shadow = NULL;
|
MetaShadow *old_shadow = NULL;
|
||||||
|
MetaShadow **shadow_location;
|
||||||
|
gboolean recompute_shadow;
|
||||||
gboolean should_have_shadow;
|
gboolean should_have_shadow;
|
||||||
|
gboolean appears_focused;
|
||||||
|
|
||||||
if (!priv->mapped)
|
if (!priv->mapped)
|
||||||
return;
|
return;
|
||||||
@ -1817,16 +1785,34 @@ check_needs_shadow (MetaWindowActor *self)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
should_have_shadow = meta_window_actor_has_shadow (self);
|
should_have_shadow = meta_window_actor_has_shadow (self);
|
||||||
|
appears_focused = meta_window_appears_focused (priv->window);
|
||||||
|
|
||||||
if (priv->shadow != NULL && (!should_have_shadow || priv->recompute_shadow))
|
if (appears_focused)
|
||||||
{
|
{
|
||||||
old_shadow = priv->shadow;
|
recompute_shadow = priv->recompute_focused_shadow;
|
||||||
priv->shadow = NULL;
|
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 (priv->shadow == NULL && should_have_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 ();
|
MetaShadowFactory *factory = meta_shadow_factory_get_default ();
|
||||||
|
const char *shadow_class = meta_window_actor_get_shadow_class (self);
|
||||||
cairo_rectangle_int_t shape_bounds;
|
cairo_rectangle_int_t shape_bounds;
|
||||||
|
|
||||||
if (priv->shadow_shape == NULL)
|
if (priv->shadow_shape == NULL)
|
||||||
@ -1839,16 +1825,14 @@ check_needs_shadow (MetaWindowActor *self)
|
|||||||
|
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
||||||
|
|
||||||
priv->shadow = meta_shadow_factory_get_shadow (factory,
|
*shadow_location = meta_shadow_factory_get_shadow (factory,
|
||||||
priv->shadow_shape,
|
priv->shadow_shape,
|
||||||
shape_bounds.width, shape_bounds.height,
|
shape_bounds.width, shape_bounds.height,
|
||||||
priv->shadow_radius, priv->shadow_top_fade);
|
shadow_class, appears_focused);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_shadow != NULL)
|
if (old_shadow != NULL)
|
||||||
meta_shadow_unref (old_shadow);
|
meta_shadow_unref (old_shadow);
|
||||||
|
|
||||||
priv->recompute_shadow = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -1949,7 +1933,7 @@ check_needs_reshape (MetaWindowActor *self)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
priv->needs_reshape = FALSE;
|
priv->needs_reshape = FALSE;
|
||||||
priv->recompute_shadow = TRUE;
|
meta_window_actor_invalidate_shadow (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1997,6 +1981,16 @@ meta_window_actor_pre_paint (MetaWindowActor *self)
|
|||||||
check_needs_shadow (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
|
void
|
||||||
meta_window_actor_update_opacity (MetaWindowActor *self)
|
meta_window_actor_update_opacity (MetaWindowActor *self)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,31 @@
|
|||||||
|
|
||||||
#include <glib-object.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_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(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_SHADOW_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_SHADOW_FACTORY, MetaShadowFactoryClass))
|
||||||
@ -47,4 +72,13 @@ MetaShadowFactory *meta_shadow_factory_get_default (void);
|
|||||||
|
|
||||||
GType meta_shadow_factory_get_type (void);
|
GType meta_shadow_factory_get_type (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__ */
|
#endif /* __META_SHADOW_FACTORY_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user