No way to avoid the window relocating effect in “OpenGL-
fullscreen”?
Feeling somewhat stubborn today, I “fixed” the problem by
hacking the library into saving positions of all desktop
windows at startup and WM_ACTIVATE. And then restoring
them. Works for me, and the couple of systems I could
test it with, although possibly not good idea universally.
Hmm… I was actually about to suggest that… any chance you could post
a patch?
Sure. Someone who knows a bit more about WIN32 or SDL can
improve on this, perhaps. And point out potential problems.
SDL_dx5video.c:
#ifdef WIN32_DESKTOP_SAVE
#define MAX_WINDOWS 256
static int num_windows = 0;
static HWND window_hwnd[MAX_WINDOWS];
static WINDOWPLACEMENT placement[MAX_WINDOWS];
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
if(num_windows < MAX_WINDOWS)
{
if(hwnd != SDL_Window && IsWindowVisible(hwnd))
{
placement[num_windows].length = sizeof(WINDOWPLACEMENT);
if(GetWindowPlacement(hwnd, &placement[num_windows]) != 0)
{
window_hwnd[num_windows] = hwnd;
num_windows++;
}
}
}
return TRUE;
}
void save_desktop(void)
{
num_windows = 0;
EnumWindows(EnumWindowsProc, 0);
}
void restore_desktop(void)
{
/* Okay, this may look strange. I don’t like it either.
We are always calling this right after ChangeDisplaySettings(),
and it seems that the mode change may still be taking place,
as sometimes the windows aren’t restored. The more delay I
put, the more likely it is that it will work. But if there
is much delay, the window movement is clearly visible. And
delay isn’t very robust way to do anything. But I couldn’t
find a reliable way to check if it worked or not.
*/
restore_desktop1();
SDL_Delay(500);
restore_desktop1();
}
void restore_desktop1(void)
{
int i;
for(i = 0; i < num_windows; i++)
{
HWND hwnd = window_hwnd[i];
if(IsWindow(hwnd))
{
SetWindowPlacement(hwnd, &placement[i]);
}
}
}
#endif /* WIN32_DESKTOP_SAVE */
DX5_SetVideoMode()
…
#ifndef NO_CHANGEDISPLAYSETTINGS
/* Unset any previous OpenGL fullscreen mode */
if ( (current->flags & (SDL_OPENGL|SDL_FULLSCREEN)) ==
(SDL_OPENGL|SDL_FULLSCREEN) ) {
ChangeDisplaySettings(NULL, 0);
#ifdef WIN32_DESKTOP_SAVE
restore_desktop();
#endif
}
#endif
…
#ifndef NO_CHANGEDISPLAYSETTINGS
/* Set fullscreen mode if appropriate.
Ugh, since our list of valid video modes comes from
the DirectX driver, we may not actually be able to
change to the desired resolution here.
FIXME: Should we do a closest match?
*/
#ifdef WIN32_DESKTOP_SAVE
save_desktop();
#endif
DX5_VideoQuit()
…
ChangeDisplaySettings(NULL, 0);
#ifdef WIN32_DESKTOP_SAVE
restore_desktop();
#endif
SDL_sysevents.c:
static void SDL_RestoreGameMode(void)
{
#ifndef NO_CHANGEDISPLAYSETTINGS
#ifdef WIN32_DESKTOP_SAVE
save_desktop();
#endif
ShowWindow(SDL_Window, SW_RESTORE);
ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
#endif
}
static void SDL_RestoreDesktopMode(void)
{
#ifndef NO_CHANGEDISPLAYSETTINGS
ShowWindow(SDL_Window, SW_MINIMIZE);
ChangeDisplaySettings(NULL, 0);
#ifdef WIN32_DESKTOP_SAVE
restore_desktop();
#endif
#endif
}