[ros-diffs] [fireball] 47947: - Implement basic support for topmost window handling. Currently limited only to windows created with this flag, no change on-the-fly. Also, moving windows with contents hasn't been fixed yet either to support always on top windows.

fireball at svn.reactos.org fireball at svn.reactos.org
Mon Jul 5 11:43:27 UTC 2010


Author: fireball
Date: Mon Jul  5 11:43:26 2010
New Revision: 47947

URL: http://svn.reactos.org/svn/reactos?rev=47947&view=rev
Log:
- Implement basic support for topmost window handling. Currently limited only to windows created with this flag, no change on-the-fly. Also, moving windows with contents hasn't been fixed yet either to support always on top windows.

Modified:
    branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h
    branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c

Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h?rev=47947&r1=47946&r2=47947&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h [iso-8859-1] Mon Jul  5 11:43:26 2010
@@ -7,6 +7,7 @@
     rectangle_t Window;
     struct region *Visible;
     BOOLEAN Hidden;
+    BOOLEAN Topmost;
     PCURSORICONENTRY Cursor;
 
     LIST_ENTRY Entry;

Modified: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c?rev=47947&r1=47946&r2=47947&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] Mon Jul  5 11:43:26 2010
@@ -23,6 +23,8 @@
 void req_update_window_zorder( const struct update_window_zorder_request *req, struct update_window_zorder_reply *reply );
 
 PSWM_WINDOW NTAPI SwmGetTopWindow();
+PSWM_WINDOW NTAPI SwmGetForegroundWindow(BOOLEAN TopMost);
+
 VOID NTAPI SwmClipAllWindows();
 
 VOID NTAPI SwmDumpRegion(struct region *Region);
@@ -340,7 +342,7 @@
 NTAPI
 SwmAddWindow(HWND hWnd, RECT *WindowRect, DWORD style, DWORD ex_style)
 {
-    PSWM_WINDOW Win;
+    PSWM_WINDOW Win, FirstNonTop;
 
     DPRINT("SwmAddWindow %x\n", hWnd);
     DPRINT("rect (%d,%d)-(%d,%d), style %x, ex_style %x\n",
@@ -349,8 +351,6 @@
 
     /* Acquire the lock */
     SwmAcquire();
-
-    if (ex_style & WS_EX_TOPMOST) DPRINT1("Creating a topmost window, ignoring\n");
 
     /* Allocate entry */
     Win = ExAllocatePool(PagedPool, sizeof(SWM_WINDOW));
@@ -364,10 +364,21 @@
     Win->Visible = create_empty_region();
     set_region_rect(Win->Visible, &Win->Window);
 
-    /* Now go through the list and remove this rect from all underlying windows visible region */
-    //SwmMarkInvisible(Win->Visible);
-
-    InsertHeadList(&SwmWindows, &Win->Entry);
+    /* Set window's flags */
+    if (ex_style & WS_EX_TOPMOST) Win->Topmost = TRUE;
+
+    /* Add it to the zorder list */
+    if (Win->Topmost)
+    {
+        /* It's a topmost window, just add it on top */
+        InsertHeadList(&SwmWindows, &Win->Entry);
+    }
+    else
+    {
+        /* Find the first topmost window and insert before it */
+        FirstNonTop = SwmGetForegroundWindow(FALSE);
+        InsertHeadList(FirstNonTop->Entry.Blink, &Win->Entry);
+    }
 
     /* Now ensure it is visible on screen */
     SwmInvalidateRegion(Win, Win->Visible, &Win->Window);
@@ -475,10 +486,8 @@
         return;
     }
 
+    /* Remove it from the zorder list */
     RemoveEntryList(&Win->Entry);
-
-    /* Mark this region as visible in other window */
-    //SwmMarkVisible(Win->Visible);
 
     /* Free the entry */
     free_region(Win->Visible);
@@ -490,6 +499,7 @@
     SwmRelease();
 }
 
+// FIXME: This one is deprecated and will be removed soon
 PSWM_WINDOW
 NTAPI
 SwmGetTopWindow()
@@ -514,6 +524,38 @@
     return NULL;
 }
 
+PSWM_WINDOW
+NTAPI
+SwmGetForegroundWindow(BOOLEAN TopMost)
+{
+    PLIST_ENTRY Current;
+    PSWM_WINDOW Window;
+
+    /* Traverse the list to find top non-hidden window */
+    Current = SwmWindows.Flink;
+    while(Current != &SwmWindows)
+    {
+        Window = CONTAINING_RECORD(Current, SWM_WINDOW, Entry);
+
+        if (TopMost)
+        {
+            /* The first visible window */
+            if (!Window->Hidden) return Window;
+        }
+        else
+        {
+            /* The first visible non-topmost window */
+            if (!Window->Hidden && !Window->Topmost) return Window;
+        }
+
+        Current = Current->Flink;
+    }
+
+    /* There should always be a desktop window */
+    ASSERT(FALSE);
+    return NULL;
+}
+
 
 VOID
 NTAPI
@@ -522,7 +564,7 @@
     PSWM_WINDOW Previous;
 
     /* Save previous focus window */
-    Previous = SwmGetTopWindow();
+    Previous = SwmGetForegroundWindow(SwmWin->Topmost);
 
     /* It's already on top */
     if (Previous->hwnd == SwmWin->hwnd)
@@ -536,8 +578,16 @@
     /* Remove it from the list */
     RemoveEntryList(&SwmWin->Entry);
 
-    /* Add it to the head of the list */
-    InsertHeadList(&SwmWindows, &SwmWin->Entry);
+    if (SwmWin->Topmost)
+    {
+        /* Add it to the head of the list */
+        InsertHeadList(&SwmWindows, &SwmWin->Entry);
+    }
+    else
+    {
+        /* Bringing non-topmost window to foreground */
+        InsertHeadList(Previous->Entry.Blink, &SwmWin->Entry);
+    }
 
     /* Make it fully visible */
     free_region(SwmWin->Visible);




More information about the Ros-diffs mailing list