How to create full-fledged full-screen Alt + Tab programs (for example, games) in Linux?

I want to create an application in which I draw a window, either in windowed or in fullscreen mode, where I have a captured mouse, but without intercepting any keyboard shortcuts, such as Alt + Tab, and I also need to be notified when the user Enters / leaves focus.

Regular apps like Google Chrome, Firefox, or gnome-terminal can handle this just fine (in full screen with F11, but with Alt + Tab), but they don't capture the mouse.

SDL has the notorious poor handling of this use case: SDL_WM_GrabInput captures the mouse, but also captures WM keyboard shortcuts; and SDL_FULLSCREEN seems to have a kind of automatic capture on its own (don't ask me why).

The solution may be to write the code for Alt + Tab yourself, but this sucks (and does not help for other WM shortcuts, for example, to move to another workspace).

Another solution is not to call SDL_WM_GrabInput, but instead fake the capture: just hide the mouse pointer (with SDL_ShowCursor) and move it back to the center whenever the user moves. Which is ugly, but works in practice - except, of course, for SDL_FULLSCREEN, because it captures automatically (as opposed to normal implementations). It is an SDL solution with full screen support, but it is still not what I want. I do not want to have hacks to enable or disable capture, I want to capture a mouse, but miss the keyboard.

So, I'm angry with SDL and want to see alternatives. I would like to use SDL, but this is optional.

This question seems to indicate that the SDL actually uses the XGrabKeyboard. When reading the man page, itโ€™s not immediately clear to me whether you can grab the mouse without grabbing the keyboard (I never used Xlib).

I know how to make "fake full-screen mode" with GTK (i.e. friendly Alt + Tab, a kind of gnome-terminal). I believe this, combined with hiding the mouse and moving it back to the center (โ€œfake gripโ€), can do the trick, but it looks like too much masking tape. There should be an easier way. (Also, I don't want to add GTK to the dependency, but I'm also not sure that making raw Xlib calls is a good idea).

What is a good solution for this?

I need a Linux / X11 solution, but it would be nice to be cross-platform - I know this can be easily resolved on Windows, so maybe there is a library that does just that. (also, I render using OpenGL, but that doesn't matter)

PS: Perhaps I have a poor understanding of this problem, and I am not asking the right question, so feel free to indicate approaches that I have not considered.

+6
source share
1 answer

I used Gtk and GtkGLExt for games on Linux these days (like my Ludum Dare entries). Here ( ) is my code, I released it under the FreeBSD license. You can see the code that I commented out to debug window state changes. I have to mention that this is part of a much larger structure that I use for things like Ludum Dare, and I prefer its SDL for exactly the same reasons you are talking about: the resulting applications more closely match users' expectations for their own applications on their platforms (Linux, OS X, Windows). Needless to say, there is a lot of work on this route.

Raw X11 software, however, is a real mess. I guess I will need a couple of weeks of solid programming and reading documents to convert my Gtk code to X11 code; it just doesn't stand for me, but you can decide differently. (Many watches simply eliminate the addiction that they have all the same installed!). Gtk's interdependence is actually not so outrageous, it is probably already loaded into memory, and ABI for 2.x is very stable, so this will not damage binary compatibility.

The big problem with programming X11 for games is that event handling is a complete mess. You cannot easily interrogate events. The Xlib interface is blocked, so you need to use a secret sequence of function calls to read data, check that there are events waiting for events, and then only read events from the queue if they exist (otherwise your application will be blocked until events occur). The xcb library is an alternative to Xlib that works much better and supports a non-blocking interface, but it does not work well with OpenGL. So you can try mixing these two together, or you can just use gtk.

Let me give you a Gtk code snippet for full screen mode:

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); } } 

Just imagine how much work with the X11 interface will be: specify the screen size (maybe more than one!), Change the window size, change the order so that it exceeds everything else, change the scenery, and then respond intelligently when the user switches virtual desktops. Blah! (In fact, this describes how my code works on OS X, but the API is much nicer.)

Moreover, if you use X11, you need to learn how to respond to the user in the expected way. X11 - since the 1980s. Gtk, by comparison, gives your application a series of appropriate default values โ€‹โ€‹from the developers of the Gtk interface. User interface design is work. And remember: you can just mix X11 with Gtk.

Summary: X11 programming for programmers with plenty of free time.

Notes: GtkGLExt adds the annoying linker flag -Wl,--export-dynamic . My build scripts remove the flag from pkg-config output.

X11 experience: I think I spent about a week trying to get everything that works in X11, and in the end I ended up a lot of dead ends. Find out about my failures.

+4
source

All Articles