[mutter] ui: Replace inline borders in MetaFrameGeometry with MetaFrameBorder



commit eeb2efe01001fef7655b2ba95ca1456f7fe9214b
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Jul 12 01:16:48 2011 -0400

    ui: Replace inline borders in MetaFrameGeometry with MetaFrameBorder
    
    ... and start compensating for invisible borders in all of the math.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644930

 src/ui/frames.c        |  182 +++++++++++++++++++++++++++---------------------
 src/ui/theme-private.h |    5 +-
 src/ui/theme.c         |   93 ++++++++++++------------
 3 files changed, 149 insertions(+), 131 deletions(-)
---
diff --git a/src/ui/frames.c b/src/ui/frames.c
index a880bb0..fe67e2a 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -860,18 +860,51 @@ meta_frames_unflicker_bg (MetaFrames *frames,
   set_background_none (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow);
 }
 
+/* The client rectangle surrounds client window; it subtracts both
+ * the visible and invisible borders from the frame window's size.
+ */
+static void
+get_client_rect (MetaFrameGeometry     *fgeom,
+                 int                    window_width,
+                 int                    window_height,
+                 cairo_rectangle_int_t *rect)
+{
+  rect->x = fgeom->borders.total.left;
+  rect->y = fgeom->borders.total.top;
+  rect->width = window_width - fgeom->borders.total.right - rect->x;
+  rect->height = window_height - fgeom->borders.total.bottom - rect->y;
+}
+
+/* The visible frame rectangle surrounds the visible portion of the
+ * frame window; it subtracts only the invisible borders from the frame
+ * window's size.
+ */
+static void
+get_visible_frame_rect (MetaFrameGeometry     *fgeom,
+                        int                    window_width,
+                        int                    window_height,
+                        cairo_rectangle_int_t *rect)
+{
+  rect->x = fgeom->borders.invisible.left;
+  rect->y = fgeom->borders.invisible.top;
+  rect->width = window_width - fgeom->borders.invisible.right - rect->x;
+  rect->height = window_height - fgeom->borders.invisible.bottom - rect->y;
+}
+
 static cairo_region_t *
