mirror of
https://github.com/glfw/glfw.git
synced 2024-11-26 06:14:35 +00:00
Cleanup of clipboard manager work.
This commit is contained in:
parent
179194a687
commit
affb62514a
@ -49,14 +49,9 @@ static Bool isSelectionMessage(Display* display, XEvent* event, XPointer pointer
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Set the specified property to the contents of the requested selection
|
||||
// Set the specified property to the selection converted to the requested target
|
||||
//
|
||||
Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
{
|
||||
int i;
|
||||
const Atom formats[] = { _glfw.x11.UTF8_STRING,
|
||||
@ -67,6 +62,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
if (request->property == None)
|
||||
{
|
||||
// The requestor is a legacy client (ICCCM section 2.2)
|
||||
// We don't support legacy clients, so fail here
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -145,8 +141,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
|
||||
if (request->target == _glfw.x11.SAVE_TARGETS)
|
||||
{
|
||||
// Conversion by clients to SAVE_TARGETS should be treated like
|
||||
// a side-effect target without side effects
|
||||
// The request is a check whether we support SAVE_TARGETS
|
||||
// It should be handled as a no-op side effect target
|
||||
|
||||
XChangeProperty(_glfw.x11.display,
|
||||
request->requestor,
|
||||
@ -160,6 +156,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
return request->property;
|
||||
}
|
||||
|
||||
// Conversion to a data target was requested
|
||||
|
||||
for (i = 0; i < formatCount; i++)
|
||||
{
|
||||
if (request->target == formats[i])
|
||||
@ -179,29 +177,42 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
|
||||
}
|
||||
}
|
||||
|
||||
// The requested target is not supported
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
// Save clipboard data to clipboard manager
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwHandleSelectionClear(XEvent* event)
|
||||
{
|
||||
free(_glfw.x11.selection.string);
|
||||
_glfw.x11.selection.string = NULL;
|
||||
}
|
||||
|
||||
void _glfwHandleSelectionRequest(XEvent* event)
|
||||
{
|
||||
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||
|
||||
XEvent response;
|
||||
memset(&response, 0, sizeof(response));
|
||||
|
||||
response.xselection.property = writeTargetToProperty(request);
|
||||
response.xselection.type = SelectionNotify;
|
||||
response.xselection.display = request->display;
|
||||
response.xselection.requestor = request->requestor;
|
||||
response.xselection.selection = request->selection;
|
||||
response.xselection.target = request->target;
|
||||
response.xselection.time = request->time;
|
||||
|
||||
XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -211,42 +222,31 @@ void _glfwPushSelectionToManager(_GLFWwindow* window)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!XCheckIfEvent(_glfw.x11.display, &request, isSelectionMessage, NULL))
|
||||
XEvent event;
|
||||
|
||||
if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionMessage, NULL))
|
||||
continue;
|
||||
|
||||
switch (request.type)
|
||||
switch (event.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);
|
||||
|
||||
_glfwHandleSelectionRequest(&event);
|
||||
break;
|
||||
}
|
||||
|
||||
case SelectionClear:
|
||||
{
|
||||
free(_glfw.x11.selection.string);
|
||||
_glfw.x11.selection.string = NULL;
|
||||
_glfwHandleSelectionClear(&event);
|
||||
break;
|
||||
}
|
||||
|
||||
case SelectionNotify:
|
||||
{
|
||||
if (request.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||
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;
|
||||
}
|
||||
@ -255,7 +255,6 @@ void _glfwPushSelectionToManager(_GLFWwindow* window)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -237,7 +237,8 @@ void _glfwTerminateJoysticks(void);
|
||||
long _glfwKeySym2Unicode(KeySym keysym);
|
||||
|
||||
// Clipboard handling
|
||||
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
|
||||
void _glfwHandleSelectionClear(XEvent* event);
|
||||
void _glfwHandleSelectionRequest(XEvent* event);
|
||||
void _glfwPushSelectionToManager(_GLFWwindow* window);
|
||||
|
||||
// Window support
|
||||
|
@ -719,33 +719,13 @@ static void processEvent(XEvent *event)
|
||||
|
||||
case SelectionClear:
|
||||
{
|
||||
// The ownership of the clipboard selection was lost
|
||||
|
||||
free(_glfw.x11.selection.string);
|
||||
_glfw.x11.selection.string = NULL;
|
||||
_glfwHandleSelectionClear(event);
|
||||
break;
|
||||
}
|
||||
|
||||
case SelectionRequest:
|
||||
{
|
||||
// The contents of the clipboard selection was requested
|
||||
|
||||
XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||
|
||||
XEvent response;
|
||||
memset(&response, 0, sizeof(response));
|
||||
|
||||
response.xselection.property = _glfwWriteSelection(request);
|
||||
response.xselection.type = SelectionNotify;
|
||||
response.xselection.display = request->display;
|
||||
response.xselection.requestor = request->requestor;
|
||||
response.xselection.selection = request->selection;
|
||||
response.xselection.target = request->target;
|
||||
response.xselection.time = request->time;
|
||||
|
||||
XSendEvent(_glfw.x11.display,
|
||||
request->requestor,
|
||||
False, 0, &response);
|
||||
_glfwHandleSelectionRequest(event);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -903,8 +883,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
_glfwDestroyContext(window);
|
||||
|
||||
if (window->x11.handle)
|
||||
{
|
||||
if (window->x11.handle ==
|
||||
XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD))
|
||||
{
|
||||
_glfwPushSelectionToManager(window);
|
||||
}
|
||||
|
||||
XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
|
||||
XUnmapWindow(_glfw.x11.display, window->x11.handle);
|
||||
|
Loading…
Reference in New Issue
Block a user