Wayland: set drop accepted operations
This commit is contained in:
parent
7fd0475c20
commit
dc55052f0c
8 changed files with 48 additions and 13 deletions
1
glfw/glfw3.h
vendored
1
glfw/glfw3.h
vendored
|
|
@ -1407,6 +1407,7 @@ typedef struct GLFWDropEvent {
|
|||
// Positions are only valid for GLFW_DROP_ENTER and GLFW_DROP_MOVE.
|
||||
// They are in window co-ordinates same as for mouse events
|
||||
double xpos, ypos;
|
||||
struct { GLFWDragOperationType preferred; int allowed; } operation;
|
||||
bool from_self; // Only valid upto GLFW_DROP_DROP
|
||||
ssize_t (*read_data)(GLFWwindow *w, struct GLFWDropEvent* ev, char *buffer, size_t sz); // Only valid for GLFW_DROP_DATA_AVAILABLE
|
||||
void (*finish_drop)(GLFWwindow *w, GLFWDragOperationType op); // Only valid for GLFW_DROP_DROP and GLFW_DROP_DATA_AVAILABLE
|
||||
|
|
|
|||
2
glfw/input.c
vendored
2
glfw/input.c
vendored
|
|
@ -415,8 +415,10 @@ size_t _glfwInputDropEvent(_GLFWwindow *window, GLFWDropEventType type, double x
|
|||
.mimes=mimes, .type=type, .xpos=xpos, .ypos=ypos, .num_mimes=num_mimes, .from_self=from_self,
|
||||
.read_data=type == GLFW_DROP_DATA_AVAILABLE ? _glfwPlatformReadAvailableDropData : NULL,
|
||||
.finish_drop=type == GLFW_DROP_DATA_AVAILABLE || type == GLFW_DROP_DROP ? _glfwPlatformEndDrop : NULL,
|
||||
.operation.allowed = window->drop_operation.allowed, .operation.preferred = window->drop_operation.preferred,
|
||||
};
|
||||
window->callbacks.drop_event((GLFWwindow*)window, &ev);
|
||||
window->drop_operation.preferred = ev.operation.preferred; window->drop_operation.allowed = ev.operation.allowed;
|
||||
return ev.num_mimes;
|
||||
}
|
||||
|
||||
|
|
|
|||
1
glfw/internal.h
vendored
1
glfw/internal.h
vendored
|
|
@ -461,6 +461,7 @@ struct _GLFWwindow
|
|||
#else
|
||||
const bool swaps_disallowed;
|
||||
#endif
|
||||
struct { GLFWDragOperationType preferred; int allowed; } drop_operation;
|
||||
|
||||
struct {
|
||||
GLFWwindowposfun pos;
|
||||
|
|
|
|||
2
glfw/wl_platform.h
vendored
2
glfw/wl_platform.h
vendored
|
|
@ -314,6 +314,8 @@ typedef struct _GLFWWaylandDataOffer
|
|||
const char **copy_mimes; // Working copy passed to callbacks; pointers into mimes[]
|
||||
size_t copy_mimes_count; // Count of entries in copy_mimes (accepted count after callback)
|
||||
bool drag_accepted, dropped;
|
||||
enum wl_data_device_manager_dnd_action preferred;
|
||||
int allowed;
|
||||
uint32_t serial;
|
||||
struct {
|
||||
id_type watch_id;
|
||||
|
|
|
|||
20
glfw/wl_window.c
vendored
20
glfw/wl_window.c
vendored
|
|
@ -2510,14 +2510,25 @@ static void handle_primary_selection_offer(void *data UNUSED, struct zwp_primary
|
|||
|
||||
// Helper function to update drop state from callback results
|
||||
static void
|
||||
update_drop_state(_GLFWWaylandDataOffer *d, _GLFWwindow* window UNUSED, size_t accepted_count) {
|
||||
update_drop_state(_GLFWWaylandDataOffer *d, _GLFWwindow* window, size_t accepted_count) {
|
||||
d->copy_mimes_count = accepted_count;
|
||||
bool accepted = accepted_count > 0;
|
||||
bool acceptance_changed = (accepted != d->drag_accepted);
|
||||
// The first entry in the accepted (sorted) copy is the preferred MIME.
|
||||
const char* new_preferred_mime = (accepted && d->copy_mimes) ? d->copy_mimes[0] : NULL;
|
||||
bool mime_changed = false;
|
||||
|
||||
enum wl_data_device_manager_dnd_action preferred = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; int allowed = 0;
|
||||
if (accepted && window->drop_operation.allowed) {
|
||||
if (window->drop_operation.allowed & GLFW_DRAG_OPERATION_GENERIC) allowed |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
if (window->drop_operation.allowed & GLFW_DRAG_OPERATION_COPY) allowed |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
|
||||
if (window->drop_operation.allowed & GLFW_DRAG_OPERATION_MOVE) allowed |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
|
||||
switch (window->drop_operation.preferred) {
|
||||
case GLFW_DRAG_OPERATION_GENERIC: preferred = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; break;
|
||||
case GLFW_DRAG_OPERATION_COPY: preferred = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; break;
|
||||
case GLFW_DRAG_OPERATION_MOVE: preferred = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; break;
|
||||
case GLFW_DRAG_OPERATION_NONE: break;
|
||||
}
|
||||
}
|
||||
// Check if the preferred MIME changed
|
||||
if (d->mime_for_drop == NULL && new_preferred_mime != NULL) {
|
||||
mime_changed = true;
|
||||
|
|
@ -2526,11 +2537,14 @@ update_drop_state(_GLFWWaylandDataOffer *d, _GLFWwindow* window UNUSED, size_t a
|
|||
} else if (d->mime_for_drop != NULL && new_preferred_mime != NULL) {
|
||||
mime_changed = (strcmp(d->mime_for_drop, new_preferred_mime) != 0);
|
||||
}
|
||||
const bool op_changed = preferred != d->preferred || allowed != d->allowed;
|
||||
|
||||
if (acceptance_changed || mime_changed) {
|
||||
if (acceptance_changed || mime_changed || op_changed) {
|
||||
d->drag_accepted = accepted;
|
||||
d->mime_for_drop = new_preferred_mime;
|
||||
d->preferred = preferred; d->allowed = allowed;
|
||||
wl_data_offer_accept(d->id, d->serial, d->mime_for_drop);
|
||||
wl_data_offer_set_actions(d->id, d->allowed, d->preferred);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
14
kitty/dnd.c
14
kitty/dnd.c
|
|
@ -305,10 +305,11 @@ drop_move_on_child(Window *w, const char** mimes, size_t num_mimes, bool is_drop
|
|||
void
|
||||
drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz, bool more) {
|
||||
if (!w->drop.accept_in_progress) {
|
||||
drop_free_accepted_mimes(w); w->drop.accept_in_progress = true; w->drop.accepted_operation = 0;
|
||||
drop_free_accepted_mimes(w); w->drop.accept_in_progress = true;
|
||||
switch(operation) {
|
||||
case 1: case 2: w->drop.accepted_operation = operation; break;
|
||||
default: w->drop.accepted_operation = 0; break;
|
||||
case 1: w->drop.accepted_operation = GLFW_DRAG_OPERATION_COPY; break;
|
||||
case 2: w->drop.accepted_operation = GLFW_DRAG_OPERATION_MOVE; break;
|
||||
default: w->drop.accepted_operation = GLFW_DRAG_OPERATION_NONE; break;
|
||||
}
|
||||
}
|
||||
if (payload_sz) {
|
||||
|
|
@ -335,17 +336,14 @@ void
|
|||
drop_finish(Window *w) {
|
||||
OSWindow *osw = os_window_for_kitty_window(w->id);
|
||||
if (osw && osw->handle) {
|
||||
int op = GLFW_DRAG_OPERATION_GENERIC;
|
||||
if (w->drop.accepted_operation == 1) op = GLFW_DRAG_OPERATION_COPY;
|
||||
else if (w->drop.accepted_operation == 2) op = GLFW_DRAG_OPERATION_MOVE;
|
||||
glfwEndDrop(osw->handle, op);
|
||||
glfwEndDrop(osw->handle, w->drop.accepted_operation);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
drop_update_mimes(Window *w, const char **allowed_mimes, size_t allowed_mimes_count) {
|
||||
if (w->drop.accept_in_progress) return allowed_mimes_count;
|
||||
if (!w->drop.accepted_operation) return 0;
|
||||
if (w->drop.accepted_operation == GLFW_DRAG_OPERATION_NONE) return 0;
|
||||
typedef struct mime_sorter { const char *m; ssize_t key; } mime_sorter;
|
||||
if (!w->drop.accepted_mimes) return allowed_mimes_count;
|
||||
RAII_ALLOC(mime_sorter, ms, malloc(sizeof(mime_sorter) * allowed_mimes_count));
|
||||
|
|
|
|||
1
kitty/glfw-wrapper.h
generated
1
kitty/glfw-wrapper.h
generated
|
|
@ -1135,6 +1135,7 @@ typedef struct GLFWDropEvent {
|
|||
// Positions are only valid for GLFW_DROP_ENTER and GLFW_DROP_MOVE.
|
||||
// They are in window co-ordinates same as for mouse events
|
||||
double xpos, ypos;
|
||||
struct { GLFWDragOperationType preferred; int allowed; } operation;
|
||||
bool from_self; // Only valid upto GLFW_DROP_DROP
|
||||
ssize_t (*read_data)(GLFWwindow *w, struct GLFWDropEvent* ev, char *buffer, size_t sz); // Only valid for GLFW_DROP_DATA_AVAILABLE
|
||||
void (*finish_drop)(GLFWwindow *w, GLFWDragOperationType op); // Only valid for GLFW_DROP_DROP and GLFW_DROP_DATA_AVAILABLE
|
||||
|
|
|
|||
20
kitty/glfw.c
20
kitty/glfw.c
|
|
@ -801,8 +801,11 @@ on_drop(GLFWwindow *window, GLFWDropEvent *ev) {
|
|||
os_window->last_drag_event.y = (int)(ev->ypos * os_window->viewport_y_ratio);
|
||||
on_mouse_position_update(ev->xpos, ev->ypos);
|
||||
if (is_client_drop) {
|
||||
if (ev->type == GLFW_DROP_ENTER) w->drop.accepted_operation = GLFW_DRAG_OPERATION_COPY;
|
||||
drop_move_on_child(w, ev->mimes, ev->num_mimes, false);
|
||||
ev->num_mimes = drop_update_mimes(w, ev->mimes, ev->num_mimes);
|
||||
ev->operation.allowed = w->drop.accepted_operation;
|
||||
ev->operation.preferred = w->drop.accepted_operation;
|
||||
return;
|
||||
}
|
||||
call_boss(on_drop_move, "KiiOO",
|
||||
|
|
@ -810,8 +813,21 @@ on_drop(GLFWwindow *window, GLFWDropEvent *ev) {
|
|||
ev->from_self ? Py_True : Py_False, Py_False);
|
||||
/* fallthrough */
|
||||
case GLFW_DROP_STATUS_UPDATE:
|
||||
if (is_client_drop) ev->num_mimes = drop_update_mimes(w, ev->mimes, ev->num_mimes);
|
||||
else update_allowed_mimes_for_drop(ev);
|
||||
if (is_client_drop) {
|
||||
ev->num_mimes = drop_update_mimes(w, ev->mimes, ev->num_mimes);
|
||||
ev->operation.allowed = w->drop.accepted_operation;
|
||||
ev->operation.preferred = w->drop.accepted_operation;
|
||||
} else {
|
||||
update_allowed_mimes_for_drop(ev);
|
||||
if (ev->num_mimes == 0) zero_at_ptr(&ev->operation);
|
||||
else if (is_kitty_ui_drag) {
|
||||
ev->operation.preferred = GLFW_DRAG_OPERATION_MOVE;
|
||||
ev->operation.allowed = GLFW_DRAG_OPERATION_MOVE;
|
||||
} else {
|
||||
ev->operation.preferred = GLFW_DRAG_OPERATION_MOVE;
|
||||
ev->operation.allowed = GLFW_DRAG_OPERATION_MOVE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GLFW_DROP_LEAVE:
|
||||
for (size_t tc = 0; tc < os_window->num_tabs; tc++) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue