Compare commits

...

3 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
b561ff2e80 Fix confusing behavior when leaving window title empty in Auto-Type
- Modified Entry::autoTypeSequences() to use empty window title associations as fallback
- Empty window title associations now act as fallback when no other matches are found
- Fallback only applies when title matching is enabled to preserve existing behavior
- 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>

Co-authored-by: droidmonkey <2809491+droidmonkey@users.noreply.github.com>
2025-06-19 14:47:39 +00:00
copilot-swe-agent[bot]
2a931231c1 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>
2025-06-19 10:24:06 -04:00
copilot-swe-agent[bot]
aedd4ae08e Initial plan for issue 2025-06-19 10:24:04 -04:00
3 changed files with 50 additions and 0 deletions

View File

@@ -334,6 +334,7 @@ QList<QString> Entry::autoTypeSequences(const QString& windowTitle) const
};
QList<QString> sequenceList;
QList<QString> emptyWindowSequences; // Store sequences with empty window titles as fallback
// Add window association matches
const auto assocList = autoTypeAssociations()->getAll();
@@ -345,6 +346,13 @@ QList<QString> Entry::autoTypeSequences(const QString& windowTitle) const
} 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();
}
}
}
@@ -358,6 +366,12 @@ QList<QString> 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;
}

View File

@@ -125,6 +125,15 @@ 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 fallback)
m_entry6 = new Entry();
m_entry6->setGroup(m_group);
m_entry6->setPassword("empty_window_test");
m_entry6->setTitle("Entry for Empty Window Test");
association.window = ""; // Empty window title
association.sequence = "empty_window_sequence";
m_entry6->autoTypeAssociations()->add(association);
}
void TestAutoType::cleanup()
@@ -280,6 +289,31 @@ void TestAutoType::testGlobalAutoTypeRegExp()
m_test->clearActions();
}
void TestAutoType::testGlobalAutoTypeEmptyWindow()
{
// 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 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("myuserassociationmypass")); // Should be from m_entry1, not empty window
m_test->clearActions();
// Reset title matching to default state
config()->set(Config::AutoTypeEntryTitleMatch, false);
}
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