SDL2 fixed aspect ratio window on Linux

Here’s how to get a fixed aspect ratio window using SDL2 on linux. When it comes to getting a fixed aspect ratio window, SDL2 just leaves you to die. So you have to go behind its back and talk to the window manager. This will be different on Windows, Mac, and Wayland. Here I only consider the X11 situation. On linux, we can give the X11 window manager a hint.

#ifdef __linux
/* This is for constraining the aspect ratio of the window since SDL2 left us to die. */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <SDL2/SDL_syswm.h> /* for SDL_GetWindowWMInfo() */
#endif


static void constrain_aspect_ratio_via_xlib(SDL_Window *window, int w, int h)
{
#ifdef __linux
        SDL_SysWMinfo info;
        Display *display;
        Window xwindow;
        long supplied_return;
        XSizeHints *hints;
        Status s;

        SDL_VERSION(&info.version);
        if (!SDL_GetWindowWMInfo(window, &info)) {
                fprintf(stderr, "SDL_GetWindowWMInfo failed.\n");
                return;
        }

        if (info.subsystem != SDL_SYSWM_X11) {
                fprintf(stderr, "Apparently not X11, no aspect ratio constraining for you!\n");
                return;
        }
        display = info.info.x11.display;
        xwindow = info.info.x11.window;
        hints = XAllocSizeHints();
        if (!hints) {
                fprintf(stderr, "Failed to allocate size hints\n");
                return;
        }
        s = XGetWMSizeHints(display, xwindow, hints, &supplied_return, XA_WM_SIZE_HINTS);
        if (s) {
                fprintf(stderr, "XGetWMSizeHints failed\n");
                XFree(hints);
                return;
        }
        hints->min_aspect.x = SCREEN_WIDTH;
        hints->min_aspect.y = SCREEN_HEIGHT;
        hints->max_aspect.x = SCREEN_WIDTH;
        hints->max_aspect.y = SCREEN_HEIGHT;
        hints->flags = PAspect;
        XSetWMNormalHints(display, xwindow, hints);
        XFree(hints);
#endif
}

Then just call constrain_aspect_ratio_via_xlib() and pass it a pointer to your SDL_Window and the width and height ratio you want to enforce.

When you compile and link your program you’ll need some extra arguments:

X11LIBS=$(shell $(PKG_CONFIG) --libs x11)
X11CFLAGS=$(shell $(PKG_CONFIG) --cflags x11)

Typically X11CFLAGS comes out empty, and X11LIBS comes out to “-lX11”, so you can just add “-lX11” to the end of your linker flags most likely.

There’s a stackoverflow question here that has some hints but doesn’t go into a lot of detail. I would have updated that question, but stackoverflow has been inhabited by assholes since about 2009, so, nope.

~ by scaryreasoner on April 21, 2020.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: