1

Programs using SDL2, for instance games built with pygame and the Mednafen emulator, do not work correctly with the default Xmonad configuration. When they are started in fullscreen mode, their window isn't shown. Here is a minimal reproducible example of an SDL2 program that fails to show its window:

#include "SDL.h"
#include <stdio.h>

int main(int argc, char* argv[]) {
  SDL_Window *window;
  SDL_Surface *screen;
  SDL_Init(SDL_INIT_VIDEO);
  window = SDL_CreateWindow("Example Window",
                            SDL_WINDOWPOS_UNDEFINED,
                            SDL_WINDOWPOS_UNDEFINED,
                            640, 480,
                            SDL_WINDOW_FULLSCREEN
                            );
  screen = SDL_GetWindowSurface(window);
  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 0));
  SDL_UpdateWindowSurface(window);
  SDL_Delay(3000);
  SDL_DestroyWindow(window);
  SDL_Quit();
  return 0;
}

You can compile this program with the command cc main.c -o main -D_REENTRANT -I/usr/include/SDL2 -lSDL2.

Here is a minimal xmonad configuration file that reproduces the problem. Note that I am using xmonad v0.15 and SDL v2.0.14.

import XMonad

main = xmonad $ def {
  modMask = mod4Mask
  }

If everything is correct, this program should show a window of 640 by 480 pixels with a red background for 3 seconds, then exit. However, the only way I can get this to work with Xmonad is by specifying the following manageHook:

import XMonad

main = xmonad $ def {
  modMask = mod4Mask,
  manageHook = composeAll [className =? "main" --> doIgnore]
  }

Currently, there are many such exceptions in my Xmonad configuration to make SDL2 programs work on a per-app basis. This is annoying, especially because SDL1.2 applications - most notably DOSBox - do not have this problem.

So, my questions are:

  • Is this a problem with SDL or with Xmonad?
  • What is the cause of this issue?
  • How can I rewrite the program above to work correctly under Xmonad?
Jaap Joris Vens
  • 3,382
  • 2
  • 26
  • 42
  • 1
    Im not an expert at SDL2 by any means, but I think SDL (not SDL2) runs off a surface as a screen and SDL2 runs off an ```SDL_Renderer```? Have you tried with a renderer instead of a surface? – Ggsgn Hdjwngnf Jan 17 '21 at 21:28
  • I have tried to reproduce the issue, and it seems to be working fine here: I get a 640x480 window upscaled to fullscreen just in the way you describe. You might want to specify which versions of xmonad and xmonad-contrib you are using and add your xmonad.hs (or a minimal version thereof that reproduces the issue) to the question. – duplode Jan 18 '21 at 00:07
  • Thank you very much for your effort! I have updated the post with version numbers and a minimal xmonad configuration file. – Jaap Joris Vens Jan 18 '21 at 09:36

1 Answers1

1

While I don't have much to say about the details of what's going on, I apparently succeeded in reproducing your issue by poking at my own xmonad.hs. After removing the call to ewmh from it, running your program resulted in an empty fullscreen window, rather than a red one. That being so, changing your minimal configuration to...

import XMonad
import XMonad.Hooks.EwmhDesktops

main = xmonad $ ewmh def {
  modMask = mod4Mask
  }

... will likely fix the issue.

While you're at it, you'll probably want to enable the additional fullscreen support offered by XMonad.Hooks.EwmhDesktops, which some applications require to work correctly. Here's how it looks like with xmonad-contrib 0.16...

import XMonad
import XMonad.Hooks.EwmhDesktops

main = xmonad $ ewmh def {
  modMask = mod4Mask,
  handleEventHook = handleEventHook def <+> fullscreenEventHook
  }

... and with post-0.16 versions, such as recent builds from GitHub, following a recommendation from a changelog entry:

import XMonad
import XMonad.Hooks.EwmhDesktops

main = xmonad $ ewmhFullscreen $ ewmh def {
  modMask = mod4Mask,
  }
duplode
  • 33,731
  • 7
  • 79
  • 150
  • Thank you so much. I could have never figured this out myself! You are right, the C example program now runs correctly. However, I am still experiencing problems with games written in [pygame](https://pygame.org). I have updated my original question with a pygame example. – Jaap Joris Vens Jan 19 '21 at 06:55
  • @hedgie Your pygame program behaves in the same way under Xfce, so it isn't a XMonad issue. I'm not familiar with pygame, but it seems you need a game loop for things to work properly (see, for instance, [this Q&A](https://stackoverflow.com/q/57642415/2751851)). Additionally, I believe you didn't mean to reassign `screen` in `screen = screen.fill((255,0,0))`. I suggest asking a separate question about those issues, if need be. – duplode Jan 19 '21 at 13:34
  • You are completely right, I have removed the pygame issue from the question. Thanks again for helping me out! – Jaap Joris Vens Jan 19 '21 at 14:06