diff --git a/reactos/win32ss/user/winsrv/consrv/console.c b/reactos/win32ss/user/winsrv/consrv/console.c index 4fc9f7db006..fb38ef078cd 100644 --- a/reactos/win32ss/user/winsrv/consrv/console.c +++ b/reactos/win32ss/user/winsrv/consrv/console.c @@ -689,6 +689,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, InitializeListHead(&Console->ProcessList); Console->NotifiedLastCloseProcess = NULL; Console->NotifyLastClose = FALSE; + Console->HasFocus = FALSE; /* Initialize pausing support */ Console->PauseFlags = 0; @@ -941,6 +942,46 @@ ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console, return Status; } +VOID +ConSrvSetProcessFocus(IN PCSR_PROCESS CsrProcess, + IN BOOLEAN SetForeground) +{ + // FIXME: Call NtUserSetInformationProcess (currently unimplemented!) + // for setting Win32 foreground/background flags. + + if (SetForeground) + CsrSetForegroundPriority(CsrProcess); + else + CsrSetBackgroundPriority(CsrProcess); +} + +NTSTATUS NTAPI +ConSrvSetConsoleProcessFocus(IN PCONSRV_CONSOLE Console, + IN BOOLEAN SetForeground) +{ + PLIST_ENTRY current_entry; + PCONSOLE_PROCESS_DATA current; + + /* If the console is already being destroyed, just return */ + if (!ConDrvValidateConsoleState((PCONSOLE)Console, CONSOLE_RUNNING)) + return STATUS_UNSUCCESSFUL; + + /* + * Loop through the process list, from the most recent process + * to the oldest one, and for each, set its foreground priority. + */ + current_entry = Console->ProcessList.Flink; + while (current_entry != &Console->ProcessList) + { + current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink); + current_entry = current_entry->Flink; + + ConSrvSetProcessFocus(current->Process, SetForeground); + } + + return STATUS_SUCCESS; +} + /* PUBLIC SERVER APIS *********************************************************/ diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index e0d3362559f..601bee63cdc 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -290,6 +290,7 @@ SendMenuEvent(PCONSRV_CONSOLE Console, UINT CmdId) if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; + /* Send a menu event */ er.EventType = MENU_EVENT; er.Event.MenuEvent.dwCommandId = CmdId; ConioProcessInputEvent(Console, &er); @@ -755,6 +756,16 @@ OnFocus(PGUI_CONSOLE_DATA GuiData, BOOL SetFocus) if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return; + /* Set console focus state */ + Console->HasFocus = SetFocus; + + /* + * Set the priority of the processes of this console + * in accordance with the console focus state. + */ + ConSrvSetConsoleProcessFocus(Console, SetFocus); + + /* Send a focus event */ er.EventType = FOCUS_EVENT; er.Event.FocusEvent.bSetFocus = SetFocus; ConioProcessInputEvent(Console, &er); @@ -1855,6 +1866,7 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) if (lParam & 0x01000000) dwControlKeyState |= ENHANCED_KEY; + /* Send a mouse event */ er.EventType = MOUSE_EVENT; er.Event.MouseEvent.dwMousePosition = PointToCoord(GuiData, lParam); er.Event.MouseEvent.dwButtonState = dwButtonState; diff --git a/reactos/win32ss/user/winsrv/consrv/handle.c b/reactos/win32ss/user/winsrv/consrv/handle.c index 822718e2edd..54a2074a0f8 100644 --- a/reactos/win32ss/user/winsrv/consrv/handle.c +++ b/reactos/win32ss/user/winsrv/consrv/handle.c @@ -579,8 +579,12 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, /* Return the console handle to the caller */ ConsoleInitInfo->ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle; - /* Insert the process into the processes list of the console */ + /* + * Insert the process into the processes list of the console, + * and set its foreground priority. + */ InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink); + ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus); /* Add a reference count because the process is tied to the console */ _InterlockedIncrement(&Console->ReferenceCount); @@ -694,8 +698,12 @@ ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, /* Return the console handle to the caller */ ConsoleStartInfo->ConsoleHandle = ProcessData->ConsoleHandle; - /* Insert the process into the processes list of the console */ + /* + * Insert the process into the processes list of the console, + * and set its foreground priority. + */ InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink); + ConSrvSetProcessFocus(ProcessData->Process, Console->HasFocus); /* Add a reference count because the process is tied to the console */ _InterlockedIncrement(&Console->ReferenceCount); diff --git a/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h b/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h index f4841ac6498..f951d8d3e3d 100644 --- a/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h +++ b/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h @@ -148,6 +148,7 @@ typedef struct _WINSRV_CONSOLE LIST_ENTRY ProcessList; /* List of processes owning the console. The first one is the so-called "Console Leader Process" */ PCONSOLE_PROCESS_DATA NotifiedLastCloseProcess; /* Pointer to the unique process that needs to be notified when the console leader process is killed */ BOOLEAN NotifyLastClose; /* TRUE if the console should send a control event when the console leader process is killed */ + BOOLEAN HasFocus; /* TRUE if the console has focus (is in the foreground) */ /******************************* Pausing support ******************************/ BYTE PauseFlags; @@ -206,6 +207,12 @@ NTSTATUS NTAPI ConSrvConsoleProcessCtrlEvent(IN PCONSRV_CONSOLE Console, IN ULONG ProcessGroupId, IN ULONG CtrlEvent); +VOID +ConSrvSetProcessFocus(IN PCSR_PROCESS CsrProcess, + IN BOOLEAN SetForeground); +NTSTATUS NTAPI +ConSrvSetConsoleProcessFocus(IN PCONSRV_CONSOLE Console, + IN BOOLEAN SetForeground); /* coninput.c */ VOID NTAPI ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg);