mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 21:14:35 +00:00
Added support for clipboard manager.
This commit is contained in:
parent
1b34887e10
commit
179194a687
@ -35,6 +35,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Returns whether the event is a selection event
|
||||||
|
//
|
||||||
|
static Bool isSelectionMessage(Display* display, XEvent* event, XPointer pointer)
|
||||||
|
{
|
||||||
|
if (event->type == SelectionRequest ||
|
||||||
|
event->type == SelectionNotify ||
|
||||||
|
event->type == SelectionClear)
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -86,7 +101,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
|||||||
|
|
||||||
count = _glfwGetWindowProperty(request->requestor,
|
count = _glfwGetWindowProperty(request->requestor,
|
||||||
request->property,
|
request->property,
|
||||||
XA_ATOM,
|
_glfw.x11.ATOM_PAIR,
|
||||||
(unsigned char**) &targets);
|
(unsigned char**) &targets);
|
||||||
|
|
||||||
for (i = 0; i < count; i += 2)
|
for (i = 0; i < count; i += 2)
|
||||||
@ -117,7 +132,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
|||||||
XChangeProperty(_glfw.x11.display,
|
XChangeProperty(_glfw.x11.display,
|
||||||
request->requestor,
|
request->requestor,
|
||||||
request->property,
|
request->property,
|
||||||
request->target,
|
_glfw.x11.ATOM_PAIR,
|
||||||
32,
|
32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char*) targets,
|
(unsigned char*) targets,
|
||||||
@ -128,6 +143,23 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
|||||||
return request->property;
|
return request->property;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (request->target == _glfw.x11.SAVE_TARGETS)
|
||||||
|
{
|
||||||
|
// Conversion by clients to SAVE_TARGETS should be treated like
|
||||||
|
// a side-effect target without side effects
|
||||||
|
|
||||||
|
XChangeProperty(_glfw.x11.display,
|
||||||
|
request->requestor,
|
||||||
|
request->property,
|
||||||
|
XInternAtom(_glfw.x11.display, "NULL", False),
|
||||||
|
32,
|
||||||
|
PropModeReplace,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
|
return request->property;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < formatCount; i++)
|
for (i = 0; i < formatCount; i++)
|
||||||
{
|
{
|
||||||
if (request->target == formats[i])
|
if (request->target == formats[i])
|
||||||
@ -150,6 +182,79 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save clipboard data to clipboard manager
|
||||||
|
//
|
||||||
|
void _glfwPushSelectionToManager(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
XEvent request;
|
||||||
|
|
||||||
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
|
||||||
|
window->x11.handle)
|
||||||
|
{
|
||||||
|
// This window does not own the clipboard selection
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD_MANAGER) ==
|
||||||
|
None)
|
||||||
|
{
|
||||||
|
// There is no running clipboard manager
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XConvertSelection(_glfw.x11.display,
|
||||||
|
_glfw.x11.CLIPBOARD_MANAGER,
|
||||||
|
_glfw.x11.SAVE_TARGETS,
|
||||||
|
None,
|
||||||
|
window->x11.handle,
|
||||||
|
CurrentTime);
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!XCheckIfEvent(_glfw.x11.display, &request, isSelectionMessage, NULL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (request.type)
|
||||||
|
{
|
||||||
|
case SelectionRequest:
|
||||||
|
{
|
||||||
|
XEvent response;
|
||||||
|
memset(&response, 0, sizeof(response));
|
||||||
|
|
||||||
|
response.xselection.property = _glfwWriteSelection(&request.xselectionrequest);
|
||||||
|
response.xselection.type = SelectionNotify;
|
||||||
|
response.xselection.display = request.xselectionrequest.display;
|
||||||
|
response.xselection.requestor = request.xselectionrequest.requestor;
|
||||||
|
response.xselection.selection = request.xselectionrequest.selection;
|
||||||
|
response.xselection.target = request.xselectionrequest.target;
|
||||||
|
response.xselection.time = request.xselectionrequest.time;
|
||||||
|
|
||||||
|
XSendEvent(_glfw.x11.display,
|
||||||
|
request.xselectionrequest.requestor,
|
||||||
|
False, 0, &response);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SelectionClear:
|
||||||
|
{
|
||||||
|
free(_glfw.x11.selection.string);
|
||||||
|
_glfw.x11.selection.string = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SelectionNotify:
|
||||||
|
{
|
||||||
|
if (request.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
|
@ -537,6 +537,7 @@ static GLboolean initDisplay(void)
|
|||||||
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
||||||
_glfw.x11.COMPOUND_STRING =
|
_glfw.x11.COMPOUND_STRING =
|
||||||
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
|
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
|
||||||
|
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
||||||
|
|
||||||
// Find or create selection property atom
|
// Find or create selection property atom
|
||||||
_glfw.x11.GLFW_SELECTION =
|
_glfw.x11.GLFW_SELECTION =
|
||||||
@ -547,6 +548,12 @@ static GLboolean initDisplay(void)
|
|||||||
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
||||||
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
||||||
|
|
||||||
|
// Find or create clipboard manager atoms
|
||||||
|
_glfw.x11.CLIPBOARD_MANAGER =
|
||||||
|
XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
|
||||||
|
_glfw.x11.SAVE_TARGETS =
|
||||||
|
XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,8 +119,11 @@ typedef struct _GLFWlibraryX11
|
|||||||
Atom TARGETS;
|
Atom TARGETS;
|
||||||
Atom MULTIPLE;
|
Atom MULTIPLE;
|
||||||
Atom CLIPBOARD;
|
Atom CLIPBOARD;
|
||||||
|
Atom CLIPBOARD_MANAGER;
|
||||||
|
Atom SAVE_TARGETS;
|
||||||
Atom UTF8_STRING;
|
Atom UTF8_STRING;
|
||||||
Atom COMPOUND_STRING;
|
Atom COMPOUND_STRING;
|
||||||
|
Atom ATOM_PAIR;
|
||||||
Atom GLFW_SELECTION;
|
Atom GLFW_SELECTION;
|
||||||
|
|
||||||
// True if window manager supports EWMH
|
// True if window manager supports EWMH
|
||||||
@ -235,6 +238,7 @@ long _glfwKeySym2Unicode(KeySym keysym);
|
|||||||
|
|
||||||
// Clipboard handling
|
// Clipboard handling
|
||||||
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
|
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
|
||||||
|
void _glfwPushSelectionToManager(_GLFWwindow* window);
|
||||||
|
|
||||||
// Window support
|
// Window support
|
||||||
_GLFWwindow* _glfwFindWindowByHandle(Window handle);
|
_GLFWwindow* _glfwFindWindowByHandle(Window handle);
|
||||||
|
@ -904,6 +904,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
if (window->x11.handle)
|
if (window->x11.handle)
|
||||||
{
|
{
|
||||||
|
_glfwPushSelectionToManager(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);
|
||||||
|
Loading…
Reference in New Issue
Block a user