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.
This commit is contained in:
Consolatis 2023-08-02 04:30:50 +02:00 committed by Johan Malm
parent cb4afadd01
commit 1ee8715d57
4 changed files with 46 additions and 42 deletions

View file

@ -26,6 +26,16 @@ enum ssd_preference {
LAB_SSD_PREF_SERVER, 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;
struct view_impl { struct view_impl {
void (*configure)(struct view *view, struct wlr_box geo); 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_set_decorations(struct view *view, bool decorations);
void view_toggle_fullscreen(struct view *view); void view_toggle_fullscreen(struct view *view);
void view_adjust_for_layout_change(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_move_to_edge(struct view *view, enum view_edge direction);
void view_snap_to_edge(struct view *view, const char *direction, void view_snap_to_edge(struct view *view, enum view_edge direction, bool store_natural_geometry);
bool store_natural_geometry); void view_snap_to_region(struct view *view, struct region *region, 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_front(struct view *view);
void view_move_to_back(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_on_output_destroy(struct view *view);
void view_destroy(struct view *view); void view_destroy(struct view *view);
enum view_edge view_edge_parse(const char *direction);
/* xdg.c */ /* xdg.c */
struct wlr_xdg_surface *xdg_surface_from_view(struct view *view); struct wlr_xdg_surface *xdg_surface_from_view(struct view *view);

View file

@ -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_MOVE_TO_EDGE:
case ACTION_TYPE_SNAP_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE:
if (!strcmp(argument, "direction")) { 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; goto cleanup;
} }
break; break;
@ -564,13 +571,16 @@ actions_run(struct view *activator, struct server *server,
break; break;
case ACTION_TYPE_MOVE_TO_EDGE: case ACTION_TYPE_MOVE_TO_EDGE:
if (view) { 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; break;
case ACTION_TYPE_SNAP_TO_EDGE: case ACTION_TYPE_SNAP_TO_EDGE:
if (view) { if (view) {
view_snap_to_edge(view, action_str_from_arg(arg), /* Config parsing makes sure that direction is a valid direction */
/*store_natural_geometry*/ true); enum view_edge edge = get_arg_value_int(action, "direction", 0);
view_snap_to_edge(view, edge, /*store_natural_geometry*/ true);
} }
break; break;
case ACTION_TYPE_NEXT_WINDOW: case ACTION_TYPE_NEXT_WINDOW:

View file

@ -119,21 +119,21 @@ snap_to_edge(struct view *view)
*/ */
struct wlr_box *area = &view->output->usable_area; struct wlr_box *area = &view->output->usable_area;
if (cursor_x <= area->x + snap_range) { 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); /*store_natural_geometry*/ false);
} else if (cursor_x >= area->x + area->width - snap_range) { } 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); /*store_natural_geometry*/ false);
} else if (cursor_y <= area->y + snap_range) { } else if (cursor_y <= area->y + snap_range) {
if (rc.snap_top_maximize) { if (rc.snap_top_maximize) {
view_maximize(view, true, view_maximize(view, true,
/*store_natural_geometry*/ false); /*store_natural_geometry*/ false);
} else { } else {
view_snap_to_edge(view, "up", view_snap_to_edge(view, VIEW_EDGE_UP,
/*store_natural_geometry*/ false); /*store_natural_geometry*/ false);
} }
} else if (cursor_y >= area->y + area->height - snap_range) { } 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); /*store_natural_geometry*/ false);
} else { } else {
/* Not close to any edge */ /* Not close to any edge */

View file

@ -25,16 +25,6 @@
* They may be called repeatably during output layout changes. * 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 static enum view_edge
view_edge_invert(enum view_edge edge) view_edge_invert(enum view_edge edge)
{ {
@ -858,7 +848,7 @@ view_on_output_destroy(struct view *view)
} }
void void
view_move_to_edge(struct view *view, const char *direction) view_move_to_edge(struct view *view, enum view_edge edge)
{ {
assert(view); assert(view);
struct output *output = view->output; 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"); wlr_log(WLR_ERROR, "view has no output, not moving to edge");
return; return;
} }
if (!direction) {
wlr_log(WLR_ERROR, "invalid edge, not moving view");
return;
}
struct border margin = ssd_get_margin(view->ssd); struct border margin = ssd_get_margin(view->ssd);
struct wlr_box usable = output_usable_area_in_layout_coords(output); 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; int x = 0, y = 0;
if (!strcasecmp(direction, "left")) { switch (edge) {
case VIEW_EDGE_LEFT:
x = usable.x + margin.left + rc.gap; x = usable.x + margin.left + rc.gap;
y = view->pending.y; y = view->pending.y;
} else if (!strcasecmp(direction, "up")) { break;
case VIEW_EDGE_UP:
x = view->pending.x; x = view->pending.x;
y = usable.y + margin.top + rc.gap; 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 x = usable.x + usable.width - view->pending.width
- margin.right - rc.gap; - margin.right - rc.gap;
y = view->pending.y; y = view->pending.y;
} else if (!strcasecmp(direction, "down")) { break;
case VIEW_EDGE_DOWN:
x = view->pending.x; x = view->pending.x;
y = usable.y + usable.height - view->pending.height y = usable.y + usable.height - view->pending.height
- margin.bottom - rc.gap; - margin.bottom - rc.gap;
} else { break;
wlr_log(WLR_ERROR, "invalid edge, not moving view"); default:
return; return;
} }
view_move(view, x, y); view_move(view, x, y);
} }
static enum view_edge enum view_edge
view_edge_parse(const char *direction) view_edge_parse(const char *direction)
{ {
if (!direction) { if (!direction) {
@ -926,8 +916,7 @@ view_edge_parse(const char *direction)
} }
void void
view_snap_to_edge(struct view *view, const char *direction, view_snap_to_edge(struct view *view, enum view_edge edge, bool store_natural_geometry)
bool store_natural_geometry)
{ {
assert(view); assert(view);
if (view->fullscreen) { 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"); wlr_log(WLR_ERROR, "view has no output, not snapping to edge");
return; 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) { if (view->tiled == edge && !view->maximized) {
/* We are already tiled for this edge and thus should switch outputs */ /* We are already tiled for this edge and thus should switch outputs */