From 6604ee9e6e3698c6cca1b5400a0cc0485a8e6a0a Mon Sep 17 00:00:00 2001
From: mklcp <22609769+mklcp@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:35:44 +0200
Subject: [PATCH 1/3] pynput support

---
 .gitignore              |  4 ++++
 nerd-dictation          | 35 +++++++++++++++++++++++++++++++++--
 package/python/setup.py |  2 +-
 3 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index dc13008..e26e815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,7 @@ __pycache__/
 
 # Fallback location used for the language model.
 /model
+/venv/
+/package/python
+!/package/python/readme.rst
+!/package/python/setup.py
\ No newline at end of file
diff --git a/nerd-dictation b/nerd-dictation
index c313dca..595a30a 100755
--- a/nerd-dictation
+++ b/nerd-dictation
@@ -39,6 +39,13 @@ USER_CONFIG = "nerd-dictation.py"
 
 SIMULATE_INPUT_CODE_COMMAND = -1
 
+try:
+    from pynput.keyboard import Key, Controller  # type: ignore
+    keyboard = Controller()
+    TAP_DELAY = 0.012
+except ImportError:
+    sys.stderr.write("Module 'pynput' is not installed. Defaulting input method to xdotool.")
+
 
 # -----------------------------------------------------------------------------
 # General Utilities
@@ -135,6 +142,26 @@ def execfile(filepath: str, mod: Optional[ModuleType] = None) -> Optional[Module
     return mod
 
 
+# -----------------------------------------------------------------------------
+# Simulate Input: PYNPUT
+#
+def simulate_typing_with_pynput(delete_prev_chars: int, text: str) -> None:
+
+    # No setup/tear-down.
+    if delete_prev_chars == SIMULATE_INPUT_CODE_COMMAND:
+        return
+
+    if delete_prev_chars:
+        for i in range(delete_prev_chars):
+            keyboard.tap(Key.backspace)
+            time.sleep(TAP_DELAY)
+    else:
+        for c in text:
+            keyboard.type(c)
+            time.sleep(TAP_DELAY)
+
+
+
 # -----------------------------------------------------------------------------
 # Simulate Input: XDOTOOL
 #
@@ -166,6 +193,7 @@ def simulate_typing_with_xdotool(delete_prev_chars: int, text: str) -> None:
     )
 
 
+
 # -----------------------------------------------------------------------------
 # Simulate Input: YDOTOOL
 #
@@ -1404,7 +1432,9 @@ def main_begin(
     # Handled the resulting text
     #
     if output == "SIMULATE_INPUT":
-        if simulate_input_tool == "XDOTOOL":
+        if simulate_input_tool == "PYNPUT":
+            handle_fn = simulate_typing_with_pynput
+        elif simulate_input_tool == "XDOTOOL":
             handle_fn = simulate_typing_with_xdotool
         elif simulate_input_tool == "YDOTOOL":
             handle_fn = simulate_typing_with_ydotool
@@ -1790,11 +1820,12 @@ def argparse_create_begin(subparsers: "argparse._SubParsersAction[argparse.Argum
         "--simulate-input-tool",
         dest="simulate_input_tool",
         default="XDOTOOL",
-        choices=("XDOTOOL", "DOTOOL", "DOTOOLC", "YDOTOOL", "WTYPE", "STDOUT"),
+        choices=("PYNPUT", "XDOTOOL", "DOTOOL", "DOTOOLC", "YDOTOOL", "WTYPE", "STDOUT"),
         metavar="SIMULATE_INPUT_TOOL",
         help=(
             "Program used to simulate keystrokes (default).\n"
             "\n"
+            "- ``PYNPUT`` Compatible with all Linux distributions and Wayland.\n"
             "- ``XDOTOOL`` Compatible with the X server only (default).\n"
             "- ``DOTOOL`` Compatible with all Linux distributions and Wayland.\n"
             "- ``DOTOOLC`` Same as DOTOOL but for use with the `dotoold` daemon.\n"
diff --git a/package/python/setup.py b/package/python/setup.py
index 697d2b6..6622574 100644
--- a/package/python/setup.py
+++ b/package/python/setup.py
@@ -59,7 +59,7 @@ def main(base_dir):
         packages=[""],
         package_data={"": [NERD_DICTATION_DST, README_DST]},
         include_package_data=True,
-        install_requires=["vosk"],
+        install_requires=["vosk", "pynput"],
         python_requires=">=3.8",
     )
 

From 363781df853be5038f7f22b1fb8a021d52e484b6 Mon Sep 17 00:00:00 2001
From: mklcp <22609769+mklcp@users.noreply.github.com>
Date: Fri, 26 Jul 2024 10:23:14 +0200
Subject: [PATCH 2/3] ran black, mypy, pylint

---
 nerd-dictation | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/nerd-dictation b/nerd-dictation
index 595a30a..6e63ceb 100755
--- a/nerd-dictation
+++ b/nerd-dictation
@@ -41,6 +41,7 @@ SIMULATE_INPUT_CODE_COMMAND = -1
 
 try:
     from pynput.keyboard import Key, Controller  # type: ignore
+
     keyboard = Controller()
     TAP_DELAY = 0.012
 except ImportError:
@@ -152,7 +153,7 @@ def simulate_typing_with_pynput(delete_prev_chars: int, text: str) -> None:
         return
 
     if delete_prev_chars:
-        for i in range(delete_prev_chars):
+        for _ in range(delete_prev_chars):
             keyboard.tap(Key.backspace)
             time.sleep(TAP_DELAY)
     else:
@@ -161,7 +162,6 @@ def simulate_typing_with_pynput(delete_prev_chars: int, text: str) -> None:
             time.sleep(TAP_DELAY)
 
 
-
 # -----------------------------------------------------------------------------
 # Simulate Input: XDOTOOL
 #
@@ -193,7 +193,6 @@ def simulate_typing_with_xdotool(delete_prev_chars: int, text: str) -> None:
     )
 
 
-
 # -----------------------------------------------------------------------------
 # Simulate Input: YDOTOOL
 #
@@ -776,7 +775,8 @@ class from_words_to_digits:
                         continue
 
                     word_list[i:i_next] = [
-                        ("{:,d}".format(int(number)) if (numbers_use_separator and allow_reformat) else number) + suffix
+                        ("{:,d}".format(int(number)) if (numbers_use_separator and allow_reformat) else number)
+                        + suffix
                     ]
 
                     if (i_number_prev != -1) and (i_number_prev + 1 != i):

From ca9f312258e713eab6fe7a1d2ac773bbee82d697 Mon Sep 17 00:00:00 2001
From: mklcp <22609769+mklcp@users.noreply.github.com>
Date: Sat, 27 Jul 2024 11:01:49 +0200
Subject: [PATCH 3/3] corrected condition

---
 nerd-dictation | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/nerd-dictation b/nerd-dictation
index 6e63ceb..20ab897 100755
--- a/nerd-dictation
+++ b/nerd-dictation
@@ -156,10 +156,9 @@ def simulate_typing_with_pynput(delete_prev_chars: int, text: str) -> None:
         for _ in range(delete_prev_chars):
             keyboard.tap(Key.backspace)
             time.sleep(TAP_DELAY)
-    else:
-        for c in text:
-            keyboard.type(c)
-            time.sleep(TAP_DELAY)
+    for c in text:
+        keyboard.type(c)
+        time.sleep(TAP_DELAY)
 
 
 # -----------------------------------------------------------------------------