summaryrefslogtreecommitdiff
path: root/src/ui/frames.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/frames.c')
-rw-r--r--src/ui/frames.c273
1 files changed, 151 insertions, 122 deletions
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 5908d991..502ff523 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -906,21 +906,60 @@ apply_cairo_region_to_window (Display *display,
}
#endif
+/* 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;
gint scale;
corners_region = cairo_region_create ();
scale = gdk_window_get_scale_factor (frame->window);
+ fgeom->borders.invisible.top *= scale;
+ fgeom->borders.invisible.bottom *= scale;
+ fgeom->borders.invisible.left *= scale;
+ fgeom->borders.invisible.right *= scale;
+
+ get_visible_frame_rect (fgeom, window_width, window_height, &frame_rect);
+
if (fgeom->top_left_corner_rounded_radius != 0)
{
const int corner = fgeom->top_left_corner_rounded_radius * scale;
@@ -930,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 = 0;
- rect.y = i;
+ rect.x = frame_rect.x;
+ rect.y = frame_rect.y + i;
rect.width = width;
rect.height = 1;
@@ -948,8 +987,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;
@@ -966,8 +1005,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;
@@ -984,8 +1023,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;
@@ -993,20 +1032,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;
}
static cairo_region_t *
@@ -1016,10 +1046,10 @@ get_client_region (MetaFrameGeometry *fgeom,
{
cairo_rectangle_int_t rect;
- rect.x = fgeom->left_width;
- rect.y = fgeom->top_height;
- rect.width = window_width - fgeom->right_width - rect.x;
- rect.height = window_height - fgeom->bottom_height - rect.y;
+ 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;
return cairo_region_create_rectangle (&rect);
}
@@ -1071,11 +1101,12 @@ meta_frames_apply_shapes (MetaFrames *frames,
return; /* nothing to do */
}
- window_region = get_bounds_region (frames,
- frame,
- &fgeom,
- new_window_width,
- new_window_height);
+ window_region = get_visible_region (frames,
+ frame,
+ &fgeom,
+ new_window_width,
+ new_window_height);
+
if (window_has_shape)
{
/* The client window is oclock or something and has a shape
@@ -1118,8 +1149,8 @@ meta_frames_apply_shapes (MetaFrames *frames,
META_CORE_GET_END);
XShapeCombineShape (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window, ShapeBounding,
- fgeom.left_width,
- fgeom.top_height,
+ fgeom.borders.total.left,
+ fgeom.borders.total.top,
client_window,
ShapeBounding,
ShapeSet);
@@ -1179,11 +1210,11 @@ 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
@@ -2285,7 +2316,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;
@@ -2319,35 +2349,43 @@ 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);
scale = gdk_window_get_scale_factor (frame->window);
- /* 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) * scale;
- pixels->piece[0].rect.height = top * scale;
+ /* 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 / scale;
+ pixels->piece[0].rect.y = borders.invisible.top / scale;
+ pixels->piece[0].rect.width = (width + borders.visible.left + borders.visible.right) * scale;
+ pixels->piece[0].rect.height = borders.visible.top * scale;
- pixels->piece[1].rect.x = 0;
- pixels->piece[1].rect.y = top / scale;
- pixels->piece[1].rect.width = left * scale;
+ /* left */
+ pixels->piece[1].rect.x = borders.invisible.left / scale;
+ pixels->piece[1].rect.y = borders.total.top / scale;
+ pixels->piece[1].rect.width = borders.visible.left * scale;
pixels->piece[1].rect.height = height * scale;
- pixels->piece[2].rect.x = (left + width) / scale;
- pixels->piece[2].rect.y = top / scale;
- pixels->piece[2].rect.width = right * scale;
+ /* right */
+ pixels->piece[2].rect.x = (borders.total.left + width) / scale;
+ pixels->piece[2].rect.y = borders.total.top / scale;
+ pixels->piece[2].rect.width = borders.visible.right * scale;
pixels->piece[2].rect.height = height * scale;
- pixels->piece[3].rect.x = 0;
- pixels->piece[3].rect.y = (top + height) / scale;
- pixels->piece[3].rect.width = (left + width + right) * scale;
- pixels->piece[3].rect.height = bottom * scale;
+ /* bottom */
+ pixels->piece[3].rect.x = borders.invisible.left / scale;
+ pixels->piece[3].rect.y = (borders.total.top + height) / scale;
+ pixels->piece[3].rect.width = (width + borders.visible.left + borders.visible.right) * scale;
+ pixels->piece[3].rect.height = borders.visible.bottom * scale;
for (i = 0; i < 4; i++)
{
@@ -2396,35 +2434,10 @@ clip_to_screen (cairo_region_t *region, MetaUIFrame *frame)
}
static void
-cached_pixels_draw (CachedPixels *pixels,
- cairo_t *cr,
- cairo_region_t *region)
+subtract_client_area (cairo_region_t *region,
+ MetaUIFrame *frame)
{
- cairo_region_t *region_piece;
- int i;
-
- for (i = 0; i < 4; i++)
- {
- CachedFramePiece *piece;
- piece = &pixels->piece[i];
-
- if (piece->pixmap)
- {
- cairo_set_source_surface (cr, piece->pixmap,
- piece->rect.x, piece->rect.y);
- cairo_paint (cr);
-
- region_piece = cairo_region_create_rectangle (&piece->rect);
- cairo_region_subtract (region, region_piece);
- cairo_region_destroy (region_piece);
- }
- }
-}
-
-static void
-subtract_client_area (cairo_region_t *region, MetaUIFrame *frame)
-{
- GdkRectangle area;
+ cairo_rectangle_int_t area;
MetaFrameFlags flags;
MetaFrameType type;
MetaFrameBorders borders;
@@ -2441,21 +2454,46 @@ subtract_client_area (cairo_region_t *region, MetaUIFrame *frame)
META_CORE_GET_CLIENT_WIDTH, &area.width,
META_CORE_GET_CLIENT_HEIGHT, &area.height,
META_CORE_GET_END);
-
meta_theme_get_frame_borders (meta_theme_get_current (),
type, frame->text_height, flags,
&borders);
area.width /= scale;
area.height /= scale;
- area.x = borders.visible.left / scale;
- area.y = borders.visible.top / scale;
+ area.x = borders.total.left / scale;
+ area.y = borders.total.top / scale;
tmp_region = cairo_region_create_rectangle (&area);
cairo_region_subtract (region, tmp_region);
cairo_region_destroy (tmp_region);
}
+static void
+cached_pixels_draw (CachedPixels *pixels,
+ cairo_t *cr,
+ cairo_region_t *region)
+{
+ cairo_region_t *region_piece;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ CachedFramePiece *piece;
+ piece = &pixels->piece[i];
+
+ if (piece->pixmap)
+ {
+ cairo_set_source_surface (cr, piece->pixmap,
+ piece->rect.x, piece->rect.y);
+ cairo_paint (cr);
+
+ region_piece = cairo_region_create_rectangle (&piece->rect);
+ cairo_region_subtract (region, region_piece);
+ cairo_region_destroy (region_piece);
+ }
+ }
+}
+
static MetaUIFrame *
find_frame_to_draw (MetaFrames *frames,
cairo_t *cr)
@@ -2787,7 +2825,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,
@@ -2799,16 +2837,12 @@ get_control (MetaFrames *frames,
GdkRectangle client;
gint scale;
- meta_frames_calc_geometry (frames, frame, &fgeom);
-
scale = gdk_window_get_scale_factor (frame->window);
x /= scale;
y /= scale;
- 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;
@@ -2882,8 +2916,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;
@@ -2892,8 +2926,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;
@@ -2902,8 +2936,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;
@@ -2912,8 +2946,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;
@@ -2922,33 +2956,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 * scale))
{
if (has_vert)
- return META_FRAME_CONTROL_RESIZE_S;
+ return META_FRAME_CONTROL_RESIZE_N;
}
- else if (y <= TOP_RESIZE_HEIGHT * scale)
+ 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