Refactor window platform helper functions

This commit is contained in:
WarmUpTill
2026-05-18 19:35:41 +02:00
parent ee1d0136d9
commit 930e8b38d4
10 changed files with 388 additions and 470 deletions

View File

@@ -14,21 +14,6 @@ bool MacroConditionWindow::_registered = MacroConditionFactory::Register(
{MacroConditionWindow::Create, MacroConditionWindowEdit::Create,
"AdvSceneSwitcher.condition.window"});
static bool windowContainsText(const std::string &window,
const std::string &matchText,
const RegexConfig &regex)
{
auto text = GetTextInWindow(window);
if (!text.has_value()) {
return false;
}
if (regex.Enabled()) {
return regex.Matches(*text, matchText);
}
return text == matchText;
}
void MacroConditionWindow::SetCheckText(bool value)
{
#ifdef _WIN32
@@ -46,92 +31,76 @@ bool MacroConditionWindow::GetCheckText()
}
bool MacroConditionWindow::WindowMatchesRequirements(
const std::string &window) const
const WindowInfo &info) const
{
const bool focusCheckOK =
(!_focus || window == ForegroundWindowTitle());
if (!focusCheckOK) {
if (_focus && !info.focused) {
return false;
}
const bool fullscreenCheckOK = (!_fullscreen || IsFullscreen(window));
if (!fullscreenCheckOK) {
if (_fullscreen && !info.fullscreen) {
return false;
}
const bool maxCheckOK = (!_maximized || IsMaximized(window));
if (!maxCheckOK) {
if (_maximized && !info.maximized) {
return false;
}
const bool textCheckOK =
(!_checkText || windowContainsText(window, _text, _textRegex));
if (!textCheckOK) {
return false;
if (_checkText) {
if (!info.text.has_value()) {
return false;
}
if (_textRegex.Enabled()) {
if (!_textRegex.Matches(*info.text, _text)) {
return false;
}
} else {
if (*info.text != std::string(_text)) {
return false;
}
}
}
return true;
}
bool MacroConditionWindow::WindowMatches(
const std::vector<std::string> &windowList)
bool MacroConditionWindow::FindMatch(const std::vector<WindowInfo> &windows)
{
bool match = !_checkTitle ||
std::find(windowList.begin(), windowList.end(),
std::string(_window)) != windowList.end();
match = match && WindowMatchesRequirements(_window);
SetVariableValueBasedOnMatch(_window);
return match;
}
#ifdef _WIN32
std::string GetWindowClassByWindowTitle(const std::string &window);
#endif
bool MacroConditionWindow::WindowRegexMatches(
const std::vector<std::string> &windowList)
{
// No need to test if checking for window title is required as if the
// user has disabled window title matching the option will always be
// enabled in the backend and use the regular expression ".*".
for (const auto &window : windowList) {
if (_windowRegex.Matches(window, _window) &&
WindowMatchesRequirements(window)) {
SetVariableValueBasedOnMatch(window);
return true;
// When regex is enabled the title check is always active (the backend
// uses ".*" when the user disables the title check), so we can use a
// single predicate for both modes.
for (const auto &info : windows) {
const bool titleOK =
_windowRegex.Enabled()
? _windowRegex.Matches(info.title, _window)
: (!_checkTitle ||
info.title == std::string(_window));
if (!titleOK || !WindowMatchesRequirements(info)) {
continue;
}
SetVariableValueBasedOnMatch(&info);
return true;
}
SetVariableValueBasedOnMatch("");
SetVariableValueBasedOnMatch(nullptr);
return false;
}
void MacroConditionWindow::SetVariableValueBasedOnMatch(
const std::string &matchWindow)
void MacroConditionWindow::SetVariableValueBasedOnMatch(const WindowInfo *info)
{
SetTempVarValue("window", matchWindow);
const auto geo = GetWindowGeometry(matchWindow);
if (geo) {
SetTempVarValue("windowX", std::to_string(geo->x));
SetTempVarValue("windowY", std::to_string(geo->y));
SetTempVarValue("windowWidth", std::to_string(geo->width));
SetTempVarValue("windowHeight", std::to_string(geo->height));
}
const std::string title = info ? info->title : "";
SetTempVarValue("window", title);
SetTempVarValue("windowX", info ? std::to_string(info->x) : "");
SetTempVarValue("windowY", info ? std::to_string(info->y) : "");
SetTempVarValue("windowWidth", info ? std::to_string(info->width) : "");
SetTempVarValue("windowHeight",
info ? std::to_string(info->height) : "");
#ifdef _WIN32
SetTempVarValue("windowClass",
GetWindowClassByWindowTitle(matchWindow));
SetTempVarValue("windowClass", info ? info->windowClass : "");
if (_checkText) {
const auto text = GetTextInWindow(matchWindow);
if (text) {
SetTempVarValue("windowText", *text);
}
SetTempVarValue("windowText",
(info && info->text) ? *info->text : "");
}
#endif
if (!IsReferencedInVars()) {
return;
}
if (_checkText) {
const auto text = GetTextInWindow(matchWindow);
SetVariableValue(text.value_or(""));
SetVariableValue((info && info->text) ? *info->text : "");
} else {
SetVariableValue(ForegroundWindowTitle());
}
@@ -144,13 +113,18 @@ static bool foregroundWindowChanged()
bool MacroConditionWindow::CheckCondition()
{
const auto windowList = GetWindowList();
bool match = false;
if (_windowRegex.Enabled()) {
match = WindowRegexMatches(windowList);
} else {
match = WindowMatches(windowList);
}
WindowQueryOptions options;
options.focus = _focus;
options.fullscreen = _fullscreen;
options.maximized = _maximized;
options.geometry = true;
#ifdef _WIN32
options.windowClass = true;
options.text = _checkText;
#endif
const auto windows = GetWindows(options);
bool match = FindMatch(windows);
match = match && (!_windowFocusChanged || foregroundWindowChanged());
return match;
}