Jaap Joris Vens
Jaap Joris Vens

Reputation: 3550

SDL2 applications do not work correctly in Xmonad

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:

Upvotes: 1

Views: 289

Answers (1)

duplode
duplode

Reputation: 34378

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,
  }

Upvotes: 1

Related Questions