From f1f869acf72df2ed5afe0973d3c443cda56116ec Mon Sep 17 00:00:00 2001 From: Alex Sanchez-Stern Date: Thu, 3 Oct 2024 13:01:59 -0700 Subject: [PATCH 1/4] Hooks to allow serving non-text selections --- include/GLFW/glfw3native.h | 7 +++++++ src/x11_init.c | 2 ++ src/x11_platform.h | 2 ++ src/x11_window.c | 12 +++++++++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 011b239c..d4daa1f5 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -442,6 +442,13 @@ GLFWAPI void glfwSetX11SelectionString(const char* string); * @ingroup native */ GLFWAPI const char* glfwGetX11SelectionString(void); + +#include +extern void (*handleSelectionRequest)(XEvent*); +void (*getSelectionRequestHandler(void))(XEvent*); +void setSelectionRequestHandler(void (*handler)(XEvent*)); +Display* getGLFWDisplay(void); + #endif #if defined(GLFW_EXPOSE_NATIVE_GLX) diff --git a/src/x11_init.c b/src/x11_init.c index 982c526c..33b827af 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -1314,6 +1314,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform) _glfw.x11.xlib.handle = module; *platform = x11; + + handleSelectionRequest = handleSelectionRequest_; return GLFW_TRUE; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 30326c5b..63fb893c 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -896,6 +896,8 @@ typedef struct _GLFWcursorX11 Cursor handle; } _GLFWcursorX11; +extern void (*handleSelectionRequest)(XEvent*); +void handleSelectionRequest_(XEvent* event); GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform); int _glfwInitX11(void); diff --git a/src/x11_window.c b/src/x11_window.c index 322349f0..787004d1 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -921,7 +921,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request) return None; } -static void handleSelectionRequest(XEvent* event) +void (*handleSelectionRequest)(XEvent*); +void handleSelectionRequest_(XEvent* event) { const XSelectionRequestEvent* request = &event->xselectionrequest; @@ -3356,6 +3357,15 @@ GLFWAPI const char* glfwGetX11SelectionString(void) return getSelectionString(_glfw.x11.PRIMARY); } +void (*getSelectionRequestHandler(void))(XEvent*) { + return handleSelectionRequest; +} +void setSelectionRequestHandler(void (*handler)(XEvent*)) { + handleSelectionRequest = handler; +} +Display* getGLFWDisplay(void) { + return _glfw.x11.display; +} #endif // _GLFW_X11 From f269a6af97b7eac847bff6140d2ceccdc3f6ed0f Mon Sep 17 00:00:00 2001 From: Alex Sanchez-Stern Date: Thu, 3 Oct 2024 16:01:51 -0700 Subject: [PATCH 2/4] Add ability to get the clipboard target window This allows users to claim the selection independently in a way that's compatible with the handlers from GLFW. --- include/GLFW/glfw3native.h | 1 + src/x11_window.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index d4daa1f5..4cbe5c45 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -448,6 +448,7 @@ extern void (*handleSelectionRequest)(XEvent*); void (*getSelectionRequestHandler(void))(XEvent*); void setSelectionRequestHandler(void (*handler)(XEvent*)); Display* getGLFWDisplay(void); +Window getGLFWHelperWindow(void); #endif diff --git a/src/x11_window.c b/src/x11_window.c index 787004d1..69569514 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3367,5 +3367,8 @@ Display* getGLFWDisplay(void) { return _glfw.x11.display; } -#endif // _GLFW_X11 +Window getGLFWHelperWindow(void) { + return _glfw.x11.helperWindowHandle; +} +#endif // _GLFW_X11 From c31de751119a73450b1efda690d8e58c2d23816a Mon Sep 17 00:00:00 2001 From: Alex Sanchez-Stern Date: Sun, 13 Oct 2024 14:41:41 -0700 Subject: [PATCH 3/4] Don't expose the function pointer symbol directly for encapsulation --- include/GLFW/glfw3native.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 4cbe5c45..c266c4ad 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -444,7 +444,6 @@ GLFWAPI void glfwSetX11SelectionString(const char* string); GLFWAPI const char* glfwGetX11SelectionString(void); #include -extern void (*handleSelectionRequest)(XEvent*); void (*getSelectionRequestHandler(void))(XEvent*); void setSelectionRequestHandler(void (*handler)(XEvent*)); Display* getGLFWDisplay(void); From 06f21df20e7e816acc121636226c878c76addeda Mon Sep 17 00:00:00 2001 From: Alex Sanchez-Stern Date: Sun, 13 Oct 2024 15:28:36 -0700 Subject: [PATCH 4/4] Add documentation of the change as described in the GLFW contributers guide --- CONTRIBUTORS.md | 1 + README.md | 7 +++++-- docs/input.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ docs/news.md | 25 +++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1371aedb..14657983 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -294,6 +294,7 @@ video tutorials. - Jonas Ådahl - Lasse Öörni - Leonard König + - Alex Sanchez-Stern - All the unmentioned and anonymous contributors in the GLFW community, for bug reports, patches, feedback, testing and encouragement diff --git a/README.md b/README.md index 10044faf..7bb5782e 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,11 @@ information on what to include when reporting a bug. - [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless` - [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to `GLFW_NATIVE_CONTEXT_API` (#2518) - + - [X11] Added `getSelectionRequestHandler`, `setSelectionRequestHander`, + `getGLFWDisplay`, and `getGLFWHelperWindow` functions. to allow + clients to implement more X clipboard functionality than is + built-in; with these primitives clients can add copy paste support + for files, images, colors, and other non-text data types. ## Contact @@ -148,4 +152,3 @@ request, please file it in the Finally, if you're interested in helping out with the development of GLFW or porting it to your favorite platform, join us on the forum or GitHub. - diff --git a/docs/input.md b/docs/input.md index 3ef1aebe..3bec380a 100644 --- a/docs/input.md +++ b/docs/input.md @@ -973,6 +973,53 @@ The contents of the system clipboard can be set to a UTF-8 encoded string with glfwSetClipboardString(NULL, "A string with words in it"); ``` +\par Advanced Usage +While GLFW does not directly support using other data types with the +system clipboard, on many platforms this is possible using platform +specific code. If you are primarily targetting a small set of +platforms, this may be viable for your application. + +\par +On Windows, you can do clipboard operations directly using winuser.h, +allowing you to copy and paste datatypes other than text. On X11 you +can also use the platform specific API to get this functionality, but +you must hook into GLFW's X11 event handling code to allow copying +out of your application. Example code for most of this functionality +can be found in general X11 documentation like this +page; the GLFW-specific part is including + +\par +@code +#include +#include +#define GLFW_EXPOSE_NATIVE_X11 +#include +@endcode + +\par +At the top of your file (guarded by platform), and then running + +\par +@code +setSelectionRequestHandler(myHandler); +@endcode + +\par +on initialization. Your selection handler must have the signature: + +\par +@code +void myHandler(XEvent*); +@endcode + +\par +and it will receive all X Selection events. To ensure compatibility +use `getGLFWDisplay()` to get a display object instead of +`XOpenDisplay()` and use the result of `getGLFWHelperWindow()` as the +target window for the selection. + ## Path drop input {#path_drop} diff --git a/docs/news.md b/docs/news.md index 148d0871..3b27a401 100644 --- a/docs/news.md +++ b/docs/news.md @@ -14,6 +14,25 @@ values over 8. For compatibility with older versions, the @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of this. + +### Support for custom X11 clipboard functionality {#x11_custom_selection} + +This change allows clients to implement custom X11 clipboard +functionality like the copying and pasting of files across +applications. + +GLFW itself only allows plain text to be copied to the +clipboard and back on all platforms. On some platforms, like Windows, +you can use platform specific APIs to add extra clipboard +functionality like copying of other data types. However, on X11, this +was previously not fully possible due to the fact that GLFW internal +code has full control over the X11 event queue. + +This change exposes several new symbols that allow you to get and set +the handler for X11 selection events that GLFW will use. It also +allows getting the internal display connection and selection helper +window, for use in that kind of code. + ## Caveats {#caveats} ## Deprecations {#deprecations} @@ -24,6 +43,12 @@ this. ### New functions {#new_functions} +#### X11-specific + - @ref getSelectionRequestHandler + - @ref setSelectionRequestHanddler + - @ref getGLFWDisplay + - @ref getGLFWHelperWindow + ### New types {#new_types} ### New constants {#new_constants}