Screens flicker when calling glViewport after window style was changed - windows

In my OpenGL application I switch between windowed and fullscreen mode using
Raymond Chen's solution:
http://blogs.msdn.com/b/oldnewthing/archive/2010/04/12/9994016.aspx
This works apart from two very annoying side effects when used in a
multi-monitor setup (only):
After the window mode was switched BOTH screens flicker/flash just in the
moment glViewport is called to accommodate the changed window dimensions.
Windows on the desktop from other applications are not painted correctly
after the switch until I e.g. minimize/maximize them (or do something similar
to force a refresh).
Does one know these effects and maybe also knows a solution?
ps: further tests showed that this only happens on my PC with an AMD card but not with my Nvidia card. If only one monitor is active it doesn't happen at all.

Related

Expected DWM behavior when an app goes full-screen

Q1: What is the expected behavior of DWM in multi-monitor setup (extended) when one of monitors is covered by a full-screen (D3D11) application (not a maximized borderless window)?
1. all remaining screens should be blank
2. all remaining screens should be actively refreshed
3. ?
Q2: Should/can applications setup DWM's behavior anyhow when they go full-screen (I mean: force it to do 1/2/3)?
I've read DXGI: Best Practices but it does not really consider DWM coexisting with a full-screen app in a multi-monitor setup.
Additional info:
I can see DWM behaving differently in such cases depending on the particular app (mine or 3rd party), the machine app is run on or even a particular run of the same app on the same machine. Googling reveals that I'm not the only one who's experienced these inconsistencies, e.g.:
a) gaming.stackexchange.com - contents of the second screen shifted
b) forums.geforce.com - second monitor blank
Thanks,
kalesony
CodeAngry: you've described behavior when application is using maximized, borderless window, not a "real full-screen" as mentioned in question.

Hide window when other application in fullscreen mode (pseudo fullscreen)

I have an application for Windows which is basically a toolbar on top of all windows.
Unfortunately, our users ask why does it overlap a fullscreen video playing in Google Chrome. Since the application works with no issues along with other fullscreen applications (such as games), it seems to be a pseudo fullscreen mode. How do we hide the toolbar in such cases?
Right now there is only one idea: keep an eye on MoveWindow, compare window class name against a predefined list and rectangle against screen size then deduce whether it is the 'pseuso fullscreen' mode. Any better ideas?

discontinuous BitBlt capture

I am using BitBlt heavily in my project. I create a number of threads and in each thread I capture the screen by BitBlt. It works great and as expected for now except the following problem.
The problem happens when the user clicks on a running program or for example already opened explorer on the taskbar. You know when you click on the running program on the taskbar, it either minimizes or appears on the screen. The issue that I am talking about happens just in this transition. At that moment, something like an interrupt, all threads stop capturing the screen for a fraction of a second and then they continue capturing. The same thing happen when you move down or up the thing on the volume control window. Could you please shed some light why this is happening and how I can prevent this happening?
Thanks.
Jay
It could be a scheduling issue. When you activate an app, it gets a small, momentary boost in its priority (so that it can seem responsive in the UI). This boost might last about as long as the animation and momentarily pre-empt your screen capture threads.
It's also possible that the desktop manager is serializing stuff, and your bitblts are simply stalled until the animation is over. Even if you've turned Aero off, I believe the desktop window manager may still be in compositing mode, which has the effect Hans Passant was describing in the comments.
If you're trying to make a video from the screen, I think it's going to be impossible to rely on GDI. I strongly suggest reading about the Desktop Window Manager. For example, this caveat directly applies to what you're trying to do:
Avoid reading from or writing to a display DC. Although supported by DWM, we do not recommend it because of decreased performance.
When you use GDI to try to read the screen, DWM has to stop what it's doing, possibly render a fresh copy of the desktop to video memory, and to copy data from video memory back to system memory. It's possible that the DWM treats these as lower-priority requests than an animation in progress, so by the time it responds to the BitBlt, the animation is over.
This question suggests that DirectShow with a screen capture filter might be the way to go.

Dragging a window over another causes a repaint of underlying window (Windows Vista, Windows 7)

