Cleanup of clipboard manager work.

This commit is contained in:
Camilla Berglund 2013-04-29 20:54:42 +02:00
parent 179194a687
commit affb62514a
3 changed files with 60 additions and 76 deletions

View File

@ -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 //////
//////////////////////////////////////////////////////////////////////////

View File

@ -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

View File

@ -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;
}
@ -904,7 +884,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->x11.handle)
{
_glfwPushSelectionToManager(window);
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);