diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 5aba22d8..c8de1864 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -125,7 +125,8 @@ struct rcxml { /* window snapping */ int snap_edge_range; - int snap_preview_timeout; + int snap_preview_interior_timeout; + int snap_preview_exterior_timeout; bool snap_top_maximize; enum tiling_events_mode snap_tiling_events_mode; diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 897c460e..c27bc1b0 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -735,6 +735,12 @@ entry(xmlNode *node, char *nodename, char *content) /* current */ static enum font_place font_place = FONT_PLACE_NONE; + static enum { + EDGE_TYPE_INTERIOR = 1, + EDGE_TYPE_EXTERIOR = 2, + EDGE_TYPE_BOTH = 1 | 2, + } edge_type = EDGE_TYPE_BOTH; + static uint32_t button_map_from; if (!nodename) { @@ -906,8 +912,19 @@ entry(xmlNode *node, char *nodename, char *content) rc.window_edge_strength = atoi(content); } else if (!strcasecmp(nodename, "range.snapping")) { rc.snap_edge_range = atoi(content); + } else if (!strcasecmp(nodename, "edgeType.previewTimeout.snapping")) { + if (!strcasecmp(content, "interior")) { + edge_type = EDGE_TYPE_INTERIOR; + } else if (!strcasecmp(content, "exterior")) { + edge_type = EDGE_TYPE_EXTERIOR; + } } else if (!strcasecmp(nodename, "previewTimeout.snapping")) { - rc.snap_preview_timeout = atoi(content); + if (edge_type & EDGE_TYPE_INTERIOR) { + rc.snap_preview_interior_timeout = atoi(content); + } + if (edge_type & EDGE_TYPE_EXTERIOR) { + rc.snap_preview_exterior_timeout = atoi(content); + } } else if (!strcasecmp(nodename, "topMaximize.snapping")) { set_bool(content, &rc.snap_top_maximize); } else if (!strcasecmp(nodename, "notifyClient.snapping")) { @@ -1185,7 +1202,8 @@ rcxml_init(void) rc.window_edge_strength = 20; rc.snap_edge_range = 1; - rc.snap_preview_timeout = 500; + rc.snap_preview_interior_timeout = 500; + rc.snap_preview_exterior_timeout = 500; rc.snap_top_maximize = true; rc.snap_tiling_events_mode = LAB_TILING_EVENTS_ALWAYS; diff --git a/src/overlay.c b/src/overlay.c index 67c7f11c..9a88a922 100644 --- a/src/overlay.c +++ b/src/overlay.c @@ -116,6 +116,35 @@ handle_edge_overlay_timeout(void *data) return 0; } +static enum wlr_direction +get_wlr_direction(enum view_edge edge) +{ + switch (edge) { + case VIEW_EDGE_LEFT: + return WLR_DIRECTION_LEFT; + case VIEW_EDGE_RIGHT: + return WLR_DIRECTION_RIGHT; + case VIEW_EDGE_UP: + case VIEW_EDGE_CENTER: + return WLR_DIRECTION_UP; + case VIEW_EDGE_DOWN: + return WLR_DIRECTION_DOWN; + default: + /* not reached */ + assert(false); + return 0; + } +} + +static bool +edge_has_adjacent_output_from_cursor(struct seat *seat, struct output *output, + enum view_edge edge) +{ + return wlr_output_layout_adjacent_output( + seat->server->output_layout, get_wlr_direction(edge), + output->wlr_output, seat->cursor->x, seat->cursor->y); +} + static void show_edge_overlay(struct seat *seat, enum view_edge edge, struct output *output) @@ -128,15 +157,21 @@ show_edge_overlay(struct seat *seat, enum view_edge edge, seat->overlay.active.edge = edge; seat->overlay.active.output = output; - if (rc.snap_preview_timeout > 0) { + int timeout; + if (edge_has_adjacent_output_from_cursor(seat, output, edge)) { + timeout = rc.snap_preview_interior_timeout; + } else { + timeout = rc.snap_preview_exterior_timeout; + } + + if (timeout > 0) { if (!seat->overlay.timer) { seat->overlay.timer = wl_event_loop_add_timer( seat->server->wl_event_loop, handle_edge_overlay_timeout, seat); } /* Show overlay ms later */ - wl_event_source_timer_update(seat->overlay.timer, - rc.snap_preview_timeout); + wl_event_source_timer_update(seat->overlay.timer, timeout); } else { /* Show overlay now */ struct wlr_box box = get_edge_snap_box(seat->overlay.active.edge,