mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-09-16 00:18:38 +00:00
Wayland: Workaround clipboard managers that restore application private MIME types. Fixes #10376
This commit is contained in:
parent
9b29654e90
commit
2db805c71e
3 changed files with 28 additions and 9 deletions
|
|
@ -226,7 +226,7 @@ Detailed list of changes
|
|||
|
||||
- Sessions: Also save/restore layouts other than the currently active layout (:pull:`10324`)
|
||||
|
||||
- Wayland: Fix clipboard sharing between kitty instances in containers with isolated PID namespaces (:iss:`10352`)
|
||||
- Wayland: Fix clipboard sharing between kitty instances in containers with isolated PID namespaces and stale paste data when used with clipboard managers that restore application private MIME types (:iss:`10352`, :iss:`10376`)
|
||||
|
||||
- When expanding a window in alternate screen mode use the most common
|
||||
background color as the color for the newly created lines leading to less
|
||||
|
|
|
|||
2
glfw/wl_platform.h
vendored
2
glfw/wl_platform.h
vendored
|
|
@ -353,6 +353,8 @@ typedef struct _GLFWlibraryWayland {
|
|||
struct zwp_primary_selection_device_manager_v1 *primarySelectionDeviceManager;
|
||||
struct zwp_primary_selection_device_v1 *primarySelectionDevice;
|
||||
struct zwp_primary_selection_source_v1 *dataSourceForPrimarySelection;
|
||||
char clipboard_copy_mime[256];
|
||||
char primary_selection_copy_mime[256];
|
||||
struct xdg_activation_v1 *xdg_activation_v1;
|
||||
struct xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager_v1;
|
||||
struct xdg_system_bell_v1 *xdg_system_bell_v1;
|
||||
|
|
|
|||
33
glfw/wl_window.c
vendored
33
glfw/wl_window.c
vendored
|
|
@ -439,12 +439,27 @@ _glfwWaylandAfterBufferSwap(_GLFWwindow *window) {
|
|||
}
|
||||
|
||||
static const char *
|
||||
clipboard_mime(void) {
|
||||
clipboard_mime_prefix(void) {
|
||||
static char buf[256] = {0};
|
||||
if (buf[0] == 0) { snprintf(buf, sizeof(buf), "application/glfw+clipboard-%d-%lld", getpid(), (long long)monotonic_start_time); }
|
||||
if (buf[0] == 0) { snprintf(buf, sizeof(buf), "application/glfw+clipboard-%d-%lld-", getpid(), (long long)monotonic_start_time); }
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_our_clipboard_mime(const char *mime) {
|
||||
const char *prefix = clipboard_mime_prefix();
|
||||
return strncmp(mime, prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
update_copy_mime(GLFWClipboardType t) {
|
||||
static uint64_t copy_id = 0;
|
||||
copy_id++;
|
||||
const char *prefix = clipboard_mime_prefix();
|
||||
char *buf = (t == GLFW_CLIPBOARD) ? _glfw.wl.clipboard_copy_mime : _glfw.wl.primary_selection_copy_mime;
|
||||
snprintf(buf, sizeof(_glfw.wl.clipboard_copy_mime), "%s%llu", prefix, (unsigned long long)copy_id);
|
||||
}
|
||||
|
||||
static GLFWwaylandinitialsizefun initial_window_size_callback = NULL;
|
||||
|
||||
GLFWAPI void
|
||||
|
|
@ -2267,6 +2282,7 @@ static void
|
|||
data_source_canceled(void *data UNUSED, struct wl_data_source *wl_data_source) {
|
||||
if (_glfw.wl.dataSourceForClipboard == wl_data_source) {
|
||||
_glfw.wl.dataSourceForClipboard = NULL;
|
||||
_glfw.wl.clipboard_copy_mime[0] = 0;
|
||||
_glfw_free_clipboard_data(&_glfw.clipboard);
|
||||
_glfwInputClipboardLost(GLFW_CLIPBOARD);
|
||||
}
|
||||
|
|
@ -2277,6 +2293,7 @@ static void
|
|||
primary_selection_source_canceled(void *data UNUSED, struct zwp_primary_selection_source_v1 *primary_selection_source) {
|
||||
if (_glfw.wl.dataSourceForPrimarySelection == primary_selection_source) {
|
||||
_glfw.wl.dataSourceForPrimarySelection = NULL;
|
||||
_glfw.wl.primary_selection_copy_mime[0] = 0;
|
||||
_glfw_free_clipboard_data(&_glfw.primary);
|
||||
_glfwInputClipboardLost(GLFW_PRIMARY_SELECTION);
|
||||
}
|
||||
|
|
@ -2373,8 +2390,7 @@ mark_primary_selection_offer(
|
|||
|
||||
static void
|
||||
add_offer_mimetype(_GLFWWaylandDataOffer *offer, const char *mime, bool is_self_offer) {
|
||||
if (is_self_offer) offer->is_self_offer = is_self_offer;
|
||||
if (strcmp(mime, clipboard_mime()) == 0) { offer->is_self_offer = true; }
|
||||
if (is_self_offer) offer->is_self_offer = true;
|
||||
if (!offer->mimes || offer->mimes_count + 1 >= offer->mimes_capacity) {
|
||||
offer->mimes = realloc(offer->mimes, sizeof(char *) * (offer->mimes_capacity + 64));
|
||||
if (offer->mimes) offer->mimes_capacity += 64;
|
||||
|
|
@ -2403,12 +2419,12 @@ add_generic_offer_mimetype(void *id, const char *mime, bool is_self_offer) {
|
|||
|
||||
static void
|
||||
handle_offer_mimetype(void *data UNUSED, struct wl_data_offer *id, const char *mime) {
|
||||
add_generic_offer_mimetype(id, mime, strcmp(mime, clipboard_mime()) == 0);
|
||||
add_generic_offer_mimetype(id, mime, strcmp(mime, _glfw.wl.clipboard_copy_mime) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_primary_selection_offer_mimetype(void *data UNUSED, struct zwp_primary_selection_offer_v1 *id, const char *mime) {
|
||||
add_generic_offer_mimetype(id, mime, strcmp(mime, clipboard_mime()) == 0);
|
||||
add_generic_offer_mimetype(id, mime, strcmp(mime, _glfw.wl.primary_selection_copy_mime) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2792,7 +2808,8 @@ _glfwPlatformSetClipboard(GLFWClipboardType t) {
|
|||
zwp_primary_selection_source_v1_add_listener(_glfw.wl.dataSourceForPrimarySelection, &primary_selection_source_listener, NULL);
|
||||
data_source = _glfw.wl.dataSourceForPrimarySelection;
|
||||
}
|
||||
f(data_source, clipboard_mime());
|
||||
update_copy_mime(t);
|
||||
f(data_source, (t == GLFW_CLIPBOARD) ? _glfw.wl.clipboard_copy_mime : _glfw.wl.primary_selection_copy_mime);
|
||||
for (size_t i = 0; i < cd->num_mime_types; i++) {
|
||||
if (strcmp(cd->mime_types[i], "text/plain") == 0) {
|
||||
f(data_source, "TEXT");
|
||||
|
|
@ -2857,7 +2874,7 @@ _glfwPlatformGetClipboard(GLFWClipboardType clipboard_type, const char *mime_typ
|
|||
for (size_t o = 0; o < d->mimes_count; o++) {
|
||||
const char *q = d->mimes[o];
|
||||
if (strchr(d->mimes[0], '/')) {
|
||||
if (strcmp(q, clipboard_mime()) == 0) continue;
|
||||
if (is_our_clipboard_mime(q)) continue;
|
||||
if (strcmp(q, "text/plain;charset=utf-8") == 0) q = "text/plain";
|
||||
} else {
|
||||
if (strcmp(q, "UTF8_STRING") == 0 || strcmp(q, "STRING") == 0 || strcmp(q, "TEXT") == 0) q = "text/plain";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue