mirror of
https://github.com/microsoft/terminal.git
synced 2026-02-04 01:04:33 +00:00
Propagate foreground through the stack instead of using tricks
This commit is contained in:
@@ -1457,31 +1457,23 @@ void IslandWindow::_globalActivateWindow(const uint32_t dropdownDuration,
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try first to send a message to the current foreground window. If it's not responding, it may
|
||||
// be waiting on us to finish launching. Passing SMTO_NOTIMEOUTIFNOTHUNG means that we get the same
|
||||
// behavior as before--that is, waiting for the message loop--but we've done an early return if
|
||||
// it turns out that it was hung.
|
||||
// SendMessageTimeoutW returns nonzero if it succeeds.
|
||||
if (0 != SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0, SMTO_NOTIMEOUTIFNOTHUNG | SMTO_BLOCK | SMTO_ABORTIFHUNG, 1000, nullptr))
|
||||
{
|
||||
const auto windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow, nullptr);
|
||||
const auto currentThreadId = GetCurrentThreadId();
|
||||
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
|
||||
ShowWindow(_window.get(), SW_SHOW);
|
||||
|
||||
LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, true));
|
||||
// Just in case, add the thread detach as a scope_exit, to make _sure_ we do it.
|
||||
auto detachThread = wil::scope_exit([windowThreadProcessId, currentThreadId]() {
|
||||
LOG_IF_WIN32_BOOL_FALSE(AttachThreadInput(windowThreadProcessId, currentThreadId, false));
|
||||
});
|
||||
LOG_IF_WIN32_BOOL_FALSE(BringWindowToTop(_window.get()));
|
||||
ShowWindow(_window.get(), SW_SHOW);
|
||||
// Activate the window too. This will force us to the virtual desktop this
|
||||
// window is on, if it's on another virtual desktop.
|
||||
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
|
||||
|
||||
// Activate the window too. This will force us to the virtual desktop this
|
||||
// window is on, if it's on another virtual desktop.
|
||||
LOG_LAST_ERROR_IF_NULL(SetActiveWindow(_window.get()));
|
||||
// Throw us on the active monitor.
|
||||
_moveToMonitor(oldForegroundWindow, toMonitor);
|
||||
}
|
||||
|
||||
// Throw us on the active monitor.
|
||||
_moveToMonitor(oldForegroundWindow, toMonitor);
|
||||
}
|
||||
if (!SetForegroundWindow(_window.get()))
|
||||
{
|
||||
TraceLoggingWrite(g_hWindowsTerminalProvider,
|
||||
"ActivateSetForegroundWindowFailed",
|
||||
//TraceLoggingUInt64(static_cast<const unsigned long long>(_window.get()), "hwnd"),
|
||||
TraceLoggingWinError(GetLastError(), "error"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,14 @@ static wil::unique_mutex acquireMutexOrAttemptHandoff(const wchar_t* className,
|
||||
DWORD processId = 0;
|
||||
if (GetWindowThreadProcessId(hwnd, &processId) && processId)
|
||||
{
|
||||
AllowSetForegroundWindow(processId);
|
||||
if (!AllowSetForegroundWindow(processId))
|
||||
{
|
||||
TraceLoggingWrite(g_hWindowsTerminalProvider,
|
||||
"EmperorAllowSetForegroundWindowFailed",
|
||||
//TraceLoggingUInt64(static_cast<const unsigned long long>(hwnd), "hwnd"),
|
||||
TraceLoggingPid(processId),
|
||||
TraceLoggingWinError(GetLastError(), "error"));
|
||||
}
|
||||
}
|
||||
|
||||
if (SendMessageTimeoutW(hwnd, WM_COPYDATA, 0, reinterpret_cast<LPARAM>(&cds), SMTO_ABORTIFHUNG | SMTO_ERRORONEXIT, 5000, nullptr))
|
||||
|
||||
@@ -6,10 +6,19 @@
|
||||
#include <wil/stl.h>
|
||||
#include <wil/resource.h>
|
||||
#include <wil/win32_helpers.h>
|
||||
#include <TraceLoggingProvider.h>
|
||||
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_hShimProvider);
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_hShimProvider,
|
||||
"Microsoft.Windows.Terminal.Shim",
|
||||
// tl:{d295502a-ab39-5565-c342-6e6d7659a422}
|
||||
(0xd295502a, 0xab39, 0x5565, 0xc3, 0x42, 0x6e, 0x6d, 0x76, 0x59, 0xa4, 0x22));
|
||||
|
||||
#pragma warning(suppress : 26461) // we can't change the signature of wWinMain
|
||||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR pCmdLine, int)
|
||||
{
|
||||
TraceLoggingRegister(g_hShimProvider);
|
||||
std::filesystem::path module{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
|
||||
|
||||
// Cache our name (wt, wtd)
|
||||
@@ -32,5 +41,19 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR pCmdLine, int)
|
||||
|
||||
// Go!
|
||||
wil::unique_process_information pi;
|
||||
return !CreateProcessW(module.c_str(), cmdline.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi);
|
||||
if (!CreateProcessW(module.c_str(), cmdline.data(), nullptr, nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!AllowSetForegroundWindow(pi.dwProcessId))
|
||||
{
|
||||
TraceLoggingWrite(g_hShimProvider,
|
||||
"ShimAllowSetForegroundWindowFailed",
|
||||
TraceLoggingPid(pi.dwProcessId, "processId"),
|
||||
TraceLoggingWinError(GetLastError(), "error"));
|
||||
}
|
||||
|
||||
ResumeThread(pi.hThread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
<Link>
|
||||
<AllowIsolation>true</AllowIsolation>
|
||||
<AdditionalDependencies>winmm.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<DelayLoadDLLs>ext-ms-win-com-ole32-l1.dll</DelayLoadDLLs>
|
||||
<DelayLoadDLLs>icu.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
@@ -544,6 +544,12 @@ try
|
||||
|
||||
myStartupInfo.wShowWindow = settings.GetShowWindow();
|
||||
|
||||
if (IsApiSetImplemented("ext-ms-win-com-ole32-l1-1-1"))
|
||||
{
|
||||
HRESULT hr = CoAllowSetForegroundWindow(handoff.Get(), nullptr);
|
||||
TraceLoggingWrite(g_hConhostV2EventTraceProvider, "PtyHandoffAllowSetForegroundWindow", TraceLoggingHResult(hr));
|
||||
}
|
||||
|
||||
wil::unique_handle inPipeOurSide;
|
||||
wil::unique_handle outPipeOurSide;
|
||||
RETURN_IF_FAILED(handoff->EstablishPtyHandoff(inPipeOurSide.addressof(),
|
||||
|
||||
Reference in New Issue
Block a user