mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 18:15:10 +00:00
Added support for clipboard manager.
This commit is contained in:
parent
1b34887e10
commit
179194a687
@ -35,6 +35,21 @@
|
||||
#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 //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -86,7 +101,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
|
||||
count = _glfwGetWindowProperty(request->requestor,
|
||||
request->property,
|
||||
XA_ATOM,
|
||||
_glfw.x11.ATOM_PAIR,
|
||||
(unsigned char**) &targets);
|
||||
|
||||
for (i = 0; i < count; i += 2)
|
||||
@ -117,7 +132,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
XChangeProperty(_glfw.x11.display,
|
||||
request->requestor,
|
||||
request->property,
|
||||
request->target,
|
||||
_glfw.x11.ATOM_PAIR,
|
||||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char*) targets,
|
||||
@ -128,6 +143,23 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
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++)
|
||||
{
|
||||
if (request->target == formats[i])
|
||||
@ -150,6 +182,79 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
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 //////
|
||||
|
@ -537,6 +537,7 @@ static GLboolean initDisplay(void)
|
||||
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
||||
_glfw.x11.COMPOUND_STRING =
|
||||
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
|
||||
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
||||
|
||||
// Find or create selection property atom
|
||||
_glfw.x11.GLFW_SELECTION =
|
||||
@ -547,6 +548,12 @@ static GLboolean initDisplay(void)
|
||||
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", 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;
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,11 @@ typedef struct _GLFWlibraryX11
|
||||
Atom TARGETS;
|
||||
Atom MULTIPLE;
|
||||
Atom CLIPBOARD;
|
||||
Atom CLIPBOARD_MANAGER;
|
||||
Atom SAVE_TARGETS;
|
||||
Atom UTF8_STRING;
|
||||
Atom COMPOUND_STRING;
|
||||
Atom ATOM_PAIR;
|
||||
Atom GLFW_SELECTION;
|
||||
|
||||
// True if window manager supports EWMH
|
||||
@ -235,6 +238,7 @@ long _glfwKeySym2Unicode(KeySym keysym);
|
||||
|
||||
// Clipboard handling
|
||||
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
|
||||
void _glfwPushSelectionToManager(_GLFWwindow* window);
|
||||
|
||||
// Window support
|
||||
_GLFWwindow* _glfwFindWindowByHandle(Window handle);
|
||||
|
@ -904,6 +904,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
|
||||
if (window->x11.handle)
|
||||
{
|
||||
_glfwPushSelectionToManager(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);
|
||||
|
Loading…
Reference in New Issue
Block a user