Cleanup previous PR
Use a single wl_surface for the drag icon. Whther it is attached to the top level drag or not is determined based on availability.
This commit is contained in:
parent
accee908aa
commit
b737eaad65
10 changed files with 54 additions and 67 deletions
|
|
@ -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);
|
||||
|
|
|
|||
2
glfw/input.c
vendored
2
glfw/input.c
vendored
|
|
@ -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;
|
||||
|
|
|
|||
2
glfw/internal.h
vendored
2
glfw/internal.h
vendored
|
|
@ -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);
|
||||
|
|
|
|||
2
glfw/null_window.c
vendored
2
glfw/null_window.c
vendored
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
1
glfw/wl_platform.h
vendored
1
glfw/wl_platform.h
vendored
|
|
@ -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;
|
||||
|
|
|
|||
99
glfw/wl_window.c
vendored
99
glfw/wl_window.c
vendored
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
3
glfw/x11_window.c
vendored
3
glfw/x11_window.c
vendored
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]: ...
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue