aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Orzechowski <alex@ozal.ski>2023-11-21 19:55:47 -0500
committerKirill Primak <vyivel@eclair.cafe>2024-01-18 18:36:54 +0300
commitc640c3015f3a7ea2987bd7854d13ff282f90804f (patch)
treed292934709dcd71bdb244546b1684e690e0511f4
parent9c17cba0b29979ae23c4521b884f7419fd558770 (diff)
scene_graph: Port seat drag icons
-rw-r--r--include/sway/input/seat.h26
-rw-r--r--include/sway/output.h4
-rw-r--r--include/sway/scene_descriptor.h1
-rw-r--r--include/sway/tree/root.h2
-rw-r--r--sway/desktop/output.c16
-rw-r--r--sway/desktop/render.c10
-rw-r--r--sway/input/cursor.c10
-rw-r--r--sway/input/seat.c98
-rw-r--r--sway/input/seatop_default.c15
-rw-r--r--sway/tree/root.c2
10 files changed, 53 insertions, 131 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 28a3ea37..3c81a713 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -3,6 +3,7 @@
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_layer_shell_v1.h>
+#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/util/edges.h>
@@ -75,20 +76,6 @@ struct sway_seat_node {
struct wl_listener destroy;
};
-struct sway_drag_icon {
- struct sway_seat *seat;
- struct wlr_drag_icon *wlr_drag_icon;
- struct wl_list link; // sway_root::drag_icons
-
- double x, y; // in layout-local coordinates
- int dx, dy; // offset in surface-local coordinates
-
- struct wl_listener surface_commit;
- struct wl_listener map;
- struct wl_listener unmap;
- struct wl_listener destroy;
-};
-
struct sway_drag {
struct sway_seat *seat;
struct wlr_drag *wlr_drag;
@@ -99,6 +86,15 @@ struct sway_seat {
struct wlr_seat *wlr_seat;
struct sway_cursor *cursor;
+ // Seat scene tree structure
+ // - scene_tree
+ // - drag icons
+ // - drag icon 1
+ // - drag icon 2
+ // - seatop specific stuff
+ struct wlr_scene_tree *scene_tree;
+ struct wlr_scene_tree *drag_icons;
+
bool has_focus;
struct wl_list focus_stack; // list of containers in focus order
struct sway_workspace *workspace;
@@ -257,7 +253,7 @@ void seat_idle_notify_activity(struct sway_seat *seat,
bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface);
-void drag_icon_update_position(struct sway_drag_icon *icon);
+void drag_icons_update_position(struct sway_seat *seat);
enum wlr_edges find_resize_edge(struct sway_container *cont,
struct wlr_surface *surface, struct sway_cursor *cursor);
diff --git a/include/sway/output.h b/include/sway/output.h
index b35f1366..28240819 100644
--- a/include/sway/output.h
+++ b/include/sway/output.h
@@ -167,10 +167,6 @@ void output_unmanaged_for_each_surface(struct sway_output *output,
void *user_data);
#endif
-void output_drag_icons_for_each_surface(struct sway_output *output,
- struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
- void *user_data);
-
void output_for_each_workspace(struct sway_output *output,
void (*f)(struct sway_workspace *ws, void *data), void *data);
diff --git a/include/sway/scene_descriptor.h b/include/sway/scene_descriptor.h
index 9761c2c0..057993ec 100644
--- a/include/sway/scene_descriptor.h
+++ b/include/sway/scene_descriptor.h
@@ -12,6 +12,7 @@
enum sway_scene_descriptor_type {
SWAY_SCENE_DESC_BUFFER_TIMER,
+ SWAY_SCENE_DESC_DRAG_ICON,
};
bool scene_descriptor_assign(struct wlr_scene_node *node,
diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h
index 9cb3d7bf..4b48a651 100644
--- a/include/sway/tree/root.h
+++ b/include/sway/tree/root.h
@@ -40,12 +40,12 @@ struct sway_root {
struct wlr_scene_tree *floating;
struct wlr_scene_tree *fullscreen;
struct wlr_scene_tree *fullscreen_global;
+ struct wlr_scene_tree *seat;
} layers;
#if HAVE_XWAYLAND
struct wl_list xwayland_unmanaged; // sway_xwayland_unmanaged::link
#endif
- struct wl_list drag_icons; // sway_drag_icon::link
// Includes disabled outputs
struct wl_list all_outputs; // sway_output::link
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index 11de25fb..321e2a72 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -259,22 +259,6 @@ void output_unmanaged_for_each_surface(struct sway_output *output,
}
#endif
-void output_drag_icons_for_each_surface(struct sway_output *output,
- struct wl_list *drag_icons, sway_surface_iterator_func_t iterator,
- void *user_data) {
- struct sway_drag_icon *drag_icon;
- wl_list_for_each(drag_icon, drag_icons, link) {
- double ox = drag_icon->x - output->lx;
- double oy = drag_icon->y - output->ly;
-
- if (drag_icon->wlr_drag_icon->surface->mapped) {
- output_surface_for_each_surface(output,
- drag_icon->wlr_drag_icon->surface, ox, oy,
- iterator, user_data);
- }
- }
-}
-
static int scale_length(int length, int offset, float scale) {
return roundf((offset + length) * scale) - roundf(offset * scale);
}
diff --git a/sway/desktop/render.c b/sway/desktop/render.c
index 168c941b..735dddb8 100644
--- a/sway/desktop/render.c
+++ b/sway/desktop/render.c
@@ -184,15 +184,6 @@ static void render_unmanaged(struct render_context *ctx, struct wl_list *unmanag
}
#endif
-static void render_drag_icons(struct render_context *ctx, struct wl_list *drag_icons) {
- struct render_data data = {
- .alpha = 1.0f,
- .ctx = ctx,
- };
- output_drag_icons_for_each_surface(ctx->output, drag_icons,
- render_surface_iterator, &data);
-}
-
// _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local
void render_rect(struct render_context *ctx, const struct wlr_box *_box,
@@ -1131,7 +1122,6 @@ render_overlay:
&output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
render_layer_popups(ctx,
&output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
- render_drag_icons(ctx, &root->drag_icons);
renderer_end:
pixman_region32_fini(&transformed_damage);
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 73aef4b0..e8604193 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -19,12 +19,12 @@
#include "log.h"
#include "util.h"
#include "sway/commands.h"
-#include "sway/desktop.h"
#include "sway/input/cursor.h"
#include "sway/input/keyboard.h"
#include "sway/input/tablet.h"
#include "sway/layers.h"
#include "sway/output.h"
+#include "sway/scene_descriptor.h"
#include "sway/tree/container.h"
#include "sway/tree/root.h"
#include "sway/tree/view.h"
@@ -543,12 +543,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
if (seat->touch_id == event->touch_id) {
seat->touch_x = lx;
seat->touch_y = ly;
- struct sway_drag_icon *drag_icon;
- wl_list_for_each(drag_icon, &root->drag_icons, link) {
- if (drag_icon->seat == seat) {
- drag_icon_update_position(drag_icon);
- }
- }
+
+ drag_icons_update_position(seat);
}
if (cursor->simulating_pointer_from_touch) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index cb8ac6a4..d2cd1ba4 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -18,7 +18,7 @@
#include "list.h"
#include "log.h"
#include "sway/config.h"
-#include "sway/desktop.h"
+#include "sway/scene_descriptor.h"
#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/keyboard.h"
@@ -92,6 +92,7 @@ void seat_destroy(struct sway_seat *seat) {
for (int i = 0; i < seat->deferred_bindings->length; i++) {
free_sway_binding(seat->deferred_bindings->items[i]);
}
+ wlr_scene_node_destroy(&seat->scene_tree->node);
list_free(seat->deferred_bindings);
free(seat->prev_workspace_name);
free(seat);
@@ -353,25 +354,15 @@ static void handle_new_node(struct wl_listener *listener, void *data) {
seat_node_from_node(seat, node);
}
-static void drag_icon_damage_whole(struct sway_drag_icon *icon) {
- if (!icon->wlr_drag_icon->surface->mapped) {
- return;
- }
- desktop_damage_surface(icon->wlr_drag_icon->surface, icon->x, icon->y, true);
-}
-
-void drag_icon_update_position(struct sway_drag_icon *icon) {
- drag_icon_damage_whole(icon);
-
- struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon;
- struct sway_seat *seat = icon->seat;
+static void drag_icon_update_position(struct sway_seat *seat, struct wlr_scene_node *node) {
+ struct wlr_drag_icon *wlr_icon = scene_descriptor_try_get(node, SWAY_SCENE_DESC_DRAG_ICON);
struct wlr_cursor *cursor = seat->cursor->cursor;
+
switch (wlr_icon->drag->grab_type) {
case WLR_DRAG_GRAB_KEYBOARD:
return;
case WLR_DRAG_GRAB_KEYBOARD_POINTER:
- icon->x = cursor->x + icon->dx;
- icon->y = cursor->y + icon->dy;
+ wlr_scene_node_set_position(node, cursor->x, cursor->y);
break;
case WLR_DRAG_GRAB_KEYBOARD_TOUCH:;
struct wlr_touch_point *point =
@@ -379,42 +370,15 @@ void drag_icon_update_position(struct sway_drag_icon *icon) {
if (point == NULL) {
return;
}
- icon->x = seat->touch_x + icon->dx;
- icon->y = seat->touch_y + icon->dy;
+ wlr_scene_node_set_position(node, seat->touch_x, seat->touch_y);
}
-
- drag_icon_damage_whole(icon);
-}
-
-static void drag_icon_handle_surface_commit(struct wl_listener *listener,
- void *data) {
- struct sway_drag_icon *icon =
- wl_container_of(listener, icon, surface_commit);
- struct wlr_drag_icon *wlr_icon = icon->wlr_drag_icon;
- icon->dx += wlr_icon->surface->current.dx;
- icon->dy += wlr_icon->surface->current.dy;
- drag_icon_update_position(icon);
-}
-
-static void drag_icon_handle_map(struct wl_listener *listener, void *data) {
- struct sway_drag_icon *icon = wl_container_of(listener, icon, map);
- drag_icon_damage_whole(icon);
-}
-
-static void drag_icon_handle_unmap(struct wl_listener *listener, void *data) {
- struct sway_drag_icon *icon = wl_container_of(listener, icon, unmap);
- drag_icon_damage_whole(icon);
}
-static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
- struct sway_drag_icon *icon = wl_container_of(listener, icon, destroy);
- icon->wlr_drag_icon->data = NULL;
- wl_list_remove(&icon->link);
- wl_list_remove(&icon->surface_commit.link);
- wl_list_remove(&icon->unmap.link);
- wl_list_remove(&icon->map.link);
- wl_list_remove(&icon->destroy.link);
- free(icon);
+void drag_icons_update_position(struct sway_seat *seat) {
+ struct wlr_scene_node *node;
+ wl_list_for_each(node, &seat->drag_icons->children, link) {
+ drag_icon_update_position(seat, node);
+ }
}
static void drag_handle_destroy(struct wl_listener *listener, void *data) {
@@ -486,27 +450,20 @@ static void handle_start_drag(struct wl_listener *listener, void *data) {
struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
if (wlr_drag_icon != NULL) {
- struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon));
- if (icon == NULL) {
- sway_log(SWAY_ERROR, "Allocation failed");
+ struct wlr_scene_tree *tree = wlr_scene_drag_icon_create(seat->drag_icons, wlr_drag_icon);
+ if (!tree) {
+ sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene tree");
return;
}
- icon->seat = seat;
- icon->wlr_drag_icon = wlr_drag_icon;
- wlr_drag_icon->data = icon;
-
- icon->surface_commit.notify = drag_icon_handle_surface_commit;
- wl_signal_add(&wlr_drag_icon->surface->events.commit, &icon->surface_commit);
- icon->unmap.notify = drag_icon_handle_unmap;
- wl_signal_add(&wlr_drag_icon->surface->events.unmap, &icon->unmap);
- icon->map.notify = drag_icon_handle_map;
- wl_signal_add(&wlr_drag_icon->surface->events.map, &icon->map);
- icon->destroy.notify = drag_icon_handle_destroy;
- wl_signal_add(&wlr_drag_icon->events.destroy, &icon->destroy);
- wl_list_insert(&root->drag_icons, &icon->link);
+ if (!scene_descriptor_assign(&tree->node, SWAY_SCENE_DESC_DRAG_ICON,
+ wlr_drag_icon)) {
+ sway_log(SWAY_ERROR, "Failed to allocate a drag icon scene descriptor");
+ wlr_scene_node_destroy(&tree->node);
+ return;
+ }
- drag_icon_update_position(icon);
+ drag_icon_update_position(seat, &tree->node);
}
seatop_begin_default(seat);
}
@@ -553,8 +510,18 @@ struct sway_seat *seat_create(const char *seat_name) {
return NULL;
}
+ bool failed = false;
+ seat->scene_tree = alloc_scene_tree(root->layers.seat, &failed);
+ seat->drag_icons = alloc_scene_tree(seat->scene_tree, &failed);
+ if (failed) {
+ wlr_scene_node_destroy(&seat->scene_tree->node);
+ free(seat);
+ return NULL;
+ }
+
seat->wlr_seat = wlr_seat_create(server.wl_display, seat_name);
if (!sway_assert(seat->wlr_seat, "could not allocate seat")) {
+ wlr_scene_node_destroy(&seat->scene_tree->node);
free(seat);
return NULL;
}
@@ -562,6 +529,7 @@ struct sway_seat *seat_create(const char *seat_name) {
seat->cursor = sway_cursor_create(seat);
if (!seat->cursor) {
+ wlr_scene_node_destroy(&seat->scene_tree->node);
wlr_seat_destroy(seat->wlr_seat);
free(seat);
return NULL;
diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c
index 1dce6dae..62261c77 100644
--- a/sway/input/seatop_default.c
+++ b/sway/input/seatop_default.c
@@ -12,6 +12,7 @@
#include "sway/input/tablet.h"
#include "sway/layers.h"
#include "sway/output.h"
+#include "sway/scene_descriptor.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "log.h"
@@ -620,12 +621,7 @@ static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
wlr_seat_pointer_notify_clear_focus(seat->wlr_seat);
}
- struct sway_drag_icon *drag_icon;
- wl_list_for_each(drag_icon, &root->drag_icons, link) {
- if (drag_icon->seat == seat) {
- drag_icon_update_position(drag_icon);
- }
- }
+ drag_icons_update_position(seat);
e->previous_node = node;
}
@@ -655,12 +651,7 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
wlr_tablet_v2_tablet_tool_notify_proximity_out(tool->tablet_v2_tool);
}
- struct sway_drag_icon *drag_icon;
- wl_list_for_each(drag_icon, &root->drag_icons, link) {
- if (drag_icon->seat == seat) {
- drag_icon_update_position(drag_icon);
- }
- }
+ drag_icons_update_position(seat);
e->previous_node = node;
}
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 75fb63f1..38fcdb7c 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -49,6 +49,7 @@ struct sway_root *root_create(struct wl_display *wl_display) {
root->layers.floating = alloc_scene_tree(&root_scene->tree, &failed);
root->layers.fullscreen = alloc_scene_tree(&root_scene->tree, &failed);
root->layers.fullscreen_global = alloc_scene_tree(&root_scene->tree, &failed);
+ root->layers.seat = alloc_scene_tree(&root_scene->tree, &failed);
if (failed) {
wlr_scene_node_destroy(&root_scene->tree.node);
@@ -63,7 +64,6 @@ struct sway_root *root_create(struct wl_display *wl_display) {
#if HAVE_XWAYLAND
wl_list_init(&root->xwayland_unmanaged);
#endif
- wl_list_init(&root->drag_icons);
wl_signal_init(&root->events.new_node);
root->outputs = create_list();
root->non_desktop_outputs = create_list();