morgant / mlvwm

Macintosh-like Virtual Window Manager (official repo)
http://www2u.biglobe.ne.jp/~y-miyata/mlvwm.html
275 stars 8 forks source link

ioquake3 fails to create window #23

Open morgant opened 3 years ago

morgant commented 3 years ago

ioquake3 fails to create a window with the following logged to the terminal:

----- R_Init -----
SDL using driver "x11"
Initializing OpenGL display
Display aspect: 1.778
...setting mode -1: 1920 1080
tty]X Error of failed request:  BadMatch (invalid parameter attributes)
  Major op code of failed request:  42 (X_SetupInputFocus)
  Serial number of failed request:  157
  Current serial number in output stream:  158
morgant commented 3 years ago

0ad also fails with the same error, though the serial numbers are different.

morgant commented 3 years ago

This seems related to this issue from SDL: X_setInputfocus BadMatch 42. It mentions needing to call XSync() and, when comparing mlvwm.c to fvwm.c in OpenBSD's Xenocara, the major difference seems to be an added XSync(dpy, 0); in Reborder() in the latter. So, that seems the likely cause.

morgant commented 3 years ago

Strange, doesn't seem to fix it.

ThomasAdam commented 3 years ago

Hey @morgant

Hope you don't mind, but I took a look at this (since you seem to be using fvwm to crib from), and I think all you need to do is make mlvwm support the _NET_WM_NAME and _NET_SUPPORTING_WM_CHECK XAtoms, as this is what SDL2 uses to determine whether it's using a WM or not to set properities on its windows.

I've not tested the below, but I believe it should work for you:

% git diff
diff --git a/mlvwm/mlvwm.c b/mlvwm/mlvwm.c
index b39be9f..f4cfdac 100644
--- a/mlvwm/mlvwm.c
+++ b/mlvwm/mlvwm.c
@@ -293,6 +293,9 @@ Atom _XA_WM_PROTOCOLS;
 Atom _XA_WM_TAKE_FOCUS;
 Atom _XA_WM_DELETE_WINDOW;
 Atom _XA_WM_DESKTOP;
+Atom _NET_SUPPORTING_WM_CHECK;
+Atom _NET_WM_NAME;
+Atom utf8string;

 void InternUsefulAtoms (void)
 {
@@ -307,6 +310,9 @@ void InternUsefulAtoms (void)
        _XA_WM_TAKE_FOCUS = XInternAtom (dpy, "WM_TAKE_FOCUS", False);
        _XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
        _XA_WM_DESKTOP = XInternAtom (dpy, "WM_DESKTOP", False);
+       _NET_SUPPORTING_WM_CHECK = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False);
+       _NET_WM_NAME = XInternAtom(dpy, "_NET_WM_NAME", False);
+       utf8string = XInternAtom(dpy, "UTF8_STRING", False);

        return;
 }
@@ -681,6 +687,13 @@ int main( int argc, char *argv[] )
        CreateMenuBar();
        LoadDefaultFonts();

+       XChangeProperty(dpy, Scr.NoFocusWin, _NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
+               PropModeReplace, (unsigned char *) &Scr.NoFocusWin, 1);
+       XChangeProperty(dpy, Scr.NoFocusWin, _NET_WM_NAME, utf8string, 8,
+               PropModeReplace, (unsigned char *) "mlvwm", 5);
+       XChangeProperty(dpy, Scr.Root, _NET_SUPPORTING_WM_CHECK, XA_WINDOW, 32,
+               PropModeReplace, (unsigned char *) &Scr.NoFocusWin, 1);
+
        if( Scr.flags & DEBUGOUT )
                DrawStringMenuBar( "Read Config File !" );
        ReadConfigFile( config_file? config_file : CONFIGNAME );
morgant commented 3 years ago

