[Workspaces] implement standalone app handling (#34948)

This commit is contained in:
Laszlo Nemeth 2024-09-26 19:54:16 +02:00 коммит произвёл GitHub
Родитель 49a828236a
Коммит dca8b7ac35
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 84 добавлений и 11 удалений

4
.github/actions/spell-check/expect.txt поставляемый
Просмотреть файл

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

Просмотреть файл

@ -19,6 +19,15 @@ namespace SnapshotUtils
namespace NonLocalizable
{
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
@ -191,6 +200,17 @@ namespace SnapshotUtils
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> apps{};
@ -269,25 +289,72 @@ namespace SnapshotUtils
if (!data.has_value() || data->name.empty())
{
Logger::info(L"Installed app not found: {}, try parent process", processPath);
bool standaloneApp = false;
bool steamLikeApp = false;
// try with parent process (fix for Steam)
auto parentPid = GetParentPid(pid);
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 (!data.has_value() || data->name.empty())
if (processPath.ends_with(NonLocalizable::ApplicationFrameHost))
{
Logger::info(L"Installed parent app not found: {}", processPath);
// filter out ApplicationFrameHost.exe
continue;
}
processPath = parentProcessPath;
else
{
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
{
Logger::info(L"Parent process path not found");
continue;
Logger::info(L"parent process: {}, The parent process is NOT a known file manager app, it is a steam-like app", parentProcessPath);
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;
}
}
}

Просмотреть файл

@ -174,13 +174,15 @@ void WindowArranger::processWindow(HWND window)
}
auto data = Utils::Apps::GetApp(processPath, m_installedApps);
if (!data.has_value() || data->name.empty())
if (!data.has_value())
{
return;
}
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())
{
Logger::info(L"A window of {} is not in the project", processPath);