diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h index 494a77b06..2e8d85fd9 100644 --- a/src/compositor/compositor-private.h +++ b/src/compositor/compositor-private.h @@ -17,7 +17,6 @@ struct _MetaCompositor { MetaDisplay *display; - Atom atom_net_wm_window_opacity; guint repaint_func_id; ClutterActor *shadow_src; diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 9e363828d..ef1318824 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -175,31 +175,6 @@ process_damage (MetaCompositor *compositor, meta_window_actor_process_damage (window_actor, event); } -static void -process_property_notify (MetaCompositor *compositor, - XPropertyEvent *event, - MetaWindow *window) -{ - MetaWindowActor *window_actor; - - if (window == NULL) - return; - - window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); - if (window_actor == NULL) - return; - - /* Check for the opacity changing */ - if (event->atom == compositor->atom_net_wm_window_opacity) - { - meta_window_actor_update_opacity (window_actor); - DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n"); - return; - } - - DEBUG_TRACE ("process_property_notify: unknown\n"); -} - static Window get_output_window (MetaScreen *screen) { @@ -877,6 +852,18 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor, meta_window_actor_update_shape (window_actor); } +void +meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window) +{ + MetaWindowActor *window_actor; + window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window)); + if (!window_actor) + return; + + meta_window_actor_update_opacity (window_actor); +} + /* Clutter makes the assumption that there is only one X window * per stage, which is a valid assumption to make for a generic * application toolkit. As such, it will ignore any events sent @@ -983,28 +970,19 @@ meta_compositor_process_event (MetaCompositor *compositor, } } - switch (event->type) + if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) { - case PropertyNotify: - process_property_notify (compositor, (XPropertyEvent *) event, window); - break; - - default: - if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify) + /* Core code doesn't handle damage events, so we need to extract the MetaWindow + * ourselves + */ + if (window == NULL) { - /* Core code doesn't handle damage events, so we need to extract the MetaWindow - * ourselves - */ - if (window == NULL) - { - Window xwin = ((XDamageNotifyEvent *) event)->drawable; - window = meta_display_lookup_x_window (compositor->display, xwin); - } - - DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); - process_damage (compositor, (XDamageNotifyEvent *) event, window); + Window xwin = ((XDamageNotifyEvent *) event)->drawable; + window = meta_display_lookup_x_window (compositor->display, xwin); } - break; + + DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n"); + process_damage (compositor, (XDamageNotifyEvent *) event, window); } /* Clutter needs to know about MapNotify events otherwise it will @@ -1508,12 +1486,7 @@ on_shadow_factory_changed (MetaShadowFactory *factory, MetaCompositor * meta_compositor_new (MetaDisplay *display) { - char *atom_names[] = { - "_NET_WM_WINDOW_OPACITY", - }; - Atom atoms[G_N_ELEMENTS(atom_names)]; MetaCompositor *compositor; - Display *xdisplay = meta_display_get_xdisplay (display); if (!composite_at_least_version (display, 0, 3)) return NULL; @@ -1525,17 +1498,11 @@ meta_compositor_new (MetaDisplay *display) if (g_getenv("META_DISABLE_MIPMAPS")) compositor->no_mipmaps = TRUE; - meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names)); - 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_net_wm_window_opacity = atoms[0]; - compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func, compositor, NULL); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 897b332df..8344d1052 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -68,8 +68,6 @@ struct _MetaWindowActorPrivate Damage damage; - guint8 opacity; - /* A region that matches the shape of the window, including frame bounds */ cairo_region_t *shape_region; /* If the window has an input shape, a region that matches the shape */ @@ -270,7 +268,6 @@ meta_window_actor_init (MetaWindowActor *self) priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, META_TYPE_WINDOW_ACTOR, MetaWindowActorPrivate); - priv->opacity = 0xff; priv->shadow_class = NULL; } @@ -319,6 +316,15 @@ window_appears_focused_notify (MetaWindow *mw, clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); } +static gboolean +is_non_opaque (MetaWindowActor *self) +{ + MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; + + return priv->argb32 || (window->opacity != 0xFF); +} + static void meta_window_actor_constructed (GObject *object) { @@ -596,7 +602,7 @@ clip_shadow_under_window (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - return (priv->argb32 || priv->opacity != 0xff) && priv->window->frame; + return is_non_opaque (self) && priv->window->frame; } static void @@ -622,6 +628,7 @@ meta_window_actor_paint (ClutterActor *actor) MetaShadowParams params; cairo_rectangle_int_t shape_bounds; cairo_region_t *clip = priv->shadow_clip; + MetaWindow *window = priv->window; meta_window_actor_get_shape_bounds (self, &shape_bounds); meta_window_actor_get_shadow_params (self, appears_focused, ¶ms); @@ -645,7 +652,7 @@ meta_window_actor_paint (ClutterActor *actor) params.y_offset + shape_bounds.y, shape_bounds.width, shape_bounds.height, - (clutter_actor_get_paint_opacity (actor) * params.opacity * priv->opacity) / (255 * 255), + (clutter_actor_get_paint_opacity (actor) * params.opacity * window->opacity) / (255 * 255), clip, clip_shadow_under_window (self)); /* clip_strictly - not just as an optimization */ @@ -732,10 +739,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self) return TRUE; /* - * Do not add shadows to ARGB windows; eventually we should generate a - * shadow from the input shape for such windows. + * Do not add shadows to non-opaque windows; eventually we should generate + * a shadow from the input shape for such windows. */ - if (priv->argb32 || priv->opacity != 0xff) + if (is_non_opaque (self)) return FALSE; /* @@ -1270,7 +1277,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self) if (meta_window_requested_dont_bypass_compositor (metaWindow)) return FALSE; - if (priv->opacity != 0xff) + if (metaWindow->opacity != 0xFF) return FALSE; if (metaWindow->shape_region != NULL) @@ -1645,8 +1652,9 @@ static cairo_region_t * meta_window_actor_get_obscured_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; + MetaWindow *window = priv->window; - if (priv->back_pixmap && priv->opacity == 0xff && !priv->window->shaded) + if (priv->back_pixmap && window->opacity != 0xFF && !priv->window->shaded) return priv->opaque_region; else return NULL; @@ -2560,23 +2568,9 @@ void meta_window_actor_update_opacity (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; - MetaDisplay *display = meta_screen_get_display (priv->screen); - MetaCompositor *compositor = meta_display_get_compositor (display); - Window xwin = meta_window_get_xwindow (priv->window); - gulong value; - guint8 opacity; + MetaWindow *window = priv->window; - if (meta_prop_get_cardinal (display, xwin, - compositor->atom_net_wm_window_opacity, - &value)) - { - opacity = (guint8)((gfloat)value * 255.0 / ((gfloat)0xffffffff)); - } - else - opacity = 255; - - self->priv->opacity = opacity; - clutter_actor_set_opacity (self->priv->actor, opacity); + clutter_actor_set_opacity (self->priv->actor, window->opacity); } void diff --git a/src/core/window-private.h b/src/core/window-private.h index cd29d9886..774b6abb5 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -355,6 +355,9 @@ struct _MetaWindow /* the input shape region for picking */ cairo_region_t *input_region; + /* _NET_WM_WINDOW_OPACITY */ + guint opacity; + /* if TRUE, the we have the new form of sync request counter which * also handles application frames */ guint extended_sync_request_counter : 1; @@ -695,6 +698,8 @@ void meta_window_update_input_region_x11 (MetaWindow *window); void meta_window_set_shape_region (MetaWindow *window, cairo_region_t *region); void meta_window_update_shape_region_x11 (MetaWindow *window); +void meta_window_set_opacity (MetaWindow *window, + guint opacity); Window meta_window_get_toplevel_xwindow (MetaWindow *window); diff --git a/src/core/window-props.c b/src/core/window-props.c index c03df1a1e..f1e2346d7 100644 --- a/src/core/window-props.c +++ b/src/core/window-props.c @@ -1709,6 +1709,20 @@ reload_bypass_compositor (MetaWindow *window, window->bypass_compositor = requested_value; } +static void +reload_window_opacity (MetaWindow *window, + MetaPropValue *value, + gboolean initial) + +{ + int requested_value = 0xFF; + + if (value->type != META_PROP_VALUE_INVALID) + requested_value = (int) value->v.cardinal; + + meta_window_set_opacity (window, requested_value); +} + #define RELOAD_STRING(var_name, propname) \ static void \ reload_ ## var_name (MetaWindow *window, \ @@ -1811,6 +1825,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display) { display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts, FALSE, FALSE }, { display->atom__NET_WM_BYPASS_COMPOSITOR, META_PROP_VALUE_CARDINAL, reload_bypass_compositor, FALSE, FALSE }, + { display->atom__NET_WM_WINDOW_OPACITY, META_PROP_VALUE_CARDINAL, reload_window_opacity, TRUE, TRUE }, { 0 }, }; diff --git a/src/core/window.c b/src/core/window.c index 005336f45..a3ba38575 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1201,6 +1201,8 @@ meta_window_new_with_attrs (MetaDisplay *display, */ window->stable_sequence = ++display->window_sequence_counter; + window->opacity = 0xFF; + /* assign the window to its group, or create a new group if needed */ window->group = NULL; @@ -11444,3 +11446,13 @@ meta_window_get_toplevel_xwindow (MetaWindow *window) { return window->frame ? window->frame->xwindow : window->xwindow; } + +void +meta_window_set_opacity (MetaWindow *window, + guint opacity) +{ + window->opacity = opacity; + + if (window->display->compositor) + meta_compositor_window_opacity_changed (window->display->compositor, window); +} diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h index 8b7346a5b..8c8d6bb93 100644 --- a/src/meta/atomnames.h +++ b/src/meta/atomnames.h @@ -179,6 +179,7 @@ item(_NET_WM_BYPASS_COMPOSITOR) item(_NET_WM_OPAQUE_REGION) item(_NET_WM_FRAME_DRAWN) item(_NET_WM_FRAME_TIMINGS) +item(_NET_WM_WINDOW_OPACITY) #if 0 /* We apparently never use: */ diff --git a/src/meta/compositor.h b/src/meta/compositor.h index 13143c992..b0e54550d 100644 --- a/src/meta/compositor.h +++ b/src/meta/compositor.h @@ -66,6 +66,8 @@ void meta_compositor_unmanage_screen (MetaCompositor *compositor, void meta_compositor_window_shape_changed (MetaCompositor *compositor, MetaWindow *window); +void meta_compositor_window_opacity_changed (MetaCompositor *compositor, + MetaWindow *window); gboolean meta_compositor_process_event (MetaCompositor *compositor, XEvent *event,