ecere/gui/Win32Interface: (#285) Fixed handling lock/fullscreen change
authorJerome St-Louis <jerome@ecere.com>
Wed, 9 Jul 2014 01:16:52 +0000 (21:16 -0400)
committerJerome St-Louis <jerome@ecere.com>
Wed, 9 Jul 2014 03:27:21 +0000 (23:27 -0400)
- Problem introduced by 2a9a3ae6df44c1a17d65136540cb29386e0f5e97
- Calling both ShowWindow() and SetWindowPlacement() caused a strange effect
 sometimes noticed when logging back in from a locked screen or when an application
 went fullscreen, happening every time when going fullscreen in a debugged app.
- Was mistakingly assuming that WM_MAXIMIZE activates, while only WM_SHOWMAXIMIZED does
- Setting 'state' data member from SetRootWindowState() to avoid redundant states being set
  again from WM_SIZE thinking that a user initiated the change
- Setting initial lastBits and lastRes on startup to avoid processing WM_DISPLAYCHANGE for the
  initial settings
- Checking whether the foreground window is taking up the fullscreen and not processing
  WM_DISPLAYCHANGE when that is the case

ecere/src/gui/drivers/Win32Interface.ec

index a7be975..b02dd85 100644 (file)
@@ -112,6 +112,9 @@ static byte key2VK[256] =
 static const uint16 className[] = L"Ecere Application";
 static HINSTANCE hInstance;
 
+static WPARAM lastBits;
+static LPARAM lastRes;
+
 static DEVMODE devMode;
 #ifndef ECERE_NODINPUT
 static HWND acquiredWindow = null;
@@ -176,6 +179,18 @@ static bool activateApp;
 
 static SystemCursor lastCursor = (SystemCursor)-1;
 
+static void SmartShowWindow(HWND windowHandle, WindowState state, bool doActivate)
+{
+   int showCmd;
+   if(state == maximized)
+      showCmd = doActivate ? SW_SHOWMAXIMIZED : SW_MAXIMIZE;
+   else if(state == minimized)
+      showCmd = SW_MINIMIZE;
+   else
+      showCmd = doActivate ? SW_SHOWNORMAL : SW_SHOWNOACTIVATE;
+   ShowWindow(windowHandle, showCmd);
+}
+
 void AeroSnapPosition(Window window, int x, int y, int w, int h)
 {
    int oldX = window.absPosition.x;
@@ -611,19 +626,26 @@ class Win32Interface : Interface
             }
             case WM_DISPLAYCHANGE:
             {
-               static int lastBits = 0;
-               static int lastRes = 0;
-               if(lastBits != wParam || lastRes != lParam)
+               if(!guiApp.fullScreenMode && (lastBits != wParam || lastRes != lParam))
                {
-                  lastBits = (int)wParam;
-                  lastRes = (int)lParam;
+                  RECT rect;
+                  HWND foregroundWindow = GetForegroundWindow();
+                  int w = LOWORD(lParam);
+                  int h = HIWORD(lParam);
+
+                  GetWindowRect(foregroundWindow, &rect);
+                  if(rect.right == w && rect.bottom == h)
+                     break;
+
+                  lastBits = wParam;
+                  lastRes = lParam;
 
                   externalDisplayChange = true;
                   if(guiApp.desktop.DisplayModeChanged())
                   {
                      char caption[2048];
                      if(!window.style.hidden)
-                        ShowWindow(windowHandle, SW_SHOWNOACTIVATE /*SW_SHOWNORMAL*/);
+                        SmartShowWindow(window.windowHandle, (window.nativeDecorations && window.state == maximized) ? maximized : normal, false);
                      window.FigureCaption(caption);
                      SetRootWindowCaption(window, caption);
                   }
@@ -1173,6 +1195,11 @@ class Win32Interface : Interface
          null,
          className
       };
+      HDC hdc = GetDC(0);
+      lastRes = MAKELPARAM(GetSystemMetrics(SM_CYSCREEN), GetSystemMetrics(SM_CXSCREEN));
+      lastBits = (WPARAM)GetDeviceCaps(hdc, BITSPIXEL);
+      ReleaseDC(0, hdc);
+
       AttachConsole(-1);
       wcl.hInstance = hInstance = GetModuleHandle(null);
       RegisterClass(&wcl);
@@ -1535,27 +1562,19 @@ class Win32Interface : Interface
    {
       if(visible)
       {
+         WindowState curState = window.state;
+         *&window.state = state;
          switch(state)
          {
             case maximized:
             case normal:
-            {
-               if((window.active || window.creationActivation == activate) && !externalDisplayChange)
-                  ShowWindow(window.windowHandle, (window.nativeDecorations && state == maximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
-               else
-               {
-                  WINDOWPLACEMENT plc = { 0 };
-                  GetWindowPlacement(window.windowHandle, &plc);
-                  plc.showCmd = (window.nativeDecorations && state == maximized) ? SW_MAXIMIZE : SW_SHOWNORMAL;
-                  ShowWindow(window.windowHandle, SW_SHOWNOACTIVATE);
-                  SetWindowPlacement(window.windowHandle, &plc);
-               }
+               SmartShowWindow(window.windowHandle, window.nativeDecorations ? state : normal, (window.active || window.creationActivation == activate) && !externalDisplayChange);
                break;
-            }
             case minimized:
                ShowWindow(window.windowHandle, SW_MINIMIZE);
                break;
          }
+         *&window.state = curState;
       }
       else
       {