[Workspaces] implement standalone app handling (#34948)

This commit is contained in:
Laszlo Nemeth
2024-09-26 19:54:16 +02:00
committed by GitHub
parent 49a828236a
commit dca8b7ac35
3 changed files with 84 additions and 11 deletions

View File

@@ -367,6 +367,7 @@ dllmain
DNLEN DNLEN
DONOTROUND DONOTROUND
DONTVALIDATEPATH DONTVALIDATEPATH
DOPUS
dotnet dotnet
DPICHANGED DPICHANGED
DPIs DPIs
@@ -1265,6 +1266,7 @@ PWSTR
pwsz pwsz
pwtd pwtd
QDC QDC
QDir
qianlifeng qianlifeng
qit qit
QITAB QITAB
@@ -1642,6 +1644,7 @@ toolkitconverters
Toolset Toolset
toolwindow toolwindow
TOPDOWNDIB TOPDOWNDIB
TOTALCMD
TOUCHEVENTF TOUCHEVENTF
TOUCHINPUT TOUCHINPUT
touchpad touchpad
@@ -1908,6 +1911,7 @@ XLoc
XNamespace XNamespace
XPels XPels
XPixel XPixel
xplorer
XResource XResource
xsi xsi
XStr XStr

View File

@@ -19,6 +19,15 @@ namespace SnapshotUtils
namespace NonLocalizable namespace NonLocalizable
{ {
const std::wstring ApplicationFrameHost = L"ApplicationFrameHost.exe"; const std::wstring ApplicationFrameHost = L"ApplicationFrameHost.exe";
namespace FileManagers
{
const std::wstring FileExplorer = L"EXPLORER"; // windows explorer
const std::wstring TotalCommander = L"TOTALCMD"; // total commander
const std::wstring DirectoryOpus = L"DOPUS"; // directory opus
const std::wstring QDir = L"Q-DIR"; // Q-Dir
const std::wstring Xplorer2 = L"XPLORER2"; // Xplorer2
}
} }
class WbemHelper class WbemHelper
@@ -191,6 +200,17 @@ namespace SnapshotUtils
return res; return res;
} }
bool IsFileManagerApp(std::wstring processPath)
{
std::wstring appName = std::filesystem::path(processPath).stem();
std::transform(appName.begin(), appName.end(), appName.begin(), towupper);
return ((appName == NonLocalizable::FileManagers::FileExplorer) // windows explorer
|| (appName.starts_with(NonLocalizable::FileManagers::TotalCommander)) // total commander
|| (appName == NonLocalizable::FileManagers::DirectoryOpus) // directory opus
|| (appName == NonLocalizable::FileManagers::QDir) // Q-Dir
|| (appName.starts_with(NonLocalizable::FileManagers::Xplorer2))); // Xplorer2
}
std::vector<WorkspacesData::WorkspacesProject::Application> GetApps(const std::function<unsigned int(HWND)> getMonitorNumberFromWindowHandle) std::vector<WorkspacesData::WorkspacesProject::Application> GetApps(const std::function<unsigned int(HWND)> getMonitorNumberFromWindowHandle)
{ {
std::vector<WorkspacesData::WorkspacesProject::Application> apps{}; std::vector<WorkspacesData::WorkspacesProject::Application> apps{};
@@ -270,24 +290,71 @@ namespace SnapshotUtils
{ {
Logger::info(L"Installed app not found: {}, try parent process", processPath); Logger::info(L"Installed app not found: {}, try parent process", processPath);
bool standaloneApp = false;
bool steamLikeApp = false;
// try with parent process (fix for Steam) // try with parent process (fix for Steam)
auto parentPid = GetParentPid(pid); auto parentPid = GetParentPid(pid);
auto parentProcessPath = get_process_path(parentPid); auto parentProcessPath = get_process_path(parentPid);
if (!parentProcessPath.empty())
// check if original process is in the subfolder of the parent process which is a sign of an steam-like app
std::wstring processDir = std::filesystem::path(processPath).parent_path().c_str();
std::wstring parentProcessDir = std::filesystem::path(parentProcessPath).parent_path().c_str();
if (parentProcessPath == L"")
{ {
data = Utils::Apps::GetApp(parentProcessPath, installedApps); if (processPath.ends_with(NonLocalizable::ApplicationFrameHost))
if (!data.has_value() || data->name.empty())
{ {
Logger::info(L"Installed parent app not found: {}", processPath); // filter out ApplicationFrameHost.exe
continue; continue;
} }
else
processPath = parentProcessPath; {
Logger::info(L"parent process unknown, the parent app is an already closed file manager app, it is a standalone app");
standaloneApp = true;
}
}
else if (processDir.starts_with(parentProcessDir))
{
Logger::info(L"parent process: {}, original process is in the subfolder of the parent process, it is a steam-like app", parentProcessPath);
steamLikeApp = true;
}
else if (IsFileManagerApp(parentProcessPath))
{
Logger::info(L"parent process: {}, The parent process is a known file manager app, it is a standalone app", parentProcessPath);
standaloneApp = true;
} }
else else
{ {
Logger::info(L"Parent process path not found"); Logger::info(L"parent process: {}, The parent process is NOT a known file manager app, it is a steam-like app", parentProcessPath);
continue; steamLikeApp = true;
}
if (standaloneApp)
{
data = Utils::Apps::AppData{
.name = std::filesystem::path(processPath).stem(),
.installPath = processPath,
};
}
else if (steamLikeApp)
{
if (!parentProcessPath.empty())
{
data = Utils::Apps::GetApp(parentProcessPath, installedApps);
if (!data.has_value() || data->name.empty())
{
Logger::info(L"Installed parent app not found: {}", processPath);
continue;
}
processPath = parentProcessPath;
}
else
{
Logger::info(L"Parent process path not found");
continue;
}
} }
} }

View File

@@ -174,13 +174,15 @@ void WindowArranger::processWindow(HWND window)
} }
auto data = Utils::Apps::GetApp(processPath, m_installedApps); auto data = Utils::Apps::GetApp(processPath, m_installedApps);
if (!data.has_value() || data->name.empty()) if (!data.has_value())
{ {
return; return;
} }
auto iter = std::find_if(m_launchingApps.begin(), m_launchingApps.end(), [&](const auto& val) auto iter = std::find_if(m_launchingApps.begin(), m_launchingApps.end(), [&](const auto& val)
{ return val.second.state == LaunchingState::Waiting && val.first.name == data.value().name; }); {
return val.second.state == LaunchingState::Waiting && !val.second.window && (val.first.name == data.value().name || val.first.path == data.value().installPath);
});
if (iter == m_launchingApps.end()) if (iter == m_launchingApps.end())
{ {
Logger::info(L"A window of {} is not in the project", processPath); Logger::info(L"A window of {} is not in the project", processPath);