Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 367139 | Differences between
and this patch

Collapse All | Expand All

(-)a/src/compositor/meta-shadow-factory-private.h (-1 / +2 lines)
Lines 47-53 void meta_shadow_paint (MetaShadow *shadow, Link Here
47
                                     int                    window_width,
47
                                     int                    window_width,
48
                                     int                    window_height,
48
                                     int                    window_height,
49
                                     guint8                 opacity,
49
                                     guint8                 opacity,
50
                                     cairo_region_t        *clip);
50
                                     cairo_region_t        *clip,
51
                                     gboolean               clip_strictly);
51
void        meta_shadow_get_bounds  (MetaShadow            *shadow,
52
void        meta_shadow_get_bounds  (MetaShadow            *shadow,
52
                                     int                    window_x,
53
                                     int                    window_x,
53
                                     int                    window_y,
54
                                     int                    window_y,
(-)a/src/compositor/meta-shadow-factory.c (-9 / +63 lines)
Lines 189-196 meta_shadow_unref (MetaShadow *shadow) Link Here
189
 * @window_width: actual width of the region to paint a shadow for
189
 * @window_width: actual width of the region to paint a shadow for
190
 * @window_height: actual height of the region to paint a shadow for
190
 * @window_height: actual height of the region to paint a shadow for
191
 * @clip: (allow-none): if non-%NULL specifies the visible portion
191
 * @clip: (allow-none): if non-%NULL specifies the visible portion
192
 *   of the shadow. Drawing won't be strictly clipped to this region
192
 *   of the shadow.
193
 *   but it will be used to optimize what is drawn.
193
 * @clip_strictly: if %TRUE, drawing will be clipped strictly
194
 *   to @clip, otherwise, it will be only used to optimize
195
 *   drawing.
194
 *
196
 *
195
 * Paints the shadow at the given position, for the specified actual
197
 * Paints the shadow at the given position, for the specified actual
196
 * size of the region. (Since a #MetaShadow can be shared between
198
 * size of the region. (Since a #MetaShadow can be shared between
Lines 204-210 meta_shadow_paint (MetaShadow *shadow, Link Here
204
                   int             window_width,
206
                   int             window_width,
205
                   int             window_height,
207
                   int             window_height,
206
                   guint8          opacity,
208
                   guint8          opacity,
207
                   cairo_region_t *clip)
209
                   cairo_region_t *clip,
210
                   gboolean        clip_strictly)
208
{
211
{
209
  float texture_width = cogl_texture_get_width (shadow->texture);
212
  float texture_width = cogl_texture_get_width (shadow->texture);
210
  float texture_height = cogl_texture_get_height (shadow->texture);
213
  float texture_height = cogl_texture_get_height (shadow->texture);
Lines 276-281 meta_shadow_paint (MetaShadow *shadow, Link Here
276
      dest_rect.y = dest_y[j];
279
      dest_rect.y = dest_y[j];
277
      dest_rect.height = dest_y[j + 1] - dest_y[j];
280
      dest_rect.height = dest_y[j + 1] - dest_y[j];
278
281
282
      if (dest_rect.height == 0)
283
        continue;
284
279
      for (i = 0; i < n_x; i++)
285
      for (i = 0; i < n_x; i++)
280
        {
286
        {
281
          cairo_region_overlap_t overlap;
287
          cairo_region_overlap_t overlap;
Lines 283-298 meta_shadow_paint (MetaShadow *shadow, Link Here
283
          dest_rect.x = dest_x[i];
289
          dest_rect.x = dest_x[i];
284
          dest_rect.width = dest_x[i + 1] - dest_x[i];
290
          dest_rect.width = dest_x[i + 1] - dest_x[i];
285
291
292
          if (dest_rect.width == 0)
293
            continue;
294
286
          if (clip)
295
          if (clip)
287
            overlap = cairo_region_contains_rectangle (clip, &dest_rect);
296
            overlap = cairo_region_contains_rectangle (clip, &dest_rect);
288
          else
297
          else
289
            overlap = CAIRO_REGION_OVERLAP_PART;
298
            overlap = CAIRO_REGION_OVERLAP_IN;
290
299
291
          if (overlap != CAIRO_REGION_OVERLAP_OUT)
300
          /* There's quite a bit of overhead from allocating a new
292
            cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
301
           * region in order to find an exact intersection and
293
                                                dest_x[i + 1], dest_y[j + 1],
302
           * generating more geometry - we make the assumption that
294
                                                src_x[i], src_y[j],
303
           * unless we have to clip strictly it will be cheaper to
295
                                                src_x[i + 1], src_y[j + 1]);
304
           * just draw the entire rectangle.
305
           */
306
          if (overlap == CAIRO_REGION_OVERLAP_IN ||
307
              (overlap == CAIRO_REGION_OVERLAP_PART && !clip_strictly))
308
            {
309
              cogl_rectangle_with_texture_coords (dest_x[i], dest_y[j],
310
                                                  dest_x[i + 1], dest_y[j + 1],
311
                                                  src_x[i], src_y[j],
312
                                                  src_x[i + 1], src_y[j + 1]);
313
            }
314
          else if (overlap == CAIRO_REGION_OVERLAP_PART)
315
            {
316
              cairo_region_t *intersection;
317
              int n_rectangles, k;
318
319
              intersection = cairo_region_create_rectangle (&dest_rect);
320
              cairo_region_intersect (intersection, clip);
321
322
              n_rectangles = cairo_region_num_rectangles (intersection);
323
              for (k = 0; k < n_rectangles; k++)
324
                {
325
                  cairo_rectangle_int_t rect;
326
                  float src_x1, src_x2, src_y1, src_y2;
327
328
                  cairo_region_get_rectangle (intersection, k, &rect);
329
330
                  /* Separately linear interpolate X and Y coordinates in the source
331
                   * based on the destination X and Y coordinates */
332
333
                  src_x1 = (src_x[i] * (dest_rect.x + dest_rect.width - rect.x) +
334
                            src_x[i + 1] * (rect.x - dest_rect.x)) / dest_rect.width;
335
                  src_x2 = (src_x[i] * (dest_rect.x + dest_rect.width - (rect.x + rect.width)) +
336
                            src_x[i + 1] * (rect.x + rect.width - dest_rect.x)) / dest_rect.width;
337
338
                  src_y1 = (src_y[j] * (dest_rect.y + dest_rect.height - rect.y) +
339
                            src_y[j + 1] * (rect.y - dest_rect.y)) / dest_rect.height;
340
                  src_y2 = (src_y[j] * (dest_rect.y + dest_rect.height - (rect.y + rect.height)) +
341
                            src_y[j + 1] * (rect.y + rect.height - dest_rect.y)) / dest_rect.height;
342
343
                  cogl_rectangle_with_texture_coords (rect.x, rect.y,
344
                                                      rect.x + rect.width, rect.y + rect.height,
345
                                                      src_x1, src_y1, src_x2, src_y2);
346
                }
347
348
              cairo_region_destroy (intersection);
349
            }
296
        }
350
        }
297
    }
351
    }
298
}
352
}
(-)a/src/compositor/meta-window-actor.c (-1 / +40 lines)
Lines 706-722 meta_window_actor_paint (ClutterActor *actor) Link Here
706
    {
706
    {
707
      MetaShadowParams params;
707
      MetaShadowParams params;
708
      cairo_rectangle_int_t shape_bounds;
708
      cairo_rectangle_int_t shape_bounds;
709
      cairo_region_t *clip = priv->shadow_clip;
709
710
710
      meta_window_actor_get_shape_bounds (self, &shape_bounds);
711
      meta_window_actor_get_shape_bounds (self, &shape_bounds);
711
      meta_window_actor_get_shadow_params (self, appears_focused, &params);
712
      meta_window_actor_get_shadow_params (self, appears_focused, &params);
712
713
714
      /* If we have an ARGB32 window that we decorate with a
715
       * frame, it's probably something like a translucent
716
       * terminal - something where the alpha channel represents
717
       * transparency rather than a shape.  We don't want to show
718
       * the shadow through the translucent areas since the shadow
719
       * is wrong for translucent windows (it should be
720
       * translucent itself and colored), and not only that will
721
       * look horribly wrong - a misplaced big black blob. As a
722
       * hack, what we want to do is just draw the shadow as
723
       * normal outside the frame, and inside the frame draw no
724
       * shadow.  This is also not even close to the right result,
725
       * but looks OK.
726
       *
727
       * The frame bounds are already subtracted from priv->shadow_clip
728
       * if that exists.
729
       */
730
      if (!clip && priv->argb32 && priv->window->frame)
731
        {
732
          cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
733
          cairo_rectangle_int_t bounds;
734
735
          meta_window_actor_get_shadow_bounds (self, appears_focused, &bounds);
736
          clip = cairo_region_create_rectangle (&bounds);
737
738
          cairo_region_subtract (clip, frame_bounds);
739
        }
740
713
      meta_shadow_paint (shadow,
741
      meta_shadow_paint (shadow,
714
                         params.x_offset + shape_bounds.x,
742
                         params.x_offset + shape_bounds.x,
715
                         params.y_offset + shape_bounds.y,
743
                         params.y_offset + shape_bounds.y,
716
                         shape_bounds.width,
744
                         shape_bounds.width,
717
                         shape_bounds.height,
745
                         shape_bounds.height,
718
                         (clutter_actor_get_paint_opacity (actor) * params.opacity) / 255,
746
                         (clutter_actor_get_paint_opacity (actor) * params.opacity) / 255,
719
                         priv->shadow_clip);
747
                         clip,
748
                         priv->argb32 && priv->window->frame);
749
750
      if (clip && clip != priv->shadow_clip)
751
        cairo_region_destroy (clip);
720
    }
752
    }
721
753
722
  CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
754
  CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
Lines 1779-1784 meta_window_actor_set_visible_region_beneath (MetaWindowActor *self, Link Here
1779
    {
1811
    {
1780
      meta_window_actor_clear_shadow_clip (self);
1812
      meta_window_actor_clear_shadow_clip (self);
1781
      priv->shadow_clip = cairo_region_copy (beneath_region);
1813
      priv->shadow_clip = cairo_region_copy (beneath_region);
1814
1815
      /* See comment in meta_window_actor_paint() */
1816
      if (priv->argb32 && priv->window->frame)
1817
        {
1818
          cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window);
1819
          cairo_region_subtract (priv->shadow_clip, frame_bounds);
1820
        }
1782
    }
1821
    }
1783
}
1822
}
1784
1823
(-)a/src/core/frame.c (-4 / +18 lines)
Lines 328-334 meta_frame_calc_geometry (MetaFrame *frame, Link Here
328
  *geomp = geom;
328
  *geomp = geom;
329
}
329
}
330
330
331
static void
331
static gboolean
332
update_shape (MetaFrame *frame)
332
update_shape (MetaFrame *frame)
333
{
333
{
334
  if (frame->need_reapply_frame_shape)
334
  if (frame->need_reapply_frame_shape)
Lines 339-348 update_shape (MetaFrame *frame) Link Here
339
                                 frame->rect.height,
339
                                 frame->rect.height,
340
                                 frame->window->has_shape);
340
                                 frame->window->has_shape);
