Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] X11: SDL tries (and fails) to hide foreign windows #1444

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 1 comment
Closed

[PATCH] X11: SDL tries (and fails) to hide foreign windows #1444

SDLBugzilla opened this issue Feb 10, 2021 · 1 comment
Labels
abandoned Bug has been abandoned for various reasons

Comments

@SDLBugzilla
Copy link
Collaborator

SDLBugzilla commented Feb 10, 2021

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: HG 2.1
Reported for operating system, platform: Linux, Other

Comments on the original bug report:

On 2014-04-15 16:54:56 +0000, Bryan Cain wrote:

I'm using the latest SDL from hg with GTK 2, using SDL_CreateWindowFrom to make SDL render inside of a GTK widget. However, when a renderer is applied to the window, SDL tries to recreate it, and tries to hide it in the process. X11 doesn't seem too happy about the idea of hiding that window for some reason, and the entire program freezes.

There's little reason to try and hide foreign windows anyway, so this proposed patch makes SDL stop trying to do so under X11. It also fixes a related issue where SDL_RecreateWindow would cause the window lose the SDL_WINDOW_FOREIGN flag.

On 2014-04-15 16:56:29 +0000, Bryan Cain wrote:

Created attachment 1620
proposed patch

On 2014-04-18 03:16:40 +0000, Sam Lantinga wrote:

You should be able to hide and show foreign windows using SDL API functions in general. Is there something else different about the state of the window that's causing it not to be hidden correctly?

On 2014-04-18 04:55:52 +0000, Bryan Cain wrote:

The only special thing I can think of about the state of the window is that it's a subwindow of a GTK window (GtkEventBox widget), not a top-level window. It seems that the X server doesn't like the idea of unmapping such a window and ignores the request; the point at which the process freezes is when it's waiting for an UnmapNotify event that never comes.

Anyway, I had forgotten that an application might want to hide a foreign window using SDL API functions. In that case, the immediate problem can be solved by changing SDL_RecreateWindow to not call SDL_HideWindow on foreign windows, as is done in the attached patch. That said, I'm not entirely sure of the purpose of hiding the window there in the first place, so I don't know if that would break something for foreign windows that don't have this problem.

Either way, though, that solution leaves another problem unsolved. When SDL_VideoQuit is called, it will destroy the foreign window, which entails trying to hide it, causing an infinite wait in the same place when the UnmapNotify event never arrives. I can't think of a solution to that problem without changing existing API behavior, unless a new SDL_WINDOW_NOHIDE flag were added indicating that SDL should not try to destroy or hide the window. Even that would be awkward since SDL_CreateWindowFrom doesn't have a flags parameter.

On 2014-04-18 04:56:28 +0000, Bryan Cain wrote:

Created attachment 1625
proposed patch v2

On 2014-04-18 05:52:51 +0000, Sam Lantinga wrote:

You're actually not supposed to pass child windows to SDL_CreateWindowFrom() - it only really works on toplevel windows.

Is there an easy way to tell whether a window is a toplevel window or not? At the very least we can flag it when we create the window and then not try to hide and show those.

On 2014-04-18 09:05:48 +0000, Bryan Cain wrote:

I wasn't aware that SDL_CreateWindowFrom() was exclusive to toplevel windows. A number of console emulators on Linux (FCEUX, Gens/GS, and probably others) depend on the ability to make SDL render into a child window. It's possible in SDL 1.2 using the SDL_WINDOWID environment variable hack, and I'd hate to see such programs stuck with the older version because of it.

I did look into how to how to tell whether a window is a child. I managed to put together a function that does so on window managers implementing EWMH by retrieving the list of toplevel windows and scanning it from newest to oldest, looking for either the window (in which case it is toplevel) or its parent (in which case the window is a child). It defaults to toplevel if it fails to find anything. This approach means that children of child windows won't be detected as such, but that seems like a reasonable enough restriction given that child windows aren't supported at all currently.

I'm attaching a new version of the patch that implements this solution, and fixes both infinite waits.

