Opening a fullscreen OpenGL window

青春壹個敷衍的年華 提交于 2019-12-03 01:32:46

Don't know about GLFW, perhaps it's buggy, but X11 fullscreen windows don't work like that. Any window manager worth its salt will force the window to fit the (single, non-virtual) screen.

You want to either bypass the window manager completely (use OverrideRedirect window attribute), or ask your WM to cooperate (use window property _NET_WM_STATE_FULLSCREEN). The first approach has numerous drawbacks, so let's use the second one. The following program will display a window on your display, and then toggle it to the full-screen mode:

#include <X11/X.h>
#include <X11/Xlib.h>
#include <strings.h>
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>

int main ()
{
    Display* dis = XOpenDisplay(NULL);
    Window win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 0, 0, 10, 10,
                                     0, BlackPixel (dis, 0), BlackPixel(dis, 0));

    Atom wm_state = XInternAtom(dis, "_NET_WM_STATE", False);
    Atom fullscreen = XInternAtom(dis, "_NET_WM_STATE_FULLSCREEN", False);

    XEvent xev;
    memset(&xev, 0, sizeof(xev));
    xev.type = ClientMessage;
    xev.xclient.window = win;
    xev.xclient.message_type = wm_state;
    xev.xclient.format = 32;
    xev.xclient.data.l[0] = 1;
    xev.xclient.data.l[1] = fullscreen;
    xev.xclient.data.l[2] = 0;

    XMapWindow(dis, win);

    XSendEvent (dis, DefaultRootWindow(dis), False,
                    SubstructureRedirectMask | SubstructureNotifyMask, &xev);

    XFlush(dis);
    /*Sleep 5 seconds before closing.*/
    sleep(5);
    return(0);

}

You probably to use your real screen dimensions for the window from the start, in order to avoid any resize animation effect.

I didn't try this on a multihead system because I don't have one, but on a single display system it works properly (covers the panel, removes window decorations etc). Please let me know if it works for you.

Update They say for multihead to work, you need to use _NET_WM_FULLSCREEN_MONITORS property (see here). It's an array of 4 integers that should be set like this:

    Atom fullmons = XInternAtom(dis, "_NET_WM_FULLSCREEN_MONITORS", False);
    XEvent xev;
    memset(&xev, 0, sizeof(xev));
    xev.type = ClientMessage;
    xev.xclient.window = win;
    xev.xclient.message_type = fullmons;
    xev.xclient.format = 32;
    xev.xclient.data.l[0] = 0; /* your topmost monitor number */
    xev.xclient.data.l[1] = 0; /* bottommost */
    xev.xclient.data.l[2] = 0; /* leftmost */
    xev.xclient.data.l[3] = 1; /* rightmost */
    xev.xclient.data.l[4] = 0; /* source indication */

    XSendEvent (dis, DefaultRootWindow(dis), False,
                    SubstructureRedirectMask | SubstructureNotifyMask, &xev);

With this, you should be able to set your fullscreen windows to occupy a single monitor, the entire desktop, or (for more than 2 monitors) anything in between.

I have not checked this because I don't have a multihead system.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!