diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index cff662ce2..538fb09bf 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -334,19 +334,25 @@ QList Entry::autoTypeSequences(const QString& windowTitle) const }; QList sequenceList; + QList emptyWindowSequences; // Store sequences with empty window titles as fallback // Add window association matches const auto assocList = autoTypeAssociations()->getAll(); for (const auto& assoc : assocList) { auto window = resolveMultiplePlaceholders(assoc.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.window.isEmpty() && windowMatches(window)) { if (!assoc.sequence.isEmpty()) { sequenceList << assoc.sequence; } else { sequenceList << effectiveAutoTypeSequence(); } + } else if (assoc.window.isEmpty()) { + // Store empty window title associations as fallback + if (!assoc.sequence.isEmpty()) { + emptyWindowSequences << assoc.sequence; + } else { + emptyWindowSequences << effectiveAutoTypeSequence(); + } } } @@ -360,6 +366,12 @@ QList Entry::autoTypeSequences(const QString& windowTitle) const sequenceList << effectiveAutoTypeSequence(); } + // If no associations, title, or URL matched, use empty window title associations as fallback + // Only use fallback when title matching is enabled to avoid interfering with existing behavior + if (sequenceList.isEmpty() && config()->get(Config::AutoTypeEntryTitleMatch).toBool()) { + sequenceList << emptyWindowSequences; + } + return sequenceList; } diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index 65ce30c8d..c5603baca 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -126,11 +126,12 @@ void TestAutoType::init() m_entry5->setTitle("some title"); m_entry5->setUrl("http://example.org"); - // Entry with empty window title (should act as default/catch-all) + // Entry with empty window title (should act as fallback) m_entry6 = new Entry(); m_entry6->setGroup(m_group); m_entry6->setPassword("empty_window_test"); - association.window = ""; // Empty window title + m_entry6->setTitle("Entry for Empty Window Test"); + association.window = ""; // Empty window title association.sequence = "empty_window_sequence"; m_entry6->autoTypeAssociations()->add(association); } @@ -290,27 +291,27 @@ void TestAutoType::testGlobalAutoTypeRegExp() 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"); + // Enable title matching for this test since our fallback logic requires it + config()->set(Config::AutoTypeEntryTitleMatch, true); + + // Test that empty window title associations work as fallback when no other associations match + // This should use the empty window association from m_entry6 when no specific window matches + m_test->setActiveWindowTitle("no_matching_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"); + // Test that empty window title associations do NOT match when other associations exist and match + // This entry has window associations that should take precedence over empty window title + m_test->setActiveWindowTitle("custom window"); // This should match m_entry1 association emit osUtils->globalShortcutTriggered("autotype"); m_autoType->performGlobalAutoType(m_dbList); - QCOMPARE(m_test->actionChars(), QString("empty_window_sequence")); + QCOMPARE(m_test->actionChars(), QString("myuserassociationmypass")); // Should be from m_entry1, not empty window 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(); + // Reset title matching to default state + config()->set(Config::AutoTypeEntryTitleMatch, false); } void TestAutoType::testAutoTypeResults()