From 28fb61668f04aebb0643330a653c6198cd566278 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Tue, 2 Jun 2026 14:30:57 +0200 Subject: [PATCH] decompose wl_backend.c: extract wl_dragicon.c --- src/Makefile.am | 3 +- src/backend/wayland/wl_backend.c | 114 +--------------------------- src/backend/wayland/wl_dragicon.c | 121 ++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 111 deletions(-) create mode 100644 src/backend/wayland/wl_dragicon.c diff --git a/src/Makefile.am b/src/Makefile.am index 88c0987..260144a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -183,7 +183,8 @@ wmaker_SOURCES += \ backend/wayland/wl_clipboard.c \ backend/wayland/wl_dnd.c \ backend/wayland/wl_grabs.c \ - backend/wayland/wl_grabstate.c + backend/wayland/wl_grabstate.c \ + backend/wayland/wl_dragicon.c endif if USE_NESTED_FUNC diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 4410cd5..dfa89c0 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -313,10 +313,10 @@ void wl_clipboard_store_to_seat(const char *text, int len); char *wl_clipboard_fetch_from_seat(int *len_out); /* Drag icon overlay for WINGs compositor-internal DND. */ -static void wl_drag_icon_show(struct W_View *view, int x, int y); -static void wl_drag_icon_move(int x, int y); -static void wl_drag_icon_hide(void); -static void wl_drag_cursor_feedback(Bool accepted); +void wl_drag_icon_show(struct W_View *view, int x, int y); +void wl_drag_icon_move(int x, int y); +void wl_drag_icon_hide(void); +void wl_drag_cursor_feedback(Bool accepted); /* Phase 28: idle inhibitor created/destroyed handler. */ static void handle_idle_new_inhibitor(struct wl_listener *listener, void *data); /* Phase 29: scroll-wheel axis event handler. */ @@ -3807,113 +3807,7 @@ handle_seat_request_cursor(struct wl_listener *listener, void *data) /* Drag icon overlay for WINGs compositor-internal DND */ /* ------------------------------------------------------------------ */ -/* State for the currently active drag icon (only one drag at a time) */ -static struct { - struct wlr_scene_buffer *scene_buf; - struct wlr_scene_tree *tree; - pixman_image_t *image; - struct wlr_buffer base; - int width, height; - int offset_x, offset_y; /* cursor hotspot relative to top-left */ -} wl_drag_icon_state = {0}; -static void -wl_drag_icon_destroy(void) -{ - if (wl_drag_icon_state.tree) { - wlr_scene_node_destroy(&wl_drag_icon_state.tree->node); - wl_drag_icon_state.tree = NULL; - wl_drag_icon_state.scene_buf = NULL; - } - if (wl_drag_icon_state.image) { - pixman_image_unref(wl_drag_icon_state.image); - wl_drag_icon_state.image = NULL; - } - memset(&wl_drag_icon_state, 0, sizeof(wl_drag_icon_state)); -} - -static void -wl_drag_icon_show(struct W_View *view, int x, int y) -{ - /* Clean up any previous drag icon */ - wl_drag_icon_destroy(); - - if (!view || !view->dragImage || !wl_state.scene) - return; - - struct W_Pixmap *p = view->dragImage; - pixman_image_t *src = (pixman_image_t *)(uintptr_t)p->pixmap; - if (!src) - return; - - int w = p->width; - int h = p->height; - - /* Copy the pixman image so we own it independently */ - pixman_image_t *copy = pixman_image_create_bits( - PIXMAN_a8r8g8b8, w, h, NULL, w * 4); - if (!copy) - return; - pixman_image_composite32(PIXMAN_OP_SRC, src, NULL, copy, - 0, 0, 0, 0, 0, 0, w, h); - - wl_drag_icon_state.image = copy; - wl_drag_icon_state.width = w; - wl_drag_icon_state.height = h; - - /* Center the icon on the cursor */ - wl_drag_icon_state.offset_x = -w / 2; - wl_drag_icon_state.offset_y = -h / 2; - - /* Wrap in wlr_buffer using the existing frame_buf_impl */ - wlr_buffer_init(&wl_drag_icon_state.base, &frame_buf_impl, w, h); - - /* Create scene tree under overlay layer */ - struct wlr_scene_tree *parent = wl_state.level_trees[WL_LAYER_OVERLAY] - ? wl_state.level_trees[WL_LAYER_OVERLAY] : &wl_state.scene->tree; - wl_drag_icon_state.tree = wlr_scene_tree_create(parent); - if (!wl_drag_icon_state.tree) { - wl_drag_icon_destroy(); - return; - } - - wl_drag_icon_state.scene_buf = wlr_scene_buffer_create( - wl_drag_icon_state.tree, &wl_drag_icon_state.base); - if (!wl_drag_icon_state.scene_buf) { - wl_drag_icon_destroy(); - return; - } - - /* Position at cursor (centered) */ - wlr_scene_node_set_position(&wl_drag_icon_state.tree->node, - x + wl_drag_icon_state.offset_x, - y + wl_drag_icon_state.offset_y); -} - -static void -wl_drag_icon_move(int x, int y) -{ - if (!wl_drag_icon_state.tree) - return; - wlr_scene_node_set_position(&wl_drag_icon_state.tree->node, - x + wl_drag_icon_state.offset_x, - y + wl_drag_icon_state.offset_y); -} - -static void -wl_drag_icon_hide(void) -{ - wl_drag_icon_destroy(); -} - -static void -wl_drag_cursor_feedback(Bool accepted) -{ - if (accepted) - wl_set_cursor_image("plus"); - else - wl_set_cursor_image("left_ptr"); -} /* * Phase 25: seat request_set_selection — client calls wl_data_device.set_selection diff --git a/src/backend/wayland/wl_dragicon.c b/src/backend/wayland/wl_dragicon.c new file mode 100644 index 0000000..7e456bf --- /dev/null +++ b/src/backend/wayland/wl_dragicon.c @@ -0,0 +1,121 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include +#include +#include +#include +#include "../../screen.h" +#include "wl_types.h" +#include + +/* Forward declarations */ +void wl_set_cursor_image(const char *name); + +static struct { + struct wlr_scene_buffer *scene_buf; + struct wlr_scene_tree *tree; + pixman_image_t *image; + struct wlr_buffer base; + int width, height; + int offset_x, offset_y; /* cursor hotspot relative to top-left */ +} wl_drag_icon_state = {0}; + +void +wl_drag_icon_destroy(void) +{ + if (wl_drag_icon_state.tree) { + wlr_scene_node_destroy(&wl_drag_icon_state.tree->node); + wl_drag_icon_state.tree = NULL; + wl_drag_icon_state.scene_buf = NULL; + } + if (wl_drag_icon_state.image) { + pixman_image_unref(wl_drag_icon_state.image); + wl_drag_icon_state.image = NULL; + } + memset(&wl_drag_icon_state, 0, sizeof(wl_drag_icon_state)); +} + +void +wl_drag_icon_show(struct W_View *view, int x, int y) +{ + /* Clean up any previous drag icon */ + wl_drag_icon_destroy(); + + if (!view || !view->dragImage || !wl_state.scene) + return; + + struct W_Pixmap *p = view->dragImage; + pixman_image_t *src = (pixman_image_t *)(uintptr_t)p->pixmap; + if (!src) + return; + + int w = p->width; + int h = p->height; + + /* Copy the pixman image so we own it independently */ + pixman_image_t *copy = pixman_image_create_bits( + PIXMAN_a8r8g8b8, w, h, NULL, w * 4); + if (!copy) + return; + pixman_image_composite32(PIXMAN_OP_SRC, src, NULL, copy, + 0, 0, 0, 0, 0, 0, w, h); + + wl_drag_icon_state.image = copy; + wl_drag_icon_state.width = w; + wl_drag_icon_state.height = h; + + /* Center the icon on the cursor */ + wl_drag_icon_state.offset_x = -w / 2; + wl_drag_icon_state.offset_y = -h / 2; + + /* Wrap in wlr_buffer using the existing frame_buf_impl */ + wlr_buffer_init(&wl_drag_icon_state.base, &frame_buf_impl, w, h); + + /* Create scene tree under overlay layer */ + struct wlr_scene_tree *parent = wl_state.level_trees[WL_LAYER_OVERLAY] + ? wl_state.level_trees[WL_LAYER_OVERLAY] : &wl_state.scene->tree; + wl_drag_icon_state.tree = wlr_scene_tree_create(parent); + if (!wl_drag_icon_state.tree) { + wl_drag_icon_destroy(); + return; + } + + wl_drag_icon_state.scene_buf = wlr_scene_buffer_create( + wl_drag_icon_state.tree, &wl_drag_icon_state.base); + if (!wl_drag_icon_state.scene_buf) { + wl_drag_icon_destroy(); + return; + } + + /* Position at cursor (centered) */ + wlr_scene_node_set_position(&wl_drag_icon_state.tree->node, + x + wl_drag_icon_state.offset_x, + y + wl_drag_icon_state.offset_y); +} + +void +wl_drag_icon_move(int x, int y) +{ + if (!wl_drag_icon_state.tree) + return; + wlr_scene_node_set_position(&wl_drag_icon_state.tree->node, + x + wl_drag_icon_state.offset_x, + y + wl_drag_icon_state.offset_y); +} + +void +wl_drag_icon_hide(void) +{ + wl_drag_icon_destroy(); +} + +void +wl_drag_cursor_feedback(Bool accepted) +{ + if (accepted) + wl_set_cursor_image("plus"); + else + wl_set_cursor_image("left_ptr"); +}