fix(xdotool): preserve input focus after injection (#564)
This commit is contained in:
@@ -1004,10 +1004,23 @@ class TextInjector:
|
||||
logger.error("Text injection timed out on final attempt")
|
||||
raise
|
||||
|
||||
# Try to reset any stuck modifiers
|
||||
# Release modifiers without sending Escape, which applications may
|
||||
# interpret as a request to cancel or leave the focused input.
|
||||
try:
|
||||
subprocess.run(
|
||||
["xdotool", "key", "--clearmodifiers", "Escape"],
|
||||
[
|
||||
"xdotool",
|
||||
"keyup",
|
||||
"--clearmodifiers",
|
||||
"Control_L",
|
||||
"Control_R",
|
||||
"Shift_L",
|
||||
"Shift_R",
|
||||
"Alt_L",
|
||||
"Alt_R",
|
||||
"Super_L",
|
||||
"Super_R",
|
||||
],
|
||||
env=env,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
|
||||
@@ -1141,6 +1141,32 @@ class TestTextInjectorEdgeCases(unittest.TestCase):
|
||||
if env_backup is not None:
|
||||
os.environ["DISPLAY"] = env_backup
|
||||
|
||||
def test_inject_with_xdotool_releases_modifiers_without_escape(self):
|
||||
"""The xdotool path must keep the target input focused after injection."""
|
||||
injector = TextInjector.__new__(TextInjector)
|
||||
injector.environment = DesktopEnvironment.X11
|
||||
|
||||
injector._inject_with_xdotool("test")
|
||||
|
||||
commands = [call.args[0] for call in self.mock_subprocess.call_args_list]
|
||||
self.assertIn(
|
||||
[
|
||||
"xdotool",
|
||||
"keyup",
|
||||
"--clearmodifiers",
|
||||
"Control_L",
|
||||
"Control_R",
|
||||
"Shift_L",
|
||||
"Shift_R",
|
||||
"Alt_L",
|
||||
"Alt_R",
|
||||
"Super_L",
|
||||
"Super_R",
|
||||
],
|
||||
commands,
|
||||
)
|
||||
self.assertFalse(any("Escape" in command for command in commands))
|
||||
|
||||
def test_inject_with_wayland_tool_ydotool(self):
|
||||
"""Test text injection with ydotool."""
|
||||
with patch.dict("os.environ", {"XDG_SESSION_TYPE": "wayland"}):
|
||||
|
||||
Reference in New Issue
Block a user