简体   繁体   中英

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:

  • 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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM