diff --git a/kitty/dnd.c b/kitty/dnd.c index df56aad42..c1bf7d7f6 100644 --- a/kitty/dnd.c +++ b/kitty/dnd.c @@ -18,13 +18,17 @@ #include #include -static const size_t MIME_LIST_SIZE_CAP = 1024 * 1024; -static const size_t PRESENT_DATA_CAP = 64 * 1024 * 1024; +#define DEFAULT_MIME_LIST_SIZE_CAP 1024u * 1024u +static size_t MIME_LIST_SIZE_CAP = DEFAULT_MIME_LIST_SIZE_CAP; +#define DEFAULT_PRESENT_DATA_CAP 64 * 1024 * 1024 +static size_t PRESENT_DATA_CAP = DEFAULT_PRESENT_DATA_CAP; +#define DEFAULT_REMOTE_DRAG_LIMIT 1024 * 1024 * 1024 +static size_t REMOTE_DRAG_LIMIT = DEFAULT_REMOTE_DRAG_LIMIT; +static PyObject *g_dnd_test_write_func = NULL; // Utils {{{ // In test mode, this callable is invoked instead of schedule_write_to_child_if_possible. // It receives (window_id: int, data: bytes) and its return value is ignored. -static PyObject *g_dnd_test_write_func = NULL; static void drop_process_queue(Window *w); static void drop_pop_request(Window *w); @@ -157,10 +161,13 @@ sanitized_filename_from_url(const char *url) { void -dnd_set_test_write_func(PyObject *func) { +dnd_set_test_write_func(PyObject *func, size_t mime_list_size_cap, size_t present_data_cap, size_t remote_drag_limit) { (void)machine_id; - Py_XDECREF(g_dnd_test_write_func); + Py_CLEAR(g_dnd_test_write_func); g_dnd_test_write_func = Py_XNewRef(func); + MIME_LIST_SIZE_CAP = mime_list_size_cap ? mime_list_size_cap : DEFAULT_MIME_LIST_SIZE_CAP; + PRESENT_DATA_CAP = present_data_cap ? present_data_cap : DEFAULT_PRESENT_DATA_CAP; + REMOTE_DRAG_LIMIT = remote_drag_limit ? remote_drag_limit : DEFAULT_REMOTE_DRAG_LIMIT; } static int @@ -1698,7 +1705,6 @@ finish_remote_data(Window *w, size_t item_idx) { } #define mi ds.items[mime_item_idx] -static size_t REMOTE_DRAG_LIMIT = 1024 * 1024 * 1024; static void populate_dir_entries(Window *w, DragRemoteItem *ri) { @@ -1736,7 +1742,7 @@ add_payload(Window *w, DragRemoteItem *ri, bool has_more, const uint8_t *payload default: { if (ri->data_sz + payload_sz > ri->data_capacity) { size_t cap = MAX(ri->data_capacity * 2, ri->data_sz + payload_sz + 4096); - if (cap > 10 * 1024) abrt(EMFILE); + if (cap > PRESENT_DATA_CAP) abrt(EMFILE); ri->data = realloc(ri->data, cap); if (!ri->data) abrt(ENOMEM); ri->data_capacity = cap; diff --git a/kitty/dnd.h b/kitty/dnd.h index 0c355320e..bcf1a0210 100644 --- a/kitty/dnd.h +++ b/kitty/dnd.h @@ -21,7 +21,7 @@ void drop_set_status(Window *w, int operation, const char *payload, size_t paylo size_t drop_update_mimes(Window *w, const char **allowed_mimes, size_t allowed_mimes_count); void drop_dispatch_data(Window *w, const char *mime_type, const char *data, ssize_t sz); void drop_finish(Window *w); -void dnd_set_test_write_func(PyObject *func); +void dnd_set_test_write_func(PyObject*, size_t, size_t, size_t); typedef enum { DRAG_NOTIFY_ACCEPTED, DRAG_NOTIFY_ACTION_CHANGED, DRAG_NOTIFY_DROPPED, DRAG_NOTIFY_FINISHED } DragNotifyType; diff --git a/kitty/glfw.c b/kitty/glfw.c index 8cc092c05..3ba1add98 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -898,9 +898,11 @@ request_drop_status_update(OSWindow *osw) { // DnD testing infrastructure {{{ static PyObject * -py_dnd_set_test_write_func(PyObject *self UNUSED, PyObject *func) { +py_dnd_set_test_write_func(PyObject *self UNUSED, PyObject *args) { + PyObject *func = Py_None; unsigned mime_list_size_cap = 0, present_data_cap = 0, remote_drag_limit = 0; + if (!PyArg_ParseTuple(args, "|OIII", &func, &mime_list_size_cap, &present_data_cap, &remote_drag_limit)) return NULL; // Pass None to clear the interceptor and restore normal operation. - dnd_set_test_write_func(func == Py_None ? NULL : func); + dnd_set_test_write_func(func == Py_None ? NULL : func, mime_list_size_cap, present_data_cap, remote_drag_limit); Py_RETURN_NONE; } @@ -3355,7 +3357,7 @@ static PyMethodDef module_methods[] = { {"glfw_get_monitor_workarea", (PyCFunction)get_monitor_workarea, METH_NOARGS, ""}, {"glfw_get_monitor_names", (PyCFunction)get_monitor_names, METH_NOARGS, ""}, {"glfw_primary_monitor_content_scale", (PyCFunction)primary_monitor_content_scale, METH_NOARGS, ""}, - {"dnd_set_test_write_func", (PyCFunction)py_dnd_set_test_write_func, METH_O, ""}, + {"dnd_set_test_write_func", (PyCFunction)py_dnd_set_test_write_func, METH_VARARGS, ""}, METHODB(dnd_test_create_fake_window, METH_NOARGS), METHODB(dnd_test_cleanup_fake_window, METH_VARARGS), METHODB(dnd_test_set_mouse_pos, METH_VARARGS),