On 2014-04-18 09:06:35 +0000, Bryan Cain wrote:

Created attachment 1626
proposed patch v3

On 2014-04-18 09:09:58 +0000, Bryan Cain wrote:

Created attachment 1627
proposed patch v3 (with typo fix)

After uploading the last patch, I noticed that there was an extra zero in the value of SDL_WINDOW_CHILD.

On 2014-04-19 21:59:00 +0000, Sam Lantinga wrote:

According to the X11 documentation, if you call MapWindow on a window who's ancestor is currently hidden, it will simply mark the window eligible for viewing and not generate any events.

Can you query the window's parent and see if it's visible? Will that do the trick? Failing that, can you query the window's parent and see if it's the root window?

On 2014-04-22 18:36:28 +0000, Bryan Cain wrote:

Simply querying the window's parent won't work because under modern window managers, the parent of a visible window may be a "virtual root" rather than the actual X root window. There's a way to query the virtual roots in the EWMH specification, but neither Metacity nor Compiz seems to implement it, and both use virtual roots.

Barring the workaround in my latest patch, do you think it would be a good idea to add a way to specify via the API whether a window is a child, e.g. a SDL_CreateWindowFromWithFlags or SDL_SetWindowChild function? After all, a worse version of this problem is going to come up when implementing CreateWindowFrom in the Wayland backend, since the core Wayland protocol provides no way for clients to query any property of a surface (or any other object).

On 2014-07-29 22:18:15 +0000, Alvin wrote:

Created attachment 1794
Do not wait for X11 replies whenr Withdrawing or raising a Xlib Window.

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.

On 2014-07-29 22:43:50 +0000, Alvin wrote:

Disclaimer: I am, by no means, an Xlib expert! Please correct me if my patch has any undesirable side effects (Xlib, SDL2, etc.) and/or my assumption, that the GUI toolkit consumes the UnmapEvent or MapEvent Xlib events, is wrong.

On 2015-08-06 18:09:56 +0000, Alvin wrote:

Created attachment 2234
Do not wait for X11 reply when withdrawing or raising a Xlib Window

Updated patch to be applied to SDL2 HG 6c7e2f0747f7

FWIW, I have been using this patch for sometime without any issues. No issues with embedding a SDL_Window inside of a FLTK managed window. Used it in openSUSE 13.2, Ubuntu 14.04 and 15.04.

On 2016-01-28 09:41:34 +0000, Rafał Mużyło wrote:

Chances are you hate me-toos, but me too.

That is if I try doing SDL_CreateWindowFrom on non-toplevel windows created by gtk2/gtk3 and qt4, I'm getting likely the same freeze and patch from comment 13 helps.

On 2017-08-14 17:29:50 +0000, Sam Lantinga wrote:

I went ahead and implemented Alvin's fix. We might need to come back to the parent issue with your patch, Bryan, but I'll do the more targeted fix for now.
https://hg.libsdl.org/SDL/rev/47a5a4999180

Thanks!

On 2018-04-16 12:51:53 +0000, Liu-shua wrote:

(In reply to Alvin from comment # 11)

Created attachment 1794 [details]
Do not wait for X11 replies whenr Withdrawing or raising a Xlib Window.

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.

Hello,I am very interested in SDL2+FLTK,but I don't understand how to Embed the SDL_Window inside a FLTK application.Can you provide an example of a code?

This bug was marked as RESOLVED LATER in Bugzilla, so it wasn't automatically closed here.

@slouken slouken removed the bug label May 11, 2022
@slouken slouken added the abandoned Bug has been abandoned for various reasons label Nov 4, 2023
@slouken
Copy link
Collaborator

slouken commented Nov 4, 2023

SDL 2.0 is now in maintenance mode, and all inactive issues are being closed. If this issue is impacting you, please feel free to reopen it with additional information.

@slouken slouken closed this as not planned Won't fix, can't repro, duplicate, stale Nov 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
abandoned Bug has been abandoned for various reasons
Projects
None yet
Development

No branches or pull requests

2 participants