From e00b1fdd6765b0022cd9ef9a6dd2f1b1e85c7f11 Mon Sep 17 00:00:00 2001 From: David Fort Date: Wed, 2 Oct 2024 21:19:42 +0200 Subject: [PATCH] clipboard: include mime types in SDL_ClipboarUpdate This patch modifies the clipboard handling so that when we receive an external clipboard update, the suppported mime types are included in the SDL_ClipboarUpdate event. The patch also introduces the owner field that allows to know if the update is because we own the clipboard (internal update) or if it was an external update. --- include/SDL3/SDL_events.h | 3 + src/core/android/SDL_android.c | 3 +- src/events/SDL_clipboardevents.c | 9 +- src/events/SDL_clipboardevents_c.h | 2 +- src/events/SDL_events.c | 3 + src/video/SDL_clipboard.c | 101 ++++++++++++++--------- src/video/SDL_clipboard_c.h | 3 + src/video/cocoa/SDL_cocoaclipboard.m | 3 +- src/video/uikit/SDL_uikitclipboard.m | 3 +- src/video/wayland/SDL_waylandevents.c | 38 ++++++++- src/video/windows/SDL_windowsclipboard.c | 68 ++++++++++++++- src/video/x11/SDL_x11clipboard.c | 2 +- src/video/x11/SDL_x11clipboard.h | 1 + src/video/x11/SDL_x11events.c | 71 +++++++++++++--- src/video/x11/SDL_x11video.c | 4 + src/video/x11/SDL_x11video.h | 4 + src/video/x11/SDL_x11window.c | 2 +- src/video/x11/SDL_x11xfixes.c | 2 +- 18 files changed, 256 insertions(+), 66 deletions(-) diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index fc175df8a..9befaf21c 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -845,6 +845,9 @@ typedef struct SDL_ClipboardEvent SDL_EventType type; /**< SDL_EVENT_CLIPBOARD_UPDATE */ Uint32 reserved; Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ + bool owner; /**< are we owning the clipboard (internal update) */ + Sint32 n_mime_types; /**< number of mime types */ + const char **mime_types; /**< current mime types */ } SDL_ClipboardEvent; /** diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index abf0a016f..78d8b7194 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1377,7 +1377,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)( JNIEnv *env, jclass jcls) { - SDL_SendClipboardUpdate(); + // TODO: compute new mime types + SDL_SendClipboardUpdate(false, NULL, 0); } // Low memory diff --git a/src/events/SDL_clipboardevents.c b/src/events/SDL_clipboardevents.c index 0bf462a16..95245e196 100644 --- a/src/events/SDL_clipboardevents.c +++ b/src/events/SDL_clipboardevents.c @@ -25,12 +25,17 @@ #include "SDL_events_c.h" #include "SDL_clipboardevents_c.h" -void SDL_SendClipboardUpdate(void) +void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t n_mime_types) { if (SDL_EventEnabled(SDL_EVENT_CLIPBOARD_UPDATE)) { SDL_Event event; event.type = SDL_EVENT_CLIPBOARD_UPDATE; - event.clipboard.timestamp = 0; + + SDL_ClipboardEvent *cevent = &event.clipboard; + cevent->timestamp = 0; + cevent->owner = owner; + cevent->mime_types = (const char **)mime_types; + cevent->n_mime_types = (Uint32)n_mime_types; SDL_PushEvent(&event); } } diff --git a/src/events/SDL_clipboardevents_c.h b/src/events/SDL_clipboardevents_c.h index 0288a3af4..140cc4821 100644 --- a/src/events/SDL_clipboardevents_c.h +++ b/src/events/SDL_clipboardevents_c.h @@ -23,6 +23,6 @@ #ifndef SDL_clipboardevents_c_h_ #define SDL_clipboardevents_c_h_ -extern void SDL_SendClipboardUpdate(void); +extern void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t n_mime_types); #endif // SDL_clipboardevents_c_h_ diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 6f2ee9058..890a78eed 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -235,6 +235,9 @@ static void SDL_TransferTemporaryMemoryToEvent(SDL_EventEntry *event) SDL_LinkTemporaryMemoryToEvent(event, event->event.drop.source); SDL_LinkTemporaryMemoryToEvent(event, event->event.drop.data); break; + case SDL_EVENT_CLIPBOARD_UPDATE: + SDL_LinkTemporaryMemoryToEvent(event, event->event.clipboard.mime_types); + break; default: break; } diff --git a/src/video/SDL_clipboard.c b/src/video/SDL_clipboard.c index 4e1cbd37e..9d663980b 100644 --- a/src/video/SDL_clipboard.c +++ b/src/video/SDL_clipboard.c @@ -22,13 +22,25 @@ #include "SDL_clipboard_c.h" #include "SDL_sysvideo.h" +#include "../events/SDL_events_c.h" #include "../events/SDL_clipboardevents_c.h" +void SDL_FreeClipboardMimeTypes(SDL_VideoDevice *_this) +{ + if (_this->clipboard_mime_types) { + for (size_t i = 0; i < _this->num_clipboard_mime_types; ++i) { + SDL_free(_this->clipboard_mime_types[i]); + } + SDL_free(_this->clipboard_mime_types); + _this->clipboard_mime_types = NULL; + _this->num_clipboard_mime_types = 0; + } +} + void SDL_CancelClipboardData(Uint32 sequence) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); - size_t i; if (sequence != _this->clipboard_sequence) { // This clipboard data was already canceled @@ -39,14 +51,7 @@ void SDL_CancelClipboardData(Uint32 sequence) _this->clipboard_cleanup(_this->clipboard_userdata); } - if (_this->clipboard_mime_types) { - for (i = 0; i < _this->num_clipboard_mime_types; ++i) { - SDL_free(_this->clipboard_mime_types[i]); - } - SDL_free(_this->clipboard_mime_types); - _this->clipboard_mime_types = NULL; - _this->num_clipboard_mime_types = 0; - } + SDL_FreeClipboardMimeTypes(_this); _this->clipboard_callback = NULL; _this->clipboard_cleanup = NULL; @@ -135,7 +140,11 @@ bool SDL_SetClipboardData(SDL_ClipboardDataCallback callback, SDL_ClipboardClean } } - SDL_SendClipboardUpdate(); + char **mime_types_copy = SDL_CopyClipboardMimeTypes(mime_types, num_mime_types, true); + if (!mime_types_copy) + return SDL_SetError("unable to copy current mime types"); + + SDL_SendClipboardUpdate(true, mime_types_copy, num_mime_types); return true; } @@ -232,6 +241,41 @@ bool SDL_HasClipboardData(const char *mime_type) } } +char **SDL_CopyClipboardMimeTypes(const char **clipboard_mime_types, size_t num_mime_types, bool temporary) +{ + size_t allocSize = sizeof(char *); + for (size_t i = 0; i < num_mime_types; i++) { + allocSize += sizeof(char *) + SDL_strlen(clipboard_mime_types[i]) + 1; + } + + char *ret; + if (temporary) + ret = (char *)SDL_AllocateTemporaryMemory(allocSize); + else + ret = (char *)SDL_malloc(allocSize); + if (!ret) { + return NULL; + } + + char **result = (char **)ret; + ret += sizeof(char *) * (num_mime_types + 1); + + for (size_t i = 0; i < num_mime_types; i++) { + result[i] = ret; + + const char *mime_type = clipboard_mime_types[i]; + // Copy the whole string including the terminating null char + char c; + do { + c = *ret++ = *mime_type++; + } while (c != '\0'); + } + result[num_mime_types] = NULL; + + return result; + +} + char **SDL_GetClipboardMimeTypes(size_t *num_mime_types) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -241,35 +285,8 @@ char **SDL_GetClipboardMimeTypes(size_t *num_mime_types) return NULL; } - size_t allocSize = sizeof(char *); - for (size_t i = 0; i < _this->num_clipboard_mime_types; i++) { - allocSize += sizeof(char *) + SDL_strlen(_this->clipboard_mime_types[i]) + 1; - } - - char *ret = (char *)SDL_malloc(allocSize); - if (!ret) { - return NULL; - } - - char **result = (char **)ret; - ret += sizeof(char *) * (_this->num_clipboard_mime_types + 1); - - for (size_t i = 0; i < _this->num_clipboard_mime_types; i++) { - result[i] = ret; - - const char *mime_type = _this->clipboard_mime_types[i]; - // Copy the whole string including the terminating null char - char c; - do { - c = *ret++ = *mime_type++; - } while (c != '\0'); - } - result[_this->num_clipboard_mime_types] = NULL; - - if (num_mime_types) { - *num_mime_types = _this->num_clipboard_mime_types; - } - return result; + *num_mime_types = _this->num_clipboard_mime_types; + return SDL_CopyClipboardMimeTypes((const char **)_this->clipboard_mime_types, _this->num_clipboard_mime_types, false); } // Clipboard text @@ -392,7 +409,11 @@ bool SDL_SetPrimarySelectionText(const char *text) _this->primary_selection_text = SDL_strdup(text); } - SDL_SendClipboardUpdate(); + char **mime_types = SDL_CopyClipboardMimeTypes((const char **)_this->clipboard_mime_types, _this->num_clipboard_mime_types, true); + if (!mime_types) + return SDL_SetError("unable to copy current mime types"); + + SDL_SendClipboardUpdate(true, mime_types, _this->num_clipboard_mime_types); return true; } diff --git a/src/video/SDL_clipboard_c.h b/src/video/SDL_clipboard_c.h index 0d5e9dc8f..7cc670b96 100644 --- a/src/video/SDL_clipboard_c.h +++ b/src/video/SDL_clipboard_c.h @@ -39,4 +39,7 @@ extern bool SDL_HasInternalClipboardData(SDL_VideoDevice *_this, const char *mim // General purpose clipboard text callback const void * SDLCALL SDL_ClipboardTextCallback(void *userdata, const char *mime_type, size_t *size); +void SDLCALL SDL_FreeClipboardMimeTypes(SDL_VideoDevice *_this); +char ** SDLCALL SDL_CopyClipboardMimeTypes(const char **clipboard_mime_types, size_t num_mime_types, bool temporary); + #endif // SDL_clipboard_c_h_ diff --git a/src/video/cocoa/SDL_cocoaclipboard.m b/src/video/cocoa/SDL_cocoaclipboard.m index 9cfdd8290..9b266fcb5 100644 --- a/src/video/cocoa/SDL_cocoaclipboard.m +++ b/src/video/cocoa/SDL_cocoaclipboard.m @@ -83,7 +83,8 @@ void Cocoa_CheckClipboardUpdate(SDL_CocoaVideoData *data) count = [pasteboard changeCount]; if (count != data.clipboard_count) { if (data.clipboard_count) { - SDL_SendClipboardUpdate(); + // TODO: compute mime types + SDL_SendClipboardUpdate(false, NULL, 0); } data.clipboard_count = count; } diff --git a/src/video/uikit/SDL_uikitclipboard.m b/src/video/uikit/SDL_uikitclipboard.m index 1ba0eca29..cf4564e6b 100644 --- a/src/video/uikit/SDL_uikitclipboard.m +++ b/src/video/uikit/SDL_uikitclipboard.m @@ -80,7 +80,8 @@ void UIKit_InitClipboard(SDL_VideoDevice *_this) object:nil queue:nil usingBlock:^(NSNotification *note) { - SDL_SendClipboardUpdate(); + // TODO: compute mime types + SDL_SendClipboardUpdate(false, NULL, 0); }]; data.pasteboardObserver = observer; diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index e71a20e68..9e8f7677f 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -2277,6 +2277,40 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_d data_device->drag_offer = NULL; } +static void notifyFromMimes(struct wl_list *mimes) { + int nformats = 0; + char **new_mime_types = NULL; + if (mimes) { + nformats = WAYLAND_wl_list_length(mimes); + size_t alloc_size = (nformats + 1) * sizeof(char *); + + /* do a first pass to compute allocation size */ + SDL_MimeDataList *item = NULL; + wl_list_for_each(item, mimes, link) { + alloc_size += SDL_strlen(item->mime_type) + 1; + } + + new_mime_types = SDL_AllocateTemporaryMemory(alloc_size); + if (!new_mime_types) { + SDL_LogError(SDL_LOG_CATEGORY_INPUT, "unable to allocate new_mime_types"); + return; + } + + /* second pass to fill*/ + char *strPtr = (char *)(new_mime_types + nformats + 1); + item = NULL; + int i = 0; + wl_list_for_each(item, mimes, link) { + new_mime_types[i] = strPtr; + strPtr = stpcpy(strPtr, item->mime_type) + 1; + i++; + } + new_mime_types[nformats] = NULL; + } + + SDL_SendClipboardUpdate(false, new_mime_types, nformats); +} + static void data_device_handle_selection(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id) { @@ -2295,7 +2329,7 @@ static void data_device_handle_selection(void *data, struct wl_data_device *wl_d data_device->selection_offer = offer; } - SDL_SendClipboardUpdate(); + notifyFromMimes(offer ? &offer->mimes : NULL); } static const struct wl_data_device_listener data_device_listener = { @@ -2341,7 +2375,7 @@ static void primary_selection_device_handle_selection(void *data, struct zwp_pri ". In zwp_primary_selection_device_v1_listener . primary_selection_device_handle_selection on primary_selection_offer 0x%08x\n", (id ? WAYLAND_wl_proxy_get_id((struct wl_proxy *)id) : -1)); - SDL_SendClipboardUpdate(); + notifyFromMimes(offer ? &offer->mimes : NULL); } static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = { diff --git a/src/video/windows/SDL_windowsclipboard.c b/src/video/windows/SDL_windowsclipboard.c index 98d8b87cc..6a0cc35c7 100644 --- a/src/video/windows/SDL_windowsclipboard.c +++ b/src/video/windows/SDL_windowsclipboard.c @@ -25,6 +25,7 @@ #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" #include "../SDL_clipboard_c.h" +#include "../../events/SDL_events_c.h" #include "../../events/SDL_clipboardevents_c.h" #ifdef UNICODE @@ -329,14 +330,73 @@ bool WIN_HasClipboardData(SDL_VideoDevice *_this, const char *mime_type) return false; } +static char **GetMimeTypes(int *pnformats) +{ + *pnformats = 0; + + int nformats = CountClipboardFormats(); + size_t allocSize = (nformats + 1) * sizeof(char*); + + UINT format = 0; + int formatsSz = 0; + int i; + for (i = 0; i < nformats; i++) { + format = EnumClipboardFormats(format); + if (!format) { + nformats = i; + break; + } + + char mimeType[200]; + int nchars = GetClipboardFormatNameA(format, mimeType, sizeof(mimeType)); + formatsSz += nchars + 1; + } + + char **new_mime_types = SDL_AllocateTemporaryMemory(allocSize + formatsSz); + if (!new_mime_types) + return NULL; + + format = 0; + char *strPtr = (char *)(new_mime_types + nformats + 1); + int formatRemains = formatsSz; + for (i = 0; i < nformats; i++) { + format = EnumClipboardFormats(format); + if (!format) { + nformats = i; + break; + } + + new_mime_types[i] = strPtr; + + int nchars = GetClipboardFormatNameA(format, strPtr, formatRemains-1); + strPtr += nchars; + *strPtr = '\0'; + strPtr++; + + formatRemains -= (nchars + 1); + } + + new_mime_types[nformats] = NULL; + *pnformats = nformats; + return new_mime_types; +} + void WIN_CheckClipboardUpdate(struct SDL_VideoData *data) { - const DWORD count = GetClipboardSequenceNumber(); - if (count != data->clipboard_count) { + const DWORD seq = GetClipboardSequenceNumber(); + if (seq != data->clipboard_count) { if (data->clipboard_count) { - SDL_SendClipboardUpdate(); + int nformats = 0; + char **new_mime_types = GetMimeTypes(&nformats); + if (new_mime_types) { + SDL_SendClipboardUpdate(false, new_mime_types, nformats); + } else { + WIN_SetError("Couldn't get clipboard mime types"); + } + } - data->clipboard_count = count; + + data->clipboard_count = seq; } } diff --git a/src/video/x11/SDL_x11clipboard.c b/src/video/x11/SDL_x11clipboard.c index 913be162b..0a72faf8e 100644 --- a/src/video/x11/SDL_x11clipboard.c +++ b/src/video/x11/SDL_x11clipboard.c @@ -38,7 +38,7 @@ static const char *text_mime_types[] = { }; // Get any application owned window handle for clipboard association -static Window GetWindow(SDL_VideoDevice *_this) +Window GetWindow(SDL_VideoDevice *_this) { SDL_VideoData *data = _this->internal; diff --git a/src/video/x11/SDL_x11clipboard.h b/src/video/x11/SDL_x11clipboard.h index cf9d07e70..dc22d69cf 100644 --- a/src/video/x11/SDL_x11clipboard.h +++ b/src/video/x11/SDL_x11clipboard.h @@ -41,5 +41,6 @@ extern bool X11_SetPrimarySelectionText(SDL_VideoDevice *_this, const char *text extern char *X11_GetPrimarySelectionText(SDL_VideoDevice *_this); extern bool X11_HasPrimarySelectionText(SDL_VideoDevice *_this); extern void X11_QuitClipboard(SDL_VideoDevice *_this); +Window GetWindow(SDL_VideoDevice *_this); #endif // SDL_x11clipboard_h_ diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 1b883b867..8d13c22c1 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -415,7 +415,7 @@ static void DispatchWindowMove(SDL_VideoDevice *_this, const SDL_WindowData *dat evt.xclient.type = ClientMessage; evt.xclient.window = data->xwindow; - evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); + evt.xclient.message_type = videodata->atoms._NET_WM_MOVERESIZE; evt.xclient.format = 32; evt.xclient.data.l[0] = (size_t)window->x + point->x; evt.xclient.data.l[1] = (size_t)window->y + point->y; @@ -450,7 +450,7 @@ static void InitiateWindowResize(SDL_VideoDevice *_this, const SDL_WindowData *d evt.xclient.type = ClientMessage; evt.xclient.window = data->xwindow; - evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); + evt.xclient.message_type = videodata->atoms._NET_WM_MOVERESIZE; evt.xclient.format = 32; evt.xclient.data.l[0] = (size_t)window->x + point->x; evt.xclient.data.l[1] = (size_t)window->y + point->y; @@ -553,7 +553,7 @@ static void X11_HandleClipboardEvent(SDL_VideoDevice *_this, const XEvent *xeven int mime_formats; unsigned char *seln_data; size_t seln_length = 0; - Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0); + Atom XA_TARGETS = videodata->atoms.TARGETS; SDLX11_ClipboardData *clipboard; #ifdef DEBUG_XEVENTS @@ -627,17 +627,52 @@ static void X11_HandleClipboardEvent(SDL_VideoDevice *_this, const XEvent *xeven case SelectionNotify: { + const XSelectionEvent *xsel = &xevent->xselection; #ifdef DEBUG_XEVENTS - SDL_Log("window CLIPBOARD: SelectionNotify (requestor = 0x%lx, target = 0x%lx)\n", - xevent->xselection.requestor, xevent->xselection.target); + const char *propName = xsel->property ? X11_XGetAtomName(display, xsel->property) : "None"; + const char *targetName = xsel->target ? X11_XGetAtomName(display, xsel->target) : "None"; + + SDL_Log("window CLIPBOARD: SelectionNotify (requestor = 0x%lx, target = %s, property = %s)\n", + xsel->requestor, targetName, propName); #endif + if (xsel->target == videodata->atoms.TARGETS && xsel->property == videodata->atoms.SDL_FORMATS) { + /* the new mime formats are the SDL_FORMATS property as an array of Atoms */ + Atom atom = None; + Atom *patom; + unsigned char* data = NULL; + int format_property = 0; + unsigned long length = 0; + unsigned long bytes_left = 0; + int j; + + X11_XGetWindowProperty(display, GetWindow(_this), videodata->atoms.SDL_FORMATS, 0, 200, + 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data); + + int allocationsize = (length + 1) * sizeof(char*); + for (j = 0, patom = (Atom*)data; j < length; j++, patom++) { + allocationsize += SDL_strlen( X11_XGetAtomName(display, *patom) ) + 1; + } + + char **new_mime_types = SDL_AllocateTemporaryMemory(allocationsize); + if (new_mime_types) { + char *strPtr = (char *)(new_mime_types + length + 1); + + for (j = 0, patom = (Atom*)data; j < length; j++, patom++) { + new_mime_types[j] = strPtr; + strPtr = stpcpy(strPtr, X11_XGetAtomName(display, *patom)) + 1; + } + new_mime_types[length] = NULL; + + SDL_SendClipboardUpdate(false, new_mime_types, length); + } + } + videodata->selection_waiting = false; } break; case SelectionClear: { - // !!! FIXME: cache atoms - Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); + Atom XA_CLIPBOARD = videodata->atoms.CLIPBOARD; SDLX11_ClipboardData *clipboard = NULL; #ifdef DEBUG_XEVENTS @@ -994,11 +1029,25 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) X11_XGetAtomName(display, ev->selection)); #endif - if (ev->selection == XA_PRIMARY || - (videodata->atoms.CLIPBOARD != None && ev->selection == videodata->atoms.CLIPBOARD)) { - SDL_SendClipboardUpdate(); - return; + if (ev->subtype == XFixesSetSelectionOwnerNotify) + { + if (ev->selection != videodata->atoms.CLIPBOARD) + return; + + if (X11_XGetSelectionOwner(display, ev->selection) == videodata->clipboard_window) + return; + + /* when here we're notified that the clipboard had an external change, we request the + * available mime types by asking for a conversion to the TARGETS format. We should get a + * SelectionNotify event later, and when treating these results, we will push a ClipboardUpdated + * event + */ + + X11_XConvertSelection(display, videodata->atoms.CLIPBOARD, videodata->atoms.TARGETS, + videodata->atoms.SDL_FORMATS, GetWindow(_this), CurrentTime); } + + return; } #endif // SDL_VIDEO_DRIVER_X11_XFIXES diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index a8d6ec86b..57e51d674 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -403,6 +403,7 @@ static bool X11_VideoInit(SDL_VideoDevice *_this) GET_ATOM(_NET_WM_STATE_ABOVE); GET_ATOM(_NET_WM_STATE_SKIP_TASKBAR); GET_ATOM(_NET_WM_STATE_SKIP_PAGER); + GET_ATOM(_NET_WM_MOVERESIZE); GET_ATOM(_NET_WM_STATE_MODAL); GET_ATOM(_NET_WM_ALLOWED_ACTIONS); GET_ATOM(_NET_WM_ACTION_FULLSCREEN); @@ -420,6 +421,9 @@ static bool X11_VideoInit(SDL_VideoDevice *_this) GET_ATOM(CLIPBOARD); GET_ATOM(INCR); GET_ATOM(SDL_SELECTION); + GET_ATOM(TARGETS); + GET_ATOM(SDL_FORMATS); + GET_ATOM(XdndAware); GET_ATOM(XdndEnter); GET_ATOM(XdndPosition); GET_ATOM(XdndStatus); diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index f97ba902b..9509ba70f 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -82,6 +82,7 @@ struct SDL_VideoData Atom _NET_WM_STATE_SKIP_TASKBAR; Atom _NET_WM_STATE_SKIP_PAGER; Atom _NET_WM_STATE_MODAL; + Atom _NET_WM_MOVERESIZE; Atom _NET_WM_ALLOWED_ACTIONS; Atom _NET_WM_ACTION_FULLSCREEN; Atom _NET_WM_NAME; @@ -98,6 +99,9 @@ struct SDL_VideoData Atom CLIPBOARD; Atom INCR; Atom SDL_SELECTION; + Atom TARGETS; + Atom SDL_FORMATS; + Atom XdndAware; Atom XdndEnter; Atom XdndPosition; Atom XdndStatus; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 7de902441..5802a2eaa 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -2001,7 +2001,7 @@ void X11_AcceptDragAndDrop(SDL_Window *window, bool accept) { SDL_WindowData *data = window->internal; Display *display = data->videodata->display; - Atom XdndAware = X11_XInternAtom(display, "XdndAware", False); + Atom XdndAware = data->videodata->atoms.XdndAware; if (accept) { Atom xdnd_version = 5; diff --git a/src/video/x11/SDL_x11xfixes.c b/src/video/x11/SDL_x11xfixes.c index 417a864a8..1e4432a11 100644 --- a/src/video/x11/SDL_x11xfixes.c +++ b/src/video/x11/SDL_x11xfixes.c @@ -51,7 +51,7 @@ void X11_InitXfixes(SDL_VideoDevice *_this) int event, error; int fixes_opcode; - Atom XA_CLIPBOARD = X11_XInternAtom(data->display, "CLIPBOARD", 0); + Atom XA_CLIPBOARD = data->atoms.CLIPBOARD; if (!SDL_X11_HAVE_XFIXES || !X11_XQueryExtension(data->display, "XFIXES", &fixes_opcode, &event, &error)) {