diff --git a/docs/labwc-actions.5.scd b/docs/labwc-actions.5.scd index 4a76a374..96e44cb6 100644 --- a/docs/labwc-actions.5.scd +++ b/docs/labwc-actions.5.scd @@ -51,9 +51,13 @@ Actions are used in menus and keyboard/mouse bindings. another window or screen edge. If set to "no", only move to the next screen edge. Default is yes. -** +** Begin interactive resize of window under cursor. + *direction* [up|down|left|right|up-left|up-right|down-left|down-right] + Edge or corner from which to start resizing. If this is not provided, + the direction is inferred from the cursor position. + ** Resize window relative to its current size. Values of left, right, top or bottom tell how much to resize on that edge of window, diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index fa4f7e58..4cb89cd5 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -349,7 +349,7 @@ this is for compatibility with Openbox. ``` -** +** *preview* [yes|no] Preview the contents of the selected window when switching between windows. Default is yes. @@ -363,6 +363,11 @@ this is for compatibility with Openbox. *unshade* [yes|no] Temporarily unshade windows when switching between them and permanently unshade on the final selection. Default is yes. + *order* [focus|age] The order in which windows are cycled. *focus* cycles by + recent focus history, starting with the previously focused window. *age* cycles + by creation/open order, a stable taskbar-style ordering that doesn’t change on + focus. Default is *focus*. + ** *show* [yes|no] Draw the OnScreenDisplay when switching between windows. Default is yes. @@ -498,13 +503,16 @@ activated with SnapToEdge actions or, optionally, by dragging windows to the edges of an output. Edge snapping causes a window to occupy half of its output, extending outward from the snapped edge. -**++ +**++ +**++ ** - If an interactive move ends with the cursor within ** pixels of an - output edge, the window is snapped to the edge. If it's also within - ** pixels of an output corner, the window is snapped to the - corner instead. A ** of 0 disables snapping. - Default is 10 for ** and 50 for **. + If an interactive move ends with the cursor within *inner* or *outer* pixels + of an output edge, the window is snapped to the edge. *inner* edges are edges + with an adjacent output and *outer* edges are edges without an adjacent output. + If it's also within ** pixels of an output corner, the window is + snapped to the corner instead. + If *inner* and *outer* is 0, snapping is disabled. + Default is 10 for ** and **, and 50 for **. ** [yes|no] Show an overlay when snapping to a window to an edge. Default is yes. @@ -700,6 +708,45 @@ extending outward from the snapped edge. invisible zones just beyond the window that serve as click targets for mouse actions. Default is 8. +# INPUT CONFIGURATION + +This section describes configuration of input devices including: + +- Keyboards +- Mice +- Touchpads (sometimes referred to as laptop trackpads) +- Touchscreens +- Tablets +- Tablet tools (like stylus pens) + +It aims to clarify related terminology and separation of concerns. + +Keyboards are configured in the ** section below and are simple in +this regard. + +Touchpads and mice are harder. They are both considered to be *pointer* devices +by the compositor, and can be configured in the ** and ** +sections. Any setting that is supported by libinput is configured in the +** section, and anything else is in **. Touchpad devices can +generate gesture events, like swipe and pinch. There are some related settings +(e.g. *threeFingerDrag* and *twoFingerScroll*) in the ** section. + +In the Wayland Compositor domain, events associated with touchscreens are +sometimes simply referred to as *touch* events. Touchscreens can be configured +in both the ** and ** sections. Note that touchscreen gestures +are not interpreted by libinput, nor labwc. Any touch point is passed to the +client (application) for any interpretation of gestures. + +Tablets are considered special by libinput although in the eyes of the Wayland +protocol they are merely a *touch* capability. Tablets and associated tablet +tools are configured in the **, ** and ** +sections. Note that the term *tablet* in libinput (and labwc) refers to graphics +tablets only (e.g. Wacom Intuos), not to tablet devices like the Apple iPad. + +References: +- https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html +- https://wayland.freedesktop.org/libinput/doc/latest/gestures.html + ## KEYBOARD ** [on|off] @@ -808,6 +855,9 @@ extending outward from the snapped edge. ## MOUSE +This section relates to mice and touchpads - which are both considered pointer +input-devices by the Wayland protocol. + ** Set double click time in milliseconds. Default is 500. @@ -918,6 +968,11 @@ extending outward from the snapped edge. ## TOUCH +This section relates to touchscreens and *not* touchpads. + +Note: To rotate touch events with output rotation, use the libinput +*calibrationMatrix* setting. + ``` ``` @@ -1080,14 +1135,9 @@ extending outward from the snapped edge. attribute is provided, a 'default' device profile will created that will act as the fallback for all libinput devices. Category can be set to any of the following types: - - *touch* - Devices which have a defined width/height, but do not - support multitouch (i.e. they cannot track multiple locations where - the screen has been touched). Drawing tablets typically fall into this - type. - - *touchpad* - Same as 'touch' but support multitouch. This typically - includes laptop track pads with two-finger scroll and swipe gestures. - - *non-touch* - Anything not described above, for example traditional - mouse pointers. + - *touch* - Includes touchscreens and drawing-tablets. + - *touchpad* - Includes touchpads (also known as laptop trackpads) + - *non-touch* - Includes traditional mice - *default* - Defines a device-category applicable to all devices not matched by anything else. This can be useful for a fallback, or if you want the same settings to be applied to all devices. diff --git a/docs/rc.xml b/docs/rc.xml index ec9a2f6f..49d36369 100644 --- a/docs/rc.xml +++ b/docs/rc.xml @@ -6,7 +6,7 @@ - + Clearlooks-3.4 8 diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 97698aac..f3d046d4 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -33,8 +33,8 @@ - - + + labwc icon:iconify,max,close @@ -161,8 +161,8 @@ - - 10 + + 50 @@ -218,9 +218,9 @@ space automatically, so is only intended for other, specialist cases. - If output is left empty, the margin will be applied to all outputs. + If 'output' is not provided, the margin will be applied to all outputs. - + --> @@ -525,7 +525,11 @@ If mouseEmulation is enabled, all touch up/down/motion events are translated to mouse button and motion events. --> - + + + + no + - + + @@ -583,10 +588,11 @@ - accelProfile [flat|adaptive] - tapButtonMap [lrm|lmr] - clickMethod [none|buttonAreas|clickfinger] + - scrollMethod [twoFinger|edge|none] - sendEventsMode [yes|no|disabledOnExternalMouse] - calibrationMatrix [six float values split by space] - scrollFactor [float] - + The following ... block may not be complete for your requirements. Default values are device specific. Only set an option if you require to override the default. Valid values must be inserted. @@ -595,21 +601,21 @@ - - - - + + + + yes - - - - - - - - - - + + + + + + + + + + 1.0 @@ -678,7 +684,7 @@ 400 2.0 0.2 - true + yes diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 55c0f877..94eb6ebe 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -151,7 +151,8 @@ struct rcxml { int unmaximize_threshold; /* window snapping */ - int snap_edge_range; + int snap_edge_range_inner; + int snap_edge_range_outer; int snap_edge_corner_range; bool snap_overlay_enabled; int snap_overlay_delay_inner; @@ -185,6 +186,7 @@ struct rcxml { enum cycle_osd_style style; enum cycle_osd_output_criteria output_criteria; char *thumbnail_label_format; + enum window_switcher_order order; } window_switcher; struct wl_list window_rules; /* struct window_rule.link */ diff --git a/include/config/types.h b/include/config/types.h index 757796a6..99c5929e 100644 --- a/include/config/types.h +++ b/include/config/types.h @@ -107,6 +107,11 @@ enum lab_window_type { LAB_WINDOW_TYPE_LEN }; +enum window_switcher_order { + WINDOW_SWITCHER_ORDER_FOCUS, + WINDOW_SWITCHER_ORDER_AGE, +}; + enum cycle_osd_style { CYCLE_OSD_STYLE_CLASSIC, CYCLE_OSD_STYLE_THUMBNAIL, diff --git a/include/labwc.h b/include/labwc.h index 40bff876..3d3ca2a3 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -188,6 +188,7 @@ struct server { struct wl_listener xdg_toplevel_icon_set_icon; struct wl_list views; + uint64_t next_view_creation_id; struct wl_list unmanaged_surfaces; struct seat seat; diff --git a/include/node.h b/include/node.h index 7b4936d6..6e459f69 100644 --- a/include/node.h +++ b/include/node.h @@ -24,6 +24,7 @@ struct node_descriptor { * @type: node descriptor type * @view: associated view * @data: struct to point to as follows: + * - LAB_NODE_CYCLE_OSD_ITEM struct cycle_osd_item * - LAB_NODE_LAYER_SURFACE struct lab_layer_surface * - LAB_NODE_LAYER_POPUP struct lab_layer_popup * - LAB_NODE_MENUITEM struct menuitem diff --git a/include/view.h b/include/view.h index 2f8aac85..fae462db 100644 --- a/include/view.h +++ b/include/view.h @@ -174,6 +174,7 @@ struct view { bool mapped; bool been_mapped; + uint64_t creation_id; enum lab_ssd_mode ssd_mode; enum ssd_preference ssd_preference; bool shaded; diff --git a/src/action.c b/src/action.c index ceeffd67..7ddba0be 100644 --- a/src/action.c +++ b/src/action.c @@ -414,6 +414,20 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char goto cleanup; } break; + case ACTION_TYPE_RESIZE: + if (!strcmp(argument, "direction")) { + enum lab_edge edge = lab_edge_parse(content, + /*tiled*/ true, /*any*/ false); + if (edge == LAB_EDGE_NONE || edge == LAB_EDGE_CENTER) { + 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; case ACTION_TYPE_RESIZE_RELATIVE: if (!strcmp(argument, "left") || !strcmp(argument, "right") || !strcmp(argument, "top") || !strcmp(argument, "bottom")) { @@ -1223,8 +1237,17 @@ run_action(struct view *view, struct server *server, struct action *action, break; case ACTION_TYPE_RESIZE: if (view) { - enum lab_edge resize_edges = cursor_get_resize_edges( - server->seat.cursor, ctx); + /* + * If a direction was specified in the config, honour it. + * Otherwise, fall back to determining the resize edges from + * the current cursor position (existing behaviour). + */ + enum lab_edge resize_edges = + action_get_int(action, "direction", LAB_EDGE_NONE); + if (resize_edges == LAB_EDGE_NONE) { + resize_edges = cursor_get_resize_edges( + server->seat.cursor, ctx); + } interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges); } diff --git a/src/config/rcxml.c b/src/config/rcxml.c index c5d94d4f..eacd3d64 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -714,6 +714,8 @@ fill_libinput_category(xmlNode *node) char *key, *content; LAB_XML_FOR_EACH(node, child, key, content) { if (string_null_or_empty(content)) { + wlr_log(WLR_ERROR, "Empty string is not allowed for " + "<%s>. Ignoring.", key); continue; } if (!strcmp(key, "category")) { @@ -1076,7 +1078,8 @@ entry(xmlNode *node, char *nodename, char *content) return true; } else if (str_space_only(content)) { - /* ignore empty leaf nodes other than above */ + wlr_log(WLR_ERROR, "Empty string is not allowed for %s. " + "Ignoring.", nodename); /* handle non-empty leaf nodes */ } else if (!strcmp(nodename, "decoration.core")) { @@ -1177,7 +1180,14 @@ entry(xmlNode *node, char *nodename, char *content) } else if (!strcasecmp(nodename, "unMaximizeThreshold.resistance")) { rc.unmaximize_threshold = atoi(content); } else if (!strcasecmp(nodename, "range.snapping")) { - rc.snap_edge_range = atoi(content); + rc.snap_edge_range_inner = atoi(content); + rc.snap_edge_range_outer = atoi(content); + wlr_log(WLR_ERROR, " is deprecated. " + "Use instead."); + } else if (!strcasecmp(nodename, "inner.range.snapping")) { + rc.snap_edge_range_inner = atoi(content); + } else if (!strcasecmp(nodename, "outer.range.snapping")) { + rc.snap_edge_range_outer = atoi(content); } else if (!strcasecmp(nodename, "cornerRange.snapping")) { rc.snap_edge_corner_range = atoi(content); } else if (!strcasecmp(nodename, "enabled.overlay.snapping")) { @@ -1230,6 +1240,15 @@ entry(xmlNode *node, char *nodename, char *content) wlr_log(WLR_ERROR, "Invalid windowSwitcher output %s: " "should be one of all|focused|cursor", content); } + } else if (!strcasecmp(nodename, "order.windowSwitcher")) { + if (!strcasecmp(content, "focus")) { + rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS; + } else if (!strcasecmp(content, "age")) { + rc.window_switcher.order = WINDOW_SWITCHER_ORDER_AGE; + } else { + wlr_log(WLR_ERROR, "Invalid windowSwitcher order %s: " + "should be one of focus|age", content); + } /* The following two are for backward compatibility only. */ } else if (!strcasecmp(nodename, "show.windowSwitcher")) { @@ -1456,7 +1475,8 @@ rcxml_init(void) rc.unsnap_threshold = 20; rc.unmaximize_threshold = 150; - rc.snap_edge_range = 10; + rc.snap_edge_range_inner = 10; + rc.snap_edge_range_outer = 10; rc.snap_edge_corner_range = 50; rc.snap_overlay_enabled = true; rc.snap_overlay_delay_inner = 500; @@ -1474,6 +1494,7 @@ rcxml_init(void) rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE | LAB_VIEW_CRITERIA_ROOT_TOPLEVEL | LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER; + rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS; rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER; rc.resize_draw_contents = true; @@ -1648,9 +1669,8 @@ load_default_window_switcher_fields(void) #endif }; - struct cycle_osd_field *field; for (size_t i = 0; i < ARRAY_SIZE(fields); i++) { - field = znew(*field); + struct cycle_osd_field *field = znew(*field); field->content = fields[i].content; field->width = fields[i].width; wl_list_append(&rc.window_switcher.fields, &field->link); diff --git a/src/cycle/cycle.c b/src/cycle/cycle.c index 8eabaf6c..adf9b05e 100644 --- a/src/cycle/cycle.c +++ b/src/cycle/cycle.c @@ -276,13 +276,31 @@ create_osd_on_output(struct output *output) assert(output->cycle_osd.tree); } +static void +insert_view_ordered_by_age(struct wl_list *views, struct view *new_view) +{ + struct wl_list *link = views; + struct view *view; + wl_list_for_each(view, views, cycle_link) { + if (view->creation_id >= new_view->creation_id) { + break; + } + link = &view->cycle_link; + } + wl_list_insert(link, &new_view->cycle_link); +} + /* Return false on failure */ static bool init_cycle(struct server *server) { struct view *view; for_each_view(view, &server->views, rc.window_switcher.criteria) { - wl_list_append(&server->cycle.views, &view->cycle_link); + if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) { + insert_view_ordered_by_age(&server->cycle.views, view); + } else { + wl_list_append(&server->cycle.views, &view->cycle_link); + } } if (wl_list_empty(&server->cycle.views)) { wlr_log(WLR_DEBUG, "no views to switch between"); diff --git a/src/cycle/osd-classic.c b/src/cycle/osd-classic.c index 67cfb8db..944b9063 100644 --- a/src/cycle/osd-classic.c +++ b/src/cycle/osd-classic.c @@ -144,7 +144,6 @@ cycle_osd_classic_create(struct output *output) y += switcher_theme->item_height; } - struct buf buf = BUF_INIT; int nr_fields = wl_list_length(&rc.window_switcher.fields); /* This is the width of the area available for text fields */ @@ -194,9 +193,9 @@ cycle_osd_classic_create(struct output *output) /* Highlight around selected window's item */ struct lab_scene_rect_options highlight_opts = { .border_colors = (float *[1]) {active_border_color}, - .bg_color = active_bg_color, .nr_borders = 1, .border_width = switcher_theme->item_active_border_width, + .bg_color = active_bg_color, .width = w - 2 * padding, .height = switcher_theme->item_height, }; @@ -216,7 +215,6 @@ cycle_osd_classic_create(struct output *output) y += switcher_theme->item_height; } - buf_reset(&buf); error:; /* Center OSD */ diff --git a/src/desktop-entry.c b/src/desktop-entry.c index 7617fa26..5ba8a2f6 100644 --- a/src/desktop-entry.c +++ b/src/desktop-entry.c @@ -251,6 +251,9 @@ err: * (e.g. "thunderbird" matches "org.mozilla.Thunderbird.desktop" * and "XTerm" matches "xterm.desktop"). This is not per any spec * but is needed to find icons for existing applications. + * + * The second loop tries to match more partial strings, for + * example "gimp-2.0" would match "org.something.gimp.desktop". */ static struct sfdo_desktop_entry * get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) @@ -258,6 +261,7 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) size_t n_entries; struct sfdo_desktop_entry **entries = sfdo_desktop_db_get_entries(db, &n_entries); + /* Would match "org.foobar.xterm" when given app-id "XTerm" */ for (size_t i = 0; i < n_entries; i++) { struct sfdo_desktop_entry *entry = entries[i]; const char *desktop_id = sfdo_desktop_entry_get_id(entry, NULL); @@ -266,6 +270,8 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) const char *desktop_id_base = dot ? (dot + 1) : desktop_id; if (!strcasecmp(app_id, desktop_id_base)) { + wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via case-insensitive match", + app_id, desktop_id); return entry; } @@ -278,20 +284,31 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id) const char *wm_class = sfdo_desktop_entry_get_startup_wm_class(entry, NULL); if (wm_class && !strcasecmp(app_id, wm_class)) { + wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via StartupWMClass", + app_id, desktop_id); return entry; } } - /* Try matching partial strings - catches GIMP, among others */ + /* Would match "org.foobar.xterm-unicode" when given app-id "XTerm" */ + const int app_id_len = strlen(app_id); for (size_t i = 0; i < n_entries; i++) { struct sfdo_desktop_entry *entry = entries[i]; const char *desktop_id = sfdo_desktop_entry_get_id(entry, NULL); const char *dot = strrchr(desktop_id, '.'); const char *desktop_id_base = dot ? (dot + 1) : desktop_id; - int alen = strlen(app_id); - int dlen = strlen(desktop_id_base); - - if (!strncasecmp(app_id, desktop_id_base, alen > dlen ? dlen : alen)) { + const int dlen = strlen(desktop_id_base); + const int cmp_len = MIN(app_id_len, dlen); + if (cmp_len < 3) { + /* + * Without this check, app-id "foot" would match + * "something.f" and any app-id would match "R.E.P.O." + */ + continue; + } + if (!strncasecmp(app_id, desktop_id_base, cmp_len)) { + wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via partial match", + app_id, desktop_id); return entry; } } @@ -304,10 +321,14 @@ get_desktop_entry(struct sfdo *sfdo, const char *app_id) { struct sfdo_desktop_entry *entry = sfdo_desktop_db_get_entry_by_id( sfdo->desktop_db, app_id, SFDO_NT); - if (!entry) { - entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id); + if (entry) { + wlr_log(WLR_DEBUG, "matched '%s.desktop' via exact match", app_id); + return entry; + } + entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id); + if (!entry) { + wlr_log(WLR_DEBUG, "failed to find .desktop file for '%s'", app_id); } - return entry; } diff --git a/src/input/cursor.c b/src/input/cursor.c index 2a681a6e..29409bea 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -840,10 +840,12 @@ apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, doub if (!seat->server->active_view) { return; } - if (!seat->current_constraint || pointer->base.type != WLR_INPUT_DEVICE_POINTER) { + if (!seat->current_constraint + || pointer->base.type != WLR_INPUT_DEVICE_POINTER + || seat->current_constraint->type + != WLR_POINTER_CONSTRAINT_V1_CONFINED) { return; } - assert(seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED); double sx = seat->cursor->x; double sy = seat->cursor->y; @@ -866,7 +868,9 @@ cursor_locked(struct seat *seat, struct wlr_pointer *pointer) { return seat->current_constraint && pointer->base.type == WLR_INPUT_DEVICE_POINTER - && seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED; + && seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED + && seat->current_constraint->surface + == seat->seat->pointer_state.focused_surface; } static void @@ -981,11 +985,6 @@ handle_motion_absolute(struct wl_listener *listener, void *data) double dx = lx - seat->cursor->x; double dy = ly - seat->cursor->y; - wlr_relative_pointer_manager_v1_send_relative_motion( - seat->server->relative_pointer_manager, - seat->seat, (uint64_t)event->time_msec * 1000, - dx, dy, dx, dy); - preprocess_cursor_motion(seat, event->pointer, event->time_msec, dx, dy); } diff --git a/src/interactive.c b/src/interactive.c index df32f46f..03c4ad53 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -186,7 +186,7 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, return false; } - if (rc.snap_edge_range == 0) { + if (rc.snap_edge_range_inner == 0 && rc.snap_edge_range_outer == 0) { return false; } @@ -197,9 +197,31 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, } *dest_output = output; - /* Translate into output local coordinates */ double cursor_x = seat->cursor->x; double cursor_y = seat->cursor->y; + + int top_range = rc.snap_edge_range_outer; + int bottom_range = rc.snap_edge_range_outer; + int left_range = rc.snap_edge_range_outer; + int right_range = rc.snap_edge_range_outer; + if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_UP, + output->wlr_output, cursor_x, cursor_y)) { + top_range = rc.snap_edge_range_inner; + } + if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_DOWN, + output->wlr_output, cursor_x, cursor_y)) { + bottom_range = rc.snap_edge_range_inner; + } + if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_LEFT, + output->wlr_output, cursor_x, cursor_y)) { + left_range = rc.snap_edge_range_inner; + } + if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_RIGHT, + output->wlr_output, cursor_x, cursor_y)) { + right_range = rc.snap_edge_range_inner; + } + + /* Translate into output local coordinates */ wlr_output_layout_output_coords(seat->server->output_layout, output->wlr_output, &cursor_x, &cursor_y); @@ -210,13 +232,13 @@ edge_from_cursor(struct seat *seat, struct output **dest_output, int left = cursor_x - area->x; int right = area->x + area->width - cursor_x; - if (top < rc.snap_edge_range) { + if (top < top_range) { *edge1 = LAB_EDGE_TOP; - } else if (bottom < rc.snap_edge_range) { + } else if (bottom < bottom_range) { *edge1 = LAB_EDGE_BOTTOM; - } else if (left < rc.snap_edge_range) { + } else if (left < left_range) { *edge1 = LAB_EDGE_LEFT; - } else if (right < rc.snap_edge_range) { + } else if (right < right_range) { *edge1 = LAB_EDGE_RIGHT; } else { return false; diff --git a/src/xdg.c b/src/xdg.c index 668dfe45..9ff24541 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -1085,6 +1085,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup); wl_list_insert(&server->views, &view->link); + view->creation_id = server->next_view_creation_id++; } static void diff --git a/src/xwayland.c b/src/xwayland.c index 564fa3e2..17eb995e 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1036,6 +1036,7 @@ xwayland_view_create(struct server *server, CONNECT_SIGNAL(xsurface, xwayland_view, map_request); wl_list_insert(&view->server->views, &view->link); + view->creation_id = view->server->next_view_creation_id++; if (xsurface->surface) { handle_associate(&xwayland_view->associate, NULL);