ecere/gui/XInterface; Win32Interface: Fixes to FlashWindow to flash owner instead
[sdk] / ecere / src / gui / drivers / Win32Interface.ec
index c13f059..9239168 100644 (file)
@@ -102,19 +102,23 @@ import "Window"
 static byte key2VK[256] =
 {
    0,VK_ESCAPE,'1','2','3','4','5','6','7','8','9','0',VK_MINUS,VK_EQUALS,VK_BACK,VK_TAB,
-   'Q','W','E','R','T','Y','U','I','O','P',VK_LBRACKET,VK_RBRACKET,VK_RETURN,VK_CONTROL,'A','S',
-   'D','F','G','H','J','K','L',VK_SEMI,VK_QUOTE,VK_TILDE,VK_SHIFT,VK_BACK_SLASH,'Z','X','C','V',
-   'B','N','M',VK_COMMA,VK_PERIOD,VK_DIVIDE,VK_SHIFT,VK_MULTIPLY,VK_LMENU,VK_SPACE,VK_CAPITAL,VK_F1,VK_F2,VK_F3,VK_F4,VK_F5,
+   'Q','W','E','R','T','Y','U','I','O','P',VK_LBRACKET,VK_RBRACKET,VK_RETURN,VK_LCONTROL,'A','S',
+   'D','F','G','H','J','K','L',VK_SEMI,VK_QUOTE,VK_TILDE,VK_LSHIFT,VK_BACK_SLASH,'Z','X','C','V',
+   'B','N','M',VK_COMMA,VK_PERIOD,VK_DIVIDE,VK_RSHIFT,VK_MULTIPLY,VK_LMENU,VK_SPACE,VK_CAPITAL,VK_F1,VK_F2,VK_F3,VK_F4,VK_F5,
    VK_F6,VK_F7,VK_F8,VK_F9,VK_F10,VK_NUMLOCK,VK_SCROLL,VK_NUMPAD7,VK_NUMPAD8,VK_NUMPAD9,VK_SUBTRACT,VK_NUMPAD4,VK_NUMPAD5,VK_NUMPAD6,VK_ADD,VK_NUMPAD1,
    VK_NUMPAD2,VK_NUMPAD3,VK_NUMPAD0,VK_DELETE,0,0,0,VK_F11,VK_F12,0,0,0,0,0,0,0,
-   0,0,0,0,0,0,VK_HOME,VK_UP,VK_PRIOR,VK_LEFT,VK_RIGHT,VK_END,VK_DOWN,VK_NEXT,VK_INSERT,VK_DELETE,
-   0,0,0,VK_SHIFT,VK_MENU,VK_CONTROL
+   0,VK_RCONTROL,0,0,VK_RMENU,0,VK_HOME,VK_UP,VK_PRIOR,VK_LEFT,VK_RIGHT,VK_END,VK_DOWN,VK_NEXT,VK_INSERT,VK_DELETE
 };
-static char className[] = "ECERE Application";
+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;
+#endif
 static HCURSOR systemCursors[SystemCursor];
 static bool fullScreenMode;
 static int desktopX = 0, desktopY = 0, desktopW = 0, desktopH = 0;
@@ -175,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;
@@ -235,14 +251,12 @@ class Win32Interface : Interface
       int c;
       static double lastTime = 0, time;
       int x = 0, y = 0;
-      int w, h;
-      static Size lastScreen;
-      static Point lastScreenPos;
-      static WINDOWPLACEMENT lastPlacement;
-      static int tryAgain;
+      int w = 0, h = 0;
+      //static Size lastScreen;
+      //static Point lastScreenPos;
       static double lastAutoHideCheck = 0;
       int newTaskBarState = taskBarState;
-      HMONITOR primaryMonitor;
+      HMONITOR primaryMonitor = 0;
 
       time = GetTime();
       if(time - lastTime < 0.1) return;
@@ -350,8 +364,8 @@ class Win32Interface : Interface
             guiApp.SetDesktopPosition(x, y, w, h, updateChildren);
          }
 
-         lastScreen = guiApp.virtualScreen;
-         lastScreenPos = guiApp.virtualScreenPos;
+         //lastScreen = guiApp.virtualScreen;
+         //lastScreenPos = guiApp.virtualScreenPos;
       }
    }
 
@@ -551,7 +565,7 @@ class Win32Interface : Interface
                   }
                   else
                   {
-                     Window window;
+                     //Window window;
 
                      if(wParam && !guiApp.desktop.active /*&& lParam != GetCurrentThreadID()*/)
                      {
@@ -612,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);
                   }
