Fixed bug 2500 - X11: SDL tries (and fails) to hide foreign windows
authorSam Lantinga <slouken@libsdl.org>
Mon, 14 Aug 2017 10:28:47 -0700
changeset 1128847a5a4999180
parent 11287 4d2a6202caa4
child 11289 ca3c2c98f2e1
Fixed bug 2500 - X11: SDL tries (and fails) to hide foreign windows

Alvin

I'm interested in this bug as well. I have experienced it when trying to embed an SDL_Window into a FLTK application. To do this, I create a FLTK window (window inside a window - think video player) and then use SDL_CreateWindowFrom() on the inner most window's Xlib Window*. After which, I create a renderer.

In my situation I am using the FLTK GUI toolkit.

What I have experienced is that the SDL_CreateRender() will recreate the window in order to properly setup OpenGL capability. As part of this process, the window is hidden and a call is executed that waits indefinitely for an acknowledgement that the window was indeed unmapped. This is where my program hangs.

Please correct me if I am wrong, but should SDL2 not make Xlib calls that effect the Xlib Window in this situation (e.g. When SDL_CreateWindowFrom() is used)? The toolkit being used typically assumes responsibility and, I presume, tracks all Xlib Windows it creates.

On line src/video/SDL_video.c:1372 the comment associated with setting SDL_WINDOW_FOREIGN reads:

/* Can't destroy and re-create foreign windows, hrm */

Since I do not know the reason for hiding the window in the first place, the attached patch simply does not wait for a response when X11_XWithdrawWindow() and X11_XMapRaised() are issued by X11_HideWindow() and X11_ShowWindow(), respectively. I presume that the GUI toolkit (GTK, FLTK, etc.) has or will consume the acknowledging event as it is managing the Xlib Window (or it thinks it is).

I have tested the patch against hg d09d4b578e77 and I have successfully tested:
* Embedding the SDL_Window inside a FLTK application.
* Calling SDL_SetWindowSize() when FLTK resizes the window (e.g. dragging cursor on the edge of the window).
* Filling the renderer's default target blue and drawing a red fill square at the centre (exciting, I know!)
* Calling SDL_Quit() when the application terminates

I do not receive any Xlib erorr messages (BadWindow, etc.) in any of those situations.
src/video/x11/SDL_x11window.c
     1.1 --- a/src/video/x11/SDL_x11window.c	Mon Aug 14 10:15:38 2017 -0700
     1.2 +++ b/src/video/x11/SDL_x11window.c	Mon Aug 14 10:28:47 2017 -0700
     1.3 @@ -1041,7 +1041,8 @@
     1.4          /* Blocking wait for "MapNotify" event.
     1.5           * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type,
     1.6           * and XCheckTypedWindowEvent doesn't block */
     1.7 -        X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
     1.8 +        if(!(window->flags & SDL_WINDOW_FOREIGN))
     1.9 +            X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
    1.10          X11_XFlush(display);
    1.11      }
    1.12  
    1.13 @@ -1063,7 +1064,8 @@
    1.14      if (X11_IsWindowMapped(_this, window)) {
    1.15          X11_XWithdrawWindow(display, data->xwindow, displaydata->screen);
    1.16          /* Blocking wait for "UnmapNotify" event */
    1.17 -        X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
    1.18 +        if(!(window->flags & SDL_WINDOW_FOREIGN))
    1.19 +            X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
    1.20          X11_XFlush(display);
    1.21      }
    1.22  }