From 2a931231c11281adcbeffdcdb92fd5fa3a09545f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Jun 2025 14:11:06 +0000 Subject: [PATCH] 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> --- src/core/Entry.cpp | 4 +++- tests/TestAutoType.cpp | 33 +++++++++++++++++++++++++++++++++ tests/TestAutoType.h | 2 ++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index 0147ec0f9..cff662ce2 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -339,7 +339,9 @@ QList 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 { diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index 91bd7d0a4..65ce30c8d 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -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(new Entry()); diff --git a/tests/TestAutoType.h b/tests/TestAutoType.h index 035c0d5c0..7b2d798ee 100644 --- a/tests/TestAutoType.h +++ b/tests/TestAutoType.h @@ -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