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;
|
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 //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user