From ca55dc7e49fb67e8664b9a077d1984d477b831ee Mon Sep 17 00:00:00 2001 From: donlaci Date: Wed, 19 Feb 2025 16:29:41 +0100 Subject: [PATCH 1/5] Fix snapshotting minimized packaged apps --- .../WorkspacesSnapshotTool/SnapshotUtils.cpp | 4 +- .../workspaces-common/WindowFilter.h | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp index 79f19219b3e9..8d0d180b57d3 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp @@ -96,7 +96,9 @@ namespace SnapshotUtils // fix for the packaged apps that are not caught when minimized, e.g., Settings. if (processPath.ends_with(NonLocalizable::ApplicationFrameHost)) { - for (auto otherWindow : windows) + auto minWindows = WindowEnumerator::Enumerate(WindowFilter::FilterMin); + + for (auto otherWindow : minWindows) { DWORD otherPid{}; GetWindowThreadProcessId(otherWindow, &otherPid); diff --git a/src/modules/Workspaces/workspaces-common/WindowFilter.h b/src/modules/Workspaces/workspaces-common/WindowFilter.h index 8e561fc74249..a434531b08c0 100644 --- a/src/modules/Workspaces/workspaces-common/WindowFilter.h +++ b/src/modules/Workspaces/workspaces-common/WindowFilter.h @@ -62,4 +62,43 @@ namespace WindowFilter return true; } + + inline bool FilterMin(HWND window) + { + auto style = GetWindowLong(window, GWL_STYLE); + auto exStyle = GetWindowLong(window, GWL_EXSTYLE); + + if (!WindowUtils::HasStyle(style, WS_VISIBLE)) + { + return false; + } + + if (!IsWindowVisible(window)) + { + return false; + } + + if (WindowUtils::HasStyle(exStyle, WS_EX_TOOLWINDOW)) + { + return false; + } + + if (!WindowUtils::IsRoot(window)) + { + // child windows such as buttons, combo boxes, etc. + return false; + } + + ////if (WindowFilter::FilterPopup(window)) + ////{ + //// return false; + ////} + + if (!VirtualDesktop::instance().IsWindowOnCurrentDesktop(window)) + { + return false; + } + + return true; + } } From d4e469b56325a6284ff9c1ed272d3309bfddcf27 Mon Sep 17 00:00:00 2001 From: donlaci Date: Fri, 21 Feb 2025 11:13:13 +0100 Subject: [PATCH 2/5] Fix window arranger to work with the same windows as the snapshot tool. --- .../WorkspacesSnapshotTool/SnapshotUtils.cpp | 7 +++--- .../WindowArranger.cpp | 24 +++++++++++++++++++ .../WorkspacesWindowArranger/WindowArranger.h | 1 + .../workspaces-common/WindowFilter.h | 9 +++---- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp index 8d0d180b57d3..fbce9b2a0077 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp @@ -49,6 +49,7 @@ namespace SnapshotUtils auto installedApps = Utils::Apps::GetAppsList(); auto windows = WindowEnumerator::Enumerate(WindowFilter::Filter); + auto additionalWindows = WindowEnumerator::Enumerate(WindowFilter::FilterAdditional); for (const auto window : windows) { @@ -93,12 +94,10 @@ namespace SnapshotUtils continue; } - // fix for the packaged apps that are not caught when minimized, e.g., Settings. + // fix for the packaged apps that are not caught when minimized, e.g. Settings, Microsoft ToDo, ... if (processPath.ends_with(NonLocalizable::ApplicationFrameHost)) { - auto minWindows = WindowEnumerator::Enumerate(WindowFilter::FilterMin); - - for (auto otherWindow : minWindows) + for (auto otherWindow : additionalWindows) { DWORD otherPid{}; GetWindowThreadProcessId(otherWindow, &otherPid); diff --git a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp index 37b24b231fb4..94c97c733598 100644 --- a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp +++ b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp @@ -14,6 +14,11 @@ #include #include +namespace NonLocalizable +{ + const std::wstring ApplicationFrameHost = L"ApplicationFrameHost.exe"; +} + namespace PlacementHelper { // When calculating the coordinates difference (== 'distance') between 2 windows, there are additional values added to the real distance @@ -170,6 +175,24 @@ std::optional WindowArranger::GetNearestWindow(const Workspa DWORD pid{}; GetWindowThreadProcessId(window, &pid); + std::wstring title = WindowUtils::GetWindowTitle(window); + + // fix for the packaged apps that are not caught when minimized, e.g. Settings, Microsoft ToDo, ... + if (processPath.ends_with(NonLocalizable::ApplicationFrameHost)) + { + for (auto otherWindow : m_windowsBeforeAdditional) + { + DWORD otherPid{}; + GetWindowThreadProcessId(otherWindow, &otherPid); + + // searching for the window with the same title but different PID + if (pid != otherPid && title == WindowUtils::GetWindowTitle(otherWindow)) + { + processPath = get_process_path(otherPid); + break; + } + } + } auto data = Utils::Apps::GetApp(processPath, pid, m_installedApps); if (!data.has_value()) @@ -237,6 +260,7 @@ std::optional WindowArranger::GetNearestWindow(const Workspa WindowArranger::WindowArranger(WorkspacesData::WorkspacesProject project) : m_project(project), m_windowsBefore(WindowEnumerator::Enumerate(WindowFilter::Filter)), + m_windowsBeforeAdditional(WindowEnumerator::Enumerate(WindowFilter::FilterAdditional)), m_monitors(MonitorUtils::IdentifyMonitors()), m_installedApps(Utils::Apps::GetAppsList()), m_ipcHelper(IPCHelperStrings::WindowArrangerPipeName, IPCHelperStrings::LauncherArrangerPipeName, std::bind(&WindowArranger::receiveIpcMessage, this, std::placeholders::_1)), diff --git a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h index 276639d08926..be41884849ec 100644 --- a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h +++ b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h @@ -23,6 +23,7 @@ class WindowArranger private: const WorkspacesData::WorkspacesProject m_project; const std::vector m_windowsBefore; + const std::vector m_windowsBeforeAdditional; const std::vector m_monitors; const Utils::Apps::AppList m_installedApps; //const WindowCreationHandler m_windowCreationHandler; diff --git a/src/modules/Workspaces/workspaces-common/WindowFilter.h b/src/modules/Workspaces/workspaces-common/WindowFilter.h index a434531b08c0..64e11abcbf7f 100644 --- a/src/modules/Workspaces/workspaces-common/WindowFilter.h +++ b/src/modules/Workspaces/workspaces-common/WindowFilter.h @@ -63,7 +63,9 @@ namespace WindowFilter return true; } - inline bool FilterMin(HWND window) + // the FilterAdditional() filter method is similar to the Filter() method (above). It does not filter out the popup styled windows + // as some packaged apps in minimized state have the same style poperties and are filtered out, which end up in not being snapshotted + inline bool FilterAdditional(HWND window) { auto style = GetWindowLong(window, GWL_STYLE); auto exStyle = GetWindowLong(window, GWL_EXSTYLE); @@ -89,11 +91,6 @@ namespace WindowFilter return false; } - ////if (WindowFilter::FilterPopup(window)) - ////{ - //// return false; - ////} - if (!VirtualDesktop::instance().IsWindowOnCurrentDesktop(window)) { return false; From e1ffb7aee8a2e6f4bf17954a98b45330fd9de2d0 Mon Sep 17 00:00:00 2001 From: donlaci Date: Fri, 21 Feb 2025 12:41:09 +0100 Subject: [PATCH 3/5] spell checker --- src/modules/Workspaces/workspaces-common/WindowFilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Workspaces/workspaces-common/WindowFilter.h b/src/modules/Workspaces/workspaces-common/WindowFilter.h index 64e11abcbf7f..c0206b3e63ea 100644 --- a/src/modules/Workspaces/workspaces-common/WindowFilter.h +++ b/src/modules/Workspaces/workspaces-common/WindowFilter.h @@ -64,7 +64,7 @@ namespace WindowFilter } // the FilterAdditional() filter method is similar to the Filter() method (above). It does not filter out the popup styled windows - // as some packaged apps in minimized state have the same style poperties and are filtered out, which end up in not being snapshotted + // as some packaged apps in minimized state have the same style properties and are filtered out, which end up in not being snapshotted inline bool FilterAdditional(HWND window) { auto style = GetWindowLong(window, GWL_STYLE); From e3b6f0faacd636047b123816a79230f83f797b7e Mon Sep 17 00:00:00 2001 From: donlaci Date: Fri, 21 Feb 2025 17:51:44 +0100 Subject: [PATCH 4/5] optimising code --- .../WorkspacesSnapshotTool/SnapshotUtils.cpp | 13 ++++--- .../WindowArranger.cpp | 8 +++-- .../WorkspacesWindowArranger/WindowArranger.h | 1 - .../workspaces-common/WindowFilter.h | 36 ------------------- 4 files changed, 12 insertions(+), 46 deletions(-) diff --git a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp index fbce9b2a0077..1d5bc8a17963 100644 --- a/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp +++ b/src/modules/Workspaces/WorkspacesSnapshotTool/SnapshotUtils.cpp @@ -49,10 +49,14 @@ namespace SnapshotUtils auto installedApps = Utils::Apps::GetAppsList(); auto windows = WindowEnumerator::Enumerate(WindowFilter::Filter); - auto additionalWindows = WindowEnumerator::Enumerate(WindowFilter::FilterAdditional); for (const auto window : windows) { + if (WindowFilter::FilterPopup(window)) + { + continue; + } + // filter by window rect size RECT rect = WindowUtils::GetWindowRect(window); if (rect.right - rect.left <= 0 || rect.bottom - rect.top <= 0) @@ -97,7 +101,7 @@ namespace SnapshotUtils // fix for the packaged apps that are not caught when minimized, e.g. Settings, Microsoft ToDo, ... if (processPath.ends_with(NonLocalizable::ApplicationFrameHost)) { - for (auto otherWindow : additionalWindows) + for (auto otherWindow : windows) { DWORD otherPid{}; GetWindowThreadProcessId(otherWindow, &otherPid); @@ -111,11 +115,6 @@ namespace SnapshotUtils } } - if (WindowFilter::FilterPopup(window)) - { - continue; - } - auto data = Utils::Apps::GetApp(processPath, pid, installedApps); if (!data.has_value() || data->name.empty()) { diff --git a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp index 94c97c733598..a9db73664dc7 100644 --- a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp +++ b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.cpp @@ -162,6 +162,11 @@ std::optional WindowArranger::GetNearestWindow(const Workspa for (HWND window : m_windowsBefore) { + if (WindowFilter::FilterPopup(window)) + { + continue; + } + if (std::find(movedWindows.begin(), movedWindows.end(), window) != movedWindows.end()) { continue; @@ -180,7 +185,7 @@ std::optional WindowArranger::GetNearestWindow(const Workspa // fix for the packaged apps that are not caught when minimized, e.g. Settings, Microsoft ToDo, ... if (processPath.ends_with(NonLocalizable::ApplicationFrameHost)) { - for (auto otherWindow : m_windowsBeforeAdditional) + for (auto otherWindow : m_windowsBefore) { DWORD otherPid{}; GetWindowThreadProcessId(otherWindow, &otherPid); @@ -260,7 +265,6 @@ std::optional WindowArranger::GetNearestWindow(const Workspa WindowArranger::WindowArranger(WorkspacesData::WorkspacesProject project) : m_project(project), m_windowsBefore(WindowEnumerator::Enumerate(WindowFilter::Filter)), - m_windowsBeforeAdditional(WindowEnumerator::Enumerate(WindowFilter::FilterAdditional)), m_monitors(MonitorUtils::IdentifyMonitors()), m_installedApps(Utils::Apps::GetAppsList()), m_ipcHelper(IPCHelperStrings::WindowArrangerPipeName, IPCHelperStrings::LauncherArrangerPipeName, std::bind(&WindowArranger::receiveIpcMessage, this, std::placeholders::_1)), diff --git a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h index be41884849ec..276639d08926 100644 --- a/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h +++ b/src/modules/Workspaces/WorkspacesWindowArranger/WindowArranger.h @@ -23,7 +23,6 @@ class WindowArranger private: const WorkspacesData::WorkspacesProject m_project; const std::vector m_windowsBefore; - const std::vector m_windowsBeforeAdditional; const std::vector m_monitors; const Utils::Apps::AppList m_installedApps; //const WindowCreationHandler m_windowCreationHandler; diff --git a/src/modules/Workspaces/workspaces-common/WindowFilter.h b/src/modules/Workspaces/workspaces-common/WindowFilter.h index c0206b3e63ea..8e561fc74249 100644 --- a/src/modules/Workspaces/workspaces-common/WindowFilter.h +++ b/src/modules/Workspaces/workspaces-common/WindowFilter.h @@ -62,40 +62,4 @@ namespace WindowFilter return true; } - - // the FilterAdditional() filter method is similar to the Filter() method (above). It does not filter out the popup styled windows - // as some packaged apps in minimized state have the same style properties and are filtered out, which end up in not being snapshotted - inline bool FilterAdditional(HWND window) - { - auto style = GetWindowLong(window, GWL_STYLE); - auto exStyle = GetWindowLong(window, GWL_EXSTYLE); - - if (!WindowUtils::HasStyle(style, WS_VISIBLE)) - { - return false; - } - - if (!IsWindowVisible(window)) - { - return false; - } - - if (WindowUtils::HasStyle(exStyle, WS_EX_TOOLWINDOW)) - { - return false; - } - - if (!WindowUtils::IsRoot(window)) - { - // child windows such as buttons, combo boxes, etc. - return false; - } - - if (!VirtualDesktop::instance().IsWindowOnCurrentDesktop(window)) - { - return false; - } - - return true; - } } From e45ae5e1d4e32d267574f4acea39da7b8d6b5ad0 Mon Sep 17 00:00:00 2001 From: donlaci Date: Mon, 24 Feb 2025 10:17:42 +0100 Subject: [PATCH 5/5] Remove filter condition. --- src/modules/Workspaces/workspaces-common/WindowFilter.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/modules/Workspaces/workspaces-common/WindowFilter.h b/src/modules/Workspaces/workspaces-common/WindowFilter.h index 8e561fc74249..c76ad81237c3 100644 --- a/src/modules/Workspaces/workspaces-common/WindowFilter.h +++ b/src/modules/Workspaces/workspaces-common/WindowFilter.h @@ -50,11 +50,6 @@ namespace WindowFilter return false; } - if (WindowFilter::FilterPopup(window)) - { - return false; - } - if (!VirtualDesktop::instance().IsWindowOnCurrentDesktop(window)) { return false;