Compare commits
	
		
			4 Commits
		
	
	
		
			wip/exalm/
			...
			wip/waylan
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					10fbaf7695 | ||
| 
						 | 
					ef73402654 | ||
| 
						 | 
					22cdf2d650 | ||
| 
						 | 
					284b497b4c | 
@@ -930,8 +930,8 @@ is_grabbed_event (MetaDisplay *display,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_window_x11_shape_changed (MetaCompositor *compositor,
 | 
			
		||||
                                          MetaWindow     *window)
 | 
			
		||||
meta_compositor_window_shape_changed (MetaCompositor *compositor,
 | 
			
		||||
                                      MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor;
 | 
			
		||||
  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
 
 | 
			
		||||
@@ -91,11 +91,10 @@ struct _MetaShapedTexturePrivate
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
 | 
			
		||||
  CoglTexture *mask_texture;
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  CoglPipeline *pipeline_unshaped;
 | 
			
		||||
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *input_shape_region;
 | 
			
		||||
  cairo_region_t *opaque_region;
 | 
			
		||||
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
 | 
			
		||||
@@ -145,8 +144,6 @@ meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
    meta_texture_tower_free (priv->paint_tower);
 | 
			
		||||
  priv->paint_tower = NULL;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->pipeline, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->pipeline_unshaped, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->texture, cogl_object_unref);
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (self, NULL);
 | 
			
		||||
@@ -155,6 +152,76 @@ meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
  G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
get_unmasked_pipeline (CoglContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
  return cogl_pipeline_new (ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
get_masked_pipeline (CoglContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
  static CoglPipeline *template = NULL;
 | 
			
		||||
  if (G_UNLIKELY (template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      template = cogl_pipeline_new (ctx);
 | 
			
		||||
      cogl_pipeline_set_layer_combine (template, 1,
 | 
			
		||||
                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
 | 
			
		||||
                                       NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cogl_pipeline_copy (template);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
get_unblended_pipeline (CoglContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
  static CoglPipeline *template = NULL;
 | 
			
		||||
  if (G_UNLIKELY (template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      CoglColor color;
 | 
			
		||||
      template = cogl_pipeline_new (ctx);
 | 
			
		||||
      cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
 | 
			
		||||
      cogl_pipeline_set_blend (template,
 | 
			
		||||
                               "RGBA = ADD (SRC_COLOR, 0)",
 | 
			
		||||
                               NULL);
 | 
			
		||||
      cogl_pipeline_set_color (template, &color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cogl_pipeline_copy (template);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
paint_clipped_rectangle (CoglFramebuffer       *fb,
 | 
			
		||||
                         CoglPipeline          *pipeline,
 | 
			
		||||
                         cairo_rectangle_int_t *rect,
 | 
			
		||||
                         ClutterActorBox       *alloc)
 | 
			
		||||
{
 | 
			
		||||
  float coords[8];
 | 
			
		||||
  float x1, y1, x2, y2;
 | 
			
		||||
 | 
			
		||||
  x1 = rect->x;
 | 
			
		||||
  y1 = rect->y;
 | 
			
		||||
  x2 = rect->x + rect->width;
 | 
			
		||||
  y2 = rect->y + rect->height;
 | 
			
		||||
 | 
			
		||||
  coords[0] = rect->x / (alloc->x2 - alloc->x1);
 | 
			
		||||
  coords[1] = rect->y / (alloc->y2 - alloc->y1);
 | 
			
		||||
  coords[2] = (rect->x + rect->width) / (alloc->x2 - alloc->x1);
 | 
			
		||||
  coords[3] = (rect->y + rect->height) / (alloc->y2 - alloc->y1);
 | 
			
		||||
 | 
			
		||||
  coords[4] = coords[0];
 | 
			
		||||
  coords[5] = coords[1];
 | 
			
		||||
  coords[6] = coords[2];
 | 
			
		||||
  coords[7] = coords[3];
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline,
 | 
			
		||||
                                                 x1, y1, x2, y2,
 | 
			
		||||
                                                 &coords[0], 8);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_cogl_texture (MetaShapedTexture *stex,
 | 
			
		||||
                  CoglTexture       *cogl_tex)
 | 
			
		||||
@@ -171,12 +238,6 @@ set_cogl_texture (MetaShapedTexture *stex,
 | 
			
		||||
 | 
			
		||||
  priv->texture = cogl_tex;
 | 
			
		||||
 | 
			
		||||
  if (priv->pipeline != NULL)
 | 
			
		||||
    cogl_pipeline_set_layer_texture (priv->pipeline, 0, COGL_TEXTURE (cogl_tex));
 | 
			
		||||
 | 
			
		||||
  if (priv->pipeline_unshaped != NULL)
 | 
			
		||||
    cogl_pipeline_set_layer_texture (priv->pipeline_unshaped, 0, COGL_TEXTURE (cogl_tex));
 | 
			
		||||
 | 
			
		||||
  if (cogl_tex != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
 | 
			
		||||
@@ -210,14 +271,14 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *stex = (MetaShapedTexture *) actor;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  CoglTexture *paint_tex;
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
  guchar opacity;
 | 
			
		||||
  CoglContext *ctx;
 | 
			
		||||
  CoglFramebuffer *fb;
 | 
			
		||||
  CoglPipeline *pipeline = NULL;
 | 
			
		||||
  CoglTexture *paint_tex;
 | 
			
		||||
  ClutterActorBox alloc;
 | 
			
		||||
 | 
			
		||||
  static CoglPipeline *pipeline_template = NULL;
 | 
			
		||||
  static CoglPipeline *pipeline_unshaped_template = NULL;
 | 
			
		||||
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  cairo_region_t *blended_region = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
 | 
			
		||||
    return;
 | 
			
		||||
@@ -254,38 +315,67 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
  if (tex_width == 0 || tex_height == 0) /* no contents yet */
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
  fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
 | 
			
		||||
  opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
  clutter_actor_get_allocation_box (actor, &alloc);
 | 
			
		||||
 | 
			
		||||
  if (priv->opaque_region != NULL && opacity == 255)
 | 
			
		||||
    {
 | 
			
		||||
      CoglPipeline *opaque_pipeline;
 | 
			
		||||
      cairo_region_t *region;
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      int i;
 | 
			
		||||
 | 
			
		||||
      region = cairo_region_copy (priv->clip_region);
 | 
			
		||||
      cairo_region_intersect (region, priv->opaque_region);
 | 
			
		||||
 | 
			
		||||
      if (cairo_region_is_empty (region))
 | 
			
		||||
        goto paint_blended;
 | 
			
		||||
 | 
			
		||||
      opaque_pipeline = get_unblended_pipeline (ctx);
 | 
			
		||||
      cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
 | 
			
		||||
 | 
			
		||||
      n_rects = cairo_region_num_rectangles (region);
 | 
			
		||||
      for (i = 0; i < n_rects; i++)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t rect;
 | 
			
		||||
          cairo_region_get_rectangle (region, i, &rect);
 | 
			
		||||
          paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cogl_object_unref (opaque_pipeline);
 | 
			
		||||
 | 
			
		||||
      if (priv->clip_region != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          blended_region = cairo_region_copy (priv->clip_region);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
          blended_region = cairo_region_create_rectangle (&rect);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cairo_region_subtract (blended_region, priv->opaque_region);
 | 
			
		||||
 | 
			
		||||
    paint_blended:
 | 
			
		||||
      cairo_region_destroy (region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (blended_region == NULL && priv->clip_region != NULL)
 | 
			
		||||
    blended_region = cairo_region_reference (priv->clip_region);
 | 
			
		||||
 | 
			
		||||
  if (blended_region != NULL && cairo_region_is_empty (blended_region))
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  if (priv->mask_texture == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Use a single-layer texture if we don't have a mask. */
 | 
			
		||||
 | 
			
		||||
      if (priv->pipeline_unshaped == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          if (G_UNLIKELY (pipeline_unshaped_template == NULL))
 | 
			
		||||
            {
 | 
			
		||||
              CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
              pipeline_unshaped_template = cogl_pipeline_new (ctx);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          priv->pipeline_unshaped = cogl_pipeline_copy (pipeline_unshaped_template);
 | 
			
		||||
        }
 | 
			
		||||
        pipeline = priv->pipeline_unshaped;
 | 
			
		||||
      pipeline = get_unmasked_pipeline (ctx);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->pipeline == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	   if (G_UNLIKELY (pipeline_template == NULL))
 | 
			
		||||
	    {
 | 
			
		||||
              CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
	      pipeline_template =  cogl_pipeline_new (ctx);
 | 
			
		||||
	      cogl_pipeline_set_layer_combine (pipeline_template, 1,
 | 
			
		||||
					   "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
 | 
			
		||||
					   NULL);
 | 
			
		||||
	    }
 | 
			
		||||
	  priv->pipeline = cogl_pipeline_copy (pipeline_template);
 | 
			
		||||
	}
 | 
			
		||||
      pipeline = priv->pipeline;
 | 
			
		||||
 | 
			
		||||
      pipeline = get_masked_pipeline (ctx);
 | 
			
		||||
      cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -293,20 +383,13 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    CoglColor color;
 | 
			
		||||
    guchar opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
    cogl_color_set_from_4ub (&color, opacity, opacity, opacity, opacity);
 | 
			
		||||
    cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
 | 
			
		||||
    cogl_pipeline_set_color (pipeline, &color);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cogl_set_source (pipeline);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_allocation_box (actor, &alloc);
 | 
			
		||||
 | 
			
		||||
  if (priv->clip_region)
 | 
			
		||||
  if (blended_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      int i;
 | 
			
		||||
      cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
 | 
			
		||||
      /* Limit to how many separate rectangles we'll draw; beyond this just
 | 
			
		||||
       * fall back and draw the whole thing */
 | 
			
		||||
@@ -315,8 +398,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
      n_rects = cairo_region_num_rectangles (priv->clip_region);
 | 
			
		||||
      if (n_rects <= MAX_RECTS)
 | 
			
		||||
	{
 | 
			
		||||
	  float coords[8];
 | 
			
		||||
          float x1, y1, x2, y2;
 | 
			
		||||
          int i;
 | 
			
		||||
          cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
 | 
			
		||||
	  for (i = 0; i < n_rects; i++)
 | 
			
		||||
	    {
 | 
			
		||||
@@ -327,32 +410,23 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
	      if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
 | 
			
		||||
		continue;
 | 
			
		||||
 | 
			
		||||
	      x1 = rect.x;
 | 
			
		||||
	      y1 = rect.y;
 | 
			
		||||
	      x2 = rect.x + rect.width;
 | 
			
		||||
	      y2 = rect.y + rect.height;
 | 
			
		||||
 | 
			
		||||
	      coords[0] = rect.x / (alloc.x2 - alloc.x1);
 | 
			
		||||
	      coords[1] = rect.y / (alloc.y2 - alloc.y1);
 | 
			
		||||
	      coords[2] = (rect.x + rect.width) / (alloc.x2 - alloc.x1);
 | 
			
		||||
	      coords[3] = (rect.y + rect.height) / (alloc.y2 - alloc.y1);
 | 
			
		||||
 | 
			
		||||
              coords[4] = coords[0];
 | 
			
		||||
              coords[5] = coords[1];
 | 
			
		||||
              coords[6] = coords[2];
 | 
			
		||||
              coords[7] = coords[3];
 | 
			
		||||
 | 
			
		||||
              cogl_rectangle_with_multitexture_coords (x1, y1, x2, y2,
 | 
			
		||||
                                                       &coords[0], 8);
 | 
			
		||||
              paint_clipped_rectangle (fb, pipeline, &rect, &alloc);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
	  return;
 | 
			
		||||
          goto out;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cogl_rectangle (0, 0,
 | 
			
		||||
		  alloc.x2 - alloc.x1,
 | 
			
		||||
		  alloc.y2 - alloc.y1);
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (fb, pipeline,
 | 
			
		||||
                                   0, 0,
 | 
			
		||||
                                   alloc.x2 - alloc.x1,
 | 
			
		||||
                                   alloc.y2 - alloc.y1);
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  if (pipeline != NULL)
 | 
			
		||||
    cogl_object_unref (pipeline);
 | 
			
		||||
  if (blended_region != NULL)
 | 
			
		||||
    cairo_region_destroy (blended_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -368,13 +442,17 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
 | 
			
		||||
  /* If there is no region then use the regular pick */
 | 
			
		||||
  if (priv->input_shape_region == NULL)
 | 
			
		||||
    CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)
 | 
			
		||||
      ->pick (actor, color);
 | 
			
		||||
    CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      float *rectangles;
 | 
			
		||||
      int i;
 | 
			
		||||
      ClutterActorBox alloc;
 | 
			
		||||
      CoglPipeline *pipeline;
 | 
			
		||||
      CoglContext *ctx;
 | 
			
		||||
      CoglFramebuffer *fb;
 | 
			
		||||
      CoglColor cogl_color;
 | 
			
		||||
 | 
			
		||||
      /* Note: We don't bother trying to intersect the pick and clip regions
 | 
			
		||||
       * since needing to copy the region, do the intersection, and probably
 | 
			
		||||
@@ -403,12 +481,17 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
          rectangles[pos + 3] = rect.y + rect.height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cogl_set_source_color4ub (color->red,
 | 
			
		||||
                                color->green,
 | 
			
		||||
                                color->blue,
 | 
			
		||||
                                color->alpha);
 | 
			
		||||
      ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
      fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
 | 
			
		||||
      cogl_rectangles (rectangles, n_rects);
 | 
			
		||||
      cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
 | 
			
		||||
 | 
			
		||||
      pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
      cogl_pipeline_set_color (pipeline, &cogl_color);
 | 
			
		||||
 | 
			
		||||
      cogl_framebuffer_draw_rectangles (fb, pipeline,
 | 
			
		||||
                                        rectangles, n_rects);
 | 
			
		||||
      cogl_object_unref (pipeline);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -845,6 +928,36 @@ meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
    priv->clip_region = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_opaque_region:
 | 
			
		||||
 * @stex: a #MetaShapedTexture
 | 
			
		||||
 * @opaque_region: (transfer full): the region of the texture that
 | 
			
		||||
 *   can have blending turned off.
 | 
			
		||||
 *
 | 
			
		||||
 * As most windows have a large portion that does not require blending,
 | 
			
		||||
 * we can easily turn off blending if we know the areas that do not
 | 
			
		||||
 * require blending. This sets the region where we will not blend for
 | 
			
		||||
 * optimization purposes.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
 | 
			
		||||
                                       cairo_region_t    *opaque_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->opaque_region)
 | 
			
		||||
    cairo_region_destroy (priv->opaque_region);
 | 
			
		||||
 | 
			
		||||
  if (opaque_region)
 | 
			
		||||
    priv->opaque_region = cairo_region_reference (opaque_region);
 | 
			
		||||
  else
 | 
			
		||||
    priv->opaque_region = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_get_image:
 | 
			
		||||
 * @stex: A #MetaShapedTexture
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/extensions/shape.h>
 | 
			
		||||
#include <X11/extensions/Xcomposite.h>
 | 
			
		||||
#include <X11/extensions/Xdamage.h>
 | 
			
		||||
#include <X11/extensions/Xrender.h>
 | 
			
		||||
@@ -71,7 +70,7 @@ struct _MetaWindowActorPrivate
 | 
			
		||||
  /* 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 */
 | 
			
		||||
  cairo_region_t   *input_shape_region;
 | 
			
		||||
  cairo_region_t   *input_region;
 | 
			
		||||
  /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with
 | 
			
		||||
   * the shape region. */
 | 
			
		||||
  cairo_region_t   *opaque_region;
 | 
			
		||||
@@ -407,8 +406,8 @@ meta_window_actor_constructed (GObject *object)
 | 
			
		||||
 | 
			
		||||
  /* Start off with empty regions to maintain the invariant that
 | 
			
		||||
     these regions are always set */
 | 
			
		||||
  priv->shape_region = cairo_region_create();
 | 
			
		||||
  priv->input_shape_region = cairo_region_create();
 | 
			
		||||
  priv->shape_region = cairo_region_create ();
 | 
			
		||||
  priv->input_region = cairo_region_create ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -438,7 +437,7 @@ meta_window_actor_dispose (GObject *object)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->shape_region, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&priv->input_shape_region, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&priv->input_region, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&priv->shadow_clip, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
@@ -1260,7 +1259,7 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
 | 
			
		||||
  if (priv->opacity != 0xff)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (metaWindow->has_shape)
 | 
			
		||||
  if (metaWindow->shape_region != NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->argb32 && !meta_window_requested_bypass_compositor (metaWindow))
 | 
			
		||||
@@ -2171,85 +2170,21 @@ build_and_scan_frame_mask (MetaWindowActor       *self,
 | 
			
		||||
  g_free (mask_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
region_create_from_x_rectangles (const XRectangle *rects,
 | 
			
		||||
                                 int n_rects,
 | 
			
		||||
                                 int dx,
 | 
			
		||||
                                 int dy)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i ++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rects[i].x = rects[i].x + dx;
 | 
			
		||||
      cairo_rects[i].y = rects[i].y + dy;
 | 
			
		||||
      cairo_rects[i].width = rects[i].width;
 | 
			
		||||
      cairo_rects[i].height = rects[i].height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cairo_region_create_rectangles (cairo_rects, n_rects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_update_x11_shape_region (MetaWindowActor *self,
 | 
			
		||||
                                           cairo_rectangle_int_t *client_area)
 | 
			
		||||
meta_window_actor_update_shape_region (MetaWindowActor       *self,
 | 
			
		||||
                                       cairo_rectangle_int_t *client_area)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
  gboolean needs_mask;
 | 
			
		||||
 | 
			
		||||
  if (priv->shadow_shape != NULL)
 | 
			
		||||
  if (priv->window->frame != NULL && priv->window->shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_shape_unref (priv->shadow_shape);
 | 
			
		||||
      priv->shadow_shape = NULL;
 | 
			
		||||
      region = cairo_region_copy (priv->window->shape_region);
 | 
			
		||||
      cairo_region_translate (region, client_area->x, client_area->y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
 | 
			
		||||
  g_clear_pointer (&priv->shape_region, cairo_region_destroy);
 | 
			
		||||
  g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  if (priv->window->has_shape)
 | 
			
		||||
  else if (priv->window->shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Translate the set of XShape rectangles that we
 | 
			
		||||
       * get from the X server to a cairo_region. */
 | 
			
		||||
      MetaScreen *screen = priv->screen;
 | 
			
		||||
      MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
      Display *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
      XRectangle *rects;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      rects = XShapeGetRectangles (xdisplay,
 | 
			
		||||
                                   priv->window->xwindow,
 | 
			
		||||
                                   ShapeBounding,
 | 
			
		||||
                                   &n_rects,
 | 
			
		||||
                                   &ordering);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
 | 
			
		||||
      if (rects)
 | 
			
		||||
        {
 | 
			
		||||
          region = region_create_from_x_rectangles (rects, n_rects,
 | 
			
		||||
                                                    client_area->x,
 | 
			
		||||
                                                    client_area->y);
 | 
			
		||||
          XFree (rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  needs_mask = (region != NULL) || (priv->window->frame != NULL);
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* The shape we get back from the client may have coordinates
 | 
			
		||||
       * outside of the frame. The X SHAPE Extension requires that
 | 
			
		||||
       * the overall shape the client provides never exceeds the
 | 
			
		||||
       * "bounding rectangle" of the window -- the shape that the
 | 
			
		||||
       * window would have gotten if it was unshaped. In our case,
 | 
			
		||||
       * this is simply the client area.
 | 
			
		||||
       */
 | 
			
		||||
      cairo_region_intersect_rectangle (region, client_area);
 | 
			
		||||
      region = cairo_region_reference (priv->window->shape_region);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
@@ -2259,11 +2194,70 @@ meta_window_actor_update_x11_shape_region (MetaWindowActor *self,
 | 
			
		||||
      region = cairo_region_create_rectangle (client_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* The region at this point should be constrained to the
 | 
			
		||||
   * bounds of the client rectangle. */
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), NULL);
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
  if (priv->shadow_shape != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_shape_unref (priv->shadow_shape);
 | 
			
		||||
      priv->shadow_shape = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_invalidate_shadow (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_update_input_region (MetaWindowActor       *self,
 | 
			
		||||
                                       cairo_rectangle_int_t *client_area)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
 | 
			
		||||
  if (priv->window->frame != NULL && priv->window->shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_t *client_region = cairo_region_copy (priv->window->input_region);
 | 
			
		||||
 | 
			
		||||
      region = meta_frame_get_frame_bounds (priv->window->frame);
 | 
			
		||||
 | 
			
		||||
      cairo_region_subtract_rectangle (region, client_area);
 | 
			
		||||
      cairo_region_translate (client_region, client_area->x, client_area->y);
 | 
			
		||||
      cairo_region_union (region, client_region);
 | 
			
		||||
      cairo_region_destroy (client_region);
 | 
			
		||||
    }
 | 
			
		||||
  else if (priv->window->shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      region = cairo_region_reference (priv->window->input_region);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* If we don't have a shape on the server, that means that
 | 
			
		||||
       * we have an implicit shape of one rectangle covering the
 | 
			
		||||
       * entire window. */
 | 
			
		||||
      region = cairo_region_create_rectangle (client_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_input_shape_region (stex, region);
 | 
			
		||||
  cairo_region_destroy (region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_update_opaque_region (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (priv->argb32 && priv->window->opaque_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      MetaFrameBorders borders;
 | 
			
		||||
 | 
			
		||||
      meta_frame_calc_borders (priv->window->frame, &borders);
 | 
			
		||||
 | 
			
		||||
      /* The opaque region is defined to be a part of the
 | 
			
		||||
       * window which ARGB32 will always paint with opaque
 | 
			
		||||
       * pixels. For these regions, we want to avoid painting
 | 
			
		||||
@@ -2275,91 +2269,16 @@ meta_window_actor_update_x11_shape_region (MetaWindowActor *self,
 | 
			
		||||
       * case, graphical glitches will occur.
 | 
			
		||||
       */
 | 
			
		||||
      priv->opaque_region = cairo_region_copy (priv->window->opaque_region);
 | 
			
		||||
      cairo_region_translate (priv->opaque_region, client_area->x, client_area->y);
 | 
			
		||||
      cairo_region_intersect (priv->opaque_region, region);
 | 
			
		||||
      cairo_region_translate (priv->opaque_region, borders.total.left, borders.total.top);
 | 
			
		||||
      cairo_region_intersect (priv->opaque_region, priv->shape_region);
 | 
			
		||||
    }
 | 
			
		||||
  else if (priv->argb32)
 | 
			
		||||
    priv->opaque_region = NULL;
 | 
			
		||||
  else
 | 
			
		||||
    priv->opaque_region = cairo_region_reference (region);
 | 
			
		||||
    priv->opaque_region = cairo_region_reference (priv->shape_region);
 | 
			
		||||
 | 
			
		||||
  if (needs_mask)
 | 
			
		||||
    {
 | 
			
		||||
      /* This takes the region, generates a mask using GTK+
 | 
			
		||||
       * and scans the mask looking for all opaque pixels,
 | 
			
		||||
       * adding it to region.
 | 
			
		||||
       */
 | 
			
		||||
      build_and_scan_frame_mask (self, client_area, region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->shape_region = region;
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_invalidate_shadow (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_actor_update_x11_input_shape_region (MetaWindowActor *self,
 | 
			
		||||
                                                 cairo_rectangle_int_t *client_area)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->input_shape_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  /* Note: we currently assume that mutter never sets an input region
 | 
			
		||||
   * when there is a frame. */
 | 
			
		||||
  if (priv->window->frame == NULL && priv->window->has_input_shape)
 | 
			
		||||
    {
 | 
			
		||||
      MetaScreen *screen = priv->screen;
 | 
			
		||||
      MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
      Display *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
      XRectangle *rects;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
 | 
			
		||||
      /* Note we only actually query the ShapeInput shape of a window
 | 
			
		||||
       * when we don't have a frame because we assume currently that
 | 
			
		||||
       * mutter never sets an ShapeInput shape on a frame. */
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      rects = XShapeGetRectangles (xdisplay,
 | 
			
		||||
                                   priv->window->xwindow,
 | 
			
		||||
                                   ShapeInput,
 | 
			
		||||
                                   &n_rects,
 | 
			
		||||
                                   &ordering);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
      if (rects)
 | 
			
		||||
        {
 | 
			
		||||
          region = region_create_from_x_rectangles (rects, n_rects,
 | 
			
		||||
                                                    client_area->x,
 | 
			
		||||
                                                    client_area->y);
 | 
			
		||||
          XFree (rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* HAVE_SHAPE */
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* The X shape extension requires us to intersect the input
 | 
			
		||||
       * region with the effective bounding shape to determine the
 | 
			
		||||
       * effective input region.
 | 
			
		||||
       */
 | 
			
		||||
      if (priv->shape_region)
 | 
			
		||||
        cairo_region_intersect (region, priv->shape_region);
 | 
			
		||||
      else
 | 
			
		||||
        cairo_region_intersect_rectangle (region, client_area);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* If we don't have a shape on the server, that means that we
 | 
			
		||||
       * have an implicit shape of one rectangle covering the entire
 | 
			
		||||
       * window. */
 | 
			
		||||
      region = cairo_region_create_rectangle (client_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->input_shape_region = region;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_input_shape_region (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                              priv->input_shape_region);
 | 
			
		||||
  meta_shaped_texture_set_opaque_region (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                         priv->opaque_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -2385,24 +2304,9 @@ check_needs_reshape (MetaWindowActor *self)
 | 
			
		||||
  else
 | 
			
		||||
    client_area.height = priv->window->rect.height;
 | 
			
		||||
 | 
			
		||||
  if (priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_actor_update_x11_shape_region (self, &client_area);
 | 
			
		||||
      meta_window_actor_update_x11_input_shape_region (self, &client_area);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* TODO: properly support setting an input region as specified
 | 
			
		||||
       * via the wayland protocol */
 | 
			
		||||
 | 
			
		||||
      g_clear_pointer (&priv->shape_region, cairo_region_destroy);
 | 
			
		||||
      g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 | 
			
		||||
      g_clear_pointer (&priv->input_shape_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
      priv->shape_region = cairo_region_create_rectangle (&client_area);
 | 
			
		||||
      priv->opaque_region = cairo_region_reference (priv->shape_region);
 | 
			
		||||
      priv->input_shape_region = cairo_region_reference (priv->shape_region);
 | 
			
		||||
    }
 | 
			
		||||
  meta_window_actor_update_shape_region (self, &client_area);
 | 
			
		||||
  meta_window_actor_update_input_region (self, &client_area);
 | 
			
		||||
  meta_window_actor_update_opaque_region (self);
 | 
			
		||||
 | 
			
		||||
  priv->needs_reshape = FALSE;
 | 
			
		||||
}
 | 
			
		||||
@@ -2463,6 +2367,8 @@ meta_window_actor_set_wayland_surface (MetaWindowActor *self,
 | 
			
		||||
                                           surface);
 | 
			
		||||
  if (surface && surface->buffer_ref.buffer)
 | 
			
		||||
    maybe_emit_size_changed (self, surface->buffer_ref.buffer);
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_invalidate_shadow (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -186,7 +186,6 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (child))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindow *meta_window;
 | 
			
		||||
          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
 | 
			
		||||
          int x, y;
 | 
			
		||||
 | 
			
		||||
@@ -201,14 +200,7 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
          meta_window_actor_set_visible_region (window_actor, visible_region);
 | 
			
		||||
 | 
			
		||||
          /* TODO: Track the opaque regions of wayland clients.
 | 
			
		||||
           * Although wayland clients can report opaque window
 | 
			
		||||
           * regions, for now we assume that all wayland clients are
 | 
			
		||||
           * transparent... */
 | 
			
		||||
          meta_window = meta_window_actor_get_meta_window (window_actor);
 | 
			
		||||
 | 
			
		||||
          if (meta_window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
 | 
			
		||||
              clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
 | 
			
		||||
          if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
 | 
			
		||||
            {
 | 
			
		||||
              cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
 | 
			
		||||
              if (obscured_region)
 | 
			
		||||
 
 | 
			
		||||
@@ -2336,59 +2336,9 @@ meta_display_handle_event (MetaDisplay *display,
 | 
			
		||||
          XShapeEvent *sev = (XShapeEvent*) event;
 | 
			
		||||
 | 
			
		||||
          if (sev->kind == ShapeBounding)
 | 
			
		||||
            {
 | 
			
		||||
              if (sev->shaped && !window->has_shape)
 | 
			
		||||
                {
 | 
			
		||||
                  window->has_shape = TRUE;                  
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s now has a shape\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
              else if (!sev->shaped && window->has_shape)
 | 
			
		||||
                {
 | 
			
		||||
                  window->has_shape = FALSE;
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s no longer has a shape\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
              else
 | 
			
		||||
                {
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s shape changed\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              if (display->compositor)
 | 
			
		||||
                meta_compositor_window_x11_shape_changed (display->compositor,
 | 
			
		||||
                                                          window);
 | 
			
		||||
            }
 | 
			
		||||
            meta_window_update_shape_region_x11 (window);
 | 
			
		||||
          else if (sev->kind == ShapeInput)
 | 
			
		||||
            {
 | 
			
		||||
              if (sev->shaped && !window->has_input_shape)
 | 
			
		||||
                {
 | 
			
		||||
                  window->has_input_shape = TRUE;                  
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s now has an input shape\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
              else if (!sev->shaped && window->has_input_shape)
 | 
			
		||||
                {
 | 
			
		||||
                  window->has_input_shape = FALSE;
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s no longer has an input shape\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
              else
 | 
			
		||||
                {
 | 
			
		||||
                  meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                              "Window %s input shape changed\n",
 | 
			
		||||
                              window->desc);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              if (display->compositor)
 | 
			
		||||
                meta_compositor_window_x11_shape_changed (display->compositor,
 | 
			
		||||
                                                          window);
 | 
			
		||||
            }
 | 
			
		||||
            meta_window_update_input_region_x11 (window);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -339,11 +339,6 @@ struct _MetaWindow
 | 
			
		||||
  guint using_net_wm_icon_name         : 1; /* vs. plain wm_icon_name */
 | 
			
		||||
  guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */
 | 
			
		||||
 | 
			
		||||
  /* has a bounding shape mask */
 | 
			
		||||
  guint has_shape : 1;
 | 
			
		||||
  /* has an input shape mask */
 | 
			
		||||
  guint has_input_shape : 1;
 | 
			
		||||
 | 
			
		||||
  /* icon props have changed */
 | 
			
		||||
  guint need_reread_icon : 1;
 | 
			
		||||
  
 | 
			
		||||
@@ -365,9 +360,15 @@ struct _MetaWindow
 | 
			
		||||
  /* if non-NULL, the bounds of the window frame */
 | 
			
		||||
  cairo_region_t *frame_bounds;
 | 
			
		||||
 | 
			
		||||
  /* if non-NULL, the bounding shape region of the window */
 | 
			
		||||
  cairo_region_t *shape_region;
 | 
			
		||||
 | 
			
		||||
  /* if non-NULL, the opaque region _NET_WM_OPAQUE_REGION */
 | 
			
		||||
  cairo_region_t *opaque_region;
 | 
			
		||||
 | 
			
		||||
  /* the input shape region for picking */
 | 
			
		||||
  cairo_region_t *input_region;
 | 
			
		||||
 | 
			
		||||
  /* if TRUE, the we have the new form of sync request counter which
 | 
			
		||||
   * also handles application frames */
 | 
			
		||||
  guint extended_sync_request_counter : 1;
 | 
			
		||||
@@ -685,7 +686,6 @@ void meta_window_update_icon_now (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
void meta_window_update_role (MetaWindow *window);
 | 
			
		||||
void meta_window_update_net_wm_type (MetaWindow *window);
 | 
			
		||||
void meta_window_update_opaque_region (MetaWindow *window);
 | 
			
		||||
void meta_window_update_for_monitors_changed (MetaWindow *window);
 | 
			
		||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
@@ -699,4 +699,16 @@ void meta_window_compute_tile_match (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_updates_are_frozen (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
void meta_window_set_opaque_region        (MetaWindow     *window,
 | 
			
		||||
                                           cairo_region_t *region);
 | 
			
		||||
void meta_window_update_opaque_region_x11 (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
void meta_window_set_input_region         (MetaWindow     *window,
 | 
			
		||||
                                           cairo_region_t *region);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -565,7 +565,7 @@ reload_opaque_region (MetaWindow    *window,
 | 
			
		||||
                      MetaPropValue *value,
 | 
			
		||||
                      gboolean       initial)
 | 
			
		||||
{
 | 
			
		||||
  meta_window_update_opaque_region (window);
 | 
			
		||||
  meta_window_update_opaque_region_x11 (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -822,8 +822,6 @@ meta_window_new_shared (MetaDisplay         *display,
 | 
			
		||||
                        Window               xwindow,
 | 
			
		||||
                        gboolean             must_be_viewable,
 | 
			
		||||
                        gulong               existing_wm_state,
 | 
			
		||||
                        gboolean             has_shape,
 | 
			
		||||
                        gboolean             has_input_shape,
 | 
			
		||||
                        MetaCompEffect       effect,
 | 
			
		||||
                        XWindowAttributes   *attrs)
 | 
			
		||||
{
 | 
			
		||||
@@ -876,9 +874,6 @@ meta_window_new_shared (MetaDisplay         *display,
 | 
			
		||||
  /* avoid tons of stack updates */
 | 
			
		||||
  meta_stack_freeze (window->screen->stack);
 | 
			
		||||
 | 
			
		||||
  window->has_shape = has_shape;
 | 
			
		||||
  window->has_input_shape = has_input_shape;
 | 
			
		||||
 | 
			
		||||
  window->rect.x = attrs->x;
 | 
			
		||||
  window->rect.y = attrs->y;
 | 
			
		||||
  window->rect.width = attrs->width;
 | 
			
		||||
@@ -1059,6 +1054,8 @@ meta_window_new_shared (MetaDisplay         *display,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      meta_display_register_x_window (display, &window->xwindow, window);
 | 
			
		||||
      meta_window_update_shape_region_x11 (window);
 | 
			
		||||
      meta_window_update_input_region_x11 (window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* assign the window to its group, or create a new group if needed
 | 
			
		||||
@@ -1425,8 +1422,6 @@ meta_window_new_for_wayland (MetaDisplay        *display,
 | 
			
		||||
                                   None,
 | 
			
		||||
                                   TRUE,
 | 
			
		||||
                                   WithdrawnState,
 | 
			
		||||
                                   FALSE, /* has shape */
 | 
			
		||||
                                   FALSE, /* has input shape */
 | 
			
		||||
                                   META_COMP_EFFECT_NONE,
 | 
			
		||||
                                   &attrs);
 | 
			
		||||
 | 
			
		||||
@@ -1455,8 +1450,6 @@ meta_window_new_with_attrs (MetaDisplay       *display,
 | 
			
		||||
  gulong existing_wm_state;
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  gulong event_mask;
 | 
			
		||||
  gboolean has_shape = FALSE;
 | 
			
		||||
  gboolean has_input_shape = FALSE;
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
 | 
			
		||||
 | 
			
		||||
@@ -1576,53 +1569,6 @@ meta_window_new_with_attrs (MetaDisplay       *display,
 | 
			
		||||
      XISelectEvents (display->xdisplay, xwindow, &mask, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  if (META_DISPLAY_HAS_SHAPE (display))
 | 
			
		||||
    {
 | 
			
		||||
      int x_bounding, y_bounding, x_clip, y_clip;
 | 
			
		||||
      unsigned w_bounding, h_bounding, w_clip, h_clip;
 | 
			
		||||
      int bounding_shaped, clip_shaped;
 | 
			
		||||
      XRectangle *input_rectangles;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
 | 
			
		||||
      XShapeSelectInput (display->xdisplay, xwindow, ShapeNotifyMask);
 | 
			
		||||
 | 
			
		||||
      XShapeQueryExtents (display->xdisplay, xwindow,
 | 
			
		||||
                          &bounding_shaped, &x_bounding, &y_bounding,
 | 
			
		||||
                          &w_bounding, &h_bounding,
 | 
			
		||||
                          &clip_shaped, &x_clip, &y_clip,
 | 
			
		||||
                          &w_clip, &h_clip);
 | 
			
		||||
 | 
			
		||||
      has_shape = bounding_shaped != FALSE;
 | 
			
		||||
 | 
			
		||||
      /* XXX: The x shape extension doesn't provide a way to only test if an
 | 
			
		||||
       * input shape has been specified, so we have to query and throw away the
 | 
			
		||||
       * rectangles. */
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      input_rectangles = XShapeGetRectangles (display->xdisplay, xwindow,
 | 
			
		||||
                                              ShapeInput, &n_rects, &ordering);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
      if (input_rectangles)
 | 
			
		||||
        {
 | 
			
		||||
          if (n_rects > 1 ||
 | 
			
		||||
              (n_rects == 1 &&
 | 
			
		||||
               (input_rectangles[0].x != x_bounding ||
 | 
			
		||||
                input_rectangles[1].y != y_bounding ||
 | 
			
		||||
                input_rectangles[2].width != w_bounding ||
 | 
			
		||||
                input_rectangles[3].height != h_bounding)))
 | 
			
		||||
            {
 | 
			
		||||
              has_input_shape = TRUE;
 | 
			
		||||
            }
 | 
			
		||||
          XFree (input_rectangles);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_SHAPES,
 | 
			
		||||
                  "Window has_shape = %d extents %d,%d %u x %u\n",
 | 
			
		||||
                  has_shape, x_bounding, y_bounding,
 | 
			
		||||
                  w_bounding, h_bounding);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Get rid of any borders */
 | 
			
		||||
  if (attrs->border_width != 0)
 | 
			
		||||
    XSetWindowBorderWidth (display->xdisplay, xwindow, 0);
 | 
			
		||||
@@ -1656,8 +1602,6 @@ meta_window_new_with_attrs (MetaDisplay       *display,
 | 
			
		||||
                                   xwindow,
 | 
			
		||||
                                   must_be_viewable,
 | 
			
		||||
                                   existing_wm_state,
 | 
			
		||||
                                   has_shape,
 | 
			
		||||
                                   has_input_shape,
 | 
			
		||||
                                   effect,
 | 
			
		||||
                                   attrs);
 | 
			
		||||
 | 
			
		||||
@@ -7810,14 +7754,25 @@ meta_window_update_net_wm_type (MetaWindow *window)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_update_opaque_region (MetaWindow *window)
 | 
			
		||||
meta_window_set_opaque_region (MetaWindow     *window,
 | 
			
		||||
                               cairo_region_t *region)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&window->opaque_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    window->opaque_region = cairo_region_reference (region);
 | 
			
		||||
 | 
			
		||||
  if (window->display->compositor)
 | 
			
		||||
    meta_compositor_window_shape_changed (window->display->compositor, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_update_opaque_region_x11 (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *opaque_region = NULL;
 | 
			
		||||
  gulong *region = NULL;
 | 
			
		||||
  int nitems;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&window->opaque_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (meta_prop_get_cardinal_list (window->display,
 | 
			
		||||
                                   window->xwindow,
 | 
			
		||||
                                   window->display->atom__NET_WM_OPAQUE_REGION,
 | 
			
		||||
@@ -7860,11 +7815,191 @@ meta_window_update_opaque_region (MetaWindow *window)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  window->opaque_region = opaque_region;
 | 
			
		||||
  meta_XFree (region);
 | 
			
		||||
 | 
			
		||||
  meta_window_set_opaque_region (window, opaque_region);
 | 
			
		||||
  cairo_region_destroy (opaque_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
region_create_from_x_rectangles (const XRectangle *rects,
 | 
			
		||||
                                 int n_rects)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i ++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rects[i].x = rects[i].x;
 | 
			
		||||
      cairo_rects[i].y = rects[i].y;
 | 
			
		||||
      cairo_rects[i].width = rects[i].width;
 | 
			
		||||
      cairo_rects[i].height = rects[i].height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cairo_region_create_rectangles (cairo_rects, n_rects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_set_input_region (MetaWindow     *window,
 | 
			
		||||
                              cairo_region_t *region)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&window->input_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    window->input_region = cairo_region_reference (region);
 | 
			
		||||
 | 
			
		||||
  if (window->display->compositor)
 | 
			
		||||
    meta_compositor_window_x11_shape_changed (window->display->compositor, window);
 | 
			
		||||
    meta_compositor_window_shape_changed (window->display->compositor, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_update_input_region_x11 (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  if (META_DISPLAY_HAS_SHAPE (window->display))
 | 
			
		||||
    {
 | 
			
		||||
      /* Translate the set of XShape rectangles that we
 | 
			
		||||
       * get from the X server to a cairo_region. */
 | 
			
		||||
      XRectangle *rects = NULL;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
 | 
			
		||||
      int x_bounding, y_bounding, x_clip, y_clip;
 | 
			
		||||
      unsigned w_bounding, h_bounding, w_clip, h_clip;
 | 
			
		||||
      int bounding_shaped, clip_shaped;
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (window->display);
 | 
			
		||||
      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
 | 
			
		||||
                          &bounding_shaped, &x_bounding, &y_bounding,
 | 
			
		||||
                          &w_bounding, &h_bounding,
 | 
			
		||||
                          &clip_shaped, &x_clip, &y_clip,
 | 
			
		||||
                          &w_clip, &h_clip);
 | 
			
		||||
 | 
			
		||||
      rects = XShapeGetRectangles (window->display->xdisplay,
 | 
			
		||||
                                   window->xwindow,
 | 
			
		||||
                                   ShapeInput,
 | 
			
		||||
                                   &n_rects,
 | 
			
		||||
                                   &ordering);
 | 
			
		||||
      meta_error_trap_pop (window->display);
 | 
			
		||||
 | 
			
		||||
      /* XXX: The x shape extension doesn't provide a way to only test if an
 | 
			
		||||
       * input shape has been specified, so we have to query and throw away the
 | 
			
		||||
       * rectangles. */
 | 
			
		||||
      if (rects)
 | 
			
		||||
        {
 | 
			
		||||
          if (n_rects > 1 ||
 | 
			
		||||
              (n_rects == 1 &&
 | 
			
		||||
               (rects[0].x != x_bounding ||
 | 
			
		||||
                rects[1].y != y_bounding ||
 | 
			
		||||
                rects[2].width != w_bounding ||
 | 
			
		||||
                rects[3].height != h_bounding)))
 | 
			
		||||
            region = region_create_from_x_rectangles (rects, n_rects);
 | 
			
		||||
 | 
			
		||||
          XFree (rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* HAVE_SHAPE */
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t client_area;
 | 
			
		||||
 | 
			
		||||
      client_area.x = 0;
 | 
			
		||||
      client_area.y = 0;
 | 
			
		||||
      client_area.width = window->rect.width;
 | 
			
		||||
      client_area.height = window->rect.height;
 | 
			
		||||
 | 
			
		||||
      /* The shape we get back from the client may have coordinates
 | 
			
		||||
       * outside of the frame. The X SHAPE Extension requires that
 | 
			
		||||
       * the overall shape the client provides never exceeds the
 | 
			
		||||
       * "bounding rectangle" of the window -- the shape that the
 | 
			
		||||
       * window would have gotten if it was unshaped. In our case,
 | 
			
		||||
       * this is simply the client area.
 | 
			
		||||
       */
 | 
			
		||||
      cairo_region_intersect_rectangle (region, &client_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_set_input_region (window, region);
 | 
			
		||||
  cairo_region_destroy (region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_set_shape_region (MetaWindow     *window,
 | 
			
		||||
                              cairo_region_t *region)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&window->shape_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    window->shape_region = cairo_region_reference (region);
 | 
			
		||||
 | 
			
		||||
  if (window->display->compositor)
 | 
			
		||||
    meta_compositor_window_shape_changed (window->display->compositor, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_update_shape_region_x11 (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  if (META_DISPLAY_HAS_SHAPE (window->display))
 | 
			
		||||
    {
 | 
			
		||||
      /* Translate the set of XShape rectangles that we
 | 
			
		||||
       * get from the X server to a cairo_region. */
 | 
			
		||||
      XRectangle *rects = NULL;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
 | 
			
		||||
      int x_bounding, y_bounding, x_clip, y_clip;
 | 
			
		||||
      unsigned w_bounding, h_bounding, w_clip, h_clip;
 | 
			
		||||
      int bounding_shaped, clip_shaped;
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (window->display);
 | 
			
		||||
      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
 | 
			
		||||
                          &bounding_shaped, &x_bounding, &y_bounding,
 | 
			
		||||
                          &w_bounding, &h_bounding,
 | 
			
		||||
                          &clip_shaped, &x_clip, &y_clip,
 | 
			
		||||
                          &w_clip, &h_clip);
 | 
			
		||||
 | 
			
		||||
      if (bounding_shaped)
 | 
			
		||||
        {
 | 
			
		||||
          rects = XShapeGetRectangles (window->display->xdisplay,
 | 
			
		||||
                                       window->xwindow,
 | 
			
		||||
                                       ShapeBounding,
 | 
			
		||||
                                       &n_rects,
 | 
			
		||||
                                       &ordering);
 | 
			
		||||
        }
 | 
			
		||||
      meta_error_trap_pop (window->display);
 | 
			
		||||
 | 
			
		||||
      if (rects)
 | 
			
		||||
        {
 | 
			
		||||
          region = region_create_from_x_rectangles (rects, n_rects);
 | 
			
		||||
          XFree (rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* HAVE_SHAPE */
 | 
			
		||||
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t client_area;
 | 
			
		||||
 | 
			
		||||
      client_area.x = 0;
 | 
			
		||||
      client_area.y = 0;
 | 
			
		||||
      client_area.width = window->rect.width;
 | 
			
		||||
      client_area.height = window->rect.height;
 | 
			
		||||
 | 
			
		||||
      /* The shape we get back from the client may have coordinates
 | 
			
		||||
       * outside of the frame. The X SHAPE Extension requires that
 | 
			
		||||
       * the overall shape the client provides never exceeds the
 | 
			
		||||
       * "bounding rectangle" of the window -- the shape that the
 | 
			
		||||
       * window would have gotten if it was unshaped. In our case,
 | 
			
		||||
       * this is simply the client area.
 | 
			
		||||
       */
 | 
			
		||||
      cairo_region_intersect_rectangle (region, &client_area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_set_shape_region (window, region);
 | 
			
		||||
  cairo_region_destroy (region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -64,8 +64,8 @@ void meta_compositor_manage_screen   (MetaCompositor *compositor,
 | 
			
		||||
void meta_compositor_unmanage_screen (MetaCompositor *compositor,
 | 
			
		||||
                                      MetaScreen     *screen);
 | 
			
		||||
 | 
			
		||||
void meta_compositor_window_x11_shape_changed (MetaCompositor *compositor,
 | 
			
		||||
                                               MetaWindow     *window);
 | 
			
		||||
void meta_compositor_window_shape_changed (MetaCompositor *compositor,
 | 
			
		||||
                                           MetaWindow     *window);
 | 
			
		||||
 | 
			
		||||
gboolean meta_compositor_process_event (MetaCompositor *compositor,
 | 
			
		||||
                                        XEvent         *event,
 | 
			
		||||
 
 | 
			
		||||
@@ -84,6 +84,9 @@ void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
 | 
			
		||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
					  cairo_region_t    *clip_region);
 | 
			
		||||
 | 
			
		||||
void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex,
 | 
			
		||||
                                            cairo_region_t    *opaque_region);
 | 
			
		||||
 | 
			
		||||
cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 | 
			
		||||
                                                 cairo_rectangle_int_t *clip);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -324,18 +324,34 @@ meta_wayland_surface_frame (struct wl_client *client,
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_surface_set_opaque_region (struct wl_client *client,
 | 
			
		||||
                                        struct wl_resource *resource,
 | 
			
		||||
                                        struct wl_resource *region)
 | 
			
		||||
                                        struct wl_resource *surface_resource,
 | 
			
		||||
                                        struct wl_resource *region_resource)
 | 
			
		||||
{
 | 
			
		||||
  g_warning ("TODO: support set_opaque_region request");
 | 
			
		||||
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
 | 
			
		||||
  MetaWaylandRegion *region = wl_resource_get_user_data (region_resource);
 | 
			
		||||
 | 
			
		||||
  /* X11 unmanaged window */
 | 
			
		||||
  if (!surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (surface->window)
 | 
			
		||||
    meta_window_set_opaque_region (surface->window, cairo_region_copy (region->region));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_surface_set_input_region (struct wl_client *client,
 | 
			
		||||
                                       struct wl_resource *resource,
 | 
			
		||||
                                       struct wl_resource *region)
 | 
			
		||||
                                       struct wl_resource *surface_resource,
 | 
			
		||||
                                       struct wl_resource *region_resource)
 | 
			
		||||
{
 | 
			
		||||
  g_warning ("TODO: support set_input_region request");
 | 
			
		||||
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
 | 
			
		||||
  MetaWaylandRegion *region = wl_resource_get_user_data (region_resource);
 | 
			
		||||
 | 
			
		||||
  /* X11 unmanaged window */
 | 
			
		||||
  if (!surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (surface->window)
 | 
			
		||||
    meta_window_set_input_region (surface->window, cairo_region_copy (region->region));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user