@ThomasAdam Huge thanks for your taking the time to look into this and propose a fix! I know that MLVWM is very behind on supported XAtoms (it's based on fvwm from 1997 or so) and I didn't even think to investigate that as a potential cause in this particular case.

Your proposed fix does allow ioquake3 & 0ad to launch under MLVWM! 0ad works without issue, but ioquake3 plays the intro video, then hangs X shortly after rendering the menu. Interestingly, it also causes chrome to not render some of the window borders. I'll dig into these issues.

Would you mind pointing me to where in the SDL2 source you found how it determines whether it's using a WM? Only if it's easy for you to find again, of course. The reason I ask is, OpenBSD's version of fvwm 2.xx (which I'm comparing with both because that's what I'm testing against and because it still has a license compatible with MLVWM's), doesn't use any of the _NET_* extended window manager hints, see: https://github.com/openbsd/xenocara/blob/e26c45de6dcbcdbd24a9f4c0b565fc5b1fb86b1e/app/fvwm/fvwm/fvwm.c#L799. So, I'm curious to figure out which of the hints that fvwm is using is allowing SDL to work.

Again, I can't thank you enough for assisting with this as it pointed me in the right direction and gave me a massive head start.

morgant commented 3 years ago

@ThomasAdam Looks like I found the SDL X11 WM code here, so no need to answer that question for me: https://github.com/libsdl-org/SDL/blob/main/src/video/x11/SDL_x11window.c

ThomasAdam commented 3 years ago

@ThomasAdam Huge thanks for your taking the time to look into this and propose a fix! I know that MLVWM is very behind on supported XAtoms (it's based on fvwm from 1997 or so) and I didn't even think to investigate that as a potential cause in this particular case.

No problem. Glad it proves the general idea (I really hadn't done much more than write the code in the correct place, so I'm pleased you didn't end up on a wild-goose chase). I think your first task should be getting some level of EWMH support in to mlvwm. For that, you could look at fvwm's NetWM implementation (it's likely closer to mlvwm). See:

http://fvwm-ewmh.sourceforge.net/

Your proposed fix does allow ioquake3 & 0ad to launch under MLVWM! 0ad works without issue, but ioquake3 plays the intro video, then hangs X shortly after rendering the menu. Interestingly, it also causes chrome to not render some of the window borders. I'll dig into these issues.

That's going to be unrelated to the XAtom's I've introduced, but might now be because there's other EWMH-specific things which have been "unlocked" by having _NET_WM_NAME and _NET_SUPPORTING_WM_CHECK being honored.

Would you mind pointing me to where in the SDL2 source you found how it determines whether it's using a WM? Only if it's easy for you to find again, of course. The reason I ask is, OpenBSD's version of fvwm 2.xx (which I'm comparing with both because that's what I'm testing against and because it still has a license compatible with MLVWM's), doesn't use any of the NET* extended window manager hints, see: https://github.com/openbsd/xenocara/blob/e26c45de6dcbcdbd24a9f4c0b565fc5b1fb86b1e/app/fvwm/fvwm/fvwm.c#L799. So, I'm curious to figure out which of the hints that fvwm is using is allowing SDL to work.

Well, OpenBSD's version of fvwm2 in base likely has a few other things in it, although I am not clear what (I've not checked what's in Xenocara in a while). I wouldn't necessarily waste your time trying to figure that out.

In terms of SDL, sure. Have a look here (src/video/x11/SDL_x11video.c) in SDL's source tree (https://github.com/libsdl-org/SDL.git):

   354      if (!wm_window) {
   355  #ifdef DEBUG_WINDOW_MANAGER
   356          printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
   357  #endif
   358          return;
   359      }
   360      data->net_wm = SDL_TRUE;
   361  
   362  #ifdef DEBUG_WINDOW_MANAGER
   363      wm_name = X11_GetWindowTitle(_this, wm_window);
   364      printf("Window manager: %s\n", wm_name);
   365      SDL_free(wm_name);
   366  #endif
   367  }

Further on, in src/video/x11/SDL_x11window.c we see this:

  1146      if (!data->videodata->net_wm) {
  1147          /* no WM means no FocusIn event, which confuses us. Force it. */
  1148          X11_XSync(display, False);
  1149          X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime);
  1150          X11_XFlush(display);
  1151      }

Which is where you were seeing those BadMatch errors from before.



> Again, I can't thank you enough for assisting with this as it pointed me in the right direction and have me a massive head start.

Pleasure.   If you need anything else, just shout.