|  |  |  | @@ -67,8 +67,12 @@ struct _MetaWindowActorPrivate | 
		
	
		
			
				|  |  |  |  |   MetaShadow       *focused_shadow; | 
		
	
		
			
				|  |  |  |  |   MetaShadow       *unfocused_shadow; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   CoglTexture      *focused_mask; | 
		
	
		
			
				|  |  |  |  |   CoglTexture      *unfocused_mask; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* A region that matches the shape of the window, including frame bounds */ | 
		
	
		
			
				|  |  |  |  |   cairo_region_t   *shape_region; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t   *focused_shape_region; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t   *unfocused_shape_region; | 
		
	
		
			
				|  |  |  |  |   /* The region we should clip to when painting the shadow */ | 
		
	
		
			
				|  |  |  |  |   cairo_region_t   *shadow_clip; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -175,6 +179,8 @@ static gboolean meta_window_actor_has_shadow (MetaWindowActor *self); | 
		
	
		
			
				|  |  |  |  | static void meta_window_actor_handle_updates (MetaWindowActor *self); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void check_needs_reshape (MetaWindowActor *self); | 
		
	
		
			
				|  |  |  |  | static void meta_window_actor_update_shape_region (MetaWindowActor *self); | 
		
	
		
			
				|  |  |  |  | static void meta_window_actor_shape_region_changed (MetaWindowActor *self); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame); | 
		
	
		
			
				|  |  |  |  | static void do_send_frame_timings (MetaWindowActor  *self, | 
		
	
	
		
			
				
					
					|  |  |  | @@ -284,6 +290,29 @@ window_appears_focused_notify (MetaWindow *mw, | 
		
	
		
			
				|  |  |  |  |                                GParamSpec *arg1, | 
		
	
		
			
				|  |  |  |  |                                gpointer    data) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   MetaWindowActor *self = META_WINDOW_ACTOR (data); | 
		
	
		
			
				|  |  |  |  |   MetaWindowActorPrivate *priv = self->priv; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (priv->surface) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       gboolean appears_focused = meta_window_appears_focused (mw); | 
		
	
		
			
				|  |  |  |  |       CoglTexture *mask = appears_focused ? self->priv->focused_mask | 
		
	
		
			
				|  |  |  |  |                                           : self->priv->unfocused_mask; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       if (mask) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           MetaShapedTexture *stex; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |           stex = meta_surface_actor_get_texture (priv->surface); | 
		
	
		
			
				|  |  |  |  |           meta_shaped_texture_set_mask_texture (stex, mask); | 
		
	
		
			
				|  |  |  |  |           meta_window_actor_shape_region_changed (self); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |       else if (priv->window->frame) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           meta_window_actor_update_shape_region (self); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   clutter_actor_queue_redraw (CLUTTER_ACTOR (data)); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -457,7 +486,8 @@ meta_window_actor_constructed (GObject *object) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* Start off with an empty shape region to maintain the invariant | 
		
	
		
			
				|  |  |  |  |    * that it's always set */ | 
		
	
		
			
				|  |  |  |  |   priv->shape_region = cairo_region_create (); | 
		
	
		
			
				|  |  |  |  |   priv->focused_shape_region = cairo_region_create (); | 
		
	
		
			
				|  |  |  |  |   priv->unfocused_shape_region = cairo_region_create (); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
	
		
			
				
					
					|  |  |  | @@ -478,9 +508,13 @@ meta_window_actor_dispose (GObject *object) | 
		
	
		
			
				|  |  |  |  |       priv->send_frame_messages_timer = 0; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->shape_region, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->focused_shape_region, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->unfocused_shape_region, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->focused_mask, cogl_object_unref); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->unfocused_mask, cogl_object_unref); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->shadow_class, g_free); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->focused_shadow, meta_shadow_unref); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->unfocused_shadow, meta_shadow_unref); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -621,8 +655,10 @@ meta_window_actor_get_shape_bounds (MetaWindowActor       *self, | 
		
	
		
			
				|  |  |  |  |                                     cairo_rectangle_int_t *bounds) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   MetaWindowActorPrivate *priv = self->priv; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   cairo_region_get_extents (priv->shape_region, bounds); | 
		
	
		
			
				|  |  |  |  |   gboolean appears_focused = meta_window_appears_focused (priv->window); | 
		
	
		
			
				|  |  |  |  |   cairo_region_t *shape_region = appears_focused ? priv->focused_shape_region | 
		
	
		
			
				|  |  |  |  |                                                  : priv->unfocused_shape_region; | 
		
	
		
			
				|  |  |  |  |   cairo_region_get_extents (shape_region, bounds); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
	
		
			
				
					
					|  |  |  | @@ -821,11 +857,11 @@ meta_window_actor_has_shadow (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  |     return FALSE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* | 
		
	
		
			
				|  |  |  |  |    * Always put a shadow around windows with a frame - This should override | 
		
	
		
			
				|  |  |  |  |    * the restriction about not putting a shadow around ARGB windows. | 
		
	
		
			
				|  |  |  |  |    * Do not put a shadow around windows with a frame - the decoration | 
		
	
		
			
				|  |  |  |  |    * includes the shadow as defined by the GTK+ theme | 
		
	
		
			
				|  |  |  |  |    */ | 
		
	
		
			
				|  |  |  |  |   if (meta_window_get_frame (priv->window)) | 
		
	
		
			
				|  |  |  |  |     return TRUE; | 
		
	
		
			
				|  |  |  |  |     return FALSE; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* | 
		
	
		
			
				|  |  |  |  |    * Do not add shadows to non-opaque (ARGB32) windows, as we can't easily | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1585,7 +1621,12 @@ check_needs_shadow (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  |   if (*shadow_location == NULL && should_have_shadow) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       if (priv->shadow_shape == NULL) | 
		
	
		
			
				|  |  |  |  |         priv->shadow_shape = meta_window_shape_new (priv->shape_region); | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |           cairo_region_t *shape_region; | 
		
	
		
			
				|  |  |  |  |           shape_region = appears_focused ? priv->focused_shape_region | 
		
	
		
			
				|  |  |  |  |                                          : priv->unfocused_shape_region; | 
		
	
		
			
				|  |  |  |  |           priv->shadow_shape = meta_window_shape_new (shape_region); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |       MetaShadowFactory *factory = meta_shadow_factory_get_default (); | 
		
	
		
			
				|  |  |  |  |       const char *shadow_class = meta_window_actor_get_shadow_class (self); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1678,10 +1719,11 @@ build_and_scan_frame_mask (MetaWindowActor       *self, | 
		
	
		
			
				|  |  |  |  |   guchar *mask_data; | 
		
	
		
			
				|  |  |  |  |   guint tex_width, tex_height; | 
		
	
		
			
				|  |  |  |  |   MetaShapedTexture *stex; | 
		
	
		
			
				|  |  |  |  |   CoglTexture *paint_tex, *mask_texture; | 
		
	
		
			
				|  |  |  |  |   CoglTexture *paint_tex, *mask_texture, **mask_ptr; | 
		
	
		
			
				|  |  |  |  |   int stride; | 
		
	
		
			
				|  |  |  |  |   cairo_t *cr; | 
		
	
		
			
				|  |  |  |  |   cairo_surface_t *surface; | 
		
	
		
			
				|  |  |  |  |   gboolean appears_focused = meta_window_appears_focused (priv->window); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   stex = meta_surface_actor_get_texture (priv->surface); | 
		
	
		
			
				|  |  |  |  |   g_return_if_fail (stex); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1762,8 +1804,10 @@ build_and_scan_frame_mask (MetaWindowActor       *self, | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   meta_shaped_texture_set_mask_texture (stex, mask_texture); | 
		
	
		
			
				|  |  |  |  |   if (mask_texture) | 
		
	
		
			
				|  |  |  |  |     cogl_object_unref (mask_texture); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   mask_ptr = appears_focused ? &priv->focused_mask : &priv->unfocused_mask; | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (mask_ptr, cogl_object_unref); | 
		
	
		
			
				|  |  |  |  |   *mask_ptr = mask_texture; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_free (mask_data); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1772,8 +1816,12 @@ static void | 
		
	
		
			
				|  |  |  |  | meta_window_actor_update_shape_region (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   MetaWindowActorPrivate *priv = self->priv; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t *region = NULL; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t *region = NULL, **shape_region; | 
		
	
		
			
				|  |  |  |  |   cairo_rectangle_int_t client_area; | 
		
	
		
			
				|  |  |  |  |   gboolean appears_focused = meta_window_appears_focused (priv->window); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   shape_region = appears_focused ? &priv->focused_shape_region | 
		
	
		
			
				|  |  |  |  |                                  : &priv->unfocused_shape_region; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   meta_window_get_client_area_rect (priv->window, &client_area); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1797,8 +1845,8 @@ meta_window_actor_update_shape_region (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  |   if ((priv->window->shape_region != NULL) || (priv->window->frame != NULL)) | 
		
	
		
			
				|  |  |  |  |     build_and_scan_frame_mask (self, &client_area, region); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->shape_region, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |   priv->shape_region = region; | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (shape_region, cairo_region_destroy); | 
		
	
		
			
				|  |  |  |  |   *shape_region = region; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1832,8 +1880,12 @@ static void | 
		
	
		
			
				|  |  |  |  | meta_window_actor_update_opaque_region (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   MetaWindowActorPrivate *priv = self->priv; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t *opaque_region; | 
		
	
		
			
				|  |  |  |  |   cairo_region_t *opaque_region, *shape_region; | 
		
	
		
			
				|  |  |  |  |   gboolean argb32 = is_argb32 (self); | 
		
	
		
			
				|  |  |  |  |   gboolean appears_focused = meta_window_appears_focused (priv->window); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   shape_region = appears_focused ? priv->focused_shape_region | 
		
	
		
			
				|  |  |  |  |                                  : priv->unfocused_shape_region; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (argb32 && priv->window->opaque_region != NULL) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1853,17 +1905,27 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  |        */ | 
		
	
		
			
				|  |  |  |  |       opaque_region = cairo_region_copy (priv->window->opaque_region); | 
		
	
		
			
				|  |  |  |  |       cairo_region_translate (opaque_region, client_area.x, client_area.y); | 
		
	
		
			
				|  |  |  |  |       cairo_region_intersect (opaque_region, priv->shape_region); | 
		
	
		
			
				|  |  |  |  |       cairo_region_intersect (opaque_region, shape_region); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   else if (argb32) | 
		
	
		
			
				|  |  |  |  |     opaque_region = NULL; | 
		
	
		
			
				|  |  |  |  |   else | 
		
	
		
			
				|  |  |  |  |     opaque_region = cairo_region_reference (priv->shape_region); | 
		
	
		
			
				|  |  |  |  |     opaque_region = cairo_region_reference (shape_region); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   meta_surface_actor_set_opaque_region (priv->surface, opaque_region); | 
		
	
		
			
				|  |  |  |  |   cairo_region_destroy (opaque_region); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | meta_window_actor_shape_region_changed (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |   if (self->priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       meta_window_actor_update_input_region (self); | 
		
	
		
			
				|  |  |  |  |       meta_window_actor_update_opaque_region (self); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static void | 
		
	
		
			
				|  |  |  |  | check_needs_reshape (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					
					|  |  |  | @@ -1872,13 +1934,11 @@ check_needs_reshape (MetaWindowActor *self) | 
		
	
		
			
				|  |  |  |  |   if (!priv->needs_reshape) | 
		
	
		
			
				|  |  |  |  |     return; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   meta_window_actor_update_shape_region (self); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->focused_mask, cogl_object_unref); | 
		
	
		
			
				|  |  |  |  |   g_clear_pointer (&priv->unfocused_mask, cogl_object_unref); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |       meta_window_actor_update_input_region (self); | 
		
	
		
			
				|  |  |  |  |       meta_window_actor_update_opaque_region (self); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   meta_window_actor_update_shape_region (self); | 
		
	
		
			
				|  |  |  |  |   meta_window_actor_shape_region_changed (self); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   priv->needs_reshape = FALSE; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  |   |