341
      frame->need_reapply_frame_shape = FALSE;
341
      frame->need_reapply_frame_shape = FALSE;
342
343
      return TRUE;
342
    }
344
    }
345
  else
346
    return FALSE;
343
}
347
}
344
348
345
void
349
gboolean
346
meta_frame_sync_to_window (MetaFrame *frame,
350
meta_frame_sync_to_window (MetaFrame *frame,
347
                           int        resize_gravity,
351
                           int        resize_gravity,
348
                           gboolean   need_move,
352
                           gboolean   need_move,
Lines 350-357 meta_frame_sync_to_window (MetaFrame *frame, Link Here
350
{
354
{
351
  if (!(need_move || need_resize))
355
  if (!(need_move || need_resize))
352
    {
356
    {
353
      update_shape (frame);
357
      return update_shape (frame);
354
      return;
355
    }
358
    }
356
359
357
  meta_topic (META_DEBUG_GEOMETRY,
360
  meta_topic (META_DEBUG_GEOMETRY,
Lines 401-406 meta_frame_sync_to_window (MetaFrame *frame, Link Here
401
        meta_ui_repaint_frame (frame->window->screen->ui,
404
        meta_ui_repaint_frame (frame->window->screen->ui,
402
                               frame->xwindow);
405
                               frame->xwindow);
403
    }
406
    }
407
408
  return need_resize;
409
}
410
411
cairo_region_t *
412
meta_frame_get_frame_bounds (MetaFrame *frame)
413
{
414
  return meta_ui_get_frame_bounds (frame->window->screen->ui,
415
                                   frame->xwindow,
416
                                   frame->rect.width,
417
                                   frame->rect.height);
404
}
418
}
405
419
406
void
420
void
(-)a/src/core/frame.h (-1 / +3 lines)
Lines 73-83 Window meta_frame_get_xwindow (MetaFrame *frame); Link Here
73
/* These should ONLY be called from meta_window_move_resize_internal */
73
/* These should ONLY be called from meta_window_move_resize_internal */
74
void meta_frame_calc_geometry      (MetaFrame         *frame,
74
void meta_frame_calc_geometry      (MetaFrame         *frame,
75
                                    MetaFrameGeometry *geomp);
75
                                    MetaFrameGeometry *geomp);
76
void meta_frame_sync_to_window     (MetaFrame         *frame,
76
gboolean meta_frame_sync_to_window (MetaFrame         *frame,
77
                                    int                gravity,
77
                                    int                gravity,
78
                                    gboolean           need_move,
78
                                    gboolean           need_move,
79
                                    gboolean           need_resize);
79
                                    gboolean           need_resize);
80
80
81
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
82
81
void meta_frame_set_screen_cursor (MetaFrame	*frame,
83
void meta_frame_set_screen_cursor (MetaFrame	*frame,
82
				   MetaCursor	cursor);
84
				   MetaCursor	cursor);
83
85
(-)a/src/core/window-private.h (+4 lines)
Lines 42-47 Link Here
42
#include "stack.h"
42
#include "stack.h"
43
#include "iconcache.h"
43
#include "iconcache.h"
44
#include <X11/Xutil.h>
44
#include <X11/Xutil.h>
45
#include <cairo.h>
45
#include <gdk-pixbuf/gdk-pixbuf.h>
46
#include <gdk-pixbuf/gdk-pixbuf.h>
46
47
47
typedef struct _MetaWindowQueue MetaWindowQueue;
48
typedef struct _MetaWindowQueue MetaWindowQueue;
Lines 318-323 struct _MetaWindow Link Here
318
  /* if TRUE, application is buggy and SYNC resizing is turned off */
319
  /* if TRUE, application is buggy and SYNC resizing is turned off */
319
  guint disable_sync : 1;
320
  guint disable_sync : 1;
320
321
322
  /* if non-NULL, the bounds of the window frame */
323
  cairo_region_t *frame_bounds;
324
321
  /* Note: can be NULL */
325
  /* Note: can be NULL */
322
  GSList *struts;
326
  GSList *struts;
323
327
(-)a/src/core/window.c (-6 / +37 lines)
Lines 180-185 meta_window_finalize (GObject *object) Link Here
180
  if (window->mini_icon)
180
  if (window->mini_icon)
181
    g_object_unref (G_OBJECT (window->mini_icon));
181
    g_object_unref (G_OBJECT (window->mini_icon));
182
182
183
  if (window->frame_bounds)
184
    cairo_region_destroy (window->frame_bounds);
185
183
  meta_icon_cache_free (&window->icon_cache);
186
  meta_icon_cache_free (&window->icon_cache);
184
187
185
  g_free (window->sm_client_id);
188
  g_free (window->sm_client_id);
Lines 4275-4280 meta_window_move_resize_internal (MetaWindow *window, Link Here
4275
  int frame_size_dy;
4278
  int frame_size_dy;
4276
  int size_dx;
4279
  int size_dx;
4277
  int size_dy;
4280
  int size_dy;
4281
  gboolean frame_shape_changed = FALSE;
4278
  gboolean is_configure_request;
4282
  gboolean is_configure_request;
4279
  gboolean do_gravity_adjust;
4283
  gboolean do_gravity_adjust;
4280
  gboolean is_user_action;
4284
  gboolean is_user_action;
Lines 4578-4586 meta_window_move_resize_internal (MetaWindow *window, Link Here
4578
    meta_window_set_gravity (window, StaticGravity);
4582
    meta_window_set_gravity (window, StaticGravity);
4579
4583
4580
  if (configure_frame_first && window->frame)
4584
  if (configure_frame_first && window->frame)
4581
    meta_frame_sync_to_window (window->frame,
4585
    frame_shape_changed = meta_frame_sync_to_window (window->frame,
4582
                               gravity,
4586
                                                     gravity,
4583
                               need_move_frame, need_resize_frame);
4587
                                                     need_move_frame, need_resize_frame);
4584
4588
4585
  values.border_width = 0;
4589
  values.border_width = 0;
4586
  values.x = client_move_x;
4590
  values.x = client_move_x;
Lines 4635-4643 meta_window_move_resize_internal (MetaWindow *window, Link Here
4635
    }
4639
    }
4636
4640
4637
  if (!configure_frame_first && window->frame)
4641
  if (!configure_frame_first && window->frame)
4638
    meta_frame_sync_to_window (window->frame,
4642
    frame_shape_changed = meta_frame_sync_to_window (window->frame,
4639
                               gravity,
4643
                                                     gravity,
4640
                               need_move_frame, need_resize_frame);
4644
                                                     need_move_frame, need_resize_frame);
4641
4645
4642
  /* Put gravity back to be nice to lesser window managers */
4646
  /* Put gravity back to be nice to lesser window managers */
4643
  if (use_static_gravity)
4647
  if (use_static_gravity)
Lines 4680-4685 meta_window_move_resize_internal (MetaWindow *window, Link Here
4680
   *   b) all constraints are obeyed by window->rect and frame->rect
4684
   *   b) all constraints are obeyed by window->rect and frame->rect
4681
   */
4685
   */
4682
4686
4687
  if (frame_shape_changed && window->frame_bounds)
4688
    {
4689
      cairo_region_destroy (window->frame_bounds);
4690
      window->frame_bounds = NULL;
4691
    }
4692
4683
  if (meta_prefs_get_attach_modal_dialogs ())
4693
  if (meta_prefs_get_attach_modal_dialogs ())
4684
    meta_window_foreach_transient (window, move_attached_dialog, NULL);
4694
    meta_window_foreach_transient (window, move_attached_dialog, NULL);
4685
}
4695
}
Lines 10174-10176 meta_window_get_frame_type (MetaWindow *window) Link Here
10174
      return base_type;
10184
      return base_type;
10175
    }
10185
    }
