mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
Improve window filter to include start menu and Cortana search box. (#474)
Also moves GetProcessPath* functions to common, renaming both to get_process_path.
This commit is contained in:
parent
298a8787d5
commit
5f8c4ea143
@ -35,10 +35,11 @@ std::optional<POINT> get_mouse_pos() {
|
|||||||
HWND get_filtered_active_window() {
|
HWND get_filtered_active_window() {
|
||||||
static auto desktop = GetDesktopWindow();
|
static auto desktop = GetDesktopWindow();
|
||||||
static auto shell = GetShellWindow();
|
static auto shell = GetShellWindow();
|
||||||
|
static HWND searchui = nullptr;
|
||||||
auto active_window = GetForegroundWindow();
|
auto active_window = GetForegroundWindow();
|
||||||
active_window = GetAncestor(active_window, GA_ROOT);
|
active_window = GetAncestor(active_window, GA_ROOT);
|
||||||
|
|
||||||
if (active_window == desktop || active_window == shell) {
|
if (active_window == desktop || active_window == shell || active_window == searchui) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +62,16 @@ HWND get_filtered_active_window() {
|
|||||||
strcmp(class_name, "Progman") == 0) {
|
strcmp(class_name, "Progman") == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (strcmp(class_name, "Windows.UI.Core.CoreWindow") == 0) {
|
||||||
|
const static std::wstring cortana_app = L"SearchUI.exe";
|
||||||
|
auto process_path = get_process_path(active_window);
|
||||||
|
if (process_path.length() >= cortana_app.length() &&
|
||||||
|
process_path.compare(process_path.length() - cortana_app.length(), cortana_app.length(), cortana_app) == 0) {
|
||||||
|
// cache the cortana HWND
|
||||||
|
searchui = active_window;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
return active_window;
|
return active_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,4 +245,48 @@ bool drop_elevated_privileges() {
|
|||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring get_process_path(DWORD pid) noexcept {
|
||||||
|
auto process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid);
|
||||||
|
std::wstring name;
|
||||||
|
if (process != INVALID_HANDLE_VALUE) {
|
||||||
|
name.resize(MAX_PATH);
|
||||||
|
DWORD name_length = static_cast<DWORD>(name.length());
|
||||||
|
if (QueryFullProcessImageNameW(process, 0, (LPWSTR)name.data(), &name_length) == 0) {
|
||||||
|
name_length = 0;
|
||||||
|
}
|
||||||
|
name.resize(name_length);
|
||||||
|
CloseHandle(process);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring get_process_path(HWND window) noexcept {
|
||||||
|
const static std::wstring app_frame_host = L"ApplicationFrameHost.exe";
|
||||||
|
DWORD pid{};
|
||||||
|
GetWindowThreadProcessId(window, &pid);
|
||||||
|
auto name = get_process_path(pid);
|
||||||
|
if (name.length() >= app_frame_host.length() &&
|
||||||
|
name.compare(name.length() - app_frame_host.length(), app_frame_host.length(), app_frame_host) == 0) {
|
||||||
|
// It is a UWP app. We will enumarate the windows and look for one created
|
||||||
|
// by something with a different PID
|
||||||
|
DWORD new_pid = pid;
|
||||||
|
EnumChildWindows(window, [](HWND hwnd, LPARAM param) -> BOOL {
|
||||||
|
auto new_pid_ptr = reinterpret_cast<DWORD*>(param);
|
||||||
|
DWORD pid;
|
||||||
|
GetWindowThreadProcessId(hwnd, &pid);
|
||||||
|
if (pid != *new_pid_ptr) {
|
||||||
|
*new_pid_ptr = pid;
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}, reinterpret_cast<LPARAM>(&new_pid));
|
||||||
|
// If we have a new pid, get the new name.
|
||||||
|
if (new_pid != pid) {
|
||||||
|
return get_process_path(new_pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
@ -43,3 +43,8 @@ bool is_process_elevated();
|
|||||||
|
|
||||||
// Drops the elevated privilages if present
|
// Drops the elevated privilages if present
|
||||||
bool drop_elevated_privileges();
|
bool drop_elevated_privileges();
|
||||||
|
|
||||||
|
// Get the executable path or module name for modern apps
|
||||||
|
std::wstring get_process_path(DWORD pid) noexcept;
|
||||||
|
// Get the executable path or module name for modern apps
|
||||||
|
std::wstring get_process_path(HWND hwnd) noexcept;
|
||||||
|
@ -169,7 +169,7 @@ IFACEMETHODIMP_(void) FancyZones::WindowCreated(HWND window) noexcept
|
|||||||
{
|
{
|
||||||
if (m_settings->GetSettings().appLastZone_moveWindows)
|
if (m_settings->GetSettings().appLastZone_moveWindows)
|
||||||
{
|
{
|
||||||
auto processPath = GetProcessPath(window);
|
auto processPath = get_process_path(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
INT zoneIndex = -1;
|
INT zoneIndex = -1;
|
||||||
@ -697,7 +697,7 @@ void FancyZones::MoveSizeEndInternal(HWND window, POINT const& ptScreen, require
|
|||||||
{
|
{
|
||||||
::RemoveProp(window, ZONE_STAMP);
|
::RemoveProp(window, ZONE_STAMP);
|
||||||
|
|
||||||
auto processPath = GetProcessPath(window);
|
auto processPath = get_process_path(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
RegistryHelpers::SaveAppLastZone(window, processPath.data(), -1);
|
RegistryHelpers::SaveAppLastZone(window, processPath.data(), -1);
|
||||||
|
@ -1252,7 +1252,7 @@ int ZoneWindow::GetSwitchButtonIndexFromPoint(POINT ptClient) noexcept
|
|||||||
|
|
||||||
IFACEMETHODIMP_(void) ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
IFACEMETHODIMP_(void) ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
|
||||||
{
|
{
|
||||||
auto processPath = GetProcessPath(window);
|
auto processPath = get_process_path(window);
|
||||||
if (!processPath.empty())
|
if (!processPath.empty())
|
||||||
{
|
{
|
||||||
DWORD zoneIndex = static_cast<DWORD>(m_activeZoneSet->GetZoneIndexFromWindow(window));
|
DWORD zoneIndex = static_cast<DWORD>(m_activeZoneSet->GetZoneIndexFromWindow(window));
|
||||||
|
@ -133,53 +133,3 @@ inline void ParseDeviceId(PCWSTR deviceId, PWSTR parsedId, size_t size)
|
|||||||
StringCchCopy(parsedId, size, L"FallbackDevice");
|
StringCchCopy(parsedId, size, L"FallbackDevice");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::wstring GetProcessPathByPID(DWORD pid)
|
|
||||||
{
|
|
||||||
wil::unique_handle process(OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, TRUE, pid));
|
|
||||||
std::wstring name;
|
|
||||||
if (process && process.get() != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
name.resize(MAX_PATH);
|
|
||||||
DWORD name_length = static_cast<DWORD>(name.length());
|
|
||||||
QueryFullProcessImageNameW(process.get(), 0, (LPWSTR)name.data(), &name_length);
|
|
||||||
name.resize(name_length);
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::wstring GetProcessPath(HWND window) noexcept
|
|
||||||
{
|
|
||||||
const static std::wstring app_frame_host = L"ApplicationFrameHost.exe";
|
|
||||||
DWORD pid{};
|
|
||||||
GetWindowThreadProcessId(window, &pid);
|
|
||||||
auto name = GetProcessPathByPID(pid);
|
|
||||||
if (name.length() >= app_frame_host.length() &&
|
|
||||||
name.compare(name.length() - app_frame_host.length(), app_frame_host.length(), app_frame_host) == 0)
|
|
||||||
{
|
|
||||||
// It is a UWP app. We will enumarate the windows and look for one created
|
|
||||||
// by something with a different PID
|
|
||||||
DWORD new_pid = pid;
|
|
||||||
EnumChildWindows(window, [](HWND hwnd, LPARAM param) -> BOOL
|
|
||||||
{
|
|
||||||
auto new_pid_ptr = reinterpret_cast<DWORD*>(param);
|
|
||||||
DWORD pid;
|
|
||||||
GetWindowThreadProcessId(hwnd, &pid);
|
|
||||||
if (pid != *new_pid_ptr)
|
|
||||||
{
|
|
||||||
*new_pid_ptr = pid;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}, reinterpret_cast<LPARAM>(&new_pid));
|
|
||||||
// If we have a new pid, get the new name.
|
|
||||||
if (new_pid != pid)
|
|
||||||
{
|
|
||||||
return GetProcessPathByPID(new_pid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
@ -111,6 +111,9 @@
|
|||||||
<ClInclude Include="Util.h" />
|
<ClInclude Include="Util.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\..\common\common.vcxproj">
|
||||||
|
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\lib\FancyZonesLib.vcxproj">
|
<ProjectReference Include="..\..\lib\FancyZonesLib.vcxproj">
|
||||||
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
|
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
Loading…
Reference in New Issue
Block a user