Change console processes priority when the console gains or loses focus. FIXME: Win2k3 backtraces show that we should call NtUserSetInformationProcess(unimplemented in ROS) to set some win32 process foreground flags.
CORE-9911

svn path=/trunk/; revision=68716
This commit is contained in:
Hermès Bélusca-Maïto 2015-08-15 17:05:13 +00:00
parent fc017a90e2
commit c8cb8d539e
4 changed files with 70 additions and 2 deletions

View file

@ -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 *********************************************************/

View file

@ -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;

View file

@ -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);

View file

@ -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);