mirror of
https://github.com/glfw/glfw.git
synced 2024-11-25 22:14:34 +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 (_glfw.x11.helperWindowHandle)
|
||||||
{
|
{
|
||||||
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||||
|
_glfw.x11.helperWindowHandle)
|
||||||
|
{
|
||||||
|
_glfwPushSelectionToManagerX11();
|
||||||
|
}
|
||||||
|
|
||||||
XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle);
|
XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle);
|
||||||
_glfw.x11.helperWindowHandle = None;
|
_glfw.x11.helperWindowHandle = None;
|
||||||
}
|
}
|
||||||
|
@ -295,4 +295,6 @@ void _glfwGrabErrorHandlerX11(void);
|
|||||||
void _glfwReleaseErrorHandlerX11(void);
|
void _glfwReleaseErrorHandlerX11(void);
|
||||||
void _glfwInputErrorX11(int error, const char* message);
|
void _glfwInputErrorX11(int error, const char* message);
|
||||||
|
|
||||||
|
void _glfwPushSelectionToManagerX11(void);
|
||||||
|
|
||||||
#endif // _glfw3_x11_platform_h_
|
#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);
|
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
|
// Make the specified window and its video mode active on its monitor
|
||||||
//
|
//
|
||||||
static GLFWbool acquireMonitor(_GLFWwindow* window)
|
static GLFWbool acquireMonitor(_GLFWwindow* window)
|
||||||
@ -1533,6 +1488,53 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
|||||||
return itemCount;
|
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 //////
|
////// GLFW platform API //////
|
||||||
@ -1619,12 +1621,6 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
if (window->x11.handle)
|
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);
|
XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
|
||||||
XUnmapWindow(_glfw.x11.display, window->x11.handle);
|
XUnmapWindow(_glfw.x11.display, window->x11.handle);
|
||||||
XDestroyWindow(_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));
|
memset(&event, 0, sizeof(event));
|
||||||
event.type = ClientMessage;
|
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.format = 32; // Data is 32-bit longs
|
||||||
event.xclient.message_type = _glfw.x11.NULL_;
|
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);
|
XFlush(_glfw.x11.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2234,10 +2230,11 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
|||||||
|
|
||||||
XSetSelectionOwner(_glfw.x11.display,
|
XSetSelectionOwner(_glfw.x11.display,
|
||||||
_glfw.x11.CLIPBOARD,
|
_glfw.x11.CLIPBOARD,
|
||||||
window->x11.handle, CurrentTime);
|
_glfw.x11.helperWindowHandle,
|
||||||
|
CurrentTime);
|
||||||
|
|
||||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
|
||||||
window->x11.handle)
|
_glfw.x11.helperWindowHandle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"X11: Failed to become owner of clipboard selection");
|
"X11: Failed to become owner of clipboard selection");
|
||||||
@ -2252,8 +2249,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
XA_STRING };
|
XA_STRING };
|
||||||
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
|
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
|
||||||
|
|
||||||
if (findWindowByHandle(XGetSelectionOwner(_glfw.x11.display,
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||||
_glfw.x11.CLIPBOARD)))
|
_glfw.x11.helperWindowHandle)
|
||||||
{
|
{
|
||||||
// Instead of doing a large number of X round-trips just to put this
|
// 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
|
// 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,
|
_glfw.x11.CLIPBOARD,
|
||||||
formats[i],
|
formats[i],
|
||||||
_glfw.x11.GLFW_SELECTION,
|
_glfw.x11.GLFW_SELECTION,
|
||||||
window->x11.handle, CurrentTime);
|
_glfw.x11.helperWindowHandle,
|
||||||
|
CurrentTime);
|
||||||
|
|
||||||
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
|
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
|
||||||
waitForEvent(NULL);
|
waitForEvent(NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user