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/win3…
==============================================================================
--- 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/win3…
==============================================================================
--- 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);