问题描述
使用 SDL2 的程序,例如使用 pygame 和 Mednafen 模拟器构建的游戏,在默认 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
}