mirror of
https://github.com/labwc/labwc.git
synced 2025-11-11 13:30:04 -05:00
ssd: fix resizing on border corners and add <resize><cornerRange>
Eliminate corner extents and instead use cursor position to map SSD borders and extents to corner contexts, with a size configurable by the <resize><cornerRange> parameter. This simplifies extent handling, eliminates bugs in the detection of corner context, and allows users to expand corner targets if they wish. Co-authored-by: Andrew J. Hesford <ajh@sideband.org>
This commit is contained in:
parent
9ad6e3c68c
commit
950337b895
9 changed files with 102 additions and 60 deletions
|
|
@ -37,17 +37,10 @@ ssd_extents_create(struct ssd *ssd)
|
|||
-(theme->border_width + extended_area),
|
||||
-(ssd->titlebar.height + theme->border_width + extended_area));
|
||||
|
||||
/* Top */
|
||||
add_extent(part_list, LAB_SSD_PART_CORNER_TOP_LEFT, parent);
|
||||
add_extent(part_list, LAB_SSD_PART_TOP, parent);
|
||||
add_extent(part_list, LAB_SSD_PART_CORNER_TOP_RIGHT, parent);
|
||||
/* Sides */
|
||||
add_extent(part_list, LAB_SSD_PART_LEFT, parent);
|
||||
add_extent(part_list, LAB_SSD_PART_RIGHT, parent);
|
||||
/* Bottom */
|
||||
add_extent(part_list, LAB_SSD_PART_CORNER_BOTTOM_LEFT, parent);
|
||||
add_extent(part_list, LAB_SSD_PART_BOTTOM, parent);
|
||||
add_extent(part_list, LAB_SSD_PART_CORNER_BOTTOM_RIGHT, parent);
|
||||
|
||||
/* Initial manual update to keep X11 applications happy */
|
||||
ssd_extents_update(ssd);
|
||||
|
|
@ -76,11 +69,6 @@ ssd_extents_update(struct ssd *ssd)
|
|||
int full_height = height + theme->border_width * 2 + ssd->titlebar.height;
|
||||
int full_width = width + 2 * theme->border_width;
|
||||
int extended_area = SSD_EXTENDED_AREA;
|
||||
int corner_width = ssd_get_corner_width();
|
||||
int corner_size = extended_area + theme->border_width +
|
||||
MIN(corner_width, width) / 2;
|
||||
int side_width = full_width + extended_area * 2 - corner_size * 2;
|
||||
int side_height = full_height + extended_area * 2 - corner_size * 2;
|
||||
|
||||
struct wlr_box part_box;
|
||||
struct wlr_box result_box;
|
||||
|
|
@ -120,54 +108,30 @@ ssd_extents_update(struct ssd *ssd)
|
|||
wl_list_for_each(part, &ssd->extents.parts, link) {
|
||||
rect = wlr_scene_rect_from_node(part->node);
|
||||
switch (part->type) {
|
||||
case LAB_SSD_PART_CORNER_TOP_LEFT:
|
||||
case LAB_SSD_PART_TOP:
|
||||
target.x = 0;
|
||||
target.y = 0;
|
||||
target.width = corner_size;
|
||||
target.height = corner_size;
|
||||
break;
|
||||
case LAB_SSD_PART_TOP:
|
||||
target.x = corner_size;
|
||||
target.y = 0;
|
||||
target.width = side_width;
|
||||
target.width = full_width + extended_area * 2;
|
||||
target.height = extended_area;
|
||||
break;
|
||||
case LAB_SSD_PART_CORNER_TOP_RIGHT:
|
||||
target.x = corner_size + side_width;
|
||||
target.y = 0;
|
||||
target.width = corner_size;
|
||||
target.height = corner_size;
|
||||
break;
|
||||
case LAB_SSD_PART_LEFT:
|
||||
target.x = 0;
|
||||
target.y = corner_size;
|
||||
target.y = extended_area;
|
||||
target.width = extended_area;
|
||||
target.height = side_height;
|
||||
target.height = full_height;
|
||||
break;
|
||||
case LAB_SSD_PART_RIGHT:
|
||||
target.x = extended_area + full_width;
|
||||
target.y = corner_size;
|
||||
target.y = extended_area;
|
||||
target.width = extended_area;
|
||||
target.height = side_height;
|
||||
break;
|
||||
case LAB_SSD_PART_CORNER_BOTTOM_LEFT:
|
||||
target.x = 0;
|
||||
target.y = corner_size + side_height;
|
||||
target.width = corner_size;
|
||||
target.height = corner_size;
|
||||
target.height = full_height;
|
||||
break;
|
||||
case LAB_SSD_PART_BOTTOM:
|
||||
target.x = corner_size;
|
||||
target.x = 0;
|
||||
target.y = extended_area + full_height;
|
||||
target.width = side_width;
|
||||
target.width = full_width + extended_area * 2;
|
||||
target.height = extended_area;
|
||||
break;
|
||||
case LAB_SSD_PART_CORNER_BOTTOM_RIGHT:
|
||||
target.x = corner_size + side_width;
|
||||
target.y = corner_size + side_height;
|
||||
target.width = corner_size;
|
||||
target.height = corner_size;
|
||||
break;
|
||||
default:
|
||||
/* not reached */
|
||||
assert(false);
|
||||
|
|
|
|||
|
|
@ -74,8 +74,69 @@ ssd_max_extents(struct view *view)
|
|||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Resizing and mouse contexts like 'Left', 'TLCorner', etc. in the vicinity of
|
||||
* SSD borders, titlebars and extents can have effective "corner regions" that
|
||||
* behave differently from single-edge contexts.
|
||||
*
|
||||
* Corner regions are active whenever the cursor is within a prescribed size
|
||||
* (generally rc.resize_corner_range, but clipped to view size) of the view
|
||||
* bounds, so check the cursor against the view here.
|
||||
*/
|
||||
static enum ssd_part_type
|
||||
get_resizing_type(const struct ssd *ssd, struct wlr_cursor *cursor)
|
||||
{
|
||||
struct view *view = ssd ? ssd->view : NULL;
|
||||
if (!view || !cursor || !view->ssd_enabled || view->fullscreen) {
|
||||
return LAB_SSD_NONE;
|
||||
}
|
||||
|
||||
struct wlr_box view_box = view->current;
|
||||
view_box.height = view_effective_height(view, /* use_pending */ false);
|
||||
|
||||
if (!view->ssd_titlebar_hidden) {
|
||||
/* If the titlebar is visible, consider it part of the view */
|
||||
int titlebar_height = view->server->theme->titlebar_height;
|
||||
view_box.y -= titlebar_height;
|
||||
view_box.height += titlebar_height;
|
||||
}
|
||||
|
||||
if (wlr_box_contains_point(&view_box, cursor->x, cursor->y)) {
|
||||
/* A cursor in bounds of the view is never in an SSD context */
|
||||
return LAB_SSD_NONE;
|
||||
}
|
||||
|
||||
int corner_height = MAX(0, MIN(rc.resize_corner_range, view_box.height / 2));
|
||||
int corner_width = MAX(0, MIN(rc.resize_corner_range, view_box.width / 2));
|
||||
bool left = cursor->x < view_box.x + corner_width;
|
||||
bool right = cursor->x > view_box.x + view_box.width - corner_width;
|
||||
bool top = cursor->y < view_box.y + corner_height;
|
||||
bool bottom = cursor->y > view_box.y + view_box.height - corner_height;
|
||||
|
||||
if (top && left) {
|
||||
return LAB_SSD_PART_CORNER_TOP_LEFT;
|
||||
} else if (top && right) {
|
||||
return LAB_SSD_PART_CORNER_TOP_RIGHT;
|
||||
} else if (bottom && left) {
|
||||
return LAB_SSD_PART_CORNER_BOTTOM_LEFT;
|
||||
} else if (bottom && right) {
|
||||
return LAB_SSD_PART_CORNER_BOTTOM_RIGHT;
|
||||
} else if (top) {
|
||||
return LAB_SSD_PART_TOP;
|
||||
} else if (bottom) {
|
||||
return LAB_SSD_PART_BOTTOM;
|
||||
} else if (left) {
|
||||
return LAB_SSD_PART_LEFT;
|
||||
} else if (right) {
|
||||
return LAB_SSD_PART_RIGHT;
|
||||
}
|
||||
|
||||
return LAB_SSD_NONE;
|
||||
}
|
||||
|
||||
enum ssd_part_type
|
||||
ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
|
||||
ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node,
|
||||
struct wlr_cursor *cursor)
|
||||
{
|
||||
if (!node) {
|
||||
return LAB_SSD_NONE;
|
||||
|
|
@ -121,25 +182,25 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
|
|||
part_list = &ssd->border.inactive.parts;
|
||||
}
|
||||
|
||||
enum ssd_part_type part_type = LAB_SSD_NONE;
|
||||
|
||||
if (part_list) {
|
||||
struct ssd_part *part;
|
||||
wl_list_for_each(part, part_list, link) {
|
||||
if (node == part->node) {
|
||||
return part->type;
|
||||
part_type = part->type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return LAB_SSD_NONE;
|
||||
}
|
||||
|
||||
enum ssd_part_type
|
||||
ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly)
|
||||
{
|
||||
assert(scene);
|
||||
double sx, sy;
|
||||
struct wlr_scene_node *node = wlr_scene_node_at(
|
||||
&scene->tree.node, lx, ly, &sx, &sy);
|
||||
return ssd_get_part_type(ssd, node);
|
||||
if (part_type == LAB_SSD_NONE) {
|
||||
return part_type;
|
||||
}
|
||||
|
||||
/* Perform cursor-based context checks */
|
||||
enum ssd_part_type resizing_type = get_resizing_type(ssd, cursor);
|
||||
return resizing_type != LAB_SSD_NONE ? resizing_type : part_type;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue