Skip to content

Commit

Permalink
Improve window filter to include start menu and Cortana search box. (#…
Browse files Browse the repository at this point in the history
…474)

Also moves GetProcessPath* functions to common, renaming both to
get_process_path.
  • Loading branch information
bzoz committed Oct 7, 2019
1 parent 298a878 commit 5f8c4ea
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 55 deletions.
59 changes: 57 additions & 2 deletions src/common/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ std::optional<POINT> get_mouse_pos() {
HWND get_filtered_active_window() {
static auto desktop = GetDesktopWindow();
static auto shell = GetShellWindow();
static HWND searchui = nullptr;
auto active_window = GetForegroundWindow();
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;
}

Expand All @@ -61,6 +62,16 @@ HWND get_filtered_active_window() {
strcmp(class_name, "Progman") == 0) {
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;
}

Expand Down Expand Up @@ -234,4 +245,48 @@ bool drop_elevated_privileges() {
CloseHandle(token);

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;
}
5 changes: 5 additions & 0 deletions src/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ bool is_process_elevated();

// Drops the elevated privilages if present
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;
4 changes: 2 additions & 2 deletions src/modules/fancyzones/lib/FancyZones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ IFACEMETHODIMP_(void) FancyZones::WindowCreated(HWND window) noexcept
{
if (m_settings->GetSettings().appLastZone_moveWindows)
{
auto processPath = GetProcessPath(window);
auto processPath = get_process_path(window);
if (!processPath.empty())
{
INT zoneIndex = -1;
Expand Down Expand Up @@ -697,7 +697,7 @@ void FancyZones::MoveSizeEndInternal(HWND window, POINT const& ptScreen, require
{
::RemoveProp(window, ZONE_STAMP);

auto processPath = GetProcessPath(window);
auto processPath = get_process_path(window);
if (!processPath.empty())
{
RegistryHelpers::SaveAppLastZone(window, processPath.data(), -1);
Expand Down
2 changes: 1 addition & 1 deletion src/modules/fancyzones/lib/ZoneWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ int ZoneWindow::GetSwitchButtonIndexFromPoint(POINT ptClient) noexcept

IFACEMETHODIMP_(void) ZoneWindow::SaveWindowProcessToZoneIndex(HWND window) noexcept
{
auto processPath = GetProcessPath(window);
auto processPath = get_process_path(window);
if (!processPath.empty())
{
DWORD zoneIndex = static_cast<DWORD>(m_activeZoneSet->GetZoneIndexFromWindow(window));
Expand Down
50 changes: 0 additions & 50 deletions src/modules/fancyzones/lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,53 +133,3 @@ inline void ParseDeviceId(PCWSTR deviceId, PWSTR parsedId, size_t size)
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;
}
3 changes: 3 additions & 0 deletions src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
<ClInclude Include="Util.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\common.vcxproj">
<Project>{74485049-c722-400f-abe5-86ac52d929b3}</Project>
</ProjectReference>
<ProjectReference Include="..\..\lib\FancyZonesLib.vcxproj">
<Project>{f9c68edf-ac74-4b77-9af1-005d9c9f6a99}</Project>
</ProjectReference>
Expand Down

0 comments on commit 5f8c4ea

Please sign in to comment.