Refine Wine dialog event presentation
This commit is contained in:
@@ -156,8 +156,206 @@ class NativeRemoteControllerTest(unittest.TestCase):
|
||||
)
|
||||
|
||||
self.assertTrue(result)
|
||||
present_message.assert_not_called()
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.assert_called_once_with("Open, button, 2 of 4, Settings")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_ignores_changes_from_unfocused_objects(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Open", "button", "", "", "", 0, 0, "Settings"
|
||||
)
|
||||
present_message.reset_mock()
|
||||
|
||||
result = interface.PresentAccessibleEvent(
|
||||
"control-2", "value", "Cancel", "button", "", "", "", 0, 0, "Settings"
|
||||
)
|
||||
|
||||
self.assertFalse(result)
|
||||
present_message.assert_not_called()
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_presents_focused_value_changes_without_repeating_title(
|
||||
self, present_message
|
||||
):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Version", "combo box", "Windows 10", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.reset_mock()
|
||||
|
||||
result = interface.PresentAccessibleEvent(
|
||||
"control-1", "value", "Version", "combo box", "Windows 11", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
|
||||
self.assertTrue(result)
|
||||
present_message.assert_called_once_with("Version, combo box, Windows 11")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_suppresses_immediate_duplicates(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
|
||||
first = interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "OK", "button", "", "", "", 0, 0, "Settings"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
second = interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "OK", "button", "", "", "", 0, 0, "Settings"
|
||||
)
|
||||
|
||||
self.assertTrue(first)
|
||||
self.assertFalse(second)
|
||||
present_message.assert_called_once_with("OK, button, Settings")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_focus_burst_presents_only_final_control(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Add application", "button", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-2", "focus", "OK", "button", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Add application", "button", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
|
||||
present_message.assert_not_called()
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.assert_called_once_with(
|
||||
"Add application, button, Wine configuration"
|
||||
)
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_focus_duplicate_clears_stale_pending_focus(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Open", "button", "", "", "", 0, 0,
|
||||
"Settings"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.reset_mock()
|
||||
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-2", "focus", "Cancel", "button", "", "", "", 0, 0,
|
||||
"Settings"
|
||||
)
|
||||
duplicate = interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Open", "button", "", "", "", 0, 0,
|
||||
"Settings"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
|
||||
self.assertFalse(duplicate)
|
||||
self.assertEqual(interface._wineAccessibleFocusSource, "control-1")
|
||||
present_message.assert_not_called()
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_focus_presents_new_window_title_without_control_fields(
|
||||
self, present_message
|
||||
):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
|
||||
result = interface.PresentAccessibleEvent(
|
||||
"window", "focus", "", "", "", "", "", 0, 0, "Wine configuration"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
|
||||
self.assertTrue(result)
|
||||
present_message.assert_called_once_with("Wine configuration")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_omits_generic_client_role(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "OK", "client", "", "", "", 0, 0, "Settings"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
|
||||
present_message.assert_called_once_with("OK, Settings")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_ignores_name_and_state_noise_on_focused_object(
|
||||
self, present_message
|
||||
):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"control-1", "focus", "Windows 10", "client", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.reset_mock()
|
||||
|
||||
name_result = interface.PresentAccessibleEvent(
|
||||
"control-1", "name", "OK", "client", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
state_result = interface.PresentAccessibleEvent(
|
||||
"control-1", "state", "OK", "client", "", "focused", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
|
||||
self.assertFalse(name_result)
|
||||
self.assertFalse(state_result)
|
||||
present_message.assert_not_called()
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_accepts_selection_from_focused_combo_child(
|
||||
self, present_message
|
||||
):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"combo", "focus", "Windows 10", "client", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.reset_mock()
|
||||
|
||||
result = interface.PresentAccessibleEvent(
|
||||
"combo-item-2", "selection", "Windows 8.1", "client", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
|
||||
self.assertTrue(result)
|
||||
present_message.assert_called_once_with("Windows 8.1")
|
||||
|
||||
@mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage")
|
||||
def test_accessible_event_rejects_selection_from_other_window(self, present_message):
|
||||
present_message.return_value = True
|
||||
interface = dbus_service.CthulhuDBusServiceInterface()
|
||||
interface.PresentAccessibleEvent(
|
||||
"combo", "focus", "Windows 10", "client", "", "", "", 0, 0,
|
||||
"Wine configuration"
|
||||
)
|
||||
interface._present_pending_accessible_focus()
|
||||
present_message.reset_mock()
|
||||
|
||||
result = interface.PresentAccessibleEvent(
|
||||
"other-item", "selection", "Unrelated", "client", "", "", "", 0, 0,
|
||||
"Other window"
|
||||
)
|
||||
|
||||
self.assertFalse(result)
|
||||
present_message.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -64,7 +64,11 @@ class LegacyTomlSchemaMigrationTests(unittest.TestCase):
|
||||
settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP,
|
||||
)
|
||||
self.assertEqual(general["cthulhuModifierKeys"], settings.DESKTOP_MODIFIER_KEYS)
|
||||
self.assertEqual(general["activePlugins"], ["Clipboard", "OCR"])
|
||||
self.assertEqual(
|
||||
general["activePlugins"],
|
||||
["Clipboard", "OCR", "WineAccessibility"],
|
||||
)
|
||||
self.assertTrue(general["wineAccessibilityPluginMigrated"])
|
||||
self.assertEqual(general["aiProvider"], settings.AI_PROVIDER_OLLAMA)
|
||||
self.assertFalse(general["aiAssistantEnabled"])
|
||||
self.assertEqual(general["ocrLanguageCode"], "eng")
|
||||
@@ -82,10 +86,35 @@ class LegacyTomlSchemaMigrationTests(unittest.TestCase):
|
||||
savedSettings = settingsPath.read_text(encoding="utf-8")
|
||||
|
||||
self.assertIn('profile = ["Default", "default"]', savedSettings)
|
||||
self.assertIn('activePlugins = ["Clipboard", "OCR"]', savedSettings)
|
||||
self.assertIn(
|
||||
'activePlugins = ["Clipboard", "OCR", "WineAccessibility"]',
|
||||
savedSettings,
|
||||
)
|
||||
self.assertIn("wineAccessibilityPluginMigrated = true", savedSettings)
|
||||
self.assertNotIn("format-version = 2", savedSettings)
|
||||
self.assertNotIn("[profiles.default.metadata]", savedSettings)
|
||||
|
||||
def test_wine_accessibility_migration_respects_later_plugin_disable(self):
|
||||
migratedSettings = """[general]
|
||||
startingProfile = ["Default", "default"]
|
||||
|
||||
[profiles.default]
|
||||
profile = ["Default", "default"]
|
||||
activePlugins = ["Clipboard", "OCR"]
|
||||
wineAccessibilityPluginMigrated = true
|
||||
"""
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempDir:
|
||||
Path(tempDir, "user-settings.toml").write_text(
|
||||
migratedSettings,
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
backend = Backend(tempDir)
|
||||
general = backend.getGeneral("default")
|
||||
|
||||
self.assertEqual(general["activePlugins"], ["Clipboard", "OCR"])
|
||||
|
||||
def test_legacy_profile_keybindings_are_preserved(self):
|
||||
legacySettings = LEGACY_SETTINGS.replace(
|
||||
'desktop-modifier-keys = ["Insert", "KP_Insert"]',
|
||||
|
||||
Reference in New Issue
Block a user