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 */