diff --git a/include/labwc.h b/include/labwc.h index adc15969..bd45c16d 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -345,8 +345,8 @@ void view_child_finish(struct view_child *child); void subsurface_create(struct view *view, struct wlr_subsurface *wlr_subsurface); void view_set_activated(struct view *view, bool activated); -void move_resistance(struct view *view, double *x, double *y, bool screen_edge); -void resize_resistance(struct view *view, struct wlr_box *new_view_geo, +void resistance_move_apply(struct view *view, double *x, double *y, bool screen_edge); +void resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo, bool screen_edge); struct border view_border(struct view *view); void view_move_resize(struct view *view, struct wlr_box geo); diff --git a/src/cursor.c b/src/cursor.c index 32d99271..11c7397d 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -81,7 +81,7 @@ process_cursor_move(struct server *server, uint32_t time) /* Move the grabbed view to the new position. */ dx += server->grab_box.x; dy += server->grab_box.y; - move_resistance(view, &dx, &dy, true); + resistance_move_apply(view, &dx, &dy, true); view_move(view, dx, dy); } @@ -125,7 +125,7 @@ process_cursor_resize(struct server *server, uint32_t time) new_view_geo.width = server->grab_box.width + dx; } - resize_resistance(view, &new_view_geo, true); + resistance_resize_apply(view, &new_view_geo, true); view_move_resize(view, new_view_geo); } diff --git a/src/resistance.c b/src/resistance.c index 862631e2..5d70c6d6 100644 --- a/src/resistance.c +++ b/src/resistance.c @@ -1,27 +1,55 @@ #include "labwc.h" #include "config/rcxml.h" -/* These functions could be extended to strength in the future. */ +struct edges { + int left; + int top; + int right; + int bottom; +}; + +static void +is_within_resistance_range(struct edges view, struct edges target, + struct edges other, struct edges *flags, int strength) +{ + if (view.left >= other.left && target.left < other.left + && target.left >= other.left - strength) { + flags->left = 1; + } else if (view.right <= other.right && target.right > other.right + && target.right <= other.right + strength) { + flags->right = 1; + } + + if (view.top >= other.top && target.top < other.top + && target.top >= other.top - strength) { + flags->top = 1; + } else if (view.bottom <= other.bottom && target.bottom > other.bottom + && target.bottom <= other.bottom + strength) { + flags->bottom = 1; + } +} + void -move_resistance(struct view *view, double *x, double *y, bool screen_edge) +resistance_move_apply(struct view *view, double *x, double *y, bool screen_edge) { struct server *server = view->server; struct wlr_box mgeom; struct output *output; struct border border = view_border(view); - int l, r, t, b; /* The edges of the current view */ - int tl, tr, tt, tb; /* The desired edges */ - int ml, mr, mt, mb; /* The edges of the monitor/other view */ + struct edges view_edges; /* The edges of the current view */ + struct edges target_edges; /* The desired edges */ + struct edges other_edges; /* The edges of the monitor/other view */ + struct edges flags; /* To be set in is_within_resistance_range() */ - l = view->x - border.left - rc.gap; - t = view->y - border.top - rc.gap; - r = view->x + view->w + border.right + rc.gap; - b = view->y + view->h + border.bottom + rc.gap; + view_edges.left = view->x - border.left - rc.gap; + view_edges.top = view->y - border.top - rc.gap; + view_edges.right = view->x + view->w + border.right + rc.gap; + view_edges.bottom = view->y + view->h + border.bottom + rc.gap; - tl = *x - border.left - rc.gap; - tt = *y - border.top - rc.gap; - tr = *x + view->w + border.right + rc.gap; - tb = *y + view->h + border.bottom + rc.gap; + target_edges.left = *x - border.left - rc.gap; + target_edges.top = *y - border.top - rc.gap; + target_edges.right = *x + view->w + border.right + rc.gap; + target_edges.bottom = *y + view->h + border.bottom + rc.gap; if (screen_edge) { if (!rc.screen_edge_strength) { @@ -31,51 +59,58 @@ move_resistance(struct view *view, double *x, double *y, bool screen_edge) wl_list_for_each(output, &server->outputs, link) { mgeom = output_usable_area_in_layout_coords(output); - ml = mgeom.x; - mt = mgeom.y; - mr = mgeom.x + mgeom.width; - mb = mgeom.y + mgeom.height; + other_edges.left = mgeom.x; + other_edges.top = mgeom.y; + other_edges.right = mgeom.x + mgeom.width; + other_edges.bottom = mgeom.y + mgeom.height; - if (l >= ml && tl < ml && tl >= ml - - rc.screen_edge_strength) { - *x = ml + border.left + rc.gap; - } else if (r <= mr && tr > mr && tr <= mr - + rc.screen_edge_strength) { - *x = mr - view->w - border.right - rc.gap; + is_within_resistance_range(view_edges, target_edges, + other_edges, &flags, rc.screen_edge_strength); + + if (flags.left == 1) { + *x = other_edges.left + border.left + rc.gap; + } else if (flags.right == 1) { + *x = other_edges.right - view->w - border.right + - rc.gap; } - if (t >= mt && tt < mt && tt >= mt - - rc.screen_edge_strength) { - *y = mt + border.top + rc.gap; - } else if (b <= mb && tb > mb && tb <= mb - + rc.screen_edge_strength) { - *y = mb - view->h - border.bottom - rc.gap; + if (flags.top == 1) { + *y = other_edges.top + border.top + rc.gap; + } else if (flags.bottom == 1) { + *y = other_edges.bottom - view->h + - border.bottom - rc.gap; } + + /* reset the flags */ + flags.left = flags.top = flags.right = flags.bottom = 0; } } } void -resize_resistance(struct view *view, struct wlr_box *new_view_geo, +resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo, bool screen_edge) { struct server *server = view->server; struct output *output; struct wlr_box mgeom; struct border border = view_border(view); - int l, r, t, b; /* The edges of the current view */ - int tl, tr, tt, tb; /* The desired edges */ - int ml, mr, mt, mb; /* The edges of the monitor/other view */ + struct edges view_edges; /* The edges of the current view */ + struct edges target_edges; /* The desired edges */ + struct edges other_edges; /* The edges of the monitor/other view */ + struct edges flags; /* To be set in is_within_resistance_range() */ - l = view->x - border.left - rc.gap; - t = view->y - border.top - rc.gap; - r = view->x + view->w + border.right + rc.gap; - b = view->y + view->h + border.bottom + rc.gap; + view_edges.left = view->x - border.left - rc.gap; + view_edges.top = view->y - border.top - rc.gap; + view_edges.right = view->x + view->w + border.right + rc.gap; + view_edges.bottom = view->y + view->h + border.bottom + rc.gap; - tl = new_view_geo->x - border.left - rc.gap; - tt = new_view_geo->y - border.top - rc.gap; - tr = new_view_geo->x + new_view_geo->width + border.right + rc.gap; - tb = new_view_geo->y + new_view_geo->height + border.bottom + rc.gap; + target_edges.left = new_view_geo->x - border.left - rc.gap; + target_edges.top = new_view_geo->y - border.top - rc.gap; + target_edges.right = new_view_geo->x + new_view_geo->width + + border.right + rc.gap; + target_edges.bottom = new_view_geo->y + new_view_geo->height + + border.bottom + rc.gap; if (screen_edge) { if (!rc.screen_edge_strength) { @@ -83,39 +118,40 @@ resize_resistance(struct view *view, struct wlr_box *new_view_geo, } wl_list_for_each(output, &server->outputs, link) { mgeom = output_usable_area_in_layout_coords(output); - ml = mgeom.x; - mt = mgeom.y; - mr = mgeom.x + mgeom.width; - mb = mgeom.y + mgeom.height; + other_edges.left = mgeom.x; + other_edges.top = mgeom.y; + other_edges.right = mgeom.x + mgeom.width; + other_edges.bottom = mgeom.y + mgeom.height; + + is_within_resistance_range(view_edges, target_edges, + other_edges, &flags, rc.screen_edge_strength); if (server->resize_edges & WLR_EDGE_LEFT) { - if (l >= ml && tl < ml && tl >= ml - - rc.screen_edge_strength) { - new_view_geo->x = ml + border.left - + rc.gap; + if (flags.left == 1) { + new_view_geo->x = other_edges.left + + border.left + rc.gap; new_view_geo->width = view->w; } } else if (server->resize_edges & WLR_EDGE_RIGHT) { - if (r <= mr && tr > mr && tr <= mr - + rc.screen_edge_strength) { - new_view_geo->width = mr - l + if (flags.right == 1) { + new_view_geo->width = other_edges.right + - view_edges.left - (border.right + rc.gap) * 2 ; } } if (server->resize_edges & WLR_EDGE_TOP) { - if (t >= mt && tt < mt && tt >= mt - - rc.screen_edge_strength) { - new_view_geo->y = mt + border.top - + rc.gap; + if (flags.top == 1) { + new_view_geo->y = other_edges.top + + border.top + rc.gap; new_view_geo->height = view->h; } } else if (server->resize_edges & WLR_EDGE_BOTTOM) { - if (b <= mb && tb > mb && tb <= mb - + rc.screen_edge_strength) { - new_view_geo->height = mb - t - - border.bottom - border.top - - rc.gap * 2; + if (flags.bottom == 1) { + new_view_geo->height = + other_edges.bottom + - view_edges.top - border.bottom + - border.top - rc.gap * 2; } } }