From 08cff6edcf4941475ee161f37ce288142965bd28 Mon Sep 17 00:00:00 2001 From: Axel Burri Date: Sat, 5 Aug 2023 23:58:40 +0200 Subject: [PATCH] MoveToEdge: Snap to window edge Add configurable option (enabled by default) to snap to next window edge instead of screen edge. --- include/view.h | 2 +- src/action.c | 8 ++++++- src/view.c | 61 +++++++++++++++++++++----------------------------- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/include/view.h b/include/view.h index 6058e520..52bd6ed4 100644 --- a/include/view.h +++ b/include/view.h @@ -370,7 +370,7 @@ void view_move_to_workspace(struct view *view, struct workspace *workspace); void view_set_decorations(struct view *view, bool decorations); void view_toggle_fullscreen(struct view *view); void view_adjust_for_layout_change(struct view *view); -void view_move_to_edge(struct view *view, enum view_edge direction); +void view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_windows); void view_snap_to_edge(struct view *view, enum view_edge direction, bool store_natural_geometry); void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry); diff --git a/src/action.c b/src/action.c index fe0a6438..6402c4ec 100644 --- a/src/action.c +++ b/src/action.c @@ -266,6 +266,11 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char } break; case ACTION_TYPE_MOVE_TO_EDGE: + if (!strcasecmp(argument, "snapWindows")) { + action_arg_add_bool(action, argument, parse_bool(content, true)); + goto cleanup; + } + /* Falls through */ case ACTION_TYPE_SNAP_TO_EDGE: if (!strcmp(argument, "direction")) { enum view_edge edge = view_edge_parse(content); @@ -638,7 +643,8 @@ actions_run(struct view *activator, struct server *server, if (view) { /* Config parsing makes sure that direction is a valid direction */ enum view_edge edge = action_get_int(action, "direction", 0); - view_move_to_edge(view, edge); + bool snap_to_windows = action_get_bool(action, "snapWindows", true); + view_move_to_edge(view, edge, snap_to_windows); } break; case ACTION_TYPE_SNAP_TO_EDGE: diff --git a/src/view.c b/src/view.c index e7d7a9e7..3eaeebee 100644 --- a/src/view.c +++ b/src/view.c @@ -9,6 +9,7 @@ #include "menu/menu.h" #include "regions.h" #include "resize_indicator.h" +#include "snap.h" #include "ssd.h" #include "view.h" #include "window-rules.h" @@ -1127,50 +1128,38 @@ view_on_output_destroy(struct view *view) } void -view_move_to_edge(struct view *view, enum view_edge edge) +view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_windows) { assert(view); - struct output *output = view->output; - if (!output_is_usable(output)) { + if (!output_is_usable(view->output)) { wlr_log(WLR_ERROR, "view has no output, not moving to edge"); return; } - struct border margin = ssd_get_margin(view->ssd); - struct wlr_box usable = output_usable_area_in_layout_coords(output); - if (usable.height == output->wlr_output->height - && output->wlr_output->scale != 1) { - usable.height /= output->wlr_output->scale; - } - if (usable.width == output->wlr_output->width - && output->wlr_output->scale != 1) { - usable.width /= output->wlr_output->scale; + int dx = 0, dy = 0; + if (snap_to_windows) { + snap_vector_to_next_edge(view, direction, &dx, &dy); + } else { + struct border distance = snap_get_max_distance(view); + switch (direction) { + case VIEW_EDGE_LEFT: + dx = distance.left; + break; + case VIEW_EDGE_UP: + dy = distance.top; + break; + case VIEW_EDGE_RIGHT: + dx = distance.right; + break; + case VIEW_EDGE_DOWN: + dy = distance.bottom; + break; + default: + return; + } } - int x = 0, y = 0; - switch (edge) { - case VIEW_EDGE_LEFT: - x = usable.x + margin.left + rc.gap; - y = view->pending.y; - break; - case VIEW_EDGE_UP: - x = view->pending.x; - y = usable.y + margin.top + rc.gap; - break; - case VIEW_EDGE_RIGHT: - x = usable.x + usable.width - view->pending.width - - margin.right - rc.gap; - y = view->pending.y; - break; - case VIEW_EDGE_DOWN: - x = view->pending.x; - y = usable.y + usable.height - view->pending.height - - margin.bottom - rc.gap; - break; - default: - return; - } - view_move(view, x, y); + view_move(view, view->pending.x + dx, view->pending.y + dy); } enum view_edge