Compare commits

...

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
bdcf3f805d Apply remaining changes 2026-06-27 19:07:31 +00:00
copilot-swe-agent[bot]
748f2192ee Initial plan 2026-06-27 18:58:19 +00:00
3 changed files with 111 additions and 8 deletions

View File

@@ -1,5 +1,7 @@
#include "pch.h"
#include "TestHelpers.h"
#include <algorithm>
#include <interop/excluded_app.h>
#include <excluded_apps.h>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@@ -75,6 +77,45 @@ namespace UnitTestsCommonUtils
Assert::IsTrue(find_app_name_in_path(path, apps));
}
TEST_METHOD(ShortcutGuideBuiltInExcludedProcessNames_ContainsAtlantisExecutables)
{
const auto containsProcessName = [](std::wstring_view processName) {
return std::find(
shortcut_guide::interop::built_in_excluded_process_names.begin(),
shortcut_guide::interop::built_in_excluded_process_names.end(),
processName) != shortcut_guide::interop::built_in_excluded_process_names.end();
};
Assert::IsTrue(containsProcessName(L"ATLANTIS.EXE"));
Assert::IsTrue(containsProcessName(L"AWP.EXE"));
}
TEST_METHOD(FindAppNameInPath_AtlantisExecutableName_ReturnsTrue)
{
std::wstring path = L"C:\\PROGRAM FILES\\ATLANTIS\\ATLANTIS.EXE";
std::vector<std::wstring> apps = { L"ATLANTIS.EXE" };
Assert::IsTrue(find_app_name_in_path(path, apps));
}
TEST_METHOD(FindAppNameInPath_AtlantisAlternateExecutableName_ReturnsTrue)
{
std::wstring path = L"C:\\PROGRAM FILES\\ATLANTIS\\AWP.EXE";
std::vector<std::wstring> apps = { L"AWP.EXE" };
Assert::IsTrue(find_app_name_in_path(path, apps));
}
TEST_METHOD(ShortcutGuideBuiltInExcludedWindowTitles_ContainsAtlantisWordProcessor)
{
const auto containsWindowTitle = [](std::wstring_view windowTitle) {
return std::find(
shortcut_guide::interop::built_in_excluded_window_titles.begin(),
shortcut_guide::interop::built_in_excluded_window_titles.end(),
windowTitle) != shortcut_guide::interop::built_in_excluded_window_titles.end();
};
Assert::IsTrue(containsWindowTitle(L"ATLANTIS WORD PROCESSOR"));
}
TEST_METHOD(FindAppNameInPath_UNCPath_Works)
{
std::wstring path = L"\\\\server\\share\\folder\\app.exe";

View File

@@ -1,7 +1,48 @@
#include "pch.h"
#include "excluded_app.h"
#include <common/utils/excluded_apps.h>
#include <../utils/string_utils.h>
namespace
{
// This shared interop file exposes Shortcut Guide's exclusion check.
// Atlantis Word Processor can hard-lock input when Shortcut Guide is invoked over it.
constexpr int maxTitleLength = 255;
const std::vector<std::wstring> builtInExcludedProcessNames(
shortcut_guide::interop::built_in_excluded_process_names.begin(),
shortcut_guide::interop::built_in_excluded_process_names.end());
bool isShortcutGuideBuiltInProcessExcluded(const std::wstring& processPath)
{
return find_app_name_in_path(processPath, builtInExcludedProcessNames);
}
bool isShortcutGuideBuiltInWindowTitleExcluded(HWND hwnd)
{
WCHAR title[maxTitleLength + 1]{};
int len = GetWindowTextW(hwnd, title, maxTitleLength + 1);
if (len <= 0)
{
return false;
}
title[len] = L'\0';
CharUpperBuffW(title, static_cast<DWORD>(len));
std::wstring titleUpper(title, len);
for (const auto& excludedTitle : shortcut_guide::interop::built_in_excluded_window_titles)
{
if (titleUpper.contains(excludedTitle))
{
return true;
}
}
return false;
}
}
extern "C"
{
__declspec(dllexport) bool IsCurrentWindowExcludedFromShortcutGuide()
@@ -14,27 +55,32 @@ extern "C"
std::wstring_view view(excludedUppercase);
view = left_trim<wchar_t>(trim<wchar_t>(view));
m_excludedApps.clear();
std::vector<std::wstring> excludedApps;
while (!view.empty())
{
auto pos = (std::min)(view.find_first_of(L"\r\n"), view.length());
m_excludedApps.emplace_back(view.substr(0, pos));
excludedApps.emplace_back(view.substr(0, pos));
view.remove_prefix(pos);
view = left_trim<wchar_t>(trim<wchar_t>(view));
}
if (m_excludedApps.empty())
{
return false;
}
if (HWND foregroundApp{ GetForegroundWindow() })
{
auto processPath = get_process_path(foregroundApp);
CharUpperBuffW(processPath.data(), static_cast<DWORD>(processPath.length()));
return check_excluded_app(foregroundApp, processPath, m_excludedApps);
if (check_excluded_app(foregroundApp, processPath, excludedApps))
{
return true;
}
if (isShortcutGuideBuiltInProcessExcluded(processPath))
{
return true;
}
return isShortcutGuideBuiltInWindowTitleExcluded(foregroundApp);
}
return false;
}

View File

@@ -1,4 +1,20 @@
#pragma once
#include <array>
#include <string>
#include <string_view>
#include <vector>
namespace shortcut_guide::interop
{
inline constexpr std::array<std::wstring_view, 2> built_in_excluded_process_names = {
L"AWP.EXE",
L"ATLANTIS.EXE",
};
inline constexpr std::array<std::wstring_view, 1> built_in_excluded_window_titles = {
L"ATLANTIS WORD PROCESSOR",
};
}
extern "C"
{