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; return False;
} }
// Set the specified property to the selection converted to the requested target
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Set the specified property to the contents of the requested selection
// //
Atom _glfwWriteSelection(XSelectionRequestEvent* request) static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{ {
int i; int i;
const Atom formats[] = { _glfw.x11.UTF8_STRING, const Atom formats[] = { _glfw.x11.UTF8_STRING,
@ -67,6 +62,7 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
if (request->property == None) if (request->property == None)
{ {
// The requestor is a legacy client (ICCCM section 2.2) // The requestor is a legacy client (ICCCM section 2.2)
// We don't support legacy clients, so fail here
return None; return None;
} }
@ -145,8 +141,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
if (request->target == _glfw.x11.SAVE_TARGETS) if (request->target == _glfw.x11.SAVE_TARGETS)
{ {
// Conversion by clients to SAVE_TARGETS should be treated like // The request is a check whether we support SAVE_TARGETS
// a side-effect target without side effects // It should be handled as a no-op side effect target
XChangeProperty(_glfw.x11.display, XChangeProperty(_glfw.x11.display,
request->requestor, request->requestor,
@ -160,6 +156,8 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
return request->property; return request->property;
} }
// Conversion to a data target was requested
for (i = 0; i < formatCount; i++) for (i = 0; i < formatCount; i++)
{ {
if (request->target == formats[i]) if (request->target == formats[i])
@ -179,29 +177,42 @@ Atom _glfwWriteSelection(XSelectionRequestEvent* request)
} }
} }
// The requested target is not supported
return None; 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) 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, XConvertSelection(_glfw.x11.display,
_glfw.x11.CLIPBOARD_MANAGER, _glfw.x11.CLIPBOARD_MANAGER,
_glfw.x11.SAVE_TARGETS, _glfw.x11.SAVE_TARGETS,
@ -211,42 +222,31 @@ void _glfwPushSelectionToManager(_GLFWwindow* window)
for (;;) for (;;)
{ {
if (!XCheckIfEvent(_glfw.x11.display, &request, isSelectionMessage, NULL)) XEvent event;
if (!XCheckIfEvent(_glfw.x11.display, &event, isSelectionMessage, NULL))
continue; continue;
switch (request.type) switch (event.type)
{ {
case SelectionRequest: case SelectionRequest:
{ _glfwHandleSelectionRequest(&event);
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; break;
}
case SelectionClear: case SelectionClear:
{ _glfwHandleSelectionClear(&event);
free(_glfw.x11.selection.string);
_glfw.x11.selection.string = NULL;
break; break;
}
case SelectionNotify: 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; return;
}
break; break;
} }
@ -255,7 +255,6 @@ void _glfwPushSelectionToManager(_GLFWwindow* window)
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -237,7 +237,8 @@ void _glfwTerminateJoysticks(void);
long _glfwKeySym2Unicode(KeySym keysym); long _glfwKeySym2Unicode(KeySym keysym);
// Clipboard handling // Clipboard handling
Atom _glfwWriteSelection(XSelectionRequestEvent* request); void _glfwHandleSelectionClear(XEvent* event);
void _glfwHandleSelectionRequest(XEvent* event);
void _glfwPushSelectionToManager(_GLFWwindow* window); void _glfwPushSelectionToManager(_GLFWwindow* window);
// Window support // Window support

View File

@ -719,33 +719,13 @@ static void processEvent(XEvent *event)
case SelectionClear: case SelectionClear:
{ {
// The ownership of the clipboard selection was lost _glfwHandleSelectionClear(event);
free(_glfw.x11.selection.string);
_glfw.x11.selection.string = NULL;
break; break;
} }
case SelectionRequest: case SelectionRequest:
{ {
// The contents of the clipboard selection was requested _glfwHandleSelectionRequest(event);
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);
break; break;
} }
@ -904,7 +884,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->x11.handle) 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); XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
XUnmapWindow(_glfw.x11.display, window->x11.handle); XUnmapWindow(_glfw.x11.display, window->x11.handle);