From 1ee8715d57ddb6b444e0b089879db6f837400539 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Wed, 2 Aug 2023 04:30:50 +0200 Subject: [PATCH] actions: use enum for _ToEdge actions This also improves the config robustness as invalid edge names will now prevent the action to be created in the first place and the user gets notified about the issue. --- include/view.h | 20 +++++++++++++++----- src/action.c | 18 ++++++++++++++---- src/interactive.c | 8 ++++---- src/view.c | 42 +++++++++++++----------------------------- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/view.h b/include/view.h index 128a4da0..6076d672 100644 --- a/include/view.h +++ b/include/view.h @@ -26,6 +26,16 @@ enum ssd_preference { LAB_SSD_PREF_SERVER, }; +enum view_edge { + VIEW_EDGE_INVALID = 0, + + VIEW_EDGE_LEFT, + VIEW_EDGE_RIGHT, + VIEW_EDGE_UP, + VIEW_EDGE_DOWN, + VIEW_EDGE_CENTER, +}; + struct view; struct view_impl { void (*configure)(struct view *view, struct wlr_box geo); @@ -196,11 +206,9 @@ 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, const char *direction); -void view_snap_to_edge(struct view *view, const char *direction, - bool store_natural_geometry); -void view_snap_to_region(struct view *view, struct region *region, - bool store_natural_geometry); +void view_move_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); void view_move_to_front(struct view *view); void view_move_to_back(struct view *view); @@ -216,6 +224,8 @@ void view_evacuate_region(struct view *view); void view_on_output_destroy(struct view *view); void view_destroy(struct view *view); +enum view_edge view_edge_parse(const char *direction); + /* xdg.c */ struct wlr_xdg_surface *xdg_surface_from_view(struct view *view); diff --git a/src/action.c b/src/action.c index f7920b31..900dcffc 100644 --- a/src/action.c +++ b/src/action.c @@ -181,7 +181,14 @@ action_arg_from_xml_node(struct action *action, char *nodename, char *content) case ACTION_TYPE_MOVE_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE: if (!strcmp(argument, "direction")) { - action_arg_add_str(action, argument, content); + enum view_edge edge = view_edge_parse(content); + if ((edge == VIEW_EDGE_CENTER && action->type != ACTION_TYPE_SNAP_TO_EDGE) + || edge == VIEW_EDGE_INVALID) { + wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s' (%s)", + action_names[action->type], argument, content); + } else { + action_arg_add_int(action, argument, edge); + } goto cleanup; } break; @@ -564,13 +571,16 @@ actions_run(struct view *activator, struct server *server, break; case ACTION_TYPE_MOVE_TO_EDGE: if (view) { - view_move_to_edge(view, action_str_from_arg(arg)); + /* Config parsing makes sure that direction is a valid direction */ + enum view_edge edge = get_arg_value_int(action, "direction", 0); + view_move_to_edge(view, edge); } break; case ACTION_TYPE_SNAP_TO_EDGE: if (view) { - view_snap_to_edge(view, action_str_from_arg(arg), - /*store_natural_geometry*/ true); + /* Config parsing makes sure that direction is a valid direction */ + enum view_edge edge = get_arg_value_int(action, "direction", 0); + view_snap_to_edge(view, edge, /*store_natural_geometry*/ true); } break; case ACTION_TYPE_NEXT_WINDOW: diff --git a/src/interactive.c b/src/interactive.c index 728c92e1..9a009d93 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -119,21 +119,21 @@ snap_to_edge(struct view *view) */ struct wlr_box *area = &view->output->usable_area; if (cursor_x <= area->x + snap_range) { - view_snap_to_edge(view, "left", + view_snap_to_edge(view, VIEW_EDGE_LEFT, /*store_natural_geometry*/ false); } else if (cursor_x >= area->x + area->width - snap_range) { - view_snap_to_edge(view, "right", + view_snap_to_edge(view, VIEW_EDGE_RIGHT, /*store_natural_geometry*/ false); } else if (cursor_y <= area->y + snap_range) { if (rc.snap_top_maximize) { view_maximize(view, true, /*store_natural_geometry*/ false); } else { - view_snap_to_edge(view, "up", + view_snap_to_edge(view, VIEW_EDGE_UP, /*store_natural_geometry*/ false); } } else if (cursor_y >= area->y + area->height - snap_range) { - view_snap_to_edge(view, "down", + view_snap_to_edge(view, VIEW_EDGE_DOWN, /*store_natural_geometry*/ false); } else { /* Not close to any edge */ diff --git a/src/view.c b/src/view.c index 9f6c34b7..8b1f5743 100644 --- a/src/view.c +++ b/src/view.c @@ -25,16 +25,6 @@ * They may be called repeatably during output layout changes. */ -enum view_edge { - VIEW_EDGE_INVALID = 0, - - VIEW_EDGE_LEFT, - VIEW_EDGE_RIGHT, - VIEW_EDGE_UP, - VIEW_EDGE_DOWN, - VIEW_EDGE_CENTER, -}; - static enum view_edge view_edge_invert(enum view_edge edge) { @@ -858,7 +848,7 @@ view_on_output_destroy(struct view *view) } void -view_move_to_edge(struct view *view, const char *direction) +view_move_to_edge(struct view *view, enum view_edge edge) { assert(view); struct output *output = view->output; @@ -866,10 +856,6 @@ view_move_to_edge(struct view *view, const char *direction) wlr_log(WLR_ERROR, "view has no output, not moving to edge"); return; } - if (!direction) { - wlr_log(WLR_ERROR, "invalid edge, not moving view"); - return; - } struct border margin = ssd_get_margin(view->ssd); struct wlr_box usable = output_usable_area_in_layout_coords(output); @@ -883,28 +869,32 @@ view_move_to_edge(struct view *view, const char *direction) } int x = 0, y = 0; - if (!strcasecmp(direction, "left")) { + switch (edge) { + case VIEW_EDGE_LEFT: x = usable.x + margin.left + rc.gap; y = view->pending.y; - } else if (!strcasecmp(direction, "up")) { + break; + case VIEW_EDGE_UP: x = view->pending.x; y = usable.y + margin.top + rc.gap; - } else if (!strcasecmp(direction, "right")) { + break; + case VIEW_EDGE_RIGHT: x = usable.x + usable.width - view->pending.width - margin.right - rc.gap; y = view->pending.y; - } else if (!strcasecmp(direction, "down")) { + break; + case VIEW_EDGE_DOWN: x = view->pending.x; y = usable.y + usable.height - view->pending.height - margin.bottom - rc.gap; - } else { - wlr_log(WLR_ERROR, "invalid edge, not moving view"); + break; + default: return; } view_move(view, x, y); } -static enum view_edge +enum view_edge view_edge_parse(const char *direction) { if (!direction) { @@ -926,8 +916,7 @@ view_edge_parse(const char *direction) } void -view_snap_to_edge(struct view *view, const char *direction, - bool store_natural_geometry) +view_snap_to_edge(struct view *view, enum view_edge edge, bool store_natural_geometry) { assert(view); if (view->fullscreen) { @@ -938,11 +927,6 @@ view_snap_to_edge(struct view *view, const char *direction, wlr_log(WLR_ERROR, "view has no output, not snapping to edge"); return; } - enum view_edge edge = view_edge_parse(direction); - if (edge == VIEW_EDGE_INVALID) { - wlr_log(WLR_ERROR, "invalid edge, not snapping view"); - return; - } if (view->tiled == edge && !view->maximized) { /* We are already tiled for this edge and thus should switch outputs */