SDL2 应用程序在 Xmonad 中无法正常工作

SDL2 applications do not work correctly in Xmonad

使用 SDL2, for instance games built with pygame and the Mednafen emulator, do not work correctly with the default Xmonad 配置的程序。当它们以全屏模式启动时,它们的 window 不会显示。这是一个 SDL2 程序的最小可重现示例,它无法显示其 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;
}

你可以用命令cc main.c -o main -D_REENTRANT -I/usr/include/SDL2 -lSDL2编译这个程序。

这是重现问题的最小 xmonad 配置文件。请注意,我使用的是 xmonad v0.15 和 SDL v2.0.14。

import XMonad

main = xmonad $ def {
  modMask = mod4Mask
  }

如果一切正确,该程序应显示 window 640 x 480 像素的红色背景 3 秒,然后退出。但是,我可以让它与 Xmonad 一起工作的唯一方法是指定以下 manageHook:

import XMonad

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

目前,我的 Xmonad 配置中有许多这样的异常,可以使 SDL2 程序在每个应用程序的基础上运行。这很烦人,尤其是因为 SDL1.2 应用程序 - 最值得注意的是 DOSBox - 没有这个问题。

所以,我的问题是:

虽然我对正在发生的事情的细节没有太多要说的,但我显然通过戳我自己的 xmonad.hs 成功地重现了你的问题。从中删除对 ewmh 的调用后,运行 您的程序会生成一个空的全屏 window,而不是红色的。既然如此,将您的最低配置更改为...

import XMonad
import XMonad.Hooks.EwmhDesktops

main = xmonad $ ewmh def {
  modMask = mod4Mask
  }

...可能会解决问题。

当您使用它时,您可能希望启用 XMonad.Hooks.EwmhDesktops 提供的额外全屏支持,某些应用程序需要它才能正常工作。这是 xmonad-contrib 0.16...

的样子
import XMonad
import XMonad.Hooks.EwmhDesktops

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

... 以及 post-0.16 版本,例如 GitHub 的最新版本,遵循 a changelog entry 的建议:

import XMonad
import XMonad.Hooks.EwmhDesktops

main = xmonad $ ewmhFullscreen $ ewmh def {
  modMask = mod4Mask,
  }