Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

X11/GLX - Fullscreen mode?

I am trying to create a Linux application - a screensaver, in this case - and it is proving remarkably difficult to find information on the simple task of making a window full-screen. Even the code of existing screensavers makes no mention of how they manage it, and I've yet to see any obvious function like XRemoveDecoration().

After much fumbling around, I did manage to create a window that's the same size as the desktop, with this:

Window win = DefaultRootWindow(disp);
XWindowAttributes getWinAttr;
XGetWindowAttributes(disp, win, &getWinAttr);
win = XCreateWindow(disp, win, 0, 0, getWinAttr.width, getWinAttr.height, 0, vInfo->depth, InputOutput, vInfo->visual, CWBorderPixel|CWColormap|CWEventMask|CWOverrideRedirect, &winAttr );

But that doesn't do anything to get rid of the titlebar and borders. I know there's a way, obviously - but I have yet to find anything even pointing in that direction that doesn't rely on some other massive library being thrown on top (which existing screensavers are definitely not using).

EDIT: Please don't remove information from my posts. There is a very good reason I explicitly pointed out that existing screensavers aren't using optional libraries, and that is because I have been analyzing source code for most of the past day.

I have chosen the answer that most directly answers the question, and applies to applications in general.

If you have found this question researching xscreensavers... the same still applies. Yes, xscreensaver has its own API - which is complicated, and actually involves writing more lines of code (yes, seriously). If you want OpenGL in your screensaver, you'll need to go through another API (xlockmore, a competing system) and a compatibility layer that translates it to xscreensaver.

However, xscreensaver is capable of running any program that can use virtual root windows (look into vroot.h) as a screensaver. So my advice is to just do that - you'll have more control, no limiting API, and greater portability. (One example I looked at can even compile for Linux or Windows, with the same file!)

like image 710
DigitalMan Avatar asked Jan 30 '12 14:01

DigitalMan


People also ask

How do I force a window to full screen?

The easiest way to go full screen in an application or a game is to use the Alt + Enter keyboard shortcut. This method works for most games and apps unless they use it to enable other features. The shortcut is also used to switch from full-screen mode to windowed.

Does Linux have exclusive fullscreen?

It seems that there is simply no support for actual/exclusive fullscreen mode on Linux. I would love for this feature to be added (for instance utilizing Vulkan's VK_EXT_full_screen_exclusive).

How do I get out of fullscreen mode?

Exit Full Screen by Hitting the F11 Key You can also press the F11 key on your keyboard to exit full screen on Windows 10. The F11 key is a function key and is often used to enter and exit full-screen mode.

Why do my apps not open full screen?

Enable Full screen view on selected apps. Make sure you are on the Aspect ratio tab, and then tap your desired app. Select Full screen or App default as your preferred view.


6 Answers

One way is to bypass the window manager:

XSetWindowAttributes wa;                                                     
wa.override_redirect = True;                                           
XCreateWindow( ..., &wa );
like image 121
eile Avatar answered Oct 26 '22 04:10

eile


The piece of information you lack is, that the screensavers are not responsible for going fullscreen. The screensaver daemon will manage the screensaver window, put it into the dedicated screensaver window layer and make it full screen.

So for writing a screensaver you're in the clear. If you were about writing a fullscreen game, you's have to set the Override Redirect attribute to prevent the window from getting managed by the WM and make it cover the whole screen.

like image 35
datenwolf Avatar answered Oct 26 '22 05:10

datenwolf


Best and easier way to achieve it is to use the ICCCM Specification atom which will work for most recent Window Managers. Just use the following code:

Atom wm_state   = XInternAtom (display, "_NET_WM_STATE", true );
Atom wm_fullscreen = XInternAtom (display, "_NET_WM_STATE_FULLSCREEN", true );

XChangeProperty(display, window, wm_state, XA_ATOM, 32,
                PropModeReplace, (unsigned char *)&wm_fullscreen, 1);

Your window might be transparent, if so, just use XSetBackground() function where you need it and it's done.

like image 40
Fábio Moreira Avatar answered Oct 26 '22 05:10

Fábio Moreira


I found freeglut fullscreen works well, even when hosting shader based opengl application inside. Here the internal code that get called (X11 branch...). HTH

#define _NET_WM_STATE_TOGGLE    2
static int fghResizeFullscrToggle(void)
{
    XWindowAttributes attributes;

    if(glutGet(GLUT_FULL_SCREEN)) {
        /* restore original window size */
        SFG_Window *win = fgStructure.CurrentWindow;
        fgStructure.CurrentWindow->State.NeedToResize = GL_TRUE;
        fgStructure.CurrentWindow->State.Width  = win->State.OldWidth;
        fgStructure.CurrentWindow->State.Height = win->State.OldHeight;

    } else {
        /* resize the window to cover the entire screen */
        XGetWindowAttributes(fgDisplay.Display,
                fgStructure.CurrentWindow->Window.Handle,
                &attributes);

        /*
         * The "x" and "y" members of "attributes" are the window's coordinates
         * relative to its parent, i.e. to the decoration window.
         */
        XMoveResizeWindow(fgDisplay.Display,
                fgStructure.CurrentWindow->Window.Handle,
                -attributes.x,
                -attributes.y,
                fgDisplay.ScreenWidth,
                fgDisplay.ScreenHeight);
    }
    return 0;
}

static int fghEwmhFullscrToggle(void)
{
    XEvent xev;
    long evmask = SubstructureRedirectMask | SubstructureNotifyMask;

    if(!fgDisplay.State || !fgDisplay.StateFullScreen) {
        return -1;
    }

    xev.type = ClientMessage;
    xev.xclient.window = fgStructure.CurrentWindow->Window.Handle;
    xev.xclient.message_type = fgDisplay.State;
    xev.xclient.format = 32;
    xev.xclient.data.l[0] = _NET_WM_STATE_TOGGLE;
    xev.xclient.data.l[1] = fgDisplay.StateFullScreen;
    xev.xclient.data.l[2] = 0;  /* no second property to toggle */
    xev.xclient.data.l[3] = 1;  /* source indication: application */
    xev.xclient.data.l[4] = 0;  /* unused */

    if(!XSendEvent(fgDisplay.Display, fgDisplay.RootWindow, 0, evmask, &xev)) {
        return -1;
    }
    return 0;
}

static int fghToggleFullscreen(void)
{
    /* first try the EWMH (_NET_WM_STATE) method ... */
    if(fghEwmhFullscrToggle() != -1) {
        return 0;
    }

    /* fall back to resizing the window */
    if(fghResizeFullscrToggle() != -1) {
        return 0;
    }
    return -1;
}


#endif  /* TARGET_HOST_POSIX_X11 */
like image 37
CapelliC Avatar answered Oct 26 '22 04:10

CapelliC


Try looking at this for an example:

Really Slick Screensavers Port to GLX http://rss-glx.sourceforge.net/

Look at the createWindow() function in driver.c.

like image 45
fdk1342 Avatar answered Oct 26 '22 06:10

fdk1342


It's absolutely not difficult. You just have to add the right atom to the right list as described here.

like image 35
moongoal Avatar answered Oct 26 '22 04:10

moongoal