Fix confusing behavior when leaving window title empty in Auto-Type

- Modified Entry::autoTypeSequences() to treat empty window titles as catch-all associations
- Empty window title associations now match any window instead of being ignored
- Added comprehensive test case to verify the new behavior
- Fixes issue where empty window title associations only appeared during search

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-06-19 14:11:06 +00:00
committed by Jonathan White
parent aedd4ae08e
commit 2a931231c1
3 changed files with 38 additions and 1 deletions

View File

@@ -339,7 +339,9 @@ QList<QString> Entry::autoTypeSequences(const QString& windowTitle) const
const auto assocList = autoTypeAssociations()->getAll();
for (const auto& assoc : assocList) {
auto window = resolveMultiplePlaceholders(assoc.window);
if (!assoc.window.isEmpty() && windowMatches(window)) {
// Empty window title matches any window (acts as default/catch-all)
// Non-empty window title must match the current window
if (assoc.window.isEmpty() || windowMatches(window)) {
if (!assoc.sequence.isEmpty()) {
sequenceList << assoc.sequence;
} else {

View File

@@ -125,6 +125,14 @@ void TestAutoType::init()
m_entry5->setPassword("example5");
m_entry5->setTitle("some title");
m_entry5->setUrl("http://example.org");
// Entry with empty window title (should act as default/catch-all)
m_entry6 = new Entry();
m_entry6->setGroup(m_group);
m_entry6->setPassword("empty_window_test");
association.window = ""; // Empty window title
association.sequence = "empty_window_sequence";
m_entry6->autoTypeAssociations()->add(association);
}
void TestAutoType::cleanup()
@@ -280,6 +288,31 @@ void TestAutoType::testGlobalAutoTypeRegExp()
m_test->clearActions();
}
void TestAutoType::testGlobalAutoTypeEmptyWindow()
{
// Test that empty window title associations work as default/catch-all
// This should match any window since the association has an empty window title
m_test->setActiveWindowTitle("any random window title");
emit osUtils->globalShortcutTriggered("autotype");
m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QString("empty_window_sequence"));
m_test->clearActions();
// Test with a different window title - should still match
m_test->setActiveWindowTitle("completely different title");
emit osUtils->globalShortcutTriggered("autotype");
m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QString("empty_window_sequence"));
m_test->clearActions();
// Test with empty window title - should still match
m_test->setActiveWindowTitle("");
emit osUtils->globalShortcutTriggered("autotype");
m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QString("empty_window_sequence"));
m_test->clearActions();
}
void TestAutoType::testAutoTypeResults()
{
QScopedPointer<Entry> entry(new Entry());

View File

@@ -47,6 +47,7 @@ private slots:
void testGlobalAutoTypeUrlSubdomainMatch();
void testGlobalAutoTypeTitleMatchDisabled();
void testGlobalAutoTypeRegExp();
void testGlobalAutoTypeEmptyWindow();
void testAutoTypeResults();
void testAutoTypeResults_data();
void testAutoTypeSyntaxChecks();
@@ -64,6 +65,7 @@ private:
Entry* m_entry3;
Entry* m_entry4;
Entry* m_entry5;
Entry* m_entry6;
};
#endif // KEEPASSX_TESTAUTOTYPE_H