Skip to content

Commit be56f2c

Browse files
authored
[rcore][GLFW] Fix GetClipboardImage() creating new connection under X11 (#5871)
* Improve GetClipboardImage implementation under X11 * Remove code for creating new connection, handle selection in GLFW connection instead. * `GetClipboardImage()`: Small fix to remove unnecessary boolean
1 parent d31c10a commit be56f2c

1 file changed

Lines changed: 24 additions & 34 deletions

File tree

src/platforms/rcore_desktop_glfw.c

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,11 +1042,6 @@ const char *GetClipboardText(void)
10421042
return glfwGetClipboardString(platform.handle);
10431043
}
10441044

1045-
#if SUPPORT_CLIPBOARD_IMAGE && defined(__linux__) && defined(_GLFW_X11)
1046-
#include <X11/Xlib.h>
1047-
#include <X11/Xatom.h>
1048-
#endif
1049-
10501045
// Get clipboard image
10511046
Image GetClipboardImage(void)
10521047
{
@@ -1066,51 +1061,46 @@ Image GetClipboardImage(void)
10661061
else image = LoadImageFromMemory(".bmp", (const unsigned char *)bmpData, (int)dataSize);
10671062

10681063
#elif defined(__linux__) && defined(_GLFW_X11)
1069-
10701064
// REF: https://github.com/ColleagueRiley/Clipboard-Copy-Paste/blob/main/x11.c
1071-
Display *dpy = XOpenDisplay(NULL);
1072-
if (!dpy) return image;
1073-
1074-
Window root = DefaultRootWindow(dpy);
1075-
Window win = XCreateSimpleWindow(
1076-
dpy, // The connection to the X Server
1077-
root, // The 'Parent' window (usually the desktop/root)
1078-
0, 0, // X and Y position on the screen
1079-
1, 1, // Width and Height (1x1 pixel)
1080-
0, // Border width
1081-
0, // Border color
1082-
0 // Background color
1083-
);
1084-
1085-
Atom clipboard = XInternAtom(dpy, "CLIPBOARD", False);
1086-
Atom targetType = XInternAtom(dpy, "image/png", False); // Ask for PNG
1087-
Atom property = XInternAtom(dpy, "RAYLIB_CLIPBOARD_MANAGER", False);
1088-
1089-
// Request the data: "Convert whatever is in CLIPBOARD to image/png and put it in RAYLIB_CLIPBOARD_MANAGER"
1090-
XConvertSelection(dpy, clipboard, targetType, property, win, CurrentTime);
1091-
1092-
// Wait for the SelectionNotify event
1065+
1066+
static Atom clipboard = 0;
1067+
static Atom targetType = 0;
1068+
static Atom property = 0;
1069+
1070+
Display *display = glfwGetX11Display();
1071+
XID window = glfwGetX11Window(platform.handle);
1072+
1073+
// Lazy-load X11 atoms
1074+
if(clipboard == 0)
1075+
{
1076+
clipboard = XInternAtom(display, "CLIPBOARD", False);
1077+
targetType = XInternAtom(display, "image/png", False);
1078+
property = XInternAtom(display, "RAYLIB_CLIPBOARD_MANAGER", False);
1079+
}
1080+
1081+
XConvertSelection(display, clipboard, targetType, property, window, CurrentTime);
1082+
XSync(display, 0);
1083+
10931084
XEvent ev = { 0 };
1094-
XNextEvent(dpy, &ev);
1085+
1086+
// Keep calling until we get SelectionNotify
1087+
while (XCheckTypedEvent(display, SelectionNotify, &ev) == False);
10951088

10961089
Atom actualType = { 0 };
10971090
int actualFormat = 0;
10981091
unsigned long nitems = 0;
10991092
unsigned long bytesAfter = 0;
11001093
unsigned char *data = NULL;
11011094

1102-
// Read the data from our ghost window's property
1103-
XGetWindowProperty(dpy, win, property, 0, ~0L, False, AnyPropertyType,
1104-
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
1095+
XGetWindowProperty(display, window, property, 0, ~0L, False, AnyPropertyType,
1096+
&actualType, &actualFormat, &nitems, &bytesAfter, &data);
11051097

11061098
if (data != NULL)
11071099
{
11081100
image = LoadImageFromMemory(".png", data, (int)nitems);
11091101
XFree(data);
11101102
}
11111103

1112-
XDestroyWindow(dpy, win);
1113-
XCloseDisplay(dpy);
11141104
#else
11151105
TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform");
11161106
#endif // _WIN32

0 commit comments

Comments
 (0)