如何在Linux中创建Alt+Tab友好的全屏程序(如游戏)



我想创建一个应用程序,在该应用程序中,我可以在窗口上绘制,无论是窗口还是全屏,我可以抓住鼠标,但不会拦截任何WM键盘快捷键,如Alt+Tab,而且每当用户输入/离开焦点时,我也需要得到通知。

像Google Chrome、Firefox或gnome终端这样的常见应用程序可以很好地处理这一问题(使用F11进行全屏显示,但仍具有Alt+Tab),但它们不会抓住鼠标。

SDL对这个用例的处理非常糟糕:SDL_WM_GrabInput抓取鼠标,但也拦截WM快捷方式;SDL_ FULLSCREEN本身似乎有某种自动抓取功能(不要问我为什么)。

一个解决方案可能是自己为Alt+Tab编写代码,但这很糟糕(对其他WM快捷方式没有帮助,比如更改到另一个工作区)。

另一种解决方案是不调用SDL_WM_GrabInput,而是伪造抓取:只需隐藏鼠标指针(使用SDL_ShowCursor),并在用户移动时将其移回中心即可。这很难看,但在实践中是有效的——当然,SDL_FULLSCREEN除外,因为它是自动抓取的(与正常的实现不同)。一个支持全屏的SDL解决方案就是这样,但这仍然不是我想要的。我不想让黑客启用和禁用抓取,我想抓取鼠标,但不想抓取键盘。

所以我对SDL很生气,希望看到其他选择。我希望使用SDL,但这不是必须的。

这个问题似乎指出SDL实际做的是使用XGrabKeyboard。通过阅读手册页,我不清楚你是否可以在不抓住键盘的情况下抓住鼠标(我自己从未使用过Xlib)。

我知道如何用GTK制作"假全屏"(也就是说,对Alt+Tab友好的gnome终端)。我想这样做,再加上鼠标隐藏并将其移回中心("假抓取")可以达到效果,但这感觉像是胶带太多了。一定有更简单的方法。(我也不想添加GTK作为依赖项;但我也不确定进行原始Xlib调用是否是个好主意)。

对此有什么好的解决方案?

我需要一个Linux/X11解决方案,但如果它是跨平台的,那就太好了——我知道这可以在Windows上顺利解决,所以也许有一个库可以做到这一点。(同样,我用OpenGL渲染,但这无关紧要)

附言:也许我对这个问题的理解不好,我没有问正确的问题,所以请随意指出我没有考虑过的方法。

这些天我一直在Linux上使用Gtk和GtkGLExt进行游戏(例如,我的Ludum Dare条目)。这里(gtk.cGist)是我的代码,我已经在FreeBSD许可证下发布了它。您可以看到我为调试窗口状态更改而注释掉的代码。我应该提到的是,这是我在Ludum Dare等应用程序中使用的一个更大框架的一部分,我更喜欢它而不是SDL,原因与您提到的相同:生成的应用程序更符合用户对其平台(Linux、OS X、Windows)上本机应用程序的期望。不用说,走这条路是一项艰巨的工作。

然而,原始的X11编程却是一团糟。我估计我需要几周的扎实编程和阅读文档才能将Gtk代码转换为X11代码;这对我来说不值得,但你可能会做出不同的决定。(许多小时只是为了消除每个人都安装的依赖项!)Gtk依赖项实际上并没有那么离谱,它可能已经加载到内存中了,2.x的ABI非常稳定,所以不会影响二进制兼容性。

X11游戏编程的一个大问题是,事件处理完全是一团糟。你不能轻易地对事件进行投票。Xlib接口是阻塞的,所以你必须使用一系列神秘的函数调用来读取数据,检查是否有挂起的事件,然后只读取队列中存在的事件(否则你的应用程序将阻塞,直到事件出现)。xcb库是Xlib的替代品,Xlib在所有方面都要好得多,并且支持非阻塞接口,但它不能很好地与OpenGL配合使用。所以你可以试着把两者混合,或者你可以只使用Gtk。

让我给你一个全屏的Gtk代码片段:

static void toggle_fullscreen()
{
    if (sg_gtk_status & SG_STATUS_VISIBLE) {
        if (sg_gtk_status & SG_STATUS_FULLSCREEN)
            gtk_window_unfullscreen(sg_window);
        else
            gtk_window_fullscreen(sg_window);
    }
}

想象一下X11界面需要做多少工作:计算屏幕的大小(可能不止一个!),调整窗口的大小,改变顺序,使其处于其他一切之上,改变装饰,然后在用户切换虚拟桌面时做出智能响应。布拉!(实际上,这描述了我的代码在OSX上的工作方式,但API要好得多。)

更重要的是,如果您使用X11,您必须学习如何以预期的方式对用户做出反应。X11来自20世纪80年代。相比之下,Gtk为您的应用程序提供了一系列来自Gtk的UI设计器的适当默认值。UI设计就是工作。记住:您可以将X11和Gtk混合使用。

总结:X11编程是为有大量空闲时间的程序员准备的。

注意:GtkGLExt添加了一个烦人的链接器标志-Wl,--export-dynamic。我的构建脚本从pkg-config的输出中删除了该标志。

X11体验:我想我花了大约一周的时间试图在X11中完成整个工作,在这个过程中我遇到了很多死胡同。从我的失败中吸取教训。

最新更新