10176
}
10186
}
10187
10188
/**
10189
 * meta_window_get_frame_bounds:
10190
 *
10191
 * Gets a region representing the outer bounds of the window's frame.
10192
 *
10193
 * Return value: (transfer none) (allow-none): a #cairo_region_t
10194
 *  holding the outer bounds of the window, or %NULL if the window
10195
 *  doesn't have a frame.
10196
 */
10197
cairo_region_t *
10198
meta_window_get_frame_bounds (MetaWindow *window)
10199
{
10200
  if (!window->frame_bounds)
10201
    {
10202
      if (window->frame)
10203
        window->frame_bounds = meta_frame_get_frame_bounds (window->frame);
10204
    }
10205
10206
  return window->frame_bounds;
10207
}
(-)a/src/meta/window.h (+3 lines)
Lines 23-28 Link Here
23
#define META_WINDOW_H
23
#define META_WINDOW_H
24
24
25
#include <glib-object.h>
25
#include <glib-object.h>
26
#include <cairo.h>
26
#include <X11/Xlib.h>
27
#include <X11/Xlib.h>
27
28
28
#include <meta/boxes.h>
29
#include <meta/boxes.h>
Lines 156-159 const char *meta_window_get_mutter_hints (MetaWindow *window); Link Here
156
157
157
MetaFrameType meta_window_get_frame_type (MetaWindow *window);
158
MetaFrameType meta_window_get_frame_type (MetaWindow *window);
158
159
160
cairo_region_t *meta_window_get_frame_bounds (MetaWindow *window);
161
159
#endif
162
#endif
(-)a/src/ui/frames.c (-71 / +116 lines)
Lines 797-856 apply_cairo_region_to_window (Display *display, Link Here
797
}
797
}
798
#endif
798
#endif
799
799
800
void
800
static cairo_region_t *
801
meta_frames_apply_shapes (MetaFrames *frames,
801
get_bounds_region (MetaFrames        *frames,
802
                          Window      xwindow,
802
                  MetaUIFrame       *frame,
803
                          int         new_window_width,
803
                  MetaFrameGeometry *fgeom,
804
                          int         new_window_height,
804
                  int                window_width,
805
                          gboolean    window_has_shape)
805
                  int                window_height)
