Fullscreen GLFW window disappears when focus is lost - c++

I am creating an OpenGL window like this:
auto mode = glfwGetVideoMode(monitor);
mWindowWidth = mode->width;
mWindowHeight = mode->height;
glfwWindowHint(GLFW_RED_BITS, mode->redBits);
glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
mWindow = glfwCreateWindow(mWindowWidth, mWindowHeight, "Test", monitor, NULL);
This works fine except for one major flaw:
When I focus another window (even if that's on a different monitor!) the GLFW window disappears in the background.
How can I create a (fullscreen) GLFW window that always stays on top on a given monitor?

The documentation for GLFW is available here http://www.glfw.org/docs/latest/window_guide.html#window_windowed_full_screen
From the above link
Section : Window related hints
GLFW_AUTO_ICONIFY specifies whether the full screen window will automatically iconify and restore the previous video mode on input focus loss. This hint is ignored for windowed mode windows.
Default Value
GLFW_TRUE
Accepted Values
GLFW_TRUE or GLFW_FALSE
Set it to GLFW_FALSE
That is
glfwWindowHint(GLFW_AUTO_ICONFIY, GLFW_FALSE);
Note that GLFW_TRUE and GLFW_FALSE are and will always be just 1 and 0.

It seems that automatic minimization on focus loss is controlled by GLFW_AUTO_ICONIFY hint, which is enabled by default.
GLFW_AUTO_ICONIFY specifies whether the full screen window will automatically iconify and restore the previous video mode on input focus loss.
This hint is ignored for windowed mode windows.
It can be disabled with:
glfwWindowHint(GLFW_AUTO_ICONIFY, 0);

Related

WIndows Flickering when changing focus in OpenGL

I'm working on a project that requires me to switch between two windows, one using OpenCV and one using OpenGL, both fullscreen.
A GLFW key event opens the OpenCV window fine, but closing the OpenCV window, and attempting to return focus to the OpenGL window results in the window flickering and repeatedly attempting to give focus. This is my code to return focus to the OpenGL window, inside a while loop.
Edit: Ive found out that it only happens when the OpenGL window is fullscreen, which is a requirement of this program. Writing to console shows that the code is being called multiple times
if(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
glfwFocusWindow(window);
while(!glfwGetWindowAttrib(window, GLFW_FOCUSED))
{
}
}
I managed to fix my problem by setting the GLFW flag GLFW_AUTO_ICONIFY to false on my openGL window.
The way you posted is not the proper way to set focus.
Use glfwSetWindowCloseCallback to set a close callback.
In that callback is where you set focus to another window.

OpenGL tearing with fullscreen native resolution

I've got an OpenGL application with win32 api without glut etc...and I run into a problem with screen tearing in fullscreen.
Basicly I have set WS_POPUP as a window style and resolution of my monitor as window size.
I'm running on AMD radeon HD 7770 and I see terrible tearing!
When I put WS_POPUPWINDOW style instead of WS_POPUP, the tearing is gone, however I have unwanted border around my scene.
Another thing I noticed is fact, that the tearing disappears when the resolution is NOT native.
So when I pass my_screen_resolution + 1 as size parameter, the tearing is gone.
RESx = 1920;
RESy = 1080;
hwnd = CreateWindowEx(NULL, NAME, NAME, WS_POPUP, 0, 0, RESx, RESy, NULL, NULL, hInstance, NULL);
SetWindowPos(hwnd, 0, -1, -1, RESx + 1, RESy + 1, 0); // With this function call, the tearing disappears!
What can I do to get rid of the tearing without having to run on not native resolution?
EDIT: (Hint: It's not V-sync)
What can I do to get rid of the tearing without having to run on not native resolution?
EDIT: (Hint: It's not V-sync)
Yes it is V-Sync.
When you make a fullscreen window, it will bypass the DWM compositor.
If the window is not covering the full screen its contents are going through the DWM compositor. The DWM compositor itself makes itself a copy of the window's contents whenever something indicates, that it is done drawing (return from WM_PAINT handler, EndPaint or SwapBuffers called). The composition itself happens V-synced.
Thanks for your advice, but I want to aviod the tearing without vsync. With vsync I have terrible input lag.
Then you're doing something wrong in your input processing. Most likely your event loop only processes one input event at a time then does a redraw. If that's the case and your scene complexity goes up, then you're getting lag, that's proportional to your scene's drawing complexity. You don't want this to happen.
What you should do is accumulate all the input events that piled up between redraws and coalesce them into a single new drawing state. Ideally input events are collected until only just before the scene is set up for drawing to reflect the most recent state. If you want to get fancy you my add a Kalman filter to predict the input state at the moment the frame gets shown to the user and use that for drawing the scene.
To remove OpenGL tearing, you should have "enable" vsync. Follow this link for details: how to enable vertical sync in opengl?

Is it possible to vsync SDL_SetVideoMode?

I am trying to change the size of the window of my app with:
mysurface = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
Although I am using vsync swapbuffers (in driver xorg-video-ati), I can see flickering when the window size changes (I guess one or more black frames):
void Video::draw()
{
if (videoChanged){
mysurface = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
scene->init(); //Update glFrustum & glViewPort
}
scene->draw();
SDL_GL_SwapBuffers();
}
So please, someone knows, if...
The SDL_SetVideoMode is not vsync'ed as is SDL_GL_SwapBuffers()?
Or is it destroying the window and creating another and the buffer is black in meantime?
Someone knows a working code to do this? Maybe in freeglut?
In SDL-1 when you're using a windowed video mode the window is completely torn down and a new one created when changing the video mode. Of course there's some undefined data inbetween, which is perceived as flicker. This issue has been addressed in SDL-2. Either use that or use a different OpenGL framework, that resizes windows without gong a full window recreation.
If you're using a FULLSCREEN video mode then something different happens additionally:
A change of the video mode actually changes the video signal timings going from the graphics card to the display. After such a change the display has to find synchronization with the new settings and that takes some time. This of course comes with some flickering as the display may try to display a frame of different timings with the old settings until it detects that those no longer match. It's a physical effect and there's nothing you can do in software to fix this, other than not changing the video mode at all.

X11 Fullscreen window (OpenGL)

I'm writing and OpenGL application on linux (Ubuntu 11.10) using Xlib (X11). What is the simplest way to implement toggle between windowed and fullscreen mode?
Here's an implementation of what Havoc P suggested, to save the next person the effort:
void fullscreen(Display* dpy, Window win) {
Atom atoms[2] = { XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False), None };
XChangeProperty(
dpy,
win,
XInternAtom(dpy, "_NET_WM_STATE", False),
XA_ATOM, 32, PropModeReplace, (unsigned char*)atoms, 1
);
}
on the protocol level, see the _NET_WM_STATE property with accompanying client message and the fullscreen state flag. this is specified in the EWMH spec. for bonus points you may want to manually implement fullscreen if the WM does not report support for the official hint, EWMH specs a way to check what is supported. You may also want to grab the mouse pointer and/or
keyboard if you don't want people to accidentally leave fullscreen.
or, to avoid learning low level X gunge, just use SDL or GTK or Qt or something and they should all have a simple method call to toggle fullscreen.

minimize fullscreen Xlib OpenGL Window

I'm currently trying to enable alt-tabbing out of my fullscreen Xlib OpenGL window, but am having some difficulties. I've tried XUnmapWindow(..), which kindof works, but the resolution does not reset (unless I should be doing that manually?) and my Xlib window does not appear as a minimized window (i.e. I can't alt-tab back into the window, even though the app still seems to be running in the background).
The next thing I tried was changing my window from fullscreen to windowed mode (i.e. re-creating the window over again in windowed mode), but obviously, I'd rather not have to do that.
I'm listening to FocusOut and FocusIn events, and the FocusOut seems to be called when I alt-tab, but I'm just not sure how to get my app to minimize properly. If I don't do anything in my code when a FocusOut event is called, my app doesn't do anything (i.e. I can't minimize the window).
Any help would be appreciated!
Edit: Unfortunately, I've been unable to get X Windows to properly minimize a fullscreen window. So, to work around this problem I've decided to destroy() the fullscreen window and then create() a new window in windowed mode. Seems to work well.
XUnmapWindow() completely removes the window from the display. Minimizing a Window happens through EMWH ICCCM state, so that the window manager knows, that the window is still there in some form. And like you already assumed you're responsible for resetting the screen resolution. This is BTW the very same in Windows.
EDIT:
Minimizing a Window in Xlib is done with XIconifyWindow, which will take care to set the right ICCCM properties, and unmaps the window. Both must be done to interact properly with the WM. However X11 only defines the methods, not the policy, so when unmapping a fullscreen window you're also responsible to reset the screen resolution, like I already wrote above.
On a side note: I suggest you don't change the resolution at all, but instead, if such is available, render to a Framebuffer Object of the target size, and map the final result to the full, native screen size. If you combine this with native resolution text/HUD overlays (I assume this is for a game or similar), you get much higher percieved quality and save the resolution switching. You may even combine this with taking a screenshot of the desktop and gradually fading to your content.
EDIT 2 for reference
:
XIconifyWindow is just a helper/convenience function, it's source code is
/*
* This function instructs the window manager to change this window from
* NormalState to IconicState.
*/
Status XIconifyWindow(Display *dpy, Window w, int screen)
{
XClientMessageEvent ev;
Atom prop;
prop = XInternAtom(dpy, "WM_CHANGE_STATE", False);
if(prop == None)
return False;
ev.type = ClientMessage;
ev.window = w;
ev.message_type = prop;
ev.format = 32;
ev.data.l[0] = IconicState;
return XSendEvent(dpy, RootWindow(dpy, screen), False,
SubstructureRedirectMask|SubstructureNotifyMask,
(XEvent *)&ev);
}
You can try to do it like this :
XEvent xev;
Atom wm_state = XInternAtom(dpy, "_NET_WM_STATE", False);
Atom wm_hide_win = XInternAtom(dpy, "_NET_WM_STATE_HIDDEN", False);
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] = _NET_WM_STATE_ADD;
xev.xclient.data.l[1] = wm_hide_win;
XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &xev);
EDIT
If you have access to gnome API, you can use wnck_window_minimize(), or take a look into the source for that function.