mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-26 18:22:09 +02:00
Wayland: Implement ridiculous workaround for broken dnd
Wayland is *the worst* window system I have ever had the displeasure of trying to support.
This commit is contained in:
2
glfw/glfw3.h
vendored
2
glfw/glfw3.h
vendored
@@ -4984,7 +4984,7 @@ GLFWAPI GLFWdragsourcefun glfwSetDragSourceCallback(GLFWwindow* window, GLFWdrag
|
||||
// Start a drag. If called with operations == -1 indicates that previously
|
||||
// requested data via GLFW_DRAG_DATA_REQUEST is ready. operations == -2 means
|
||||
// that the drag image is changed.
|
||||
GLFWAPI int glfwStartDrag(GLFWwindow* window, const GLFWDragSourceItem *items, size_t mime_count, const GLFWimage* thumbnail, int operations);
|
||||
GLFWAPI int glfwStartDrag(GLFWwindow* window, const GLFWDragSourceItem *items, size_t mime_count, const GLFWimage* thumbnail, int operations, bool needs_toplevel_on_wayland);
|
||||
|
||||
/*! @brief Returns whether the specified joystick is present.
|
||||
*
|
||||
|
||||
3
glfw/input.c
vendored
3
glfw/input.c
vendored
@@ -1161,7 +1161,7 @@ _glfwFreeDragSourceData(void) {
|
||||
}
|
||||
|
||||
GLFWAPI int
|
||||
glfwStartDrag(GLFWwindow* handle, const GLFWDragSourceItem *items, size_t item_count, const GLFWimage* thumbnail, int operations) {
|
||||
glfwStartDrag(GLFWwindow* handle, const GLFWDragSourceItem *items, size_t item_count, const GLFWimage* thumbnail, int operations, bool needs_toplevel_on_wayland) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(EINVAL);
|
||||
@@ -1188,6 +1188,7 @@ glfwStartDrag(GLFWwindow* handle, const GLFWDragSourceItem *items, size_t item_c
|
||||
}
|
||||
_glfw.drag.window_id = window->id;
|
||||
_glfw.drag.operations = operations;
|
||||
_glfw.drag.needs_toplevel_on_wayland = needs_toplevel_on_wayland;
|
||||
int ans = _glfwPlatformStartDrag(window, thumbnail);
|
||||
if (ans != 0) _glfwFreeDragSourceData();
|
||||
return ans;
|
||||
|
||||
1
glfw/internal.h
vendored
1
glfw/internal.h
vendored
@@ -668,6 +668,7 @@ struct _GLFWlibrary
|
||||
struct {
|
||||
GLFWDragSourceItem *items; size_t item_count;
|
||||
GLFWid window_id, instance_id; int operations;
|
||||
bool needs_toplevel_on_wayland;
|
||||
} drag;
|
||||
};
|
||||
|
||||
|
||||
2
glfw/wl_init.c
vendored
2
glfw/wl_init.c
vendored
@@ -789,7 +789,7 @@ get_compositor_missing_capabilities(void) {
|
||||
C(single_pixel_buffer, wp_single_pixel_buffer_manager_v1); C(preferred_scale, has_preferred_buffer_scale);
|
||||
C(idle_inhibit, idle_inhibit_manager); C(icon, xdg_toplevel_icon_manager_v1); C(bell, xdg_system_bell_v1);
|
||||
C(window-tag, xdg_toplevel_tag_manager_v1); C(keyboard_shortcuts_inhibit, keyboard_shortcuts_inhibit_manager);
|
||||
C(key-repeat, has_key_repeat_events);
|
||||
C(key-repeat, has_key_repeat_events); C(top_level_drag, xdg_toplevel_drag_manager_v1);
|
||||
#define P(x) p += snprintf(p, sizeof(buf) - (p - buf), "%s ", x);
|
||||
if (_glfw.wl.xdg_wm_base_version < 6) P("window-state-suspended");
|
||||
if (_glfw.wl.xdg_wm_base_version < 5) P("window-capabilities");
|
||||
|
||||
6
glfw/wl_window.c
vendored
6
glfw/wl_window.c
vendored
@@ -3325,8 +3325,8 @@ drag_source_cancelled(void *data UNUSED, struct wl_data_source *source UNUSED) {
|
||||
// Uber competent Wayland people contravene their own spec and make it
|
||||
// impossible to distinguish between drag cancelled and dropped but not
|
||||
// accepted. https://gitlab.freedesktop.org/wayland/wayland/-/issues/140
|
||||
// so we assume this is a drop. Sigh.
|
||||
cancel_drag(GLFW_DRAG_DROPPED);
|
||||
// so we assume this is a drop unless we are in top-level mode. Sigh.
|
||||
cancel_drag(_glfw.wl.drag.toplevel_xdg_toplevel ? GLFW_DRAG_CANCELLED : GLFW_DRAG_DROPPED);
|
||||
}
|
||||
|
||||
|
||||
@@ -3411,7 +3411,7 @@ _glfwPlatformStartDrag(_GLFWwindow* window, const GLFWimage* thumbnail) {
|
||||
wl_surface_set_buffer_scale(_glfw.wl.drag.drag_icon, scale);
|
||||
}
|
||||
|
||||
if (_glfw.wl.xdg_toplevel_drag_manager_v1) {
|
||||
if (_glfw.drag.needs_toplevel_on_wayland && _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;
|
||||
|
||||
Reference in New Issue
Block a user