806
{
806
{
807
#ifdef HAVE_SHAPE
808
  /* Apply shapes as if window had new_window_width, new_window_height */
809
  MetaUIFrame *frame;
810
  MetaFrameGeometry fgeom;
811
  cairo_rectangle_int_t rect;
812
  cairo_region_t *corners_region;
807
  cairo_region_t *corners_region;
813
  cairo_region_t *window_region;
808
  cairo_region_t *bounds_region;
814
  Display *display;
809
  cairo_rectangle_int_t rect;
815
  
816
  frame = meta_frames_lookup_window (frames, xwindow);
817
  g_return_if_fail (frame != NULL);
818
819
  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
820
821
  meta_frames_calc_geometry (frames, frame, &fgeom);
822
810
823
  if (!(fgeom.top_left_corner_rounded_radius != 0 ||
824
        fgeom.top_right_corner_rounded_radius != 0 ||
825
        fgeom.bottom_left_corner_rounded_radius != 0 ||
826
        fgeom.bottom_right_corner_rounded_radius != 0 ||
827
        window_has_shape))
828
    {
829
      if (frame->shape_applied)
830
        {
831
          meta_topic (META_DEBUG_SHAPES,
832
                      "Unsetting shape mask on frame 0x%lx\n",
833
                      frame->xwindow);
834
          
835
          XShapeCombineMask (display, frame->xwindow,
836
                             ShapeBounding, 0, 0, None, ShapeSet);
837
          frame->shape_applied = FALSE;
838
        }
839
      else
840
        {
841
          meta_topic (META_DEBUG_SHAPES,
842
                      "Frame 0x%lx still doesn't need a shape mask\n",
843
                      frame->xwindow);
844
        }
845
      
846
      return; /* nothing to do */
847
    }
848
  
849
  corners_region = cairo_region_create ();
811
  corners_region = cairo_region_create ();
850
  
812
  
851
  if (fgeom.top_left_corner_rounded_radius != 0)
813
  if (fgeom->top_left_corner_rounded_radius != 0)
852
    {
814
    {
853
      const int corner = fgeom.top_left_corner_rounded_radius;
815
      const int corner = fgeom->top_left_corner_rounded_radius;
854
      const float radius = sqrt(corner) + corner;
816
      const float radius = sqrt(corner) + corner;
855
      int i;
817
      int i;
856
818
Lines 866-881 meta_frames_apply_shapes (MetaFrames *frames, Link Here
866
        }
828
        }
867
    }
829
    }
868
830
869
  if (fgeom.top_right_corner_rounded_radius != 0)
831
  if (fgeom->top_right_corner_rounded_radius != 0)
870
    {
832
    {
871
      const int corner = fgeom.top_right_corner_rounded_radius;
833
      const int corner = fgeom->top_right_corner_rounded_radius;
872
      const float radius = sqrt(corner) + corner;
834
      const float radius = sqrt(corner) + corner;
873
      int i;
835
      int i;
874
836
875
      for (i=0; i<corner; i++)
837
      for (i=0; i<corner; i++)
876
        {
838
        {
877
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
839
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
878
          rect.x = new_window_width - width;
840
          rect.x = window_width - width;
879
          rect.y = i;
841
          rect.y = i;
880
          rect.width = width;
842
          rect.width = width;
881
          rect.height = 1;
843
          rect.height = 1;
Lines 884-892 meta_frames_apply_shapes (MetaFrames *frames, Link Here
884
        }
846
        }
885
    }
847
    }
886
848
887
  if (fgeom.bottom_left_corner_rounded_radius != 0)
849
  if (fgeom->bottom_left_corner_rounded_radius != 0)
888
    {
850
    {
889
      const int corner = fgeom.bottom_left_corner_rounded_radius;
851
      const int corner = fgeom->bottom_left_corner_rounded_radius;
890
      const float radius = sqrt(corner) + corner;
852
      const float radius = sqrt(corner) + corner;
891
      int i;
853
      int i;
892
854
Lines 894-900 meta_frames_apply_shapes (MetaFrames *frames, Link Here
894
        {
856
        {
895
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
857
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
896
          rect.x = 0;
858
          rect.x = 0;
897
          rect.y = new_window_height - i - 1;
859
          rect.y = window_height - i - 1;
898
          rect.width = width;
860
          rect.width = width;
899
          rect.height = 1;
861
          rect.height = 1;
900
          
862
          
Lines 902-918 meta_frames_apply_shapes (MetaFrames *frames, Link Here
902
        }
864
        }
903
    }
865
    }
904
866
905
  if (fgeom.bottom_right_corner_rounded_radius != 0)
867
  if (fgeom->bottom_right_corner_rounded_radius != 0)
906
    {
868
    {
907
      const int corner = fgeom.bottom_right_corner_rounded_radius;
869
      const int corner = fgeom->bottom_right_corner_rounded_radius;
908
      const float radius = sqrt(corner) + corner;
870
      const float radius = sqrt(corner) + corner;
909
      int i;
871
      int i;
910
872
911
      for (i=0; i<corner; i++)
873
      for (i=0; i<corner; i++)
912
        {
874
        {
913
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
875
          const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
914
          rect.x = new_window_width - width;
876
          rect.x = window_width - width;
915
          rect.y = new_window_height - i - 1;
877
          rect.y = window_height - i - 1;
916
          rect.width = width;
878
          rect.width = width;
917
          rect.height = 1;
879
          rect.height = 1;
918
          
880
          
Lines 920-938 meta_frames_apply_shapes (MetaFrames *frames, Link Here
920
        }
882
        }
921
    }
883
    }
922
  
884
  
923
  window_region = cairo_region_create ();
885
  bounds_region = cairo_region_create ();
924
  
886
  
925
  rect.x = 0;
887
  rect.x = 0;
926
  rect.y = 0;
888
  rect.y = 0;
927
  rect.width = new_window_width;
889
  rect.width = window_width;
928
  rect.height = new_window_height;
890
  rect.height = window_height;
929
891
930
  cairo_region_union_rectangle (window_region, &rect);
892
  cairo_region_union_rectangle (bounds_region, &rect);
931
893
932
  cairo_region_subtract (window_region, corners_region);
894
  cairo_region_subtract (bounds_region, corners_region);
933
895
934
  cairo_region_destroy (corners_region);
896
  cairo_region_destroy (corners_region);
897
898
  return bounds_region;
899
}
900
901
static cairo_region_t *
902
get_client_region (MetaFrameGeometry *fgeom,
903
                   int                window_width,
904
                   int                window_height)
905
{
906
  cairo_rectangle_int_t rect;
907
908
  rect.x = fgeom->left_width;
909
  rect.y = fgeom->top_height;
910
  rect.width = window_width - fgeom->right_width - rect.x;
911
  rect.height = window_height - fgeom->bottom_height - rect.y;
912
913
  return cairo_region_create_rectangle (&rect);
914
}
915
916
void
917
meta_frames_apply_shapes (MetaFrames *frames,
918
                          Window      xwindow,
919
                          int         new_window_width,
920
                          int         new_window_height,
921
                          gboolean    window_has_shape)
922
{
923
#ifdef HAVE_SHAPE
924
  /* Apply shapes as if window had new_window_width, new_window_height */
925
  MetaUIFrame *frame;
926
  MetaFrameGeometry fgeom;
927
  cairo_region_t *window_region;
928
  Display *display;
935
  
929
  
930
  frame = meta_frames_lookup_window (frames, xwindow);
931
  g_return_if_fail (frame != NULL);
932
933
  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
934
935
  meta_frames_calc_geometry (frames, frame, &fgeom);
936
937
  if (!(fgeom.top_left_corner_rounded_radius != 0 ||
938
        fgeom.top_right_corner_rounded_radius != 0 ||
939
        fgeom.bottom_left_corner_rounded_radius != 0 ||
940
        fgeom.bottom_right_corner_rounded_radius != 0 ||
941
        window_has_shape))
942
    {
943
      if (frame->shape_applied)
944
        {
945
          meta_topic (META_DEBUG_SHAPES,
946
                      "Unsetting shape mask on frame 0x%lx\n",
947
                      frame->xwindow);
948
949
          XShapeCombineMask (display, frame->xwindow,
950
                             ShapeBounding, 0, 0, None, ShapeSet);
951
          frame->shape_applied = FALSE;
952
        }
953
      else
954
        {
955
          meta_topic (META_DEBUG_SHAPES,
956
                      "Frame 0x%lx still doesn't need a shape mask\n",
957
                      frame->xwindow);
958
        }
959
960
      return; /* nothing to do */
961
    }
962
963
  window_region = get_bounds_region (frames, frame,
964
                                     &fgeom,
965
                                     new_window_width, new_window_height);
966
936
  if (window_has_shape)
967
  if (window_has_shape)
937
    {
968
    {
938
      /* The client window is oclock or something and has a shape
969
      /* The client window is oclock or something and has a shape
Lines 984-998 meta_frames_apply_shapes (MetaFrames *frames, Link Here
984
      /* Punch the client area out of the normal frame shape,
1015
      /* Punch the client area out of the normal frame shape,
985
       * then union it with the shape_window's existing shape
1016
       * then union it with the shape_window's existing shape
986
       */
1017
       */
987
      client_region = cairo_region_create ();
1018
      client_region = get_client_region (&fgeom,
988
  
1019
                                         new_window_width,
989
      rect.x = fgeom.left_width;
1020
                                         new_window_height);
990
      rect.y = fgeom.top_height;
991
      rect.width = new_window_width - fgeom.right_width - rect.x;
992
      rect.height = new_window_height - fgeom.bottom_height - rect.y;
993
1021
994
      cairo_region_union_rectangle (client_region, &rect);
995
      
996
      cairo_region_subtract (window_region, client_region);
1022
      cairo_region_subtract (window_region, client_region);
997
1023
998
      cairo_region_destroy (client_region);
1024
      cairo_region_destroy (client_region);
Lines 1027-1032 meta_frames_apply_shapes (MetaFrames *frames, Link Here
1027
#endif /* HAVE_SHAPE */
1053
#endif /* HAVE_SHAPE */
1028
}
1054
}
1029
1055
1056
cairo_region_t *
1057
meta_frames_get_frame_bounds (MetaFrames *frames,
1058
                              Window      xwindow,
1059
                              int         window_width,
1060
                              int         window_height)
1061
{
1062
  MetaUIFrame *frame;
1063
  MetaFrameGeometry fgeom;
1064
1065
  frame = meta_frames_lookup_window (frames, xwindow);
1066
  g_return_val_if_fail (frame != NULL, NULL);
1067
1068
  meta_frames_calc_geometry (frames, frame, &fgeom);
1069
1070
  return get_bounds_region (frames, frame,
1071
                            &fgeom,
1072
                            window_width, window_height);
1073
}
1074
1030
void
1075
void
1031
meta_frames_move_resize_frame (MetaFrames *frames,
1076
meta_frames_move_resize_frame (MetaFrames *frames,
1032
                               Window      xwindow,
1077
                               Window      xwindow,
(-)a/src/ui/frames.h (+4 lines)
Lines 144-149 void meta_frames_apply_shapes (MetaFrames *frames, Link Here
144
                               int         new_window_width,
144
                               int         new_window_width,
145
                               int         new_window_height,
145
                               int         new_window_height,
146
                               gboolean    window_has_shape);
146
                               gboolean    window_has_shape);
147
cairo_region_t *meta_frames_get_frame_bounds (MetaFrames *frames,
148
                                              Window      xwindow,
149
                                              int         window_width,
150
                                              int         window_height);
147
void meta_frames_move_resize_frame (MetaFrames *frames,
151
void meta_frames_move_resize_frame (MetaFrames *frames,
148
				    Window      xwindow,
152
				    Window      xwindow,
149
				    int         x,
153
				    int         x,
(-)a/src/ui/ui.c (+10 lines)
Lines 470-475 meta_ui_apply_frame_shape (MetaUI *ui, Link Here
470
                            window_has_shape);
470
                            window_has_shape);
471
}
471
}
472
472
473
cairo_region_t *
474
meta_ui_get_frame_bounds (MetaUI  *ui,
475
                          Window   xwindow,
476
                          int      window_width,
477
                          int      window_height)
478
{
479
  return meta_frames_get_frame_bounds (ui->frames, xwindow,
480
                                       window_width, window_height);
481
}
482
473
void
483
void
474
meta_ui_queue_frame_draw (MetaUI *ui,
484
meta_ui_queue_frame_draw (MetaUI *ui,
475
                          Window xwindow)
485
                          Window xwindow)
(-)a/src/ui/ui.h (-1 / +6 lines)
Lines 28-33 Link Here
28
#include <meta/common.h>
28
#include <meta/common.h>
29
#include <X11/Xlib.h>
29
#include <X11/Xlib.h>
30
#include <X11/Xutil.h>
30
#include <X11/Xutil.h>
31
#include <cairo.h>
31
#include <glib.h>
32
#include <glib.h>
32
#include <gdk-pixbuf/gdk-pixbuf.h>
33
#include <gdk-pixbuf/gdk-pixbuf.h>
33
34
Lines 104-109 void meta_ui_apply_frame_shape (MetaUI *ui, Link Here
104
                                 int      new_window_height,
105
                                 int      new_window_height,
105
                                 gboolean window_has_shape);
106
                                 gboolean window_has_shape);
106
107
108
cairo_region_t *meta_ui_get_frame_bounds (MetaUI  *ui,
109
                                          Window   xwindow,
110
                                          int      window_width,
111
                                          int      window_height);
112
107
void meta_ui_queue_frame_draw (MetaUI *ui,
113
void meta_ui_queue_frame_draw (MetaUI *ui,
108
                               Window xwindow);
114
                               Window xwindow);
109
115
110
- 

Return to bug 367139