diff --git a/include/view.h b/include/view.h index 52bd6ed4..471e52dd 100644 --- a/include/view.h +++ b/include/view.h @@ -371,6 +371,8 @@ 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, bool snap_to_windows); +void view_grow_to_edge(struct view *view, enum view_edge direction); +void view_shrink_to_edge(struct view *view, enum view_edge direction); 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 6402c4ec..f9b15c38 100644 --- a/src/action.c +++ b/src/action.c @@ -66,6 +66,8 @@ enum action_type { ACTION_TYPE_EXIT, ACTION_TYPE_MOVE_TO_EDGE, ACTION_TYPE_SNAP_TO_EDGE, + ACTION_TYPE_GROW_TO_EDGE, + ACTION_TYPE_SHRINK_TO_EDGE, ACTION_TYPE_NEXT_WINDOW, ACTION_TYPE_PREVIOUS_WINDOW, ACTION_TYPE_RECONFIGURE, @@ -105,6 +107,8 @@ const char *action_names[] = { "Exit", "MoveToEdge", "SnapToEdge", + "GrowToEdge", + "ShrinkToEdge", "NextWindow", "PreviousWindow", "Reconfigure", @@ -272,6 +276,8 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char } /* Falls through */ case ACTION_TYPE_SNAP_TO_EDGE: + case ACTION_TYPE_GROW_TO_EDGE: + case ACTION_TYPE_SHRINK_TO_EDGE: if (!strcmp(argument, "direction")) { enum view_edge edge = view_edge_parse(content); if ((edge == VIEW_EDGE_CENTER && action->type != ACTION_TYPE_SNAP_TO_EDGE) @@ -411,6 +417,8 @@ action_is_valid(struct action *action) break; case ACTION_TYPE_MOVE_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE: + case ACTION_TYPE_GROW_TO_EDGE: + case ACTION_TYPE_SHRINK_TO_EDGE: arg_name = "direction"; arg_type = LAB_ACTION_ARG_INT; break; @@ -654,6 +662,20 @@ actions_run(struct view *activator, struct server *server, view_snap_to_edge(view, edge, /*store_natural_geometry*/ true); } break; + case ACTION_TYPE_GROW_TO_EDGE: + if (view) { + /* Config parsing makes sure that direction is a valid direction */ + enum view_edge edge = action_get_int(action, "direction", 0); + view_grow_to_edge(view, edge); + } + break; + case ACTION_TYPE_SHRINK_TO_EDGE: + if (view) { + /* Config parsing makes sure that direction is a valid direction */ + enum view_edge edge = action_get_int(action, "direction", 0); + view_shrink_to_edge(view, edge); + } + break; case ACTION_TYPE_NEXT_WINDOW: server->osd_state.cycle_view = desktop_cycle_view(server, server->osd_state.cycle_view, LAB_CYCLE_DIR_FORWARD); diff --git a/src/view.c b/src/view.c index 3eaeebee..e85934bf 100644 --- a/src/view.c +++ b/src/view.c @@ -1162,6 +1162,40 @@ view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_wind view_move(view, view->pending.x + dx, view->pending.y + dy); } +void +view_grow_to_edge(struct view *view, enum view_edge direction) +{ + assert(view); + if (view->fullscreen || view->maximized) { + return; + } + if (!output_is_usable(view->output)) { + wlr_log(WLR_ERROR, "view has no output, not growing view"); + return; + } + + struct wlr_box geo = view->pending; + snap_grow_to_next_edge(view, direction, &geo); + view_move_resize(view, geo); +} + +void +view_shrink_to_edge(struct view *view, enum view_edge direction) +{ + assert(view); + if (view->fullscreen || view->maximized) { + return; + } + if (!output_is_usable(view->output)) { + wlr_log(WLR_ERROR, "view has no output, not shrinking view"); + return; + } + + struct wlr_box geo = view->pending; + snap_shrink_to_next_edge(view, direction, &geo); + view_move_resize(view, geo); +} + enum view_edge view_edge_parse(const char *direction) {