mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 13:04:35 +00:00
X11: Make clipboard IPC use helper window
This commit is contained in:
parent
706868dad8
commit
ccfd6dde45
@ -797,6 +797,12 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
if (_glfw.x11.helperWindowHandle)
|
||||
{
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||
_glfw.x11.helperWindowHandle)
|
||||
{
|
||||
_glfwPushSelectionToManagerX11();
|
||||
}
|
||||
|
||||
XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle);
|
||||
_glfw.x11.helperWindowHandle = None;
|
||||
}
|
||||
|
@ -295,4 +295,6 @@ void _glfwGrabErrorHandlerX11(void);
|
||||
void _glfwReleaseErrorHandlerX11(void);
|
||||
void _glfwInputErrorX11(int error, const char* message);
|
||||
|
||||
void _glfwPushSelectionToManagerX11(void);
|
||||
|
||||
#endif // _glfw3_x11_platform_h_
|
||||
|
114
src/x11_window.c
114
src/x11_window.c
@ -815,51 +815,6 @@ static void handleSelectionRequest(XEvent* event)
|
||||
XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);
|
||||
}
|
||||
|
||||
static void pushSelectionToManager(_GLFWwindow* window)
|
||||
{
|
||||
XConvertSelection(_glfw.x11.display,
|
||||
_glfw.x11.CLIPBOARD_MANAGER,
|
||||
_glfw.x11.SAVE_TARGETS,
|
||||
None,
|
||||
window->x11.handle,
|
||||
CurrentTime);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SelectionRequest:
|
||||
handleSelectionRequest(&event);
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
handleSelectionClear(&event);
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
{
|
||||
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||
{
|
||||
// This means one of two things; either the selection was
|
||||
// not owned, which means there is no clipboard manager, or
|
||||
// the transfer to the clipboard manager has completed
|
||||
// In either case, it means we are done here
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForEvent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the specified window and its video mode active on its monitor
|
||||
//
|
||||
static GLFWbool acquireMonitor(_GLFWwindow* window)
|
||||
@ -1533,6 +1488,53 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
// Push contents of our selection to clipboard manager
|
||||
//
|
||||
void _glfwPushSelectionToManagerX11(void)
|
||||
{
|
||||
XConvertSelection(_glfw.x11.display,
|
||||
_glfw.x11.CLIPBOARD_MANAGER,
|
||||
_glfw.x11.SAVE_TARGETS,
|
||||
None,
|
||||
_glfw.x11.helperWindowHandle,
|
||||
CurrentTime);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
XEvent event;
|
||||
|
||||
while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SelectionRequest:
|
||||
handleSelectionRequest(&event);
|
||||
break;
|
||||
|
||||
case SelectionClear:
|
||||
handleSelectionClear(&event);
|
||||
break;
|
||||
|
||||
case SelectionNotify:
|
||||
{
|
||||
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||
{
|
||||
// This means one of two things; either the selection was
|
||||
// not owned, which means there is no clipboard manager, or
|
||||
// the transfer to the clipboard manager has completed
|
||||
// In either case, it means we are done here
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForEvent(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
@ -1619,12 +1621,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
|
||||
if (window->x11.handle)
|
||||
{
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||
window->x11.handle)
|
||||
{
|
||||
pushSelectionToManager(window);
|
||||
}
|
||||
|
||||
XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
|
||||
XUnmapWindow(_glfw.x11.display, window->x11.handle);
|
||||
XDestroyWindow(_glfw.x11.display, window->x11.handle);
|
||||
@ -2094,11 +2090,11 @@ void _glfwPlatformPostEmptyEvent(void)
|
||||
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = _glfw.x11.helper;
|
||||
event.xclient.window = _glfw.x11.helperWindowHandle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NULL_;
|
||||
|
||||
XSendEvent(_glfw.x11.display, _glfw.x11.helper, False, 0, &event);
|
||||
XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
@ -2234,10 +2230,11 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||
|
||||
XSetSelectionOwner(_glfw.x11.display,
|
||||
_glfw.x11.CLIPBOARD,
|
||||
window->x11.handle, CurrentTime);
|
||||
_glfw.x11.helperWindowHandle,
|
||||
CurrentTime);
|
||||
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
|
||||
window->x11.handle)
|
||||
_glfw.x11.helperWindowHandle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to become owner of clipboard selection");
|
||||
@ -2252,8 +2249,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
XA_STRING };
|
||||
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
|
||||
|
||||
if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display,
|
||||
_glfw.x11.CLIPBOARD)))
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||
_glfw.x11.helperWindowHandle)
|
||||
{
|
||||
// Instead of doing a large number of X round-trips just to put this
|
||||
// string into a window property and then read it back, just return it
|
||||
@ -2272,7 +2269,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
_glfw.x11.CLIPBOARD,
|
||||
formats[i],
|
||||
_glfw.x11.GLFW_SELECTION,
|
||||
window->x11.handle, CurrentTime);
|
||||
_glfw.x11.helperWindowHandle,
|
||||
CurrentTime);
|
||||
|
||||
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
|
||||
waitForEvent(NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user