On my system, this is a problem if you have a 3D application with running, which takes some time to redraw, and drag any window over it. It causes a very jerky movement. This also happens if you drag a dialog from the 3D app over its 3D window. The application actually gets a redraw message (WM_PAINT?) which causes it to do a full redraw. Shouldn't the background window be cached by Windows as a bitmap or something?
I've pasted the NVIDIA system information dump below, note that I have 2 GPUs. Don't know if that's significant, but we're seeing this problem on another machine in the office, which also has 2 GPUs and Windows 7. Other machines which have 1 GPU don't have this problem.
Found out what the issue was. I was running Windows Vista Basic color scheme, instead of Aero. In basic, Windows probably only has one buffer for the whole screen, so whenever a window is moved, any window it overlaps must be redrawn. In Aero, each windows' "buffer" is cached to enable gpu accelerated blending (for the transparent parts of the window). So in Aero, there's no redraw of underlying windows as a result of dragging another window across it.

Does Windows 7 treat full-screen applications differently?

I have a hidden process that waits for non-standard hardware button messages and runs an application (with CreateProcess). No problem with the user disturbing, it's an action that the user approved himself. Everything is fine when it's usual layout with taskbar shown and multiply captioned and non captioned- windows. But the situation is different in XP and 7, when the current application is full-screen. Full-screen application in this case is window without borders having exactly the same dimension as the screen. Windows hides taskbar for such application even if it's always on.
In Xp, it's ok, the taskbar is being shown in this case and appication (for example calculator) also, the full-screen app is still visible in areas other than the launched app's and taskbar'. But in Windows 7 nothing visual happens, the full-screen app is still on and if I switch to taskbar, the executed application is there. I tried to solve it with SetForegroundWindow, BringWindowToTop, even AllowSetForegroundWindow(GetCurrentProcessId()) call for a window handle found with CreateProcess-WaitForIntputIdle-EnumThreadWindows, no change. So did something change since XP related to full-screen windows that officially documented?
Thanks,
Max
I would imagine that, if you have your own hardware device, that there is some API for generating "real" user input. Clearly the legacy keyboard and mouse, and now USB HID drivers (many of which are usermode I think?) have access to an API to do so.
Synergy+ for example can generate fake keyboard and mouse events on connected PCs, and the consequence of the faked input is windows switching activation normally.
So, my initial idea is for your usermode "Device" application to synthesize actual keyboard messages - SendInput seems a likely candidate for "the API that can "fake" real user input events.
Then, use an API like RegisterHotKey in your "UI" app to respond to the hotkey combination your device app generates.
Now, (assuming that SendInput IS generating user input events at the correct level), you should (from within the WM_HOTKEY handler in your UI app) have permission (because everything was "user initiated") to change the foreground window (to yourself).
Vista introduced the desktop composition feature. In short, all windows are drawing to a memory bitmaps and the Desktop Window Manager is then composing these bitmaps and drawing on a full-screen Direct3D surface. Full-screen windows do not participate in the desktop composition and get to draw directly on the screen (mostly because the majority of full-screen apps are games that need real-time screen updates).
In particular, this means that when a full screen app is up and running, it is covering the DWM composed image and the user needs to switch to a DWM-managed window for the DWM to start drawing on top of the full-screen app.
I don't have a good solution for your problem, unfortunately. One way to solve it would be to add the WS_CAPTION style to your app and then handle WM_NCPAINT/WM_NCCALCSIZE/WM_NCHITTEST yourself. This would allow you to lie to the DWM that you are a regular windowed application, but change visually your NC area to look like you have no title. However, this does require certain amount of additional code and might be a bit more effort you want to invest.
Another way you can try to solve your problem is to explicitly minimize your full-screen application window when launching the new process. However, you will then have to solve the problem of when to maximize it back again.
Btw, you might find the comments on this post from Raymond Chen interesting.
Windows supports multiple desktops and my guess would be that the full screen up is using a different desktop than the default one (where your application will be shown). A desktop object in Windows is "a logical display surface and contains user interface objects such as windows, menus, and hooks". For example, screen savers normally are started on a separate desktop.
You can find out which desktop an application is running on using Process Explorer:
Set Process Explorer to replace Task Manager and to run always on top.
When your full screen up is shown, launch Process Explorer by pressing Ctrl + Shift + Esc
Within Process Explorer, select the full screen process and press Ctrl + H to display the handles of this process
See the value of the Desktop item in the list. Usually this would be set to Default
If you know what desktop this app is running on you can start your process on the same desktop by first calling OpenDesktop to get a handle to this desktop and then pass it into the STARTUPINFO of your CreateProcess call.

Resources