|
@@ -614,6 +614,17 @@ static void X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int SelectionRequestErrorHandler(Display *d, XErrorEvent *e)
|
|
|
|
|
+{
|
|
|
|
|
+ // Ignore BadWindow, as it can happen during XChangeProperty if the target window was already destroyed.
|
|
|
|
|
+ if (e->error_code != BadWindow) {
|
|
|
|
|
+ char err_msg[128];
|
|
|
|
|
+ X11_XGetErrorText(d, e->error_code, err_msg, sizeof(err_msg));
|
|
|
|
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to handle SelectionRequest: %hhu (%s)", e->error_code, err_msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
|
|
static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
|
|
|
{
|
|
{
|
|
|
int i;
|
|
int i;
|
|
@@ -627,6 +638,7 @@ static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
|
|
|
/* Copy the selection from our own CUTBUFFER to the requested property */
|
|
/* Copy the selection from our own CUTBUFFER to the requested property */
|
|
|
case SelectionRequest:
|
|
case SelectionRequest:
|
|
|
{
|
|
{
|
|
|
|
|
+ int (*prev_handler)(Display *, XErrorEvent *);
|
|
|
const XSelectionRequestEvent *req = &xevent->xselectionrequest;
|
|
const XSelectionRequestEvent *req = &xevent->xselectionrequest;
|
|
|
XEvent sevent;
|
|
XEvent sevent;
|
|
|
int seln_format, mime_formats;
|
|
int seln_format, mime_formats;
|
|
@@ -641,6 +653,11 @@ static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
|
|
|
req->requestor, req->target);
|
|
req->requestor, req->target);
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+ /* If the requesting window was already destroyed, XChangeProperty can generate a BadWindow
|
|
|
|
|
+ * error. Register an error handler to catch this, and prevent it from being fatal.
|
|
|
|
|
+ */
|
|
|
|
|
+ prev_handler = X11_XSetErrorHandler(SelectionRequestErrorHandler);
|
|
|
|
|
+
|
|
|
SDL_zero(sevent);
|
|
SDL_zero(sevent);
|
|
|
sevent.xany.type = SelectionNotify;
|
|
sevent.xany.type = SelectionNotify;
|
|
|
sevent.xselection.selection = req->selection;
|
|
sevent.xselection.selection = req->selection;
|
|
@@ -690,6 +707,8 @@ static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent)
|
|
|
}
|
|
}
|
|
|
X11_XSendEvent(display, req->requestor, False, 0, &sevent);
|
|
X11_XSendEvent(display, req->requestor, False, 0, &sevent);
|
|
|
X11_XSync(display, False);
|
|
X11_XSync(display, False);
|
|
|
|
|
+
|
|
|
|
|
+ X11_XSetErrorHandler(prev_handler);
|
|
|
} break;
|
|
} break;
|
|
|
|
|
|
|
|
case SelectionNotify:
|
|
case SelectionNotify:
|