@@ -641,7 +662,7 @@ class Win32Interface : Interface
             //case WM_DEADCHAR:
             {
                MSG charMsg;
-               DWORD min, max;
+               DWORD min = 0, max = 0;
 
                if(msg != WM_CHAR && window.composing)
                   break;
@@ -650,7 +671,7 @@ class Win32Interface : Interface
                {
                   case WM_SYSKEYDOWN: min = max = WM_SYSCHAR; break;
                   case WM_KEYDOWN: min = max = WM_CHAR; break;
-                  case WM_SYSKEYUP: min = WM_SYSCHAR;  max = WM_SYSDEADCHAR; break;
+                  case WM_SYSKEYUP: min = WM_SYSCHAR; max = WM_SYSDEADCHAR; break;
                   case WM_KEYUP: min = WM_CHAR; max = WM_DEADCHAR; break;
                }
 
@@ -925,7 +946,7 @@ class Win32Interface : Interface
             {
                RECT * rect = (RECT *)lParam;
                MinMaxValue ew, eh;
-               int x, y, w, h;
+               int w, h;
 
                window.GetDecorationsSize(&ew, &eh);
 
@@ -1105,8 +1126,6 @@ class Win32Interface : Interface
 
    void ::AcquireDirectInput(HWND windowHandle, bool state)
    {
-      POINT oldPosition;
-
       if((state && !acquiredWindow) || (!state && acquiredWindow == windowHandle))
       {
          int j;
@@ -1176,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);
@@ -1266,11 +1290,11 @@ class Win32Interface : Interface
 
    }
 
-   char ** GraphicsDrivers(int * numDrivers)
+   const char ** GraphicsDrivers(int * numDrivers)
    {
-      static char *graphicsDrivers[] = { "GDI", "DirectDraw", "OpenGL", "Direct3D", "Direct3D8", "Direct3D9" };
+      static const char *graphicsDrivers[] = { "GDI", "DirectDraw", "OpenGL", "Direct3D", "Direct3D8", "Direct3D9" };
       *numDrivers = sizeof(graphicsDrivers) / sizeof(char *);
-      return (char **)graphicsDrivers;
+      return (const char **)graphicsDrivers;
    }
 
    void GetCurrentMode(bool * fullScreen, Resolution * resolution, PixelFormat * colorDepth, int * refreshRate)
@@ -1458,7 +1482,7 @@ class Win32Interface : Interface
 
    // -- Window manipulation ---
 
-   void SetRootWindowCaption(Window window, char * name)
+   void SetRootWindowCaption(Window window, const char * name)
    {
       uint16 * text = UTF8toUTF16(name, null);
       guiApp.Unlock();
@@ -1499,7 +1523,6 @@ class Win32Interface : Interface
 
    void SetRootWindowColor(Window window)
    {
-      DWORD style = GetWindowLong(window.windowHandle, GWL_EXSTYLE);
       if(window.alphaBlend && window.display.pixelFormat == pixelFormat888)
       {
          /*if(A(window.background) == 255)
@@ -1510,6 +1533,7 @@ class Win32Interface : Interface
          else*/
          {
 #ifndef ECERE_NOBLENDING
+            DWORD style = GetWindowLong(window.windowHandle, GWL_EXSTYLE);
             if((style & WS_EX_LAYERED) != WS_EX_LAYERED)
                SetWindowLong(window.windowHandle, GWL_EXSTYLE, style | WS_EX_LAYERED);
 #endif
@@ -1538,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
       {
@@ -1574,9 +1590,14 @@ class Win32Interface : Interface
 
    void FlashRootWindow(Window window)
    {
+      HWND hwnd = window.windowHandle;
       FLASHWINFO flashInfo = { 0 };
+      Window master = window.master, rootWindow = (master && master != guiApp.desktop) ? master.rootWindow : null;
+      if(!window.style.showInTaskBar && rootWindow && (window._isModal || window.style.interim))
+         hwnd = rootWindow.windowHandle;
+
       flashInfo.cbSize = sizeof(FLASHWINFO);
-      flashInfo.hwnd = window.windowHandle;
+      flashInfo.hwnd = hwnd;
       flashInfo.uCount = 1;
       flashInfo.dwFlags = FLASHW_TRAY; // FLASHW_ALL;
       guiApp.Unlock();
@@ -1595,7 +1616,8 @@ class Win32Interface : Interface
       {
          SetWindowPos(window.windowHandle, HWND_TOPMOST, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
          mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
-         SetWindowPos(window.windowHandle, HWND_NOTOPMOST, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
+         if(!window.stayOnTop)
+            SetWindowPos(window.windowHandle, HWND_NOTOPMOST, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
       }
    }
 
@@ -1675,7 +1697,7 @@ class Win32Interface : Interface
       bool result = false;
       if(clipBoard.text)
       {
-         uint wordCount;
+         int wordCount;
          uint16 * u16text = UTF8toUTF16(clipBoard.text, &wordCount);
          wordCount++;
          clipBoard.handle = GlobalAlloc(GHND | GMEM_DDESHARE, wordCount * 2);
@@ -1831,18 +1853,25 @@ class Win32Interface : Interface
    bool GetKeyState(Key key)
    {
       bool keyState = false;
-      if(key < 256)
+      if(key < 256 || key == alt || key == shift || key == control)
       {
-         if(key2VK[key])
-            keyState = GetAsyncKeyState(key2VK[key]);
-         keyState = (keyState & 0x80000) ? true : false;
+         uint ks = 0;
+         if(key == alt)
+            ks = GetAsyncKeyState(VK_MENU);
+         else if(key == control)
+            ks = GetAsyncKeyState(VK_CONTROL);
+         else if(key == shift)
+            ks = GetAsyncKeyState(VK_SHIFT);
+         else if(key2VK[key])
+            ks = GetAsyncKeyState(key2VK[key]);
+         keyState = (ks & 0x80000) ? true : false;
       }
       else if(key == capsState)
-         keyState = ::GetKeyState(VK_CAPITAL) & 0x00000001;
+         keyState = (::GetKeyState(VK_CAPITAL) & 0x00000001) != 0;
       else if(key == numState)
-         keyState = ::GetKeyState(VK_NUMLOCK) & 0x00000001;
+         keyState = (::GetKeyState(VK_NUMLOCK) & 0x00000001) != 0;
       else if(key == scrollState)
-         keyState = ::GetKeyState(VK_SCROLL) & 0x00000001;
+         keyState = (::GetKeyState(VK_SCROLL) & 0x00000001) != 0;
       return keyState;
    }