mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[Workspaces] implement standalone app handling (#34948)
This commit is contained in:
4
.github/actions/spell-check/expect.txt
vendored
4
.github/actions/spell-check/expect.txt
vendored
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user