diff --git a/gsk/gskroundedrect.c b/gsk/gskroundedrect.c index f66dadf8e0e97aa444d2d8c6d110a211dfe17273..e852e014a1b4c193bd0682d90e65e72953ac9d64 100644 --- a/gsk/gskroundedrect.c +++ b/gsk/gskroundedrect.c @@ -1075,3 +1075,47 @@ gsk_rounded_rect_get_largest_cover (const GskRoundedRect *self, *result = high; } +/*< private > + * gsk_rounded_rect_corner_box_contains_point: + * @self: a rounded rectangle + * @corner: the corner + * @point: the point + * + * Returns whether @point is inside the rectangle defining + * the quarter ellipses of the given corner. + * + * Returns: true if @point is inside the @corner's box + */ +gboolean +gsk_rounded_rect_corner_box_contains_point (const GskRoundedRect *self, + GskCorner corner, + const graphene_point_t *point) +{ + graphene_rect_t rect; + + graphene_size_init_from_size (&rect.size, &self->corner[corner]); + + switch (corner) + { + case GSK_CORNER_TOP_LEFT: + rect.origin.x = self->bounds.origin.x; + rect.origin.y = self->bounds.origin.y; + break; + case GSK_CORNER_TOP_RIGHT: + rect.origin.x = self->bounds.origin.x + self->bounds.size.width - self->corner[corner].width; + rect.origin.y = self->bounds.origin.y; + break; + case GSK_CORNER_BOTTOM_RIGHT: + rect.origin.x = self->bounds.origin.x + self->bounds.size.width - self->corner[corner].width; + rect.origin.y = self->bounds.origin.y + self->bounds.size.height - self->corner[corner].height; + break; + case GSK_CORNER_BOTTOM_LEFT: + rect.origin.x = self->bounds.origin.x; + rect.origin.y = self->bounds.origin.y + self->bounds.size.height - self->corner[corner].height; + break; + default: + g_assert_not_reached (); + } + + return graphene_rect_contains_point (&rect, point); +} diff --git a/gsk/gskroundedrectprivate.h b/gsk/gskroundedrectprivate.h index e83e1aed1c8d4a0e21660b08ebfc6e6d44ecd0a2..d9f5f56cce3e3a404ecb7c8c97149440d7804b57 100644 --- a/gsk/gskroundedrectprivate.h +++ b/gsk/gskroundedrectprivate.h @@ -75,6 +75,10 @@ GskRoundedRectIntersection gsk_rounded_rect_intersection (const GskRoun const GskRoundedRect *b, GskRoundedRect *result); +gboolean gsk_rounded_rect_corner_box_contains_point (const GskRoundedRect *self, + GskCorner corner, + const graphene_point_t *point); + G_END_DECLS diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 38d288fe30a51b023ae95f974b83ffe5cb798311..0be15aff600d9ed63fc97325322659bc5f092960 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -70,6 +70,8 @@ #include "gdk/gdktextureprivate.h" #include "gdk/gdktoplevelprivate.h" +#include "gsk/gskroundedrectprivate.h" + #include #include #include @@ -1440,6 +1442,9 @@ get_edge_for_coordinates (GtkWindow *window, GtkCssBoxes css_boxes; const graphene_rect_t *border_rect; float left, top; + const GskRoundedRect *border; + graphene_point_t p; + int resize_handle_size; #define edge_or_minus_one(edge) ((supports_edge_constraints && (priv->edge_constraints & constraints_for_edge (edge)) != constraints_for_edge (edge)) ? -1 : edge) @@ -1455,8 +1460,16 @@ get_edge_for_coordinates (GtkWindow *window, return -1; gtk_css_boxes_init (&css_boxes, GTK_WIDGET (window)); + border = gtk_css_boxes_get_content_box (&css_boxes); border_rect = gtk_css_boxes_get_content_rect (&css_boxes); + resize_handle_size = RESIZE_HANDLE_CORNER_SIZE; + for (int i = 0 ; i < 4; i++) + { + resize_handle_size = MAX (resize_handle_size, border->corner[i].width); + resize_handle_size = MAX (resize_handle_size, border->corner[i].height); + } + get_box_border (gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (window))), &handle_size); @@ -1478,10 +1491,10 @@ get_edge_for_coordinates (GtkWindow *window, if (x < left && x >= left - handle_size.left) { - if (y < top + RESIZE_HANDLE_CORNER_SIZE && y >= top - handle_size.top) + if (y < top + resize_handle_size && y >= top - handle_size.top) return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_WEST); - if (y > top + border_rect->size.height - RESIZE_HANDLE_CORNER_SIZE && + if (y > top + border_rect->size.height - resize_handle_size && y <= top + border_rect->size.height + handle_size.bottom) return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_WEST); @@ -1490,10 +1503,10 @@ get_edge_for_coordinates (GtkWindow *window, else if (x > left + border_rect->size.width && x <= left + border_rect->size.width + handle_size.right) { - if (y < top + RESIZE_HANDLE_CORNER_SIZE && y >= top - handle_size.top) + if (y < top + resize_handle_size && y >= top - handle_size.top) return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_EAST); - if (y > top + border_rect->size.height - RESIZE_HANDLE_CORNER_SIZE && + if (y > top + border_rect->size.height - resize_handle_size && y <= top + border_rect->size.height + handle_size.bottom) return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_EAST); @@ -1501,10 +1514,10 @@ get_edge_for_coordinates (GtkWindow *window, } else if (y < top && y >= top - handle_size.top) { - if (x < left + RESIZE_HANDLE_CORNER_SIZE && x >= left - handle_size.left) + if (x < left + resize_handle_size && x >= left - handle_size.left) return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_WEST); - if (x > left + border_rect->size.width - RESIZE_HANDLE_CORNER_SIZE && + if (x > left + border_rect->size.width - resize_handle_size && x <= left + border_rect->size.width + handle_size.right) return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_EAST); @@ -1513,16 +1526,32 @@ get_edge_for_coordinates (GtkWindow *window, else if (y > top + border_rect->size.height && y <= top + border_rect->size.height + handle_size.bottom) { - if (x < left + RESIZE_HANDLE_CORNER_SIZE && x >= left - handle_size.left) + if (x < left + resize_handle_size && x >= left - handle_size.left) return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_WEST); - if (x > left + border_rect->size.width - RESIZE_HANDLE_CORNER_SIZE && + if (x > left + border_rect->size.width - resize_handle_size && x <= left + border_rect->size.width + handle_size.right) return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_EAST); return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH); } + p = GRAPHENE_POINT_INIT (x,y ); + if (!gsk_rounded_rect_contains_point (border, &p)) + { + if (gsk_rounded_rect_corner_box_contains_point (border, GSK_CORNER_TOP_LEFT, &p)) + return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_WEST); + + if (gsk_rounded_rect_corner_box_contains_point (border, GSK_CORNER_TOP_RIGHT, &p)) + return edge_or_minus_one (GDK_SURFACE_EDGE_NORTH_EAST); + + if (gsk_rounded_rect_corner_box_contains_point (border, GSK_CORNER_BOTTOM_RIGHT, &p)) + return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_EAST); + + if (gsk_rounded_rect_corner_box_contains_point (border, GSK_CORNER_BOTTOM_LEFT, &p)) + return edge_or_minus_one (GDK_SURFACE_EDGE_SOUTH_WEST); + } + return -1; }