mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-05 23:51:29 +02:00
Yet another workaround for Wayland's awful design
This commit is contained in:
1
glfw/glfw3.h
vendored
1
glfw/glfw3.h
vendored
@@ -1840,6 +1840,7 @@ typedef struct GLFWDragEvent {
|
||||
const char *data; size_t data_sz;
|
||||
int err_num; // POSIX error code indicating failure fetching data
|
||||
GLFWDragOperationType action; // can be 0 indicating no action
|
||||
bool drop_maybe_a_cancel; // Happens on wayland compositors that dont implement top-level drag
|
||||
} GLFWDragEvent;
|
||||
|
||||
typedef void (* GLFWdragsourcefun)(GLFWwindow* window, GLFWDragEvent *ev);
|
||||
|
||||
16
glfw/wl_window.c
vendored
16
glfw/wl_window.c
vendored
@@ -3190,15 +3190,17 @@ static const struct xdg_toplevel_listener drag_toplevel_listener = {
|
||||
};
|
||||
|
||||
static void
|
||||
cancel_drag(GLFWDragEventType type) {
|
||||
cancel_drag2(GLFWDragEventType type, bool maybe_a_cancel) {
|
||||
_GLFWwindow *window = _glfwWindowForId(_glfw.drag.window_id);
|
||||
if (window) {
|
||||
GLFWDragEvent ev = {.type=type};
|
||||
GLFWDragEvent ev = {.type=type, .drop_maybe_a_cancel=maybe_a_cancel};
|
||||
_glfwInputDragSourceRequest(window, &ev);
|
||||
}
|
||||
_glfwFreeDragSourceData();
|
||||
}
|
||||
|
||||
static void cancel_drag(GLFWDragEventType type) { cancel_drag2(type, false); }
|
||||
|
||||
#define dr _glfw.wl.drag.data_requests[i]
|
||||
|
||||
static void
|
||||
@@ -3424,9 +3426,13 @@ drag_source_cancelled(void *data UNUSED, struct wl_data_source *source UNUSED) {
|
||||
// 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 unless we are in top-level mode. Sigh.
|
||||
const GLFWDragEventType t = _glfw.wl.drag.toplevel_xdg_toplevel ? GLFW_DRAG_CANCELLED : GLFW_DRAG_DROPPED;
|
||||
debug_input("Drag source cancelled: is_drop: %d\n", t == GLFW_DRAG_DROPPED);
|
||||
cancel_drag(t);
|
||||
if (_glfw.wl.drag.toplevel_xdg_toplevel) {
|
||||
debug_input("Drag source cancelled\n");
|
||||
cancel_drag(GLFW_DRAG_CANCELLED);
|
||||
} else {
|
||||
debug_input("Drag source cancelled or dropped on something that doesnt accept it\n");
|
||||
cancel_drag2(GLFW_DRAG_DROPPED, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
kitty/glfw-wrapper.h
generated
1
kitty/glfw-wrapper.h
generated
@@ -1568,6 +1568,7 @@ typedef struct GLFWDragEvent {
|
||||
const char *data; size_t data_sz;
|
||||
int err_num; // POSIX error code indicating failure fetching data
|
||||
GLFWDragOperationType action; // can be 0 indicating no action
|
||||
bool drop_maybe_a_cancel; // Happens on wayland compositors that dont implement top-level drag
|
||||
} GLFWDragEvent;
|
||||
|
||||
typedef void (* GLFWdragsourcefun)(GLFWwindow* window, GLFWDragEvent *ev);
|
||||
|
||||
@@ -943,8 +943,14 @@ drag_source_callback(GLFWwindow *window UNUSED, GLFWDragEvent *ev) {
|
||||
if (ds.from_window && (w = window_for_window_id(ds.from_window)) && w->drag_source.state) {
|
||||
is_client_drag = true;
|
||||
}
|
||||
// On Wayland, wen compositor doesnt support top level drag protocol we get
|
||||
// a drop event for what is either a cancel or a drop on something that
|
||||
// does not accept the drop. In both of these cases we need to send the
|
||||
// client a drop cancel.
|
||||
GLFWDragEventType t = ev->type;
|
||||
if (is_client_drag && ev->drop_maybe_a_cancel) t = GLFW_DRAG_CANCELLED;
|
||||
|
||||
switch (ev->type) {
|
||||
switch (t) {
|
||||
case GLFW_DRAG_DATA_REQUEST:
|
||||
if (is_client_drag) {
|
||||
ev->err_num = 0;
|
||||
|
||||
Reference in New Issue
Block a user