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... ============================================================================== --- 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... ============================================================================== --- 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);