-get_bounds_region (MetaFrames        *frames,
-                  MetaUIFrame       *frame,
-                  MetaFrameGeometry *fgeom,
-                  int                window_width,
-                  int                window_height)
+get_visible_region (MetaFrames        *frames,
+                    MetaUIFrame       *frame,
+                    MetaFrameGeometry *fgeom,
+                    int                window_width,
+                    int                window_height)
 {
   cairo_region_t *corners_region;
-  cairo_region_t *bounds_region;
+  cairo_region_t *visible_region;
   cairo_rectangle_int_t rect;
+  cairo_rectangle_int_t frame_rect;
 
   corners_region = cairo_region_create ();
+  get_visible_frame_rect (fgeom, window_width, window_height, &frame_rect);
   
   if (fgeom->top_left_corner_rounded_radius != 0)
     {
@@ -882,8 +915,8 @@ get_bounds_region (MetaFrames        *frames,
       for (i=0; i<corner; i++)
         {
           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
-          rect.x = 0;
-          rect.y = i;
+          rect.x = frame_rect.x;
+          rect.y = frame_rect.y + i;
           rect.width = width;
           rect.height = 1;
           
@@ -900,8 +933,8 @@ get_bounds_region (MetaFrames        *frames,
       for (i=0; i<corner; i++)
         {
           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
-          rect.x = window_width - width;
-          rect.y = i;
+          rect.x = frame_rect.x + frame_rect.width - width;
+          rect.y = frame_rect.y + i;
           rect.width = width;
           rect.height = 1;
           
@@ -918,8 +951,8 @@ get_bounds_region (MetaFrames        *frames,
       for (i=0; i<corner; i++)
         {
           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
-          rect.x = 0;
-          rect.y = window_height - i - 1;
+          rect.x = frame_rect.x;
+          rect.y = frame_rect.y + frame_rect.height - i - 1;
           rect.width = width;
           rect.height = 1;
           
@@ -936,8 +969,8 @@ get_bounds_region (MetaFrames        *frames,
       for (i=0; i<corner; i++)
         {
           const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5))));
-          rect.x = window_width - width;
-          rect.y = window_height - i - 1;
+          rect.x = frame_rect.x + frame_rect.width + width;
+          rect.y = frame_rect.y + frame_rect.height - i - 1;
           rect.width = width;
           rect.height = 1;
           
@@ -945,20 +978,11 @@ get_bounds_region (MetaFrames        *frames,
         }
     }
   
-  bounds_region = cairo_region_create ();
-  
-  rect.x = 0;
-  rect.y = 0;
-  rect.width = window_width;
-  rect.height = window_height;
-
-  cairo_region_union_rectangle (bounds_region, &rect);
-
-  cairo_region_subtract (bounds_region, corners_region);
-
+  visible_region = cairo_region_create_rectangle (&frame_rect);
+  cairo_region_subtract (visible_region, corners_region);
   cairo_region_destroy (corners_region);
 
-  return bounds_region;
+  return visible_region;
 }
 
 cairo_region_t *
@@ -975,9 +999,9 @@ meta_frames_get_frame_bounds (MetaFrames *frames,
 
   meta_frames_calc_geometry (frames, frame, &fgeom);
 
-  return get_bounds_region (frames, frame,
-                            &fgeom,
-                            window_width, window_height);
+  return get_visible_region (frames, frame,
+                             &fgeom,
+                             window_width, window_height);
 }
 
 void
@@ -2048,7 +2072,6 @@ static void
 populate_cache (MetaFrames *frames,
                 MetaUIFrame *frame)
 {
-  int top, bottom, left, right;
   MetaFrameBorders borders;
   int width, height;
   int frame_width, frame_height, screen_width, screen_height;
@@ -2082,34 +2105,42 @@ populate_cache (MetaFrames *frames,
                                 frame_flags,
                                 &borders);
 
-  top    = borders.visible.top;
-  left   = borders.visible.left;
-  right  = borders.visible.right;
-  bottom = borders.visible.bottom;
-
   pixels = get_cache (frames, frame);
 
-  /* Setup the rectangles for the four frame borders. First top, then
-     left, right and bottom. */
-  pixels->piece[0].rect.x = 0;
-  pixels->piece[0].rect.y = 0;
-  pixels->piece[0].rect.width = left + width + right;
-  pixels->piece[0].rect.height = top;
+  /* Setup the rectangles for the four visible frame borders. First top, then
+   * left, right and bottom. Top and bottom extend to the invisible borders
+   * while left and right snugly fit in between:
+   *   -----
+   *   |   |
+   *   -----
+   */
+
+  /* width and height refer to the client window's
+   * size without any border added. */
+
+  /* top */
+  pixels->piece[0].rect.x = borders.invisible.left;
+  pixels->piece[0].rect.y = borders.invisible.top;
+  pixels->piece[0].rect.width = width + borders.visible.left + borders.visible.right;
+  pixels->piece[0].rect.height = borders.visible.top;
 
-  pixels->piece[1].rect.x = 0;
-  pixels->piece[1].rect.y = top;
-  pixels->piece[1].rect.width = left;
+  /* left */
+  pixels->piece[1].rect.x = borders.invisible.left;
+  pixels->piece[1].rect.y = borders.total.top;
   pixels->piece[1].rect.height = height;
+  pixels->piece[1].rect.width = borders.visible.left;
 
-  pixels->piece[2].rect.x = left + width;
-  pixels->piece[2].rect.y = top;
-  pixels->piece[2].rect.width = right;
+  /* right */
+  pixels->piece[2].rect.x = borders.total.left + width;
+  pixels->piece[2].rect.y = borders.total.top;
+  pixels->piece[2].rect.width = borders.visible.right;
   pixels->piece[2].rect.height = height;
 
-  pixels->piece[3].rect.x = 0;
-  pixels->piece[3].rect.y = top + height;
-  pixels->piece[3].rect.width = left + width + right;
-  pixels->piece[3].rect.height = bottom;
+  /* bottom */
+  pixels->piece[3].rect.x = borders.invisible.left;
+  pixels->piece[3].rect.y = borders.total.top + height;
+  pixels->piece[3].rect.width = width + borders.visible.left + borders.visible.right;
+  pixels->piece[3].rect.height = borders.visible.bottom;
 
   for (i = 0; i < 4; i++)
     {
@@ -2188,8 +2219,8 @@ subtract_client_area (cairo_region_t *region,
                                 type, frame->text_height, flags, 
                                 &borders);
 
-  area.x = borders.visible.left;
-  area.y = borders.visible.top;
+  area.x = borders.total.left;
+  area.y = borders.total.top;
 
   tmp_region = cairo_region_create_rectangle (&area);
   cairo_region_subtract (region, tmp_region);
@@ -2573,7 +2604,7 @@ control_rect (MetaFrameControl control,
 }
 
 #define RESIZE_EXTENDS 15
-#define TOP_RESIZE_HEIGHT 2
+#define TOP_RESIZE_HEIGHT 4
 static MetaFrameControl
 get_control (MetaFrames *frames,
              MetaUIFrame *frame,
@@ -2583,13 +2614,9 @@ get_control (MetaFrames *frames,
   MetaFrameFlags flags;
   gboolean has_vert, has_horiz;
   cairo_rectangle_int_t client;
-  
-  meta_frames_calc_geometry (frames, frame, &fgeom);
 
-  client.x = fgeom.left_width;
-  client.y = fgeom.top_height;
-  client.width = fgeom.width - fgeom.left_width - fgeom.right_width;
-  client.height = fgeom.height - fgeom.top_height - fgeom.bottom_height;  
+  meta_frames_calc_geometry (frames, frame, &fgeom);
+  get_client_rect (&fgeom, fgeom.width, fgeom.height, &client);
 
   if (POINT_IN_RECT (x, y, client))
     return META_FRAME_CONTROL_CLIENT_AREA;
@@ -2661,8 +2688,8 @@ get_control (MetaFrames *frames,
    * in case of overlap.
    */
 
-  if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
-      x >= (fgeom.width - fgeom.right_width - RESIZE_EXTENDS))
+  if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS) &&
+      x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS))
     {
       if (has_vert && has_horiz)
         return META_FRAME_CONTROL_RESIZE_SE;
@@ -2671,8 +2698,8 @@ get_control (MetaFrames *frames,
       else if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_E;
     }
-  else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS) &&
-           x <= (fgeom.left_width + RESIZE_EXTENDS))
+  else if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS) &&
+           x <= (fgeom.borders.total.left + RESIZE_EXTENDS))
     {
       if (has_vert && has_horiz)
         return META_FRAME_CONTROL_RESIZE_SW;
@@ -2681,8 +2708,8 @@ get_control (MetaFrames *frames,
       else if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_W;
     }
-  else if (y < (fgeom.top_height + RESIZE_EXTENDS) &&
-           x < RESIZE_EXTENDS)
+  else if (y < (fgeom.borders.invisible.top + RESIZE_EXTENDS) &&
+           x <= (fgeom.borders.total.left + RESIZE_EXTENDS))
     {
       if (has_vert && has_horiz)
         return META_FRAME_CONTROL_RESIZE_NW;
@@ -2691,8 +2718,8 @@ get_control (MetaFrames *frames,
       else if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_W;
     }
-  else if (y < (fgeom.top_height + RESIZE_EXTENDS) &&
-           x >= (fgeom.width - RESIZE_EXTENDS))
+  else if (y < (fgeom.borders.invisible.top + RESIZE_EXTENDS) &&
+           x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS))
     {
       if (has_vert && has_horiz)
         return META_FRAME_CONTROL_RESIZE_NE;
@@ -2701,33 +2728,28 @@ get_control (MetaFrames *frames,
       else if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_E;
     }
-  else if (y >= (fgeom.height - fgeom.bottom_height - RESIZE_EXTENDS))
+  else if (y < (fgeom.borders.invisible.top + TOP_RESIZE_HEIGHT))
     {
       if (has_vert)
-        return META_FRAME_CONTROL_RESIZE_S;
+        return META_FRAME_CONTROL_RESIZE_N;
     }
-  else if (y <= TOP_RESIZE_HEIGHT)
+  else if (y >= (fgeom.height - fgeom.borders.total.bottom - RESIZE_EXTENDS))
     {
       if (has_vert)
-        return META_FRAME_CONTROL_RESIZE_N;
-      else if (has_horiz)
-        return META_FRAME_CONTROL_TITLE;
+        return META_FRAME_CONTROL_RESIZE_S;
     }
-  else if (x <= fgeom.left_width)
+  else if (x <= fgeom.borders.total.left + RESIZE_EXTENDS)
     {
       if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_W;
     }
-  else if (x >= (fgeom.width - fgeom.right_width))
+  else if (x >= (fgeom.width - fgeom.borders.total.right - RESIZE_EXTENDS))
     {
       if (has_horiz)
         return META_FRAME_CONTROL_RESIZE_E;
     }
 
-  if (y >= fgeom.top_height)
-    return META_FRAME_CONTROL_NONE;
-  else
-    return META_FRAME_CONTROL_TITLE;
+  return META_FRAME_CONTROL_NONE;
 }
 
 void
diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h
index 6dd7c8c..1128d34 100644
--- a/src/ui/theme-private.h
+++ b/src/ui/theme-private.h
@@ -217,10 +217,7 @@ struct _MetaButtonSpace
  */
 struct _MetaFrameGeometry
 {
-  int left_width;
-  int right_width;
-  int top_height;
-  int bottom_height;
+  MetaFrameBorders borders;
 
   int width;
   int height;  
diff --git a/src/ui/theme.c b/src/ui/theme.c
index bad8842..8e6f521 100644
--- a/src/ui/theme.c
+++ b/src/ui/theme.c
@@ -639,16 +639,12 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
                                  flags,
                                  &borders);
 
+  fgeom->borders = borders;
 
-  fgeom->left_width = borders.visible.left;
-  fgeom->right_width = borders.visible.right;
-  fgeom->top_height = borders.visible.top;
-  fgeom->bottom_height = borders.visible.bottom;
-
-  width = client_width + fgeom->left_width + fgeom->right_width;
+  width = client_width + borders.total.left + borders.total.right;
 
   height = ((flags & META_FRAME_SHADED) ? 0: client_height) +
-    fgeom->top_height + fgeom->bottom_height;
+    borders.total.top + borders.total.bottom;
 
   fgeom->width = width;
   fgeom->height = height;
@@ -665,7 +661,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
   switch (layout->button_sizing)
     {
     case META_BUTTON_SIZING_ASPECT:
-      button_height = fgeom->top_height - layout->button_border.top - layout->button_border.bottom;
+      button_height = borders.visible.top - layout->button_border.top - layout->button_border.bottom;
       button_width = button_height / layout->button_aspect;
       break;
     case META_BUTTON_SIZING_FIXED:
@@ -850,11 +846,11 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
   fgeom->n_right_buttons = n_right;
   
   /* center buttons vertically */
-  button_y = (fgeom->top_height -
-              (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top;
+  button_y = (borders.visible.top -
+              (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top + borders.invisible.top;
 
   /* right edge of farthest-right button */
-  x = width - layout->right_titlebar_edge;
+  x = width - layout->right_titlebar_edge - borders.invisible.right;
   
   i = n_right - 1;
   while (i >= 0)
@@ -902,7 +898,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
   /* Now x changes to be position from the left and we go through
    * the left-side buttons
    */
-  x = layout->left_titlebar_edge;
+  x = layout->left_titlebar_edge + borders.invisible.left;
   for (i = 0; i < n_left; i++)
     {
       MetaButtonSpace *rect;
@@ -945,9 +941,9 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
    * rather than centering it like the buttons
    */
   fgeom->title_rect.x = x + layout->title_border.left;
-  fgeom->title_rect.y = layout->title_border.top;
+  fgeom->title_rect.y = layout->title_border.top + borders.invisible.top;
   fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
-  fgeom->title_rect.height = fgeom->top_height - layout->title_border.top - layout->title_border.bottom;
+  fgeom->title_rect.height = borders.visible.top - layout->title_border.top - layout->title_border.bottom;
 
   /* Nuke title if it won't fit */
   if (fgeom->title_rect.width < 0 ||
@@ -967,14 +963,14 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout  *layout,
   fgeom->bottom_left_corner_rounded_radius = 0;
   fgeom->bottom_right_corner_rounded_radius = 0;
 
-  if (fgeom->top_height + fgeom->left_width >= min_size_for_rounding)
+  if (borders.visible.top + borders.visible.left >= min_size_for_rounding)
     fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius;
-  if (fgeom->top_height + fgeom->right_width >= min_size_for_rounding)
+  if (borders.visible.top + borders.visible.right >= min_size_for_rounding)
     fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius;
 
-  if (fgeom->bottom_height + fgeom->left_width >= min_size_for_rounding)
+  if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding)
     fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius;
-  if (fgeom->bottom_height + fgeom->right_width >= min_size_for_rounding)
+  if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding)
     fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius;
 }
 
@@ -3573,10 +3569,10 @@ fill_env (MetaPositionExprEnv *env,
   env->object_height = -1;
   if (info->fgeom)
     {
-      env->left_width = info->fgeom->left_width;
-      env->right_width = info->fgeom->right_width;
-      env->top_height = info->fgeom->top_height;
-      env->bottom_height = info->fgeom->bottom_height;
+      env->left_width = info->fgeom->borders.visible.left;
+      env->right_width = info->fgeom->borders.visible.right;
+      env->top_height = info->fgeom->borders.visible.top;
+      env->bottom_height = info->fgeom->borders.visible.bottom;
       env->frame_x_center = info->fgeom->width / 2 - logical_region.x;
       env->frame_y_center = info->fgeom->height / 2 - logical_region.y;
     }
@@ -4625,6 +4621,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
                                   GdkPixbuf               *icon)
 {
   int i, j;
+  GdkRectangle visible_rect;
   GdkRectangle titlebar_rect;
   GdkRectangle left_titlebar_edge;
   GdkRectangle right_titlebar_edge;
@@ -4633,11 +4630,19 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
   GdkRectangle left_edge, right_edge, bottom_edge;
   PangoRectangle logical_rect;
   MetaDrawInfo draw_info;
-  
-  titlebar_rect.x = 0;
-  titlebar_rect.y = 0;
-  titlebar_rect.width = fgeom->width;
-  titlebar_rect.height = fgeom->top_height;
+  const MetaFrameBorders *borders;
+
+  borders = &fgeom->borders;
+
+  visible_rect.x = borders->invisible.left;
+  visible_rect.y = borders->invisible.top;
+  visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right;
+  visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom;
+
+  titlebar_rect.x = visible_rect.x;
+  titlebar_rect.y = visible_rect.y;
+  titlebar_rect.width = visible_rect.width;
+  titlebar_rect.height = borders->visible.top;
 
   left_titlebar_edge.x = titlebar_rect.x;
   left_titlebar_edge.y = titlebar_rect.y + fgeom->top_titlebar_edge;
@@ -4659,20 +4664,20 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
   bottom_titlebar_edge.height = fgeom->bottom_titlebar_edge;
   bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height;
 
-  left_edge.x = 0;
-  left_edge.y = fgeom->top_height;
-  left_edge.width = fgeom->left_width;
-  left_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height;
+  left_edge.x = visible_rect.x;
+  left_edge.y = visible_rect.y + borders->visible.top;
+  left_edge.width = borders->visible.left;
+  left_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom;
 
-  right_edge.x = fgeom->width - fgeom->right_width;
-  right_edge.y = fgeom->top_height;
-  right_edge.width = fgeom->right_width;
-  right_edge.height = fgeom->height - fgeom->top_height - fgeom->bottom_height;
+  right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right;
+  right_edge.y = visible_rect.y + borders->visible.top;
+  right_edge.width = borders->visible.right;
+  right_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom;
 
-  bottom_edge.x = 0;
-  bottom_edge.y = fgeom->height - fgeom->bottom_height;
-  bottom_edge.width = fgeom->width;
-  bottom_edge.height = fgeom->bottom_height;
+  bottom_edge.x = visible_rect.x;
+  bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom;
+  bottom_edge.width = visible_rect.width;
+  bottom_edge.height = borders->visible.bottom;
 
   if (title_layout)
     pango_layout_get_pixel_extents (title_layout,
@@ -4694,10 +4699,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
       switch ((MetaFramePiece) i)
         {
         case META_FRAME_PIECE_ENTIRE_BACKGROUND:
-          rect.x = 0;
-          rect.y = 0;
-          rect.width = fgeom->width;
-          rect.height = fgeom->height;
+          rect = visible_rect;
           break;
 
         case META_FRAME_PIECE_TITLEBAR:
@@ -4745,10 +4747,7 @@ meta_frame_style_draw_with_style (MetaFrameStyle          *style,
           break;
 
         case META_FRAME_PIECE_OVERLAY:
-          rect.x = 0;
-          rect.y = 0;
-          rect.width = fgeom->width;
-          rect.height = fgeom->height;
+          rect = visible_rect;
           break;
 
         case META_FRAME_PIECE_LAST:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]