From 469411d4842e265295de5897cbcf879487cb46e8 Mon Sep 17 00:00:00 2001 From: llyyr Date: Wed, 28 Feb 2024 01:57:56 +0530 Subject: [PATCH 01/13] text_input: don't destroy scene_node twice --- sway/input/text_input.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sway/input/text_input.c b/sway/input/text_input.c index 5e96c3a8..c38a3bb2 100644 --- a/sway/input/text_input.c +++ b/sway/input/text_input.c @@ -293,10 +293,6 @@ static void input_popup_update(struct sway_input_popup *popup) { return; } - wlr_scene_node_destroy(&popup->scene_tree->node); - wlr_scene_node_destroy(popup->desc.relative); - popup->scene_tree = NULL; - bool cursor_rect = text_input->input->current.features & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; struct wlr_surface *focused_surface = text_input->input->focused_surface; From fca8474e9bd64bff8df16fdaf409d5f575ba9501 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 28 Feb 2024 17:49:58 +0100 Subject: [PATCH 02/13] Convert to new pointer enums References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4575 --- include/sway/input/cursor.h | 2 +- include/sway/input/seat.h | 6 ++--- sway/commands/seat/cursor.c | 14 ++++++------ sway/input/cursor.c | 16 +++++++------- sway/input/seat.c | 4 ++-- sway/input/seatop_default.c | 34 ++++++++++++++--------------- sway/input/seatop_down.c | 2 +- sway/input/seatop_move_floating.c | 2 +- sway/input/seatop_move_tiling.c | 2 +- sway/input/seatop_resize_floating.c | 2 +- sway/input/seatop_resize_tiling.c | 2 +- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 1e21c66f..527d0350 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h @@ -114,7 +114,7 @@ void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, void dispatch_cursor_button(struct sway_cursor *cursor, struct wlr_input_device *device, uint32_t time_msec, uint32_t button, - enum wlr_button_state state); + enum wl_pointer_button_state state); void dispatch_cursor_axis(struct sway_cursor *cursor, struct wlr_pointer_axis_event *event); diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index e5aa8478..475753d8 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -17,7 +17,7 @@ struct sway_seat; struct sway_seatop_impl { void (*button)(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state); + enum wl_pointer_button_state state); void (*pointer_motion)(struct sway_seat *seat, uint32_t time_msec); void (*pointer_axis)(struct sway_seat *seat, struct wlr_pointer_axis_event *event); @@ -286,13 +286,13 @@ struct sway_container *seat_get_focus_inactive_floating(struct sway_seat *seat, struct sway_workspace *workspace); void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, - uint32_t button, enum wlr_button_state state); + uint32_t button, enum wl_pointer_button_state state); void seat_consider_warp_to_focus(struct sway_seat *seat); void seatop_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state); + enum wl_pointer_button_state state); void seatop_pointer_motion(struct sway_seat *seat, uint32_t time_msec); diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index 85c5edca..df7c379d 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c @@ -84,12 +84,12 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { static struct cmd_results *press_or_release(struct sway_cursor *cursor, char *action, char *button_str) { - enum wlr_button_state state; + enum wl_pointer_button_state state; uint32_t button; if (strcasecmp(action, "press") == 0) { - state = WLR_BUTTON_PRESSED; + state = WL_POINTER_BUTTON_STATE_PRESSED; } else if (strcasecmp(action, "release") == 0) { - state = WLR_BUTTON_RELEASED; + state = WL_POINTER_BUTTON_STATE_RELEASED; } else { return cmd_results_new(CMD_INVALID, "%s", expected_syntax); } @@ -104,16 +104,16 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor, } else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN || button == SWAY_SCROLL_LEFT || button == SWAY_SCROLL_RIGHT) { // Dispatch axis event - enum wlr_axis_orientation orientation = + enum wl_pointer_axis orientation = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN) - ? WLR_AXIS_ORIENTATION_VERTICAL - : WLR_AXIS_ORIENTATION_HORIZONTAL; + ? WL_POINTER_AXIS_VERTICAL_SCROLL + : WL_POINTER_AXIS_HORIZONTAL_SCROLL; double delta = (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_LEFT) ? -1 : 1; struct wlr_pointer_axis_event event = { .pointer = NULL, .time_msec = 0, - .source = WLR_AXIS_SOURCE_WHEEL, + .source = WL_POINTER_AXIS_SOURCE_WHEEL, .orientation = orientation, .delta = delta * 15, .delta_discrete = delta diff --git a/sway/input/cursor.c b/sway/input/cursor.c index e8cd8112..7d66a89d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -356,7 +356,7 @@ static void handle_pointer_motion_absolute( void dispatch_cursor_button(struct sway_cursor *cursor, struct wlr_input_device *device, uint32_t time_msec, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { if (time_msec == 0) { time_msec = get_current_time_msec(); } @@ -368,7 +368,7 @@ static void handle_pointer_button(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, button); struct wlr_pointer_button_event *event = data; - if (event->state == WLR_BUTTON_PRESSED) { + if (event->state == WL_POINTER_BUTTON_STATE_PRESSED) { cursor->pressed_button_count++; } else { if (cursor->pressed_button_count > 0) { @@ -430,7 +430,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) { if (cursor->pointer_touch_id == cursor->seat->touch_id) { cursor->pointer_touch_up = true; dispatch_cursor_button(cursor, &event->touch->base, - event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); + event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); } } else { seatop_touch_up(seat, event); @@ -448,7 +448,7 @@ static void handle_touch_cancel(struct wl_listener *listener, void *data) { if (cursor->pointer_touch_id == cursor->seat->touch_id) { cursor->pointer_touch_up = true; dispatch_cursor_button(cursor, &event->touch->base, - event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED); + event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); } } else { seatop_touch_cancel(seat, event); @@ -661,7 +661,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { event->state == WLR_TABLET_TOOL_TIP_UP) { cursor->simulating_pointer_from_tool_tip = false; dispatch_cursor_button(cursor, &event->tablet->base, event->time_msec, - BTN_LEFT, WLR_BUTTON_RELEASED); + BTN_LEFT, WL_POINTER_BUTTON_STATE_RELEASED); wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); } else if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { // If we started holding the tool tip down on a surface that accepts @@ -673,7 +673,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { } else { cursor->simulating_pointer_from_tool_tip = true; dispatch_cursor_button(cursor, &event->tablet->base, - event->time_msec, BTN_LEFT, WLR_BUTTON_PRESSED); + event->time_msec, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); } } else { @@ -776,13 +776,13 @@ static void handle_tool_button(struct wl_listener *listener, void *data) { case WLR_BUTTON_PRESSED: if (cursor->tool_buttons == 0) { dispatch_cursor_button(cursor, &event->tablet->base, - event->time_msec, BTN_RIGHT, event->state); + event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_PRESSED); } break; case WLR_BUTTON_RELEASED: if (cursor->tool_buttons <= 1) { dispatch_cursor_button(cursor, &event->tablet->base, - event->time_msec, BTN_RIGHT, event->state); + event->time_msec, BTN_RIGHT, WL_POINTER_BUTTON_STATE_RELEASED); } break; } diff --git a/sway/input/seat.c b/sway/input/seat.c index 9dd078c6..7ae29828 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1520,7 +1520,7 @@ struct seat_config *seat_get_config_by_name(const char *name) { } void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, - uint32_t button, enum wlr_button_state state) { + uint32_t button, enum wl_pointer_button_state state) { seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); } @@ -1557,7 +1557,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con) { void seatop_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { if (seat->seatop_impl->button) { seat->seatop_impl->button(seat, time_msec, device, button, state); } diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index f2a9c2cd..0c6f7c5e 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c @@ -290,7 +290,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat, static bool trigger_pointer_button_binding(struct sway_seat *seat, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state, uint32_t modifiers, + enum wl_pointer_button_state state, uint32_t modifiers, bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) { // We can reach this for non-pointer devices if we're currently emulating // pointer input for one. Emulated input should not trigger bindings. The @@ -304,7 +304,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat, char *device_identifier = device ? input_device_get_identifier(device) : strdup("*"); struct sway_binding *binding = NULL; - if (state == WLR_BUTTON_PRESSED) { + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { state_add_button(e, button); binding = get_active_mouse_binding(e, config->current_mode->mouse_bindings, modifiers, false, @@ -329,7 +329,7 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat, static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { struct sway_cursor *cursor = seat->cursor; // Determine what's under the cursor @@ -362,7 +362,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle clicking an empty workspace if (node && node->type == N_WORKSPACE) { - if (state == WLR_BUTTON_PRESSED) { + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { seat_set_focus(seat, node); transaction_commit_dirty(); } @@ -377,7 +377,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, seat_set_focus_layer(seat, layer); transaction_commit_dirty(); } - if (state == WLR_BUTTON_PRESSED) { + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { seatop_begin_down_on_surface(seat, surface, sx, sy); } seat_pointer_notify_button(seat, time_msec, button, state); @@ -386,7 +386,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle tiling resize via border if (cont && resize_edge && button == BTN_LEFT && - state == WLR_BUTTON_PRESSED && !is_floating) { + state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating) { // If a resize is triggered on a tabbed or stacked container, change // focus to the tab which already had inactive focus -- otherwise, we'd // change the active tab when the user probably just wanted to resize. @@ -404,7 +404,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle tiling resize via mod bool mod_pressed = modifiers & config->floating_mod; if (cont && !is_floating_or_child && mod_pressed && - state == WLR_BUTTON_PRESSED) { + state == WL_POINTER_BUTTON_STATE_PRESSED) { uint32_t btn_resize = config->floating_mod_inverse ? BTN_LEFT : BTN_RIGHT; if (button == btn_resize) { @@ -432,7 +432,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, } // Handle changing focus when clicking on a container - if (cont && state == WLR_BUTTON_PRESSED) { + if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { // Default case: focus the container that was just clicked. node = &cont->node; @@ -453,7 +453,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle beginning floating move if (cont && is_floating_or_child && !is_fullscreen_or_child && - state == WLR_BUTTON_PRESSED) { + state == WL_POINTER_BUTTON_STATE_PRESSED) { uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT; if (button == btn_move && (mod_pressed || on_titlebar)) { seatop_begin_move_floating(seat, container_toplevel_ancestor(cont)); @@ -463,7 +463,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle beginning floating resize if (cont && is_floating_or_child && !is_fullscreen_or_child && - state == WLR_BUTTON_PRESSED) { + state == WL_POINTER_BUTTON_STATE_PRESSED) { // Via border if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) { seat_set_focus_container(seat, cont); @@ -489,7 +489,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, // Handle moving a tiling container if (config->tiling_drag && (mod_pressed || on_titlebar) && - state == WLR_BUTTON_PRESSED && !is_floating_or_child && + state == WL_POINTER_BUTTON_STATE_PRESSED && !is_floating_or_child && cont && cont->pending.fullscreen_mode == FULLSCREEN_NONE) { // If moving a container by its title bar, use a threshold for the drag if (!mod_pressed && config->tiling_drag_threshold > 0) { @@ -502,14 +502,14 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, } // Handle mousedown on a container surface - if (surface && cont && state == WLR_BUTTON_PRESSED) { + if (surface && cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { seatop_begin_down(seat, cont, sx, sy); - seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED); + seat_pointer_notify_button(seat, time_msec, button, WL_POINTER_BUTTON_STATE_PRESSED); return; } // Handle clicking a container surface or decorations - if (cont && state == WLR_BUTTON_PRESSED) { + if (cont && state == WL_POINTER_BUTTON_STATE_PRESSED) { seat_pointer_notify_button(seat, time_msec, button, state); return; } @@ -684,7 +684,7 @@ static void handle_touch_down(struct sway_seat *seat, pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy, dx, dy); dispatch_cursor_button(cursor, &event->touch->base, event->time_msec, - BTN_LEFT, WLR_BUTTON_PRESSED); + BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); } } @@ -694,9 +694,9 @@ static void handle_touch_down(struct sway_seat *seat, static uint32_t wl_axis_to_button(struct wlr_pointer_axis_event *event) { switch (event->orientation) { - case WLR_AXIS_ORIENTATION_VERTICAL: + case WL_POINTER_AXIS_VERTICAL_SCROLL: return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN; - case WLR_AXIS_ORIENTATION_HORIZONTAL: + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: return event->delta < 0 ? SWAY_SCROLL_LEFT : SWAY_SCROLL_RIGHT; default: sway_log(SWAY_DEBUG, "Unknown axis orientation"); diff --git a/sway/input/seatop_down.c b/sway/input/seatop_down.c index 12d7ae7a..35fd3bcb 100644 --- a/sway/input/seatop_down.c +++ b/sway/input/seatop_down.c @@ -142,7 +142,7 @@ static void handle_pointer_axis(struct sway_seat *seat, static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { seat_pointer_notify_button(seat, time_msec, button, state); if (seat->cursor->pressed_button_count == 0) { diff --git a/sway/input/seatop_move_floating.c b/sway/input/seatop_move_floating.c index 7de3f4d8..83668d88 100644 --- a/sway/input/seatop_move_floating.c +++ b/sway/input/seatop_move_floating.c @@ -21,7 +21,7 @@ static void finalize_move(struct sway_seat *seat) { static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { if (seat->cursor->pressed_button_count == 0) { finalize_move(seat); } diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c index 4f4d6e41..c525b77a 100644 --- a/sway/input/seatop_move_tiling.c +++ b/sway/input/seatop_move_tiling.c @@ -405,7 +405,7 @@ static void finalize_move(struct sway_seat *seat) { static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { if (seat->cursor->pressed_button_count == 0) { finalize_move(seat); } diff --git a/sway/input/seatop_resize_floating.c b/sway/input/seatop_resize_floating.c index 168dfffe..bec86e33 100644 --- a/sway/input/seatop_resize_floating.c +++ b/sway/input/seatop_resize_floating.c @@ -20,7 +20,7 @@ struct seatop_resize_floating_event { static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { struct seatop_resize_floating_event *e = seat->seatop_data; struct sway_container *con = e->con; diff --git a/sway/input/seatop_resize_tiling.c b/sway/input/seatop_resize_tiling.c index 9ce4ff8b..15fd333b 100644 --- a/sway/input/seatop_resize_tiling.c +++ b/sway/input/seatop_resize_tiling.c @@ -45,7 +45,7 @@ static struct sway_container *container_get_resize_sibling( static void handle_button(struct sway_seat *seat, uint32_t time_msec, struct wlr_input_device *device, uint32_t button, - enum wlr_button_state state) { + enum wl_pointer_button_state state) { struct seatop_resize_tiling_event *e = seat->seatop_data; if (seat->cursor->pressed_button_count == 0) { From 2867ef646b67138a796b7d5ae46428c255cc928f Mon Sep 17 00:00:00 2001 From: llyyr Date: Tue, 27 Feb 2024 01:40:22 +0530 Subject: [PATCH 03/13] ipc: add `floating` property to GET_TREE i3 has had this property for over a decade but it wasn't documented until a couple of years ago, so it was likely missed when developing sway. Add the property to get us closer to ipc parity with i3. --- sway/ipc-json.c | 8 +++++++- sway/sway-ipc.7.scd | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 58356d4e..84e164e4 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -288,6 +288,7 @@ static json_object *ipc_json_create_node(int id, const char* type, char *name, json_object_object_add(object, "focus", focus); json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); json_object_object_add(object, "sticky", json_object_new_boolean(false)); + json_object_object_add(object, "floating", NULL); return object; } @@ -675,7 +676,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object static void ipc_json_describe_container(struct sway_container *c, json_object *object) { json_object_object_add(object, "name", c->title ? json_object_new_string(c->title) : NULL); - if (container_is_floating(c)) { + bool floating = container_is_floating(c); + if (floating) { json_object_object_add(object, "type", json_object_new_string("floating_con")); } @@ -693,6 +695,10 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); + // sway doesn't track the floating reason, so we can't use "auto_on" or "user_off" + json_object_object_add(object, "floating", + json_object_new_string(floating ? "user_on" : "auto_off")); + json_object_object_add(object, "fullscreen_mode", json_object_new_int(c->pending.fullscreen_mode)); diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index f4a5ccff..5859558f 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -376,6 +376,9 @@ node and will have the following properties: : integer : (Only containers and views) The fullscreen mode of the node. 0 means none, 1 means full workspace, and 2 means global fullscreen +|- floating +: string +: Floating state of container. Can be either "auto_off" or "user_on" |- app_id : string : (Only views) For an xdg-shell view, the name of the application, if set. From 0b84d82b9aad05010479140774ac5ee1fea8ea97 Mon Sep 17 00:00:00 2001 From: llyyr Date: Tue, 27 Feb 2024 02:06:27 +0530 Subject: [PATCH 04/13] ipc: add `scratchpad_state` property to GET_TREE See previous commit. This restores ipc parity with i3. --- sway/ipc-json.c | 5 +++++ sway/sway-ipc.7.scd | 3 +++ 2 files changed, 8 insertions(+) diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 84e164e4..dfbb7a6e 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -289,6 +289,7 @@ static json_object *ipc_json_create_node(int id, const char* type, char *name, json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); json_object_object_add(object, "sticky", json_object_new_boolean(false)); json_object_object_add(object, "floating", NULL); + json_object_object_add(object, "scratchpad_state", NULL); return object; } @@ -702,6 +703,10 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o json_object_object_add(object, "fullscreen_mode", json_object_new_int(c->pending.fullscreen_mode)); + // sway doesn't track if window was resized in scratchpad, so we can't use "changed" + json_object_object_add(object, "scratchpad_state", + json_object_new_string(!c->scratchpad ? "none" : "fresh")); + struct sway_node *parent = node_get_parent(&c->node); struct wlr_box parent_box = {0, 0, 0, 0}; diff --git a/sway/sway-ipc.7.scd b/sway/sway-ipc.7.scd index 5859558f..c9895e52 100644 --- a/sway/sway-ipc.7.scd +++ b/sway/sway-ipc.7.scd @@ -379,6 +379,9 @@ node and will have the following properties: |- floating : string : Floating state of container. Can be either "auto_off" or "user_on" +|- scratchpad_state +: string +: Whether the window is in the scratchpad. Can be either "none" or "fresh" |- app_id : string : (Only views) For an xdg-shell view, the name of the application, if set. From 2058209a130f5051b59d8ebb24196409695deaaf Mon Sep 17 00:00:00 2001 From: Luofan Chen Date: Fri, 1 Mar 2024 11:43:14 +0800 Subject: [PATCH 05/13] input: Rename WLR_INPUT_DEVICE_TABLET_TOOL to WLR_INPUT_DEVICE_TABLET MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wlroots has changed the naming, causing the following build errors when building: error: ‘WLR_INPUT_DEVICE_TABLET_TOOL’ undeclared --- sway/input/cursor.c | 4 ++-- sway/input/input-manager.c | 2 +- sway/input/seat.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 7d66a89d..3d04826c 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -243,7 +243,7 @@ static enum sway_input_idle_source idle_source_from_device( return IDLE_SOURCE_POINTER; case WLR_INPUT_DEVICE_TOUCH: return IDLE_SOURCE_TOUCH; - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: return IDLE_SOURCE_TABLET_TOOL; case WLR_INPUT_DEVICE_TABLET_PAD: return IDLE_SOURCE_TABLET_PAD; @@ -518,7 +518,7 @@ static void apply_mapping_from_region(struct wlr_input_device *device, double x1 = region->x1, x2 = region->x2; double y1 = region->y1, y2 = region->y2; - if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { + if (region->mm && device->type == WLR_INPUT_DEVICE_TABLET) { struct wlr_tablet *tablet = wlr_tablet_from_input_device(device); if (tablet->width_mm == 0 || tablet->height_mm == 0) { return; diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index 9ee635af..056cc3ea 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -111,7 +111,7 @@ const char *input_device_get_type(struct sway_input_device *device) { return "keyboard"; case WLR_INPUT_DEVICE_TOUCH: return "touch"; - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: return "tablet_tool"; case WLR_INPUT_DEVICE_TABLET_PAD: return "tablet_pad"; diff --git a/sway/input/seat.c b/sway/input/seat.c index 7ae29828..f2486893 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -607,7 +607,7 @@ static void seat_update_capabilities(struct sway_seat *seat) { case WLR_INPUT_DEVICE_TOUCH: caps |= WL_SEAT_CAPABILITY_TOUCH; break; - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: caps |= WL_SEAT_CAPABILITY_POINTER; break; case WLR_INPUT_DEVICE_SWITCH: @@ -665,7 +665,7 @@ static const char *get_builtin_output_name(void) { static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) { switch (seat_device->input_device->wlr_device->type) { case WLR_INPUT_DEVICE_TOUCH: - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: return true; default: return false; @@ -680,7 +680,7 @@ static void seat_apply_input_mapping(struct sway_seat *seat, switch (sway_device->input_device->wlr_device->type) { case WLR_INPUT_DEVICE_POINTER: case WLR_INPUT_DEVICE_TOUCH: - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: break; default: return; // these devices don't support mappings @@ -873,7 +873,7 @@ void seat_configure_device(struct sway_seat *seat, case WLR_INPUT_DEVICE_TOUCH: seat_configure_touch(seat, seat_device); break; - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: seat_configure_tablet_tool(seat, seat_device); break; case WLR_INPUT_DEVICE_TABLET_PAD: @@ -912,7 +912,7 @@ void seat_reset_device(struct sway_seat *seat, case WLR_INPUT_DEVICE_TOUCH: seat_reset_input_config(seat, seat_device); break; - case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET: seat_reset_input_config(seat, seat_device); break; case WLR_INPUT_DEVICE_TABLET_PAD: From 5e18ed3cf03eee9e83909fede46dd98dff652647 Mon Sep 17 00:00:00 2001 From: Ronan Pigott Date: Wed, 28 Feb 2024 17:51:03 -0700 Subject: [PATCH 06/13] commands/move: do not force focus on the moved container My code archaeology isn't good enough to determine what this is here for, but it isn't correct. We should be able to move containers in a direction without focusing them. AFAICT i3 doesn't do this, so we shouldn't either. This fixes ipc commands like move with criteria that apply to containers which are not the current focus. --- sway/commands/move.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sway/commands/move.c b/sway/commands/move.c index bcbdaa2d..8addf26e 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -769,15 +769,6 @@ static struct cmd_results *cmd_move_in_direction( ipc_event_window(container, "move"); } - // Hack to re-focus container - seat_set_raw_focus(config->handler_context.seat, &new_ws->node); - seat_set_focus_container(config->handler_context.seat, container); - - if (old_ws != new_ws) { - ipc_event_workspace(old_ws, new_ws, "focus"); - workspace_detect_urgent(old_ws); - workspace_detect_urgent(new_ws); - } container_end_mouse_operation(container); return cmd_results_new(CMD_SUCCESS, NULL); From fd9ab9ee0659d5b4c2bd148e25b8bc6378f604d6 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 5 Mar 2024 08:44:04 +0100 Subject: [PATCH 07/13] config: error out on keysym translation XKB state failure If we can't create the XKB keymap used for keysym translation, gracefully error out instead of crashing. This can happen if the XKB_DEFAULT_LAYOUT is set to an invalid value, for instance. Closes: https://github.com/swaywm/sway/issues/7789 --- sway/config.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sway/config.c b/sway/config.c index 568c8b53..d46b81ee 100644 --- a/sway/config.c +++ b/sway/config.c @@ -43,13 +43,20 @@ static struct xkb_state *keysym_translation_state_create( context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); - xkb_context_unref(context); + if (xkb_keymap == NULL) { + sway_log(SWAY_ERROR, "Failed to compile keysym translation XKB keymap"); + return NULL; + } + return xkb_state_new(xkb_keymap); } static void keysym_translation_state_destroy( struct xkb_state *state) { + if (state == NULL) { + return; + } xkb_keymap_unref(xkb_state_get_keymap(state)); xkb_state_unref(state); } @@ -339,6 +346,9 @@ static void config_defaults(struct sway_config *config) { struct xkb_rule_names rules = {0}; config->keysym_translation_state = keysym_translation_state_create(rules); + if (config->keysym_translation_state == NULL) { + goto cleanup; + } return; cleanup: @@ -987,6 +997,11 @@ void translate_keysyms(struct input_config *input_config) { input_config_fill_rule_names(input_config, &rules); config->keysym_translation_state = keysym_translation_state_create(rules); + if (config->keysym_translation_state == NULL) { + sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state " + "for device '%s'", input_config->identifier); + return; + } for (int i = 0; i < config->modes->length; ++i) { struct sway_mode *mode = config->modes->items[i]; From 59f629238309e230b0e353e73d4f37a7de7fe820 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 5 Mar 2024 08:47:21 +0100 Subject: [PATCH 08/13] config: add fallback without env vars for keysym translation XKB keymap --- sway/config.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sway/config.c b/sway/config.c index d46b81ee..72fc41e7 100644 --- a/sway/config.c +++ b/sway/config.c @@ -37,8 +37,8 @@ struct sway_config *config = NULL; static struct xkb_state *keysym_translation_state_create( - struct xkb_rule_names rules) { - struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV); + struct xkb_rule_names rules, uint32_t context_flags) { + struct xkb_context *context = xkb_context_new(context_flags | XKB_CONTEXT_NO_SECURE_GETENV); struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( context, &rules, @@ -344,8 +344,11 @@ static void config_defaults(struct sway_config *config) { // The keysym to keycode translation struct xkb_rule_names rules = {0}; - config->keysym_translation_state = - keysym_translation_state_create(rules); + config->keysym_translation_state = keysym_translation_state_create(rules, 0); + if (config->keysym_translation_state == NULL) { + config->keysym_translation_state = keysym_translation_state_create(rules, + XKB_CONTEXT_NO_ENVIRONMENT_NAMES); + } if (config->keysym_translation_state == NULL) { goto cleanup; } @@ -995,8 +998,7 @@ void translate_keysyms(struct input_config *input_config) { struct xkb_rule_names rules = {0}; input_config_fill_rule_names(input_config, &rules); - config->keysym_translation_state = - keysym_translation_state_create(rules); + config->keysym_translation_state = keysym_translation_state_create(rules, 0); if (config->keysym_translation_state == NULL) { sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state " "for device '%s'", input_config->identifier); From f2a0e81b2438853e12a2b8fe9bddde154852d85d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 7 Mar 2024 12:16:11 +0100 Subject: [PATCH 09/13] Fetch input device vendor/product from libinput References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4582 --- sway/input/input-manager.c | 11 +++++++++-- sway/ipc-json.c | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index 056cc3ea..089e1e71 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -65,8 +65,15 @@ struct sway_seat *input_manager_sway_seat_from_wlr_seat(struct wlr_seat *wlr_sea } char *input_device_get_identifier(struct wlr_input_device *device) { - int vendor = device->vendor; - int product = device->product; + int vendor = 0, product = 0; +#if WLR_HAS_LIBINPUT_BACKEND + if (wlr_input_device_is_libinput(device)) { + struct libinput_device *libinput_dev = wlr_libinput_get_device_handle(device); + vendor = libinput_device_get_id_vendor(libinput_dev); + product = libinput_device_get_id_product(libinput_dev); + } +#endif + char *name = strdup(device->name ? device->name : ""); strip_whitespace(name); diff --git a/sway/ipc-json.c b/sway/ipc-json.c index dfbb7a6e..81ca3483 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1097,10 +1097,6 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { json_object_new_string(device->identifier)); json_object_object_add(object, "name", json_object_new_string(device->wlr_device->name)); - json_object_object_add(object, "vendor", - json_object_new_int(device->wlr_device->vendor)); - json_object_object_add(object, "product", - json_object_new_int(device->wlr_device->product)); json_object_object_add(object, "type", json_object_new_string( input_device_get_type(device))); @@ -1154,6 +1150,10 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); json_object_object_add(object, "libinput", describe_libinput_device(libinput_dev)); + json_object_object_add(object, "vendor", + json_object_new_int(libinput_device_get_id_vendor(libinput_dev))); + json_object_object_add(object, "product", + json_object_new_int(libinput_device_get_id_product(libinput_dev))); } #endif From 4e6d7612ffbd8e29713ae063937c8460e091bb75 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 27 Feb 2024 15:04:31 +0100 Subject: [PATCH 10/13] xdg-shell: implement popup repositioning --- include/sway/tree/view.h | 1 + sway/desktop/xdg_shell.c | 8 ++++++++ sway/server.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index ef1a26b8..7faacdcc 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -192,6 +192,7 @@ struct sway_xdg_popup { struct wl_listener surface_commit; struct wl_listener new_popup; + struct wl_listener reposition; struct wl_listener destroy; }; diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 27a73f8a..47ab902e 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -35,6 +35,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&popup->new_popup.link); wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->surface_commit.link); + wl_list_remove(&popup->reposition.link); wlr_scene_node_destroy(&popup->scene_tree->node); free(popup); } @@ -70,6 +71,11 @@ static void popup_handle_surface_commit(struct wl_listener *listener, void *data } } +static void popup_handle_reposition(struct wl_listener *listener, void *data) { + struct sway_xdg_popup *popup = wl_container_of(listener, popup, reposition); + popup_unconstrain(popup); +} + static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, struct sway_view *view, struct wlr_scene_tree *parent) { struct wlr_xdg_surface *xdg_surface = wlr_popup->base; @@ -116,6 +122,8 @@ static struct sway_xdg_popup *popup_create(struct wlr_xdg_popup *wlr_popup, popup->surface_commit.notify = popup_handle_surface_commit; wl_signal_add(&xdg_surface->events.new_popup, &popup->new_popup); popup->new_popup.notify = popup_handle_new_popup; + wl_signal_add(&wlr_popup->events.reposition, &popup->reposition); + popup->reposition.notify = popup_handle_reposition; wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); popup->destroy.notify = popup_handle_destroy; diff --git a/sway/server.c b/sway/server.c index 684b1dbd..cb8bdbf9 100644 --- a/sway/server.c +++ b/sway/server.c @@ -65,7 +65,7 @@ #include #endif -#define SWAY_XDG_SHELL_VERSION 2 +#define SWAY_XDG_SHELL_VERSION 3 #define SWAY_LAYER_SHELL_VERSION 4 #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 From 3ef5abd405a6fd32aeeffb2f48a6cadd9fc14574 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 27 Feb 2024 15:10:09 +0100 Subject: [PATCH 11/13] xdg-shell: send WM capabilities --- sway/desktop/xdg_shell.c | 4 ++++ sway/server.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 47ab902e..7c417891 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -289,6 +289,7 @@ static void handle_commit(struct wl_listener *listener, void *data) { } // XXX: https://github.com/swaywm/sway/issues/2176 wlr_xdg_surface_schedule_configure(xdg_surface); + // TODO: wlr_xdg_toplevel_set_bounds() return; } @@ -574,4 +575,7 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) { wlr_scene_xdg_surface_create(xdg_shell_view->view.content_tree, xdg_toplevel->base); xdg_toplevel->base->data = xdg_shell_view; + + wlr_xdg_toplevel_set_wm_capabilities(xdg_toplevel, + XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); } diff --git a/sway/server.c b/sway/server.c index cb8bdbf9..2a0dc1e7 100644 --- a/sway/server.c +++ b/sway/server.c @@ -65,7 +65,7 @@ #include #endif -#define SWAY_XDG_SHELL_VERSION 3 +#define SWAY_XDG_SHELL_VERSION 5 #define SWAY_LAYER_SHELL_VERSION 4 #define SWAY_FOREIGN_TOPLEVEL_LIST_VERSION 1 From 23389ebd1f301403e4b2331855a224dff89e1ad1 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 8 Mar 2024 12:35:10 +0100 Subject: [PATCH 12/13] config/output: drop enabling flag This was useful when wlroots backends were updating the current mode on their own. This is no longer the case. --- include/sway/output.h | 2 +- sway/config/output.c | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 30595f54..d546d488 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -50,7 +50,7 @@ struct sway_output { enum wl_output_subpixel detected_subpixel; enum scale_filter_mode scale_filter; - bool enabling, enabled; + bool enabled; list_t *workspaces; struct sway_output_state current; diff --git a/sway/config/output.c b/sway/config/output.c index 55779771..1b2332e9 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -510,9 +510,6 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { struct wlr_output *wlr_output = output->wlr_output; - // Flag to prevent the output mode event handler from calling us - output->enabling = (!oc || oc->enabled); - struct wlr_output_state pending = {0}; queue_output_config(oc, output, &pending); @@ -522,12 +519,9 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { // Leave the output disabled for now and try again when the output gets // the mode we asked for. sway_log(SWAY_ERROR, "Failed to commit output %s", wlr_output->name); - output->enabling = false; return false; } - output->enabling = false; - if (oc && !oc->enabled) { sway_log(SWAY_DEBUG, "Disabling output %s", oc->name); if (output->enabled) { From 2e951163c5a5f24fe9cf7ee348e56b09719a99a9 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Thu, 7 Mar 2024 18:03:40 -0500 Subject: [PATCH 13/13] Force bilinear scaling when scaling down --- sway/desktop/output.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 600423bc..b8f2d32d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -183,7 +183,15 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer, } } -static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output) { +static enum wlr_scale_filter_mode get_scale_filter(struct sway_output *output, + struct wlr_scene_buffer *buffer) { + // if we are scaling down, we should always choose linear + if (buffer->dst_width > 0 && buffer->dst_height > 0 && ( + buffer->dst_width < buffer->buffer_width || + buffer->dst_height < buffer->buffer_height)) { + return WLR_SCALE_FILTER_BILINEAR; + } + switch (output->scale_filter) { case SCALE_FILTER_LINEAR: return WLR_SCALE_FILTER_BILINEAR; @@ -212,7 +220,7 @@ static void output_configure_scene(struct sway_output *output, // hack: don't call the scene setter because that will damage all outputs // We don't want to damage outputs that aren't our current output that // we're configuring - buffer->filter_mode = get_scale_filter(output); + buffer->filter_mode = get_scale_filter(output, buffer); wlr_scene_buffer_set_opacity(buffer, opacity); } else if (node->type == WLR_SCENE_NODE_TREE) {