diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 54b214082..36536c6c1 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -4214,7 +4214,7 @@ - (void)filePromiseProvider:(NSFilePromiseProvider*)filePromiseProvider } int -_glfwPlatformChangeDragImage(const GLFWimage *thumbnail, int make_toplevel) {@autoreleasepool{ +_glfwPlatformChangeDragImage(const GLFWimage *thumbnail) {@autoreleasepool{ (void)make_toplevel; if (!_glfw.ns.drag_session || !_glfw.ns.drag_view) return 0; _GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id); diff --git a/glfw/input.c b/glfw/input.c index 3a03e505f..0518a39dc 100644 --- a/glfw/input.c +++ b/glfw/input.c @@ -1166,7 +1166,7 @@ glfwStartDrag(GLFWwindow* handle, const GLFWDragSourceItem *items, size_t item_c assert(window != NULL); _GLFW_REQUIRE_INIT_OR_RETURN(EINVAL); if (operations == -1) return _glfwPlatformDragDataReady(items[0].mime_type); - if (operations == -2) return _glfwPlatformChangeDragImage(thumbnail, item_count); + if (operations == -2) return _glfwPlatformChangeDragImage(thumbnail); _glfwFreeDragSourceData(); _glfw.drag.instance_id++; if (!items || !item_count) return 0; diff --git a/glfw/internal.h b/glfw/internal.h index b377e3ef7..d7e58e50a 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -837,7 +837,7 @@ void _glfwFreeDragSourceData(void); void _glfwPlatformFreeDragSourceData(void); void _glfwInputDragSourceRequest(_GLFWwindow* window, GLFWDragEvent *ev); int _glfwPlatformDragDataReady(const char *mime_type); -int _glfwPlatformChangeDragImage(const GLFWimage *thumbnail, int make_toplevel); +int _glfwPlatformChangeDragImage(const GLFWimage *thumbnail); void _glfwInputColorScheme(GLFWColorScheme, bool); diff --git a/glfw/null_window.c b/glfw/null_window.c index 675332f34..b46279c9d 100644 --- a/glfw/null_window.c +++ b/glfw/null_window.c @@ -542,7 +542,7 @@ _glfwPlatformStartDrag(_GLFWwindow* window, const GLFWimage* thumbnail) { } void _glfwPlatformFreeDragSourceData(void) {} int _glfwPlatformDragDataReady(const char *mime_type) { (void) mime_type; return 0; } -int _glfwPlatformChangeDragImage(const GLFWimage *thumbnail, int make_toplevel) { (void)thumbnail; (void)make_toplevel; return 0; } +int _glfwPlatformChangeDragImage(const GLFWimage *thumbnail) { (void)thumbnail; return 0; } const char** _glfwPlatformGetDropMimeTypes(GLFWDropData* drop UNUSED, int* count) { diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 0d6c2e929..930076ea5 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -418,7 +418,6 @@ typedef struct _GLFWlibraryWayland struct wl_surface *drag_icon; struct wp_viewport *drag_viewport; struct xdg_toplevel_drag_v1 *toplevel_drag; - struct wl_surface *toplevel_surface; struct xdg_surface *toplevel_xdg_surface; struct xdg_toplevel *toplevel_xdg_toplevel; struct wl_buffer *toplevel_buffer; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index efc9e5ba6..989ca8167 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -3083,12 +3083,12 @@ static void drag_toplevel_xdg_surface_configure(void *data UNUSED, struct xdg_surface *surface, uint32_t serial) { xdg_surface_ack_configure(surface, serial); if (_glfw.wl.drag.toplevel_buffer) { - wl_surface_attach(_glfw.wl.drag.toplevel_surface, _glfw.wl.drag.toplevel_buffer, 0, 0); - wl_surface_damage(_glfw.wl.drag.toplevel_surface, 0, 0, INT32_MAX, INT32_MAX); + wl_surface_attach(_glfw.wl.drag.drag_icon, _glfw.wl.drag.toplevel_buffer, 0, 0); + wl_surface_damage(_glfw.wl.drag.drag_icon, 0, 0, INT32_MAX, INT32_MAX); wl_buffer_destroy(_glfw.wl.drag.toplevel_buffer); _glfw.wl.drag.toplevel_buffer = NULL; } - if (_glfw.wl.drag.toplevel_surface) wl_surface_commit(_glfw.wl.drag.toplevel_surface); + if (_glfw.wl.drag.drag_icon) wl_surface_commit(_glfw.wl.drag.drag_icon); } static const struct xdg_surface_listener drag_toplevel_xdg_surface_listener = { @@ -3226,30 +3226,8 @@ add_drag_watch(int fd) { } int -_glfwPlatformChangeDragImage(const GLFWimage *thumbnail, int make_toplevel) { - if (make_toplevel && _glfw.wl.drag.toplevel_drag && !_glfw.wl.drag.toplevel_surface - && _glfw.wl.wmBase && thumbnail && thumbnail->pixels) { - _glfw.wl.drag.toplevel_surface = wl_compositor_create_surface(_glfw.wl.compositor); - if (_glfw.wl.drag.toplevel_surface) { - _glfw.wl.drag.toplevel_xdg_surface = xdg_wm_base_get_xdg_surface( - _glfw.wl.wmBase, _glfw.wl.drag.toplevel_surface); - if (_glfw.wl.drag.toplevel_xdg_surface) { - xdg_surface_add_listener(_glfw.wl.drag.toplevel_xdg_surface, - &drag_toplevel_xdg_surface_listener, NULL); - _glfw.wl.drag.toplevel_xdg_toplevel = xdg_surface_get_toplevel( - _glfw.wl.drag.toplevel_xdg_surface); - if (_glfw.wl.drag.toplevel_xdg_toplevel) { - xdg_toplevel_add_listener(_glfw.wl.drag.toplevel_xdg_toplevel, - &drag_toplevel_listener, NULL); - _glfw.wl.drag.toplevel_buffer = createShmBuffer(thumbnail, false, true); - xdg_toplevel_drag_v1_attach(_glfw.wl.drag.toplevel_drag, - _glfw.wl.drag.toplevel_xdg_toplevel, 0, 0); - wl_surface_commit(_glfw.wl.drag.toplevel_surface); - } - } - } - } - if (!_glfw.wl.drag.drag_icon || !thumbnail || !thumbnail->pixels) return 0; +_glfwPlatformChangeDragImage(const GLFWimage *thumbnail) { + if (!thumbnail || !thumbnail->pixels) return 0; struct wl_buffer* icon_buffer = createShmBuffer(thumbnail, false, true); if (!icon_buffer) return ENOMEM; _GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id); @@ -3364,12 +3342,11 @@ static const struct wl_data_source_listener drag_source_listener = { void _glfwPlatformFreeDragSourceData(void) { if (_glfw.wl.drag.drag_viewport) wp_viewport_destroy(_glfw.wl.drag.drag_viewport); - if (_glfw.wl.drag.drag_icon) wl_surface_destroy(_glfw.wl.drag.drag_icon); if (_glfw.wl.drag.toplevel_drag) xdg_toplevel_drag_v1_destroy(_glfw.wl.drag.toplevel_drag); if (_glfw.wl.drag.toplevel_buffer) wl_buffer_destroy(_glfw.wl.drag.toplevel_buffer); if (_glfw.wl.drag.toplevel_xdg_toplevel) xdg_toplevel_destroy(_glfw.wl.drag.toplevel_xdg_toplevel); if (_glfw.wl.drag.toplevel_xdg_surface) xdg_surface_destroy(_glfw.wl.drag.toplevel_xdg_surface); - if (_glfw.wl.drag.toplevel_surface) wl_surface_destroy(_glfw.wl.drag.toplevel_surface); + if (_glfw.wl.drag.drag_icon) wl_surface_destroy(_glfw.wl.drag.drag_icon); if (_glfw.wl.drag.source) wl_data_source_destroy(_glfw.wl.drag.source); if (_glfw.wl.drag.data_requests) { for (size_t i = 0; i < _glfw.wl.drag.count; i++) { @@ -3416,37 +3393,49 @@ _glfwPlatformStartDrag(_GLFWwindow* window, const GLFWimage* thumbnail) { wl_data_source_add_listener(_glfw.wl.drag.source, &drag_source_listener, NULL); // Set up the drag icon surface if thumbnail is provided - _glfw.wl.drag.drag_icon = wl_compositor_create_surface(_glfw.wl.compositor); if (thumbnail && thumbnail->pixels) { + _glfw.wl.drag.drag_icon = wl_compositor_create_surface(_glfw.wl.compositor); + if (!_glfw.wl.drag.drag_icon) return ENOMEM; struct wl_buffer* icon_buffer = NULL; - if (_glfw.wl.drag.drag_icon) { - icon_buffer = createShmBuffer(thumbnail, false, true); - if (icon_buffer) { - if (_glfw.wl.wp_viewporter) { - double f_scale = _glfwWaylandWindowScale(window); - int logical_width = (int)(thumbnail->width / f_scale); - int logical_height = (int)(thumbnail->height / f_scale); - _glfw.wl.drag.drag_viewport = wp_viewporter_get_viewport( - _glfw.wl.wp_viewporter, _glfw.wl.drag.drag_icon); - wp_viewport_set_destination(_glfw.wl.drag.drag_viewport, logical_width, logical_height); - } else { - int scale = _glfwWaylandIntegerWindowScale(window); - wl_surface_set_buffer_scale(_glfw.wl.drag.drag_icon, scale); - } - wl_surface_attach(_glfw.wl.drag.drag_icon, icon_buffer, 0, 0); - wl_surface_commit(_glfw.wl.drag.drag_icon); - wl_buffer_destroy(icon_buffer); - } + icon_buffer = createShmBuffer(thumbnail, false, true); + if (!icon_buffer) return ENOMEM; + if (_glfw.wl.wp_viewporter) { + double f_scale = _glfwWaylandWindowScale(window); + int logical_width = (int)(thumbnail->width / f_scale); + int logical_height = (int)(thumbnail->height / f_scale); + _glfw.wl.drag.drag_viewport = wp_viewporter_get_viewport( + _glfw.wl.wp_viewporter, _glfw.wl.drag.drag_icon); + wp_viewport_set_destination(_glfw.wl.drag.drag_viewport, logical_width, logical_height); + } else { + int scale = _glfwWaylandIntegerWindowScale(window); + wl_surface_set_buffer_scale(_glfw.wl.drag.drag_icon, scale); } - } - // Create xdg_toplevel_drag_v1 before starting the drag (must precede start_drag) - if (_glfw.wl.xdg_toplevel_drag_manager_v1) { - _glfw.wl.drag.toplevel_drag = xdg_toplevel_drag_manager_v1_get_xdg_toplevel_drag( - _glfw.wl.xdg_toplevel_drag_manager_v1, _glfw.wl.drag.source); + + if (_glfw.wl.xdg_toplevel_drag_manager_v1) { + _glfw.wl.drag.toplevel_drag = xdg_toplevel_drag_manager_v1_get_xdg_toplevel_drag( + _glfw.wl.xdg_toplevel_drag_manager_v1, _glfw.wl.drag.source); + if (!_glfw.wl.drag.toplevel_drag) return ENOMEM; + _glfw.wl.drag.toplevel_xdg_surface = xdg_wm_base_get_xdg_surface( + _glfw.wl.wmBase, _glfw.wl.drag.drag_icon); + if (!_glfw.wl.drag.toplevel_xdg_surface) return ENOMEM; + xdg_surface_add_listener(_glfw.wl.drag.toplevel_xdg_surface, + &drag_toplevel_xdg_surface_listener, NULL); + _glfw.wl.drag.toplevel_xdg_toplevel = xdg_surface_get_toplevel( + _glfw.wl.drag.toplevel_xdg_surface); + if (!_glfw.wl.drag.toplevel_xdg_toplevel) return ENOMEM; + xdg_toplevel_add_listener(_glfw.wl.drag.toplevel_xdg_toplevel, &drag_toplevel_listener, NULL); + _glfw.wl.drag.toplevel_buffer = icon_buffer; icon_buffer = NULL; + xdg_toplevel_drag_v1_attach(_glfw.wl.drag.toplevel_drag, + _glfw.wl.drag.toplevel_xdg_toplevel, 0, 0); + } else wl_surface_attach(_glfw.wl.drag.drag_icon, icon_buffer, 0, 0); + wl_surface_commit(_glfw.wl.drag.drag_icon); + if (icon_buffer) wl_buffer_destroy(icon_buffer); } // Start the drag operation - wl_data_device_start_drag(_glfw.wl.dataDevice, _glfw.wl.drag.source, window->wl.surface, _glfw.wl.drag.drag_icon, - _glfw.wl.pointer_serial); + wl_data_device_start_drag( + _glfw.wl.dataDevice, _glfw.wl.drag.source, window->wl.surface, + _glfw.wl.xdg_toplevel_drag_manager_v1 ? NULL : _glfw.wl.drag.drag_icon, + _glfw.wl.pointer_serial); return 0; } diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 4ced436db..5d52d5e91 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -4471,8 +4471,7 @@ _glfwPlatformFreeDragSourceData(void) { } int -_glfwPlatformChangeDragImage(const GLFWimage *thumbnail, int make_toplevel) { - (void)make_toplevel; +_glfwPlatformChangeDragImage(const GLFWimage *thumbnail) { if (!_glfw.x11.drag.active) return 0; if (!thumbnail || !thumbnail->pixels || thumbnail->width <= 0 || thumbnail->height <= 0) return 0; diff --git a/kitty/boss.py b/kitty/boss.py index f3a4a02e1..480b010b2 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -1902,7 +1902,7 @@ def on_drop_move(self, os_window_id: int, x: int, y: int, from_self: bool, is_le central, tab_bar = viewport_for_window(os_window_id)[:2] in_tab_bar = tab_bar.left <= x < tab_bar.right and tab_bar.top <= y < tab_bar.bottom detach = not in_tab_bar or tab.os_window_id != tm.os_window_id or is_leave - change_drag_thumbnail(tab.os_window_id, 1 if detach else 0, detach) + change_drag_thumbnail(tab.os_window_id, 1 if detach else 0) for q in self.all_tab_managers: is_dest = q is tm and (in_tab_bar or os_window_id != tab.os_window_id) and not is_leave q.on_tab_drop_move(tab_id, is_dest, x, y) diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 98eb19bfb..d69c105dc 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1817,7 +1817,7 @@ def start_drag_with_data( os_window_id: int, data_map: dict[str, bytes], thumbnails: Sequence[tuple[bytes, int, int]], operations: int = GLFW_DRAG_OPERATION_MOVE ) -> None: ... -def change_drag_thumbnail(os_window_id: int, idx: int = -1, make_toplevel: bool = False) -> None: ... +def change_drag_thumbnail(os_window_id: int, idx: int = -1) -> None: ... def draw_single_line_of_text(os_window_id: int, text: str, fg: int, bg: int, width: int, padding_y: int = 2) -> bytes: ... def set_tab_being_dragged(tab_id: int = 0, drag_started: bool = False, x: float = 0, y: float = 0) -> None: ... def get_tab_being_dragged() -> tuple[int, bool, float, float]: ... diff --git a/kitty/glfw.c b/kitty/glfw.c index 94e043f39..d7bc8a9da 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -2802,8 +2802,8 @@ get_thumbnail(PyObject *thumbnails, GLFWimage *thumbnail, int idx) { static PyObject* change_drag_thumbnail(PyObject *self UNUSED, PyObject *args) { - unsigned long long os_window_id; int idx = -1; int make_toplevel = 0; - if (!PyArg_ParseTuple(args, "K|ip", &os_window_id, &idx, &make_toplevel)) return NULL; + unsigned long long os_window_id; int idx = -1; + if (!PyArg_ParseTuple(args, "K|i", &os_window_id, &idx)) return NULL; if (global_state.drag_source.thumbnail_idx == idx) Py_RETURN_NONE; OSWindow *w = os_window_for_id(os_window_id); if (!w || !w->handle) { PyErr_SetString(PyExc_KeyError, "OS Window with specified id does not exist"); return NULL; } @@ -2812,7 +2812,7 @@ change_drag_thumbnail(PyObject *self UNUSED, PyObject *args) { if (!get_thumbnail(global_state.drag_source.thumbnails, &thumbnail, idx)) return NULL; global_state.drag_source.thumbnail_idx = idx; } else global_state.drag_source.thumbnail_idx = -1; - errno = glfwStartDrag(w->handle, NULL, make_toplevel, thumbnail.pixels ? &thumbnail : NULL, -2); + errno = glfwStartDrag(w->handle, NULL, 0, thumbnail.pixels ? &thumbnail : NULL, -2); if (errno != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL;