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

问题描述

使用 SDL2 的程序,例如使用 pygameMednafen 模拟器构建的游戏,在Xmonad 配置下无法正常运行。当它们以全屏模式启动时,它们的窗口不会显示。这是一个 SDL2 程序无法显示其窗口的最小可重现示例:

#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,640,480,SDL_WINDOW_FULLSCREEN
                            );
  screen = SDL_GetwindowSurface(window);
  SDL_FillRect(screen,NULL,SDL_MapRGB(screen->format,255,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
  }

如果一切正常,该程序应显示一个 640 x 480 像素的红色背景窗口 3 秒钟,然后退出。但是,我可以让它与 Xmonad 一起使用的唯一方法是指定以下 manageHook

import XMonad

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

目前,在我的 Xmonad 配置中有很多这样的例外,使 SDL2 程序在每个应用程序的基础上工作。这很烦人,尤其是因为 SDL1.2 应用程序 - 最显着的是 DOSBox - 没有这个问题。

所以,我的问题是:

  • 这是 SDL 还是 Xmonad 的问题?
  • 这个问题的原因是什么?
  • 如何重写上述程序以在 Xmonad 下正常工作?

解决方法

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

xmonad.hs

... 可能会解决问题。

在此过程中,您可能希望启用 import XMonad import XMonad.Hooks.EwmhDesktops main = xmonad $ ewmh def { modMask = mod4Mask } 提供的额外全屏支持,某些应用程序需要这些支持才能正常工作。下面是 xmonad-contrib 0.16 的样子...

XMonad.Hooks.EwmhDesktops

... 以及 0.16 之后的版本,例如来自 GitHub 的最新版本,遵循 a changelog entry 的建议:

import XMonad
import XMonad.Hooks.EwmhDesktops

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