[User32]
authorJames Tabor <james.tabor@reactos.org>
Sun, 1 Jun 2014 22:32:24 +0000 (22:32 +0000)
committerJames Tabor <james.tabor@reactos.org>
Sun, 1 Jun 2014 22:32:24 +0000 (22:32 +0000)
- Fix recursive loops during Alt+Esc and Tab. Dedicated to Hermès Bélusca-Maïto.

svn path=/trunk/; revision=63531

reactos/win32ss/user/user32/controls/appswitch.c

index 4b2800b..5e1f7ce 100644 (file)
@@ -17,7 +17,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
 #define MAX_WINDOWS 120
 
 // Global variables
-HWND switchdialog;
+HWND switchdialog = NULL;
 HFONT dialogFont;
 int selectedWindow = 0;
 BOOL isOpen = FALSE;
@@ -334,19 +334,26 @@ void ProcessHotKey()
 
 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
 {
-   HWND hwnd;
+   HWND hwnd, hwndActive;
    MSG msg;
    BOOL Esc = FALSE;
    INT Count = 0;
    WCHAR Text[1024];
 
-   switchdialog = NULL;
+   // Already in the loop.
+   if (switchdialog) return 0;
+
+   hwndActive = GetActiveWindow();
+   // Nothing is active so exit.
+   if (!hwndActive) return 0;
+   // Capture current active window.
+   SetCapture( hwndActive );
 
    switch (lParam)
    {
       case VK_TAB:
-         if( !CreateSwitcherWindow(User32Instance) ) return 0;
-         if( !GetDialogFont() ) return 0;
+         if( !CreateSwitcherWindow(User32Instance) ) goto Exit;
+         if( !GetDialogFont() ) goto Exit;
          ProcessHotKey();
          break;
 
@@ -354,7 +361,7 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
          windowCount = 0;
          Count = 0;
          EnumWindowsZOrder(EnumerateCallback, 0);
-         if (windowCount < 2) return 0;
+         if (windowCount < 2) goto Exit;
          if (wParam == SC_NEXTWINDOW)
             Count = 1;
          else
@@ -373,7 +380,7 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
          break;
 
       default:
-         return 0;
+         goto Exit;
    }
    // Main message loop:
    while (1)
@@ -471,6 +478,7 @@ LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam )
       }
    }
 Exit:
+   ReleaseCapture();
    if (switchdialog) DestroyWindow(switchdialog);
    switchdialog = NULL;
    selectedWindow = 0;