From d1bad818cdd08bb61dc14e6683aebabb5b5d7b77 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Wed, 16 Jul 2025 19:34:56 -0400 Subject: [PATCH 1/4] initial improvements to pty driver. Improved clipboard handling of multibyte characters. Added emoji menu to vmenu. It places the emoji to the clipboard to be used wherever. --- .../onScreenUpdate/65000-progress_detector.py | 24 ++ .../vmenu-profiles/KEY/emoji/__init__.py | 1 + .../KEY/emoji/flags/__init__.py | 1 + .../vmenu-profiles/KEY/emoji/flags/canada.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/uk.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/usa.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/__init__.py | 1 + .../vmenu-profiles/KEY/emoji/food/beer.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/coffee.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/donut.py | 22 ++ .../KEY/emoji/food/hamburger.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/pizza.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/taco.py | 22 ++ .../KEY/emoji/holidays/__init__.py | 1 + .../vmenu-profiles/KEY/emoji/holidays/bat.py | 22 ++ .../KEY/emoji/holidays/bunny.py | 22 ++ .../KEY/emoji/holidays/christmas_tree.py | 22 ++ .../KEY/emoji/holidays/easter_egg.py | 22 ++ .../KEY/emoji/holidays/fireworks.py | 22 ++ .../KEY/emoji/holidays/ghost.py | 22 ++ .../vmenu-profiles/KEY/emoji/holidays/gift.py | 22 ++ .../KEY/emoji/holidays/jack_o_lantern.py | 22 ++ .../KEY/emoji/holidays/santa.py | 22 ++ .../KEY/emoji/holidays/shamrock.py | 22 ++ .../KEY/emoji/holidays/skull.py | 22 ++ .../KEY/emoji/holidays/snowman.py | 22 ++ .../KEY/emoji/holidays/spider.py | 22 ++ .../KEY/emoji/holidays/turkey.py | 22 ++ .../KEY/emoji/nature/__init__.py | 1 + .../vmenu-profiles/KEY/emoji/nature/cat.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/dog.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/moon.py | 22 ++ .../KEY/emoji/nature/rainbow.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/sun.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/tree.py | 22 ++ .../KEY/emoji/people/__init__.py | 1 + .../vmenu-profiles/KEY/emoji/people/angry.py | 22 ++ .../vmenu-profiles/KEY/emoji/people/cool.py | 22 ++ .../vmenu-profiles/KEY/emoji/people/crying.py | 22 ++ .../vmenu-profiles/KEY/emoji/people/devil.py | 22 ++ .../KEY/emoji/people/laughing.py | 22 ++ .../vmenu-profiles/KEY/emoji/people/poop.py | 22 ++ .../vmenu-profiles/KEY/emoji/people/sad.py | 22 ++ .../KEY/emoji/people/shocked.py | 22 ++ .../KEY/emoji/people/smiling.py | 22 ++ .../KEY/emoji/people/thumbs_up.py | 22 ++ .../KEY/emoji/people/winking.py | 22 ++ .../KEY/emoji/symbols/__init__.py | 1 + .../KEY/emoji/symbols/checkmark.py | 22 ++ .../vmenu-profiles/KEY/emoji/symbols/fire.py | 22 ++ .../vmenu-profiles/KEY/emoji/symbols/heart.py | 22 ++ .../KEY/emoji/symbols/lightning.py | 22 ++ .../vmenu-profiles/KEY/emoji/symbols/peace.py | 22 ++ .../KEY/emoji/symbols/rock_on.py | 22 ++ .../KEY/emoji/symbols/skull_crossbones.py | 22 ++ .../vmenu-profiles/KEY/emoji/symbols/star.py | 22 ++ src/fenrirscreenreader/fenrirVersion.py | 2 +- .../inputDriver/ptyDriver.py | 176 +++++++++- .../screenDriver/ptyDriver.py | 322 +++++++++++++----- .../screenDriver/vcsaDriver.py | 5 +- 60 files changed, 1503 insertions(+), 89 deletions(-) create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/canada.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/uk.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/usa.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/beer.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/coffee.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/donut.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/hamburger.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/pizza.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/taco.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bat.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bunny.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/christmas_tree.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/easter_egg.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/fireworks.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/ghost.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/gift.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/jack_o_lantern.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/santa.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/shamrock.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/skull.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/snowman.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/spider.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/turkey.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cat.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/dog.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/moon.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rainbow.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sun.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/tree.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/angry.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/cool.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/crying.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/devil.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/laughing.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/poop.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/sad.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/shocked.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smiling.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/thumbs_up.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/winking.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/__init__.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/checkmark.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/fire.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/heart.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/lightning.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/peace.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/rock_on.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/skull_crossbones.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/star.py diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py index e195d1b7..010b49b8 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py @@ -235,6 +235,30 @@ class command: ): self.play_activity_beep() self.env["commandBuffer"]["lastProgressTime"] = current_time + return + + # Pattern 5: Braille progress indicators + braille_match = re.search(r'[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⡿⣟⣯⣷⣾⣽⣻⢿]', text) + if braille_match: + if current_time - self.env["commandBuffer"]["lastProgressTime"] >= 1.0: + self.play_activity_beep() + self.env["commandBuffer"]["lastProgressTime"] = current_time + return + + # Pattern 6: Moon phase progress indicators + moon_match = re.search(r'[🌑🌒🌓🌔🌕🌖🌗🌘]', text) + if moon_match: + moon_phases = { + '🌑': 0, '🌒': 12.5, '🌓': 25, '🌔': 37.5, + '🌕': 50, '🌖': 62.5, '🌗': 75, '🌘': 87.5 + } + moon_char = moon_match.group(0) + if moon_char in moon_phases: + percentage = moon_phases[moon_char] + if percentage != self.env["commandBuffer"]["lastProgressValue"]: + self.play_progress_tone(percentage) + self.env["commandBuffer"]["lastProgressValue"] = percentage + return def play_progress_tone(self, percentage): # Map 0-100% to 400-1200Hz frequency range diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/__init__.py new file mode 100644 index 00000000..bb261d58 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/__init__.py @@ -0,0 +1 @@ +# Emoji VMenu category \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/__init__.py new file mode 100644 index 00000000..9dfb5e09 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/__init__.py @@ -0,0 +1 @@ +# Flags emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/canada.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/canada.py new file mode 100644 index 00000000..613803e6 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/canada.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇨🇦" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Canada flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Canada flag to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/uk.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/uk.py new file mode 100644 index 00000000..3bbbd3eb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/uk.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇬🇧" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add UK flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added UK flag to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/usa.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/usa.py new file mode 100644 index 00000000..9b1a9d9c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/usa.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇺🇸" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add USA flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added USA flag to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/__init__.py new file mode 100644 index 00000000..b03a398b --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/__init__.py @@ -0,0 +1 @@ +# Food emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/beer.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/beer.py new file mode 100644 index 00000000..80dc013f --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/beer.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍺" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Beer emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added beer to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/coffee.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/coffee.py new file mode 100644 index 00000000..eee79401 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/coffee.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "☕" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add coffee emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added coffee to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/donut.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/donut.py new file mode 100644 index 00000000..695d9dcf --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/donut.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍩" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Donut emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added donut to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/hamburger.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/hamburger.py new file mode 100644 index 00000000..d4fa4ee4 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/hamburger.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍔" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add hamburger emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added hamburger to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/pizza.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/pizza.py new file mode 100644 index 00000000..c777fdb7 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/pizza.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍕" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add pizza emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added pizza to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/taco.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/taco.py new file mode 100644 index 00000000..c61f9121 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/taco.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌮" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Taco emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added taco to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/__init__.py new file mode 100644 index 00000000..2fc1e37a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/__init__.py @@ -0,0 +1 @@ +# Holidays emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bat.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bat.py new file mode 100644 index 00000000..befdcafe --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bat.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🦇" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add bat emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added bat to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bunny.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bunny.py new file mode 100644 index 00000000..8cd6d6fc --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/bunny.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🐰" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add bunny emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added bunny to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/christmas_tree.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/christmas_tree.py new file mode 100644 index 00000000..5600eb96 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/christmas_tree.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎄" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Christmas tree emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Christmas tree to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/easter_egg.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/easter_egg.py new file mode 100644 index 00000000..372f74e5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/easter_egg.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🥚" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Easter egg emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Easter egg to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/fireworks.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/fireworks.py new file mode 100644 index 00000000..d5d89b86 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/fireworks.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎆" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add fireworks emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added fireworks to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/ghost.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/ghost.py new file mode 100644 index 00000000..32d265fb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/ghost.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "👻" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add ghost emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added ghost to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/gift.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/gift.py new file mode 100644 index 00000000..296ab6b3 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/gift.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎁" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add gift emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added gift to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/jack_o_lantern.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/jack_o_lantern.py new file mode 100644 index 00000000..cc7336fa --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/jack_o_lantern.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎃" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add jack o'lantern emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added jack o'lantern to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/santa.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/santa.py new file mode 100644 index 00000000..5fe56316 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/santa.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎅" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Santa emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Santa to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/shamrock.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/shamrock.py new file mode 100644 index 00000000..4892abc5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/shamrock.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "☘️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add shamrock emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added shamrock to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/skull.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/skull.py new file mode 100644 index 00000000..3e2221cc --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/skull.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "💀" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add skull emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added skull to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/snowman.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/snowman.py new file mode 100644 index 00000000..a1c54d31 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/snowman.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "⛄" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add snowman emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added snowman to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/spider.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/spider.py new file mode 100644 index 00000000..94a7a8b0 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/spider.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🕷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add spider emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added spider to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/turkey.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/turkey.py new file mode 100644 index 00000000..c8d6d89f --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/turkey.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🦃" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add turkey emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added turkey to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/__init__.py new file mode 100644 index 00000000..069e4fc1 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/__init__.py @@ -0,0 +1 @@ +# Nature emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cat.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cat.py new file mode 100644 index 00000000..d494a60a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cat.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🐱" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Cat emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added cat to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/dog.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/dog.py new file mode 100644 index 00000000..e2ccd8ee --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/dog.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🐶" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Dog emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added dog to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/moon.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/moon.py new file mode 100644 index 00000000..e7c528cc --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/moon.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌙" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add moon emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added moon to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rainbow.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rainbow.py new file mode 100644 index 00000000..4a98959f --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rainbow.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌈" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Rainbow emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added rainbow to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sun.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sun.py new file mode 100644 index 00000000..bab1eec5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sun.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "☀️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add sun emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added sun to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/tree.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/tree.py new file mode 100644 index 00000000..53d0ae28 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/tree.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌳" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add tree emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added tree to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/__init__.py new file mode 100644 index 00000000..dbd3765e --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/__init__.py @@ -0,0 +1 @@ +# People emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/angry.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/angry.py new file mode 100644 index 00000000..8f14278e --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/angry.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😠" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Angry face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added angry face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/cool.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/cool.py new file mode 100644 index 00000000..cbaff6d8 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/cool.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😎" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Cool face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added cool face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/crying.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/crying.py new file mode 100644 index 00000000..1be9574c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/crying.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😭" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Crying face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added crying face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/devil.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/devil.py new file mode 100644 index 00000000..073de67a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/devil.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😈" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Devil face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added devil face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/laughing.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/laughing.py new file mode 100644 index 00000000..e31b0d1b --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/laughing.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😂" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add laughing face emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added laughing face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/poop.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/poop.py new file mode 100644 index 00000000..b3ff0670 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/poop.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "💩" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Poop emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added poop to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/sad.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/sad.py new file mode 100644 index 00000000..3743e0fb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/sad.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😢" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Sad face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added sad face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/shocked.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/shocked.py new file mode 100644 index 00000000..6f0a045c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/shocked.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😱" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Shocked face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added shocked face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smiling.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smiling.py new file mode 100644 index 00000000..9c6dce41 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smiling.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😊" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add smiling face emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added smiling face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/thumbs_up.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/thumbs_up.py new file mode 100644 index 00000000..c9209a1a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/thumbs_up.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "👍" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add thumbs up emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added thumbs up to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/winking.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/winking.py new file mode 100644 index 00000000..a623f6c0 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/winking.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😉" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add winking face emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added winking face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/__init__.py new file mode 100644 index 00000000..bea3d4b5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/__init__.py @@ -0,0 +1 @@ +# Symbols emoji subcategory \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/checkmark.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/checkmark.py new file mode 100644 index 00000000..648741ab --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/checkmark.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "✅" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add checkmark emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added checkmark to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/fire.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/fire.py new file mode 100644 index 00000000..6b7bf53c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/fire.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🔥" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Fire emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added fire to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/heart.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/heart.py new file mode 100644 index 00000000..47735601 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/heart.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "❤️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add heart emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added heart to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/lightning.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/lightning.py new file mode 100644 index 00000000..c4485deb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/lightning.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "⚡" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Lightning emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added lightning to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/peace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/peace.py new file mode 100644 index 00000000..3016dd96 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/peace.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "✌️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Peace sign emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added peace sign to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/rock_on.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/rock_on.py new file mode 100644 index 00000000..7e1e87f3 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/rock_on.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🤘" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Sign of the horns emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added sign of the horns to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/skull_crossbones.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/skull_crossbones.py new file mode 100644 index 00000000..f78545a2 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/skull_crossbones.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "☠️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Skull and crossbones emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added skull and crossbones to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/star.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/star.py new file mode 100644 index 00000000..bc94145c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/star.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "⭐" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add star emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added star to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index 086b56af..0e664a47 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,6 +4,6 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. -version = "2025.07.15" +version = "2025.07.16" codeName = "testing" code_name = "testing" diff --git a/src/fenrirscreenreader/inputDriver/ptyDriver.py b/src/fenrirscreenreader/inputDriver/ptyDriver.py index 7ca54df9..74f26ee3 100644 --- a/src/fenrirscreenreader/inputDriver/ptyDriver.py +++ b/src/fenrirscreenreader/inputDriver/ptyDriver.py @@ -39,7 +39,177 @@ class driver(inputDriver): Args: environment: Fenrir environment dictionary + + Returns: + bool: True if initialization successful, False otherwise """ - self.env = environment - self.env["runtime"]["InputManager"].set_shortcut_type("BYTE") - self._is_initialized = True + try: + if environment is None: + raise ValueError("Environment cannot be None") + + self.env = environment + + # Validate required managers are available + if "runtime" not in self.env: + raise ValueError("Runtime environment missing") + if "InputManager" not in self.env["runtime"]: + raise ValueError("InputManager not available") + + self.env["runtime"]["InputManager"].set_shortcut_type("BYTE") + self._is_initialized = True + + self.env["runtime"]["DebugManager"].write_debug_out( + "PTY inputDriver: Initialized with byte-based shortcuts", + debug.DebugLevel.INFO + ) + return True + + except Exception as e: + # Log error if possible, otherwise fallback to print + try: + if hasattr(self, 'env') and self.env and "runtime" in self.env: + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY inputDriver: Initialization failed: {e}", + debug.DebugLevel.ERROR + ) + else: + print(f"PTY inputDriver initialization error: {e}") + except: + print(f"PTY inputDriver initialization error: {e}") + + self._is_initialized = False + return False + + def shutdown(self): + """Shutdown the PTY input driver. + + Performs cleanup operations when the driver is being stopped. + For PTY driver, this involves cleaning up any resources and + logging the shutdown. + """ + if not self._is_initialized: + return + + try: + self.env["runtime"]["DebugManager"].write_debug_out( + "PTY inputDriver: Shutting down", + debug.DebugLevel.INFO + ) + except Exception as e: + # Fallback logging if debug manager is unavailable + print(f"PTY inputDriver shutdown error: {e}") + finally: + self._is_initialized = False + + def get_input_event(self): + """Get input event from PTY. + + For PTY driver, input events are handled through the byte-based + shortcut system rather than direct device events. This method + returns None as PTY input is processed through the screen driver + and InputManager's byte processing. + + Returns: + None: PTY driver uses byte-based processing, not event-based + """ + return None + + def is_device_connected(self): + """Check if PTY input device is connected. + + For PTY driver, the "device" is the terminal interface itself, + which is considered connected if the driver is initialized. + + Returns: + bool: True if driver is initialized, False otherwise + """ + return self._is_initialized + + def get_device_name(self): + """Get the name of the PTY input device. + + Returns: + str: Human-readable name of the PTY input device + """ + return "PTY (Pseudo-terminal) Input" + + def grab_devices(self, grab=True): + """Grab or release input devices. + + For PTY driver, device grabbing is not applicable since input + is processed through terminal emulation rather than direct + device access. + + Args: + grab (bool): Whether to grab (True) or release (False) devices + + Returns: + bool: Always returns True for PTY driver (no-op success) + """ + if not self._is_initialized: + return False + + action = "grab" if grab else "release" + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY inputDriver: {action} devices (no-op for PTY)", + debug.DebugLevel.INFO + ) + return True + + def has_device_detection(self): + """Check if driver supports device detection. + + PTY driver does not support dynamic device detection since + it operates on the terminal interface directly. + + Returns: + bool: Always False for PTY driver + """ + return False + + def get_device_list(self): + """Get list of available input devices. + + For PTY driver, there is only one logical device - the terminal + interface itself. + + Returns: + list: Single-item list containing PTY device info + """ + if not self._is_initialized: + return [] + + return [{ + 'name': 'PTY Terminal', + 'path': '/dev/pts/*', + 'type': 'terminal', + 'connected': True + }] + + def get_led_state(self, led_mask=None): + """Get LED state information. + + PTY driver cannot access LED states since it operates through + terminal emulation rather than direct hardware access. + + Args: + led_mask: LED mask parameter (ignored for PTY) + + Returns: + dict: Empty dict (no LED access for PTY) + """ + return {} + + def set_led_state(self, led_dict): + """Set LED states. + + PTY driver cannot control LEDs since it operates through + terminal emulation rather than direct hardware access. + + Args: + led_dict (dict): LED state dictionary (ignored for PTY) + + Returns: + bool: Always False (LED control not supported) + """ + return False diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py index 68b3b617..e70d78ad 100644 --- a/src/fenrirscreenreader/screenDriver/ptyDriver.py +++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py @@ -13,6 +13,7 @@ import signal import struct import sys import termios +import threading import time import tty from select import select @@ -32,16 +33,39 @@ class FenrirScreen(pyte.Screen): class Terminal: - def __init__(self, columns, lines, p_in): + def __init__(self, columns, lines, p_in, env=None): self.text = "" self.attributes = None self.screen = FenrirScreen(columns, lines) + self.env = env # Environment for proper logging + + # Pre-create default attribute template to avoid repeated allocation + self._default_attribute = [ + "default", "default", False, False, False, False, False, False, + "default", "default" + ] self.screen.write_process_input = lambda data: p_in.write( data.encode() ) self.stream = pyte.ByteStream() self.stream.attach(self.screen) + def _log_error(self, message, level=None): + """Log error message using proper debug manager if available.""" + if self.env and "runtime" in self.env and "DebugManager" in self.env["runtime"]: + try: + log_level = level if level else debug.DebugLevel.ERROR + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY Terminal: {message}", + log_level + ) + return + except Exception: + pass # Fallback to print if debug manager fails + + # Fallback logging when debug manager unavailable + print(f"PTY Terminal: {message}") + def feed(self, data): self.stream.feed(data) @@ -52,45 +76,57 @@ class Terminal: lines = self.screen.dirty else: lines = range(self.screen.lines) - self.attributes = [ - [ - list(attribute[1:]) + [False, "default", "default"] - for attribute in line.values() - ] - for line in buffer.values() - ] - for y in lines: try: - t = self.attributes[y] + self.attributes = [ + [ + list(attribute[1:]) + [False, "default", "default"] + if len(attribute) > 1 else [False, "default", "default"] + for attribute in line.values() + ] + for line in buffer.values() + ] except Exception as e: - # Terminal class doesn't have access to env, use fallback - # logging - print( - f"ptyDriver Terminal update_attributes: Error accessing " - f"attributes: {e}" + self._log_error(f"Error initializing attributes: {e}") + # Fallback to empty attributes + self.attributes = [[] for _ in range(self.screen.lines)] + for y in lines: + # Validate y is within reasonable bounds (prevent memory exhaustion) + max_lines = 10000 # Reasonable maximum for terminal applications + if y >= max_lines: + self._log_error( + f"Line index {y} exceeds maximum {max_lines}, " + f"skipping attribute update", + debug.DebugLevel.WARNING ) + continue + + # Check if line y exists in buffer before accessing it + if y not in buffer: + # Only log this occasionally to prevent spam + if y % 10 == 0: # Log every 10th missing line + self._log_error( + f"Lines {y}-{y+9} not found in buffer, skipping attribute updates", + debug.DebugLevel.WARNING + ) + continue + + # Ensure attributes array is large enough for line y + while len(self.attributes) <= y: self.attributes.append([]) - - self.attributes[y] = [ - list(attribute[1:]) + [False, "default", "default"] - for attribute in (buffer[y].values()) - ] + + try: + self.attributes[y] = [ + list(attribute[1:]) + [False, "default", "default"] + for attribute in (buffer[y].values()) + ] + except Exception as e: + self._log_error(f"Error updating attributes for line {y}: {e}") + # Initialize with empty attributes if update fails + self.attributes[y] = [] if len(self.attributes[y]) < self.screen.columns: diff = self.screen.columns - len(self.attributes[y]) - self.attributes[y] += [ - [ - "default", - "default", - False, - False, - False, - False, - False, - False, - "default", - "default", - ] - ] * diff + # Use pre-created template for efficiency + self.attributes[y] += [self._default_attribute[:] for _ in range(diff)] def resize(self, lines, columns): self.screen.resize(lines, columns) @@ -98,31 +134,35 @@ class Terminal: self.update_attributes(True) def set_cursor(self, x=-1, y=-1): - x_pos = x - y_pos = y - if x_pos == -1: - x_pos = self.screen.cursor.x - if y_pos == -1: - y_pos = self.screen.cursor.y - self.screen.cursor.x = min( - self.screen.cursor.x, self.screen.columns - 1 - ) - self.screen.cursor.y = min(self.screen.cursor.y, self.screen.lines - 1) + # Determine target cursor position + x_pos = x if x != -1 else self.screen.cursor.x + y_pos = y if y != -1 else self.screen.cursor.y + + # Validate and clamp cursor position to screen bounds + max_x = max(0, self.screen.columns - 1) + max_y = max(0, self.screen.lines - 1) + + self.screen.cursor.x = max(0, min(x_pos, max_x)) + self.screen.cursor.y = max(0, min(y_pos, max_y)) def get_screen_content(self): cursor = self.screen.cursor self.text = "\n".join(self.screen.display) self.update_attributes(self.attributes is None) self.screen.dirty.clear() - return { + + # Return screen content without unnecessary copying + # Only copy attributes if they exist and need protection + screen_data = { "cursor": (cursor.x, cursor.y), "lines": self.screen.lines, "columns": self.screen.columns, "text": self.text, - "attributes": self.attributes.copy(), + "attributes": self.attributes[:] if self.attributes else [], # Shallow copy only if needed "screen": "pty", "screenUpdateTime": time.time(), - }.copy() + } + return screen_data class driver(screenDriver): @@ -132,6 +172,7 @@ class driver(screenDriver): self.p_out = None self.terminal = None self.p_pid = -1 + self.terminal_lock = threading.Lock() # Synchronize terminal operations signal.signal(signal.SIGWINCH, self.handle_sigwinch) def initialize(self, environment): @@ -163,28 +204,56 @@ class driver(screenDriver): self.env["general"]["curr_user"] = getpass.getuser() def read_all(self, fd, timeout=0.3, interruptFd=None, len=65536): + """Read all available data from file descriptor with efficient polling. + + Uses progressively longer wait times to balance responsiveness with CPU usage. + """ msg_bytes = b"" - fd_list = [] - fd_list += [fd] + fd_list = [fd] if interruptFd: - fd_list += [interruptFd] + fd_list.append(interruptFd) + starttime = time.time() + poll_timeout = 0.001 # Start with 1ms, stay responsive + while True: - r = screen_utils.has_more_what(fd_list, 0.0001) - # nothing more to read + # Use consistent short polling for responsiveness + r = screen_utils.has_more_what(fd_list, poll_timeout) + + # Nothing more to read if fd not in r: + # Check overall timeout + if (time.time() - starttime) >= timeout: + break + continue + + try: + data = os.read(fd, len) + if data == b"": + raise EOFError + msg_bytes += data + except OSError as e: + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver read_all: OS error reading from fd {fd}: {e}", + debug.DebugLevel.ERROR + ) + # For I/O errors, exit immediately to prevent endless retry loops + if e.errno == 5: # Input/output error + self.env["runtime"]["DebugManager"].write_debug_out( + "PTY screenDriver: Terminal connection lost, stopping read loop", + debug.DebugLevel.ERROR + ) + raise EOFError("Terminal connection lost") break - data = os.read(fd, len) - if data == b"": - raise EOFError - msg_bytes += data - # exit on interrupt available - if interruptFd in r: + + # Exit on interrupt available + if interruptFd and interruptFd in r: break - # respect timeout but wait a little bit of time to see if something - # more is here + + # Check overall timeout if (time.time() - starttime) >= timeout: break + return msg_bytes def open_terminal(self, columns, lines, command): @@ -197,16 +266,16 @@ class driver(screenDriver): if env["TERM"] == "": env["TERM"] = "linux" except Exception as e: - # Child process doesn't have access to env, use fallback - # logging + # Child process doesn't have access to debug manager + # Use fallback logging with more context print( - f"ptyDriver spawnTerminal: Error checking TERM environment: {e}" + f"ptyDriver open_terminal (child): TERM environment error: {e}" ) env["TERM"] = "linux" os.execvpe(argv[0], argv, env) # File-like object for I/O with the child process aka command. p_out = os.fdopen(master_fd, "w+b", 0) - return Terminal(columns, lines, p_out), p_pid, p_out + return Terminal(columns, lines, p_out, self.env), p_pid, p_out def resize_terminal(self, fd): s = struct.pack("HHHH", 0, 0, 0, 0) @@ -239,7 +308,7 @@ class driver(screenDriver): self.terminal.resize(lines, columns) fd_list = [sys.stdin, self.p_out, self.signalPipe[0]] while active.value: - r, _, _ = select(fd_list, [], [], 1) + r, _, _ = select(fd_list, [], [], 0.05) # 50ms timeout for responsiveness # none if r == []: continue @@ -251,7 +320,7 @@ class driver(screenDriver): # input if sys.stdin in r: try: - msg_bytes = self.read_all(sys.stdin.fileno(), len=4096) + msg_bytes = self.read_all(sys.stdin.fileno(), timeout=0.01, len=4096) except (EOFError, OSError): event_queue.put( { @@ -299,34 +368,121 @@ class driver(screenDriver): } ) break - # feed and send event bevore write, the pyte already has the right state - # so fenrir already can progress bevore os.write what - # should give some better reaction time - self.terminal.feed(msg_bytes) - event_queue.put( - { - "Type": FenrirEventType.screen_update, - "data": screen_utils.create_screen_event_data( - self.terminal.get_screen_content() - ), - } - ) + # Synchronize terminal operations to prevent race conditions + with self.terminal_lock: + # Feed data to terminal and get consistent screen state + self.terminal.feed(msg_bytes) + screen_content = self.terminal.get_screen_content() + + # Send screen update event with consistent state + event_queue.put( + { + "Type": FenrirEventType.screen_update, + "data": screen_utils.create_screen_event_data( + screen_content + ), + } + ) + + # Inject to actual screen (outside lock to avoid blocking) self.inject_text_to_screen( msg_bytes, screen=sys.stdout.fileno() ) except Exception as e: # Process died? - print(e) + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver terminal_emulation: Exception occurred: {e}", + debug.DebugLevel.ERROR + ) event_queue.put( {"Type": FenrirEventType.stop_main_loop, "data": None} ) finally: - os.kill(self.p_pid, signal.SIGTERM) - self.p_out.close() - termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr) + self._safe_cleanup_process() + self._safe_cleanup_resources(old_attr) event_queue.put( {"Type": FenrirEventType.stop_main_loop, "data": None} ) - sys.exit(0) + + def _safe_cleanup_process(self): + """Safely terminate the child process with timeout and fallback to SIGKILL.""" + if not hasattr(self, 'p_pid') or self.p_pid is None: + return + + try: + # Check if process is still alive + os.kill(self.p_pid, 0) # Signal 0 checks if process exists + except OSError: + # Process already dead + self.p_pid = None + return + + try: + # Try graceful termination first + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Terminating process {self.p_pid} gracefully", + debug.DebugLevel.INFO + ) + os.kill(self.p_pid, signal.SIGTERM) + + # Wait up to 3 seconds for graceful termination + timeout = 3.0 + start_time = time.time() + while time.time() - start_time < timeout: + try: + os.kill(self.p_pid, 0) # Check if still alive + time.sleep(0.1) + except OSError: + # Process terminated gracefully + self.p_pid = None + return + + # Process didn't terminate gracefully, use SIGKILL + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Process {self.p_pid} didn't terminate gracefully, using SIGKILL", + debug.DebugLevel.WARNING + ) + os.kill(self.p_pid, signal.SIGKILL) + time.sleep(0.5) # Give it a moment + + except OSError as e: + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Error terminating process {self.p_pid}: {e}", + debug.DebugLevel.ERROR + ) + finally: + self.p_pid = None + + def _safe_cleanup_resources(self, old_attr=None): + """Safely clean up file descriptors and terminal attributes.""" + # Close output pipe safely + if hasattr(self, 'p_out') and self.p_out is not None: + try: + self.p_out.close() + self.env["runtime"]["DebugManager"].write_debug_out( + "PTY screenDriver: Closed output pipe", + debug.DebugLevel.INFO + ) + except Exception as e: + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Error closing output pipe: {e}", + debug.DebugLevel.ERROR + ) + finally: + self.p_out = None + + # Restore terminal attributes safely + if old_attr is not None: + try: + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr) + self.env["runtime"]["DebugManager"].write_debug_out( + "PTY screenDriver: Restored terminal attributes", + debug.DebugLevel.INFO + ) + except Exception as e: + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Error restoring terminal attributes: {e}", + debug.DebugLevel.ERROR + ) def get_curr_application(self): pass diff --git a/src/fenrirscreenreader/screenDriver/vcsaDriver.py b/src/fenrirscreenreader/screenDriver/vcsaDriver.py index bdc95684..9c170f40 100644 --- a/src/fenrirscreenreader/screenDriver/vcsaDriver.py +++ b/src/fenrirscreenreader/screenDriver/vcsaDriver.py @@ -170,8 +170,9 @@ class driver(screenDriver): if screen is not None: use_screen = screen with open(use_screen, "w") as fd: - for c in text: - fcntl.ioctl(fd, termios.TIOCSTI, c) + text_bytes = text.encode('utf-8') + for byte in text_bytes: + fcntl.ioctl(fd, termios.TIOCSTI, bytes([byte])) def get_session_information(self): """Retrieve session information via D-Bus logind interface. From 579bf0f0f0676e849416d14267632f15be942b1b Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Wed, 16 Jul 2025 19:43:07 -0400 Subject: [PATCH 2/4] More work on the pty driver. --- .../screenDriver/ptyDriver.py | 95 ++++++++++++++++--- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py index e70d78ad..27ce7852 100644 --- a/src/fenrirscreenreader/screenDriver/ptyDriver.py +++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py @@ -25,6 +25,26 @@ from fenrirscreenreader.core.eventData import FenrirEventType from fenrirscreenreader.core.screenDriver import ScreenDriver as screenDriver from fenrirscreenreader.utils import screen_utils +# PTY Driver Constants +class PTYConstants: + # Timeouts (in seconds) + DEFAULT_READ_TIMEOUT = 0.3 + INPUT_READ_TIMEOUT = 0.01 + SELECT_TIMEOUT = 0.05 + PROCESS_TERMINATION_TIMEOUT = 3.0 + PROCESS_KILL_DELAY = 0.5 + + # Polling intervals (in seconds) + MIN_POLL_INTERVAL = 0.001 + + # Limits + MAX_TERMINAL_LINES = 10000 + DEFAULT_READ_BUFFER_SIZE = 65536 + INPUT_BUFFER_SIZE = 4096 + + # Error codes + IO_ERROR_ERRNO = 5 + class FenrirScreen(pyte.Screen): def set_margins(self, *args, **kwargs): @@ -91,10 +111,9 @@ class Terminal: self.attributes = [[] for _ in range(self.screen.lines)] for y in lines: # Validate y is within reasonable bounds (prevent memory exhaustion) - max_lines = 10000 # Reasonable maximum for terminal applications - if y >= max_lines: + if y >= PTYConstants.MAX_TERMINAL_LINES: self._log_error( - f"Line index {y} exceeds maximum {max_lines}, " + f"Line index {y} exceeds maximum {PTYConstants.MAX_TERMINAL_LINES}, " f"skipping attribute update", debug.DebugLevel.WARNING ) @@ -104,8 +123,10 @@ class Terminal: if y not in buffer: # Only log this occasionally to prevent spam if y % 10 == 0: # Log every 10th missing line + # Pre-format string to avoid repeated f-string operations + line_range = f"{y}-{y+9}" self._log_error( - f"Lines {y}-{y+9} not found in buffer, skipping attribute updates", + f"Lines {line_range} not found in buffer, skipping attribute updates", debug.DebugLevel.WARNING ) continue @@ -147,7 +168,9 @@ class Terminal: def get_screen_content(self): cursor = self.screen.cursor - self.text = "\n".join(self.screen.display) + # Only regenerate text if screen is dirty or text doesn't exist + if not hasattr(self, 'text') or self.screen.dirty: + self.text = "\n".join(self.screen.display) self.update_attributes(self.attributes is None) self.screen.dirty.clear() @@ -174,12 +197,58 @@ class driver(screenDriver): self.p_pid = -1 self.terminal_lock = threading.Lock() # Synchronize terminal operations signal.signal(signal.SIGWINCH, self.handle_sigwinch) + + # Runtime configuration storage + self.pty_config = {} + + def _load_pty_settings(self): + """Load PTY-specific settings from configuration with fallbacks to defaults.""" + try: + settings_manager = self.env["runtime"]["SettingsManager"] + + # Load timeout settings with defaults + self.pty_config = { + 'input_timeout': float(settings_manager.get_setting( + 'screen', 'ptyInputTimeout', PTYConstants.INPUT_READ_TIMEOUT + )), + 'select_timeout': float(settings_manager.get_setting( + 'screen', 'ptySelectTimeout', PTYConstants.SELECT_TIMEOUT + )), + 'process_termination_timeout': float(settings_manager.get_setting( + 'screen', 'ptyProcessTimeout', PTYConstants.PROCESS_TERMINATION_TIMEOUT + )), + 'poll_interval': float(settings_manager.get_setting( + 'screen', 'ptyPollInterval', PTYConstants.MIN_POLL_INTERVAL + )) + } + + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Loaded configuration: {self.pty_config}", + debug.DebugLevel.INFO + ) + + except Exception as e: + # Fallback to constants if settings fail + self.env["runtime"]["DebugManager"].write_debug_out( + f"PTY screenDriver: Failed to load settings, using defaults: {e}", + debug.DebugLevel.WARNING + ) + self.pty_config = { + 'input_timeout': PTYConstants.INPUT_READ_TIMEOUT, + 'select_timeout': PTYConstants.SELECT_TIMEOUT, + 'process_termination_timeout': PTYConstants.PROCESS_TERMINATION_TIMEOUT, + 'poll_interval': PTYConstants.MIN_POLL_INTERVAL + } def initialize(self, environment): self.env = environment self.command = self.env["runtime"]["SettingsManager"].get_setting( "general", "shell" ) + + # Load configurable timeouts from settings + self._load_pty_settings() + self.shortcutType = self.env["runtime"][ "InputManager" ].get_shortcut_type() @@ -203,7 +272,7 @@ class driver(screenDriver): self.env["general"]["prev_user"] = getpass.getuser() self.env["general"]["curr_user"] = getpass.getuser() - def read_all(self, fd, timeout=0.3, interruptFd=None, len=65536): + def read_all(self, fd, timeout=PTYConstants.DEFAULT_READ_TIMEOUT, interruptFd=None, len=PTYConstants.DEFAULT_READ_BUFFER_SIZE): """Read all available data from file descriptor with efficient polling. Uses progressively longer wait times to balance responsiveness with CPU usage. @@ -214,7 +283,7 @@ class driver(screenDriver): fd_list.append(interruptFd) starttime = time.time() - poll_timeout = 0.001 # Start with 1ms, stay responsive + poll_timeout = self.pty_config.get('poll_interval', PTYConstants.MIN_POLL_INTERVAL) # Use configured interval while True: # Use consistent short polling for responsiveness @@ -238,7 +307,7 @@ class driver(screenDriver): debug.DebugLevel.ERROR ) # For I/O errors, exit immediately to prevent endless retry loops - if e.errno == 5: # Input/output error + if e.errno == PTYConstants.IO_ERROR_ERRNO: # Input/output error self.env["runtime"]["DebugManager"].write_debug_out( "PTY screenDriver: Terminal connection lost, stopping read loop", debug.DebugLevel.ERROR @@ -308,7 +377,7 @@ class driver(screenDriver): self.terminal.resize(lines, columns) fd_list = [sys.stdin, self.p_out, self.signalPipe[0]] while active.value: - r, _, _ = select(fd_list, [], [], 0.05) # 50ms timeout for responsiveness + r, _, _ = select(fd_list, [], [], self.pty_config.get('select_timeout', PTYConstants.SELECT_TIMEOUT)) # Configurable timeout # none if r == []: continue @@ -320,7 +389,7 @@ class driver(screenDriver): # input if sys.stdin in r: try: - msg_bytes = self.read_all(sys.stdin.fileno(), timeout=0.01, len=4096) + msg_bytes = self.read_all(sys.stdin.fileno(), timeout=self.pty_config.get('input_timeout', PTYConstants.INPUT_READ_TIMEOUT), len=PTYConstants.INPUT_BUFFER_SIZE) except (EOFError, OSError): event_queue.put( { @@ -424,8 +493,8 @@ class driver(screenDriver): ) os.kill(self.p_pid, signal.SIGTERM) - # Wait up to 3 seconds for graceful termination - timeout = 3.0 + # Wait for graceful termination + timeout = self.pty_config.get('process_termination_timeout', PTYConstants.PROCESS_TERMINATION_TIMEOUT) start_time = time.time() while time.time() - start_time < timeout: try: @@ -442,7 +511,7 @@ class driver(screenDriver): debug.DebugLevel.WARNING ) os.kill(self.p_pid, signal.SIGKILL) - time.sleep(0.5) # Give it a moment + time.sleep(PTYConstants.PROCESS_KILL_DELAY) # Give it a moment except OSError as e: self.env["runtime"]["DebugManager"].write_debug_out( From 8c668cc0ccab6a6d8a08adb648eedf63040d686c Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Wed, 16 Jul 2025 19:48:48 -0400 Subject: [PATCH 3/4] Final batch of pty driver fixes... For now. --- src/fenrirscreenreader/screenDriver/ptyDriver.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py index 27ce7852..1ca7f5a6 100644 --- a/src/fenrirscreenreader/screenDriver/ptyDriver.py +++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py @@ -30,6 +30,7 @@ class PTYConstants: # Timeouts (in seconds) DEFAULT_READ_TIMEOUT = 0.3 INPUT_READ_TIMEOUT = 0.01 + OUTPUT_READ_TIMEOUT = 0.05 # Faster than default but allows for network lag SELECT_TIMEOUT = 0.05 PROCESS_TERMINATION_TIMEOUT = 3.0 PROCESS_KILL_DELAY = 0.5 @@ -211,6 +212,9 @@ class driver(screenDriver): 'input_timeout': float(settings_manager.get_setting( 'screen', 'ptyInputTimeout', PTYConstants.INPUT_READ_TIMEOUT )), + 'output_timeout': float(settings_manager.get_setting( + 'screen', 'ptyOutputTimeout', PTYConstants.OUTPUT_READ_TIMEOUT + )), 'select_timeout': float(settings_manager.get_setting( 'screen', 'ptySelectTimeout', PTYConstants.SELECT_TIMEOUT )), @@ -235,6 +239,7 @@ class driver(screenDriver): ) self.pty_config = { 'input_timeout': PTYConstants.INPUT_READ_TIMEOUT, + 'output_timeout': PTYConstants.OUTPUT_READ_TIMEOUT, 'select_timeout': PTYConstants.SELECT_TIMEOUT, 'process_termination_timeout': PTYConstants.PROCESS_TERMINATION_TIMEOUT, 'poll_interval': PTYConstants.MIN_POLL_INTERVAL @@ -427,7 +432,9 @@ class driver(screenDriver): if self.p_out in r: try: msg_bytes = self.read_all( - self.p_out.fileno(), interruptFd=sys.stdin.fileno() + self.p_out.fileno(), + timeout=self.pty_config.get('output_timeout', PTYConstants.OUTPUT_READ_TIMEOUT), + interruptFd=sys.stdin.fileno() ) except (EOFError, OSError): event_queue.put( From b68a28e857d202d47f9938515bce341d42713e29 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Thu, 17 Jul 2025 11:11:06 -0400 Subject: [PATCH 4/4] Added more emojis. --- .../KEY/emoji/flags/argentina.py | 22 ++ .../KEY/emoji/flags/australia.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/belgium.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/brazil.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/china.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/denmark.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/finland.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/france.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/germany.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/greece.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/india.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/ireland.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/israel.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/italy.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/japan.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/mexico.py | 22 ++ .../KEY/emoji/flags/netherlands.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/norway.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/poland.py | 22 ++ .../KEY/emoji/flags/portugal.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/russia.py | 22 ++ .../KEY/emoji/flags/south_africa.py | 22 ++ .../KEY/emoji/flags/south_korea.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/spain.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/sweden.py | 22 ++ .../KEY/emoji/flags/switzerland.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/turkey.py | 22 ++ .../vmenu-profiles/KEY/emoji/flags/ukraine.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/apple.py | 22 ++ .../vmenu-profiles/KEY/emoji/food/avocado.py | 22 ++ .../KEY/emoji/food/birthday_cake.py | 22 ++ .../KEY/emoji/food/strawberry.py | 22 ++ .../KEY/emoji/holidays/black_cat.py | 22 ++ .../KEY/emoji/holidays/cauldron.py | 22 ++ .../KEY/emoji/holidays/vampire.py | 22 ++ .../KEY/emoji/holidays/witch.py | 22 ++ .../KEY/emoji/nature/butterfly.py | 22 ++ .../KEY/emoji/nature/cherry_blossom.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/rose.py | 22 ++ .../KEY/emoji/nature/sunflower.py | 22 ++ .../vmenu-profiles/KEY/emoji/nature/wolf.py | 22 ++ .../KEY/emoji/people/a_grinning.py | 22 ++ .../KEY/emoji/people/beaming.py | 22 ++ .../KEY/emoji/people/blowing_kiss.py | 22 ++ .../KEY/emoji/people/grinning_sweat.py | 22 ++ .../KEY/emoji/people/heart_eyes.py | 22 ++ .../KEY/emoji/people/hearts_around.py | 22 ++ .../KEY/emoji/people/pleading.py | 22 ++ .../KEY/emoji/people/rolling_laughing.py | 22 ++ .../KEY/emoji/people/savoring_food.py | 22 ++ .../KEY/emoji/people/smirking.py | 22 ++ .../KEY/emoji/symbols/folded_hands.py | 22 ++ .../KEY/emoji/symbols/hundred_points.py | 22 ++ .../KEY/emoji/symbols/sparkles.py | 22 ++ src/fenrirscreenreader/fenrirVersion.py | 2 +- .../screenDriver/vcsaDriver.py | 239 +++++++++++++----- 56 files changed, 1371 insertions(+), 58 deletions(-) create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/argentina.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/australia.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/belgium.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/brazil.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/china.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/denmark.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/finland.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/france.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/germany.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/greece.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/india.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ireland.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/israel.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/italy.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/japan.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/mexico.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/netherlands.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/norway.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/poland.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/portugal.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/russia.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_africa.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_korea.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/spain.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/sweden.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/switzerland.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/turkey.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ukraine.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/apple.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/avocado.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/birthday_cake.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/strawberry.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/black_cat.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/cauldron.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/vampire.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/witch.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/butterfly.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cherry_blossom.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rose.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sunflower.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/wolf.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/a_grinning.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/beaming.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/blowing_kiss.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/grinning_sweat.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/heart_eyes.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/hearts_around.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/pleading.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/rolling_laughing.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/savoring_food.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smirking.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/folded_hands.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/hundred_points.py create mode 100644 src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/sparkles.py diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/argentina.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/argentina.py new file mode 100644 index 00000000..fef5e552 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/argentina.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇦🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Argentina flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Argentina flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/australia.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/australia.py new file mode 100644 index 00000000..e42751f3 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/australia.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇦🇺" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Australia flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Australia flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/belgium.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/belgium.py new file mode 100644 index 00000000..39bb538c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/belgium.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇧🇪" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Belgium flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Belgium flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/brazil.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/brazil.py new file mode 100644 index 00000000..ac885380 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/brazil.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇧🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Brazil flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Brazil flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/china.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/china.py new file mode 100644 index 00000000..2f875650 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/china.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇨🇳" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add China flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added China flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/denmark.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/denmark.py new file mode 100644 index 00000000..f0b325eb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/denmark.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇩🇰" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Denmark flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Denmark flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/finland.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/finland.py new file mode 100644 index 00000000..7b4a0ffe --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/finland.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇫🇮" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Finland flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Finland flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/france.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/france.py new file mode 100644 index 00000000..926e8691 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/france.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇫🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add France flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added France flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/germany.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/germany.py new file mode 100644 index 00000000..88933cdb --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/germany.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇩🇪" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Germany flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Germany flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/greece.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/greece.py new file mode 100644 index 00000000..e924ee8c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/greece.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇬🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Greece flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Greece flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/india.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/india.py new file mode 100644 index 00000000..8265a0b0 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/india.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇮🇳" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add India flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added India flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ireland.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ireland.py new file mode 100644 index 00000000..a8a92062 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ireland.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇮🇪" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Ireland flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Ireland flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/israel.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/israel.py new file mode 100644 index 00000000..a57a888e --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/israel.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇮🇱" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Israel flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Israel flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/italy.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/italy.py new file mode 100644 index 00000000..512498e0 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/italy.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇮🇹" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Italy flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Italy flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/japan.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/japan.py new file mode 100644 index 00000000..d9e32271 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/japan.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇯🇵" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Japan flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Japan flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/mexico.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/mexico.py new file mode 100644 index 00000000..c6d1c1d5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/mexico.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇲🇽" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Mexico flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Mexico flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/netherlands.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/netherlands.py new file mode 100644 index 00000000..a3b84db8 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/netherlands.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇳🇱" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Netherlands flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Netherlands flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/norway.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/norway.py new file mode 100644 index 00000000..2a749b56 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/norway.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇳🇴" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Norway flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Norway flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/poland.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/poland.py new file mode 100644 index 00000000..4de31994 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/poland.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇵🇱" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Poland flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Poland flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/portugal.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/portugal.py new file mode 100644 index 00000000..760019b9 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/portugal.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇵🇹" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Portugal flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Portugal flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/russia.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/russia.py new file mode 100644 index 00000000..a1b20548 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/russia.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇷🇺" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Russia flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Russia flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_africa.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_africa.py new file mode 100644 index 00000000..d36dd740 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_africa.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇿🇦" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add South Africa flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added South Africa flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_korea.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_korea.py new file mode 100644 index 00000000..94651481 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/south_korea.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇰🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add South Korea flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added South Korea flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/spain.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/spain.py new file mode 100644 index 00000000..89f27953 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/spain.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇪🇸" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Spain flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Spain flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/sweden.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/sweden.py new file mode 100644 index 00000000..ffb4da28 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/sweden.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇸🇪" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Sweden flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Sweden flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/switzerland.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/switzerland.py new file mode 100644 index 00000000..b32461f2 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/switzerland.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇨🇭" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Switzerland flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Switzerland flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/turkey.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/turkey.py new file mode 100644 index 00000000..432960f7 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/turkey.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇹🇷" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Turkey flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Turkey flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ukraine.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ukraine.py new file mode 100644 index 00000000..2a36f794 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/flags/ukraine.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🇺🇦" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Add Ukraine flag emoji to clipboard" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added Ukraine flag to clipboard", + interrupt=False, flush=False + ) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/apple.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/apple.py new file mode 100644 index 00000000..a8212d61 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/apple.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍎" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Red apple emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added red apple to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/avocado.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/avocado.py new file mode 100644 index 00000000..4784e249 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/avocado.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🥑" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Avocado emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added avocado to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/birthday_cake.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/birthday_cake.py new file mode 100644 index 00000000..29dffc9b --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/birthday_cake.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🎂" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Birthday cake emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added birthday cake to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/strawberry.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/strawberry.py new file mode 100644 index 00000000..90874b7f --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/food/strawberry.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🍓" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Strawberry emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added strawberry to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/black_cat.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/black_cat.py new file mode 100644 index 00000000..7175d61d --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/black_cat.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🐈‍⬛" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Black cat emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added black cat to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/cauldron.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/cauldron.py new file mode 100644 index 00000000..22426f64 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/cauldron.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🧙" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Magic cauldron emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added magic cauldron to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/vampire.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/vampire.py new file mode 100644 index 00000000..5c065707 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/vampire.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🧛" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Vampire emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added vampire to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/witch.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/witch.py new file mode 100644 index 00000000..3573668b --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/holidays/witch.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🧙‍♀️" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Witch emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added witch to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/butterfly.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/butterfly.py new file mode 100644 index 00000000..2064d4ab --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/butterfly.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🦋" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Butterfly emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added butterfly to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cherry_blossom.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cherry_blossom.py new file mode 100644 index 00000000..24e18fbd --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/cherry_blossom.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌸" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Cherry blossom emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added cherry blossom to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rose.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rose.py new file mode 100644 index 00000000..8756f027 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/rose.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌹" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Rose emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added rose to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sunflower.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sunflower.py new file mode 100644 index 00000000..4ce9547a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/sunflower.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🌻" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Sunflower emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added sunflower to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/wolf.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/wolf.py new file mode 100644 index 00000000..5e3a363c --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/nature/wolf.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🐺" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Wolf emoji - The mighty Fenrir!" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added the mighty wolf Fenrir to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/a_grinning.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/a_grinning.py new file mode 100644 index 00000000..4930dd87 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/a_grinning.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😀" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Grinning face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added grinning face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/beaming.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/beaming.py new file mode 100644 index 00000000..08e9766f --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/beaming.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😁" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Beaming face with smiling eyes emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added beaming face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/blowing_kiss.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/blowing_kiss.py new file mode 100644 index 00000000..38d5c0a9 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/blowing_kiss.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😘" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Face blowing a kiss emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added face blowing kiss to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/grinning_sweat.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/grinning_sweat.py new file mode 100644 index 00000000..f59543f4 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/grinning_sweat.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😅" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Grinning face with sweat emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added grinning face with sweat to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/heart_eyes.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/heart_eyes.py new file mode 100644 index 00000000..2298019e --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/heart_eyes.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😍" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Smiling face with heart-eyes emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added heart-eyes face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/hearts_around.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/hearts_around.py new file mode 100644 index 00000000..4a45a9d7 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/hearts_around.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🥰" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Smiling face with hearts emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added smiling face with hearts to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/pleading.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/pleading.py new file mode 100644 index 00000000..d6709e00 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/pleading.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🥺" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Pleading face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added pleading face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/rolling_laughing.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/rolling_laughing.py new file mode 100644 index 00000000..6adcf4f5 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/rolling_laughing.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🤣" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Rolling on floor laughing emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added rolling on floor laughing to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/savoring_food.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/savoring_food.py new file mode 100644 index 00000000..1581cf8a --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/savoring_food.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😋" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Face savoring food emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added face savoring food to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smirking.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smirking.py new file mode 100644 index 00000000..e0de7aaa --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/people/smirking.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "😏" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Smirking face emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added smirking face to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/folded_hands.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/folded_hands.py new file mode 100644 index 00000000..cf07966e --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/folded_hands.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "🙏" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Folded hands emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added folded hands to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/hundred_points.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/hundred_points.py new file mode 100644 index 00000000..1ab3b8d0 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/hundred_points.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "💯" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Hundred points symbol emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added hundred points to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/sparkles.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/sparkles.py new file mode 100644 index 00000000..0aed7e40 --- /dev/null +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/emoji/symbols/sparkles.py @@ -0,0 +1,22 @@ +class command(): + def initialize(self, environment): + self.env = environment + self.emoji = "✨" + + def shutdown(self): + pass + + def setCallback(self, callback): + pass + + def getDescription(self): + return "Sparkles emoji" + + def run(self): + self.env["runtime"]["MemoryManager"].add_value_to_first_index( + "clipboardHistory", self.emoji + ) + self.env["runtime"]["OutputManager"].present_text( + "Added sparkles to clipboard", + interrupt=False, flush=False + ) \ No newline at end of file diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index 0e664a47..48eecad9 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,6 +4,6 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributors. -version = "2025.07.16" +version = "2025.07.17" codeName = "testing" code_name = "testing" diff --git a/src/fenrirscreenreader/screenDriver/vcsaDriver.py b/src/fenrirscreenreader/screenDriver/vcsaDriver.py index 9c170f40..aef34b4e 100644 --- a/src/fenrirscreenreader/screenDriver/vcsaDriver.py +++ b/src/fenrirscreenreader/screenDriver/vcsaDriver.py @@ -772,10 +772,11 @@ class driver(screenDriver): import re # Find all application processes (non-bash, non-screen) - app_pattern = r'([a-zA-Z0-9_-]+)\((\d+)\)' + # Pattern excludes --- prefix from pstree connection lines + app_pattern = r'([a-zA-Z0-9_]+)\((\d+)\)' matches = re.findall(app_pattern, pstree_output) - skip_processes = {'screen', 'bash', 'sh', 'grep', 'ps'} + skip_processes = {'screen', 'bash', 'sh', 'grep', 'ps', 'sudo', 'sleep', 'clipboard_sync'} applications = [] for app_name, pid in matches: @@ -788,16 +789,30 @@ class driver(screenDriver): if ps_result.returncode == 0: stat = ps_result.stdout.strip() - # Look for processes that are active (S+ state or similar) - if '+' in stat or 'l' in stat.lower(): - applications.append((app_name, pid, stat)) + # Prioritize active processes + priority = 0 + if 'S' in stat or 'R' in stat: # Active processes + priority += 10 + if '+' in stat: # Foreground processes + priority += 20 + if 'l' in stat.lower(): # Locked processes + priority += 5 + + applications.append((app_name, pid, priority, stat)) except: - # If we can't check status, still consider it - applications.append((app_name, pid, 'unknown')) + # If we can't check status, still consider it with low priority + applications.append((app_name, pid, 1, 'unknown')) - # Return the first active application found + # Sort by priority and return the highest priority application if applications: - return applications[0][0].upper() + applications.sort(key=lambda x: (x[2], int(x[1])), reverse=True) + best_app = applications[0][0].upper() + + self.env["runtime"]["DebugManager"].write_debug_out( + f"parse_active_app_from_pstree found {len(applications)} apps, selected: {best_app}", + debug.DebugLevel.INFO + ) + return best_app except Exception as e: self.env["runtime"]["DebugManager"].write_debug_out( @@ -806,39 +821,95 @@ class driver(screenDriver): return None def get_app_from_screen_session(self, tty_num): - """Get current application from screen session on specific TTY""" + """Get current application from active screen window on specific TTY""" try: - # Step 1: Find screen process for this TTY - screen_tty_pid = self.get_screen_process_for_tty(tty_num) - if not screen_tty_pid: - return None - - self.env["runtime"]["DebugManager"].write_debug_out( - f"Found screen TTY process: {screen_tty_pid} for TTY{tty_num}", - debug.DebugLevel.INFO - ) - - # Step 2: Find session manager process - session_pid = self.get_screen_session_process(screen_tty_pid) - if not session_pid: - return None - - self.env["runtime"]["DebugManager"].write_debug_out( - f"Found screen session process: {session_pid}", - debug.DebugLevel.INFO - ) - - # Step 3: Get process tree and find active app - result = subprocess.run([ - 'pstree', '-p', session_pid - ], capture_output=True, text=True, timeout=3) + # Find the screen session PID for this TTY + ps_result = subprocess.run([ + 'ps', '-eo', 'pid,ppid,comm,tty,args', '--no-headers' + ], capture_output=True, text=True, timeout=2) - if result.returncode == 0: + if ps_result.returncode == 0: + # Find the main screen process for our TTY + screen_pid = None + for line in ps_result.stdout.split('\n'): + if not line.strip(): + continue + parts = line.split(None, 4) + if len(parts) >= 4 and parts[2] == 'screen' and f'tty{tty_num}' in parts[3]: + screen_pid = parts[0] + break + + if not screen_pid: + return None + + # Get the session manager screen process (child of TTY screen) + session_pid = None + for line in ps_result.stdout.split('\n'): + if not line.strip(): + continue + parts = line.split(None, 4) + if len(parts) >= 3 and parts[1] == screen_pid and parts[2] == 'screen': + session_pid = parts[0] + break + + if not session_pid: + return None + self.env["runtime"]["DebugManager"].write_debug_out( - f"Pstree output: {result.stdout[:200]}...", + f"Found screen session PID: {session_pid}", debug.DebugLevel.INFO ) - return self.parse_active_app_from_pstree(result.stdout) + + # Get all bash processes under this screen session + bash_processes = [] + for line in ps_result.stdout.split('\n'): + if not line.strip(): + continue + parts = line.split(None, 4) + if len(parts) >= 3 and parts[1] == session_pid and parts[2] == 'bash': + bash_processes.append(parts[0]) + + # Check each bash for child applications, prioritizing active ones + best_app = None + best_priority = 0 + + for bash_pid in bash_processes: + child_result = subprocess.run([ + 'ps', '--ppid', bash_pid, '-o', 'comm,stat', '--no-headers' + ], capture_output=True, text=True, timeout=1) + + if child_result.returncode == 0: + for child_line in child_result.stdout.split('\n'): + if not child_line.strip(): + continue + child_parts = child_line.split() + if len(child_parts) >= 2: + child_comm, child_stat = child_parts[0], child_parts[1] + if child_comm.lower() not in ['grep', 'ps', 'bash', 'sh', 'sudo', 'sleep']: + # Calculate priority based on process state + priority = 0 + if 'R' in child_stat: # Running + priority += 30 + elif 'S' in child_stat: # Sleeping + priority += 20 + if '+' in child_stat: # Foreground + priority += 20 + + self.env["runtime"]["DebugManager"].write_debug_out( + f"Found child process: {child_comm} ({child_stat}) priority: {priority}", + debug.DebugLevel.INFO + ) + + if priority > best_priority: + best_app = child_comm.upper() + best_priority = priority + + if best_app: + self.env["runtime"]["DebugManager"].write_debug_out( + f"Selected best app: {best_app} (priority: {best_priority})", + debug.DebugLevel.INFO + ) + return best_app except (subprocess.TimeoutExpired, subprocess.CalledProcessError, FileNotFoundError) as e: self.env["runtime"]["DebugManager"].write_debug_out( @@ -846,6 +917,62 @@ class driver(screenDriver): ) return None + def parse_latest_active_app_from_pstree(self, pstree_output): + """Parse pstree output to find the most recently active application""" + try: + import re + + # Find all application processes with PIDs + app_pattern = r'([a-zA-Z0-9_]+)\((\d+)\)' + matches = re.findall(app_pattern, pstree_output) + + skip_processes = {'screen', 'bash', 'sh', 'grep', 'ps', 'sudo', 'sleep', 'clipboard_sync'} + applications = [] + + for app_name, pid in matches: + if app_name.lower() not in skip_processes: + # Check if this process is still active and get its start time + try: + ps_result = subprocess.run([ + 'ps', '-p', pid, '-o', 'stat,lstart', '--no-headers' + ], capture_output=True, text=True, timeout=1) + + if ps_result.returncode == 0: + stat_info = ps_result.stdout.strip().split(None, 1) + if len(stat_info) >= 2: + stat = stat_info[0] + start_time = stat_info[1] + + # Prioritize processes that are active or have recent activity + priority = 0 + if 'S' in stat or 'R' in stat: # Running or sleeping (active) + priority += 10 + if '+' in stat: # Foreground process + priority += 20 + + applications.append((app_name, pid, priority, start_time)) + except: + # If we can't get status, still consider it but with low priority + applications.append((app_name, pid, 1, 'unknown')) + + # Sort by priority (highest first), then by PID (most recent) + if applications: + applications.sort(key=lambda x: (x[2], int(x[1])), reverse=True) + best_app = applications[0][0].upper() + + self.env["runtime"]["DebugManager"].write_debug_out( + f"Found {len(applications)} applications, selected: {best_app}", + debug.DebugLevel.INFO + ) + return best_app + + except Exception as e: + self.env["runtime"]["DebugManager"].write_debug_out( + f"Error parsing latest active app from pstree: {str(e)}", + debug.DebugLevel.ERROR + ) + return None + def get_app_from_tmux_session(self, tty_num): """Get current application from tmux session on specific TTY""" try: @@ -948,28 +1075,26 @@ class driver(screenDriver): ) def get_app_via_standard_ps(self, curr_screen): - """Original ps-based application detection as fallback""" + """Fallback ps-based application detection for non-screen/tmux environments""" try: - apps = ( - subprocess.Popen( - "ps -t tty" + curr_screen + " -o comm,tty,stat", - shell=True, - stdout=subprocess.PIPE, - ) - .stdout.read() - .decode()[:-1] - .split("\n") - ) + # Simple TTY-specific detection as fallback + result = subprocess.run([ + 'ps', '-t', f'tty{curr_screen}', '-o', 'comm,stat', '--no-headers' + ], capture_output=True, text=True, timeout=2) - for i in apps: - i = i.upper() - i = i.split() - if len(i) >= 3: - comm, tty, stat = i[0], i[1], i[2] - if "+" in stat and comm != "": - if comm not in ["GREP", "SH", "PS", "BASH"]: - if "TTY" + curr_screen in tty: - return comm + if result.returncode == 0: + for line in result.stdout.split('\n'): + if not line.strip(): + continue + parts = line.split() + if len(parts) >= 2: + comm, stat = parts[0], parts[1] + if '+' in stat and comm.upper() not in ['BASH', 'SH', 'SCREEN', 'GREP', 'PS']: + self.env["runtime"]["DebugManager"].write_debug_out( + f"Fallback detection found: {comm}", + debug.DebugLevel.INFO + ) + return comm.upper() except Exception as e: self.env["runtime"]["DebugManager"].write_debug_out( f"Standard ps detection error: {str(e)}", debug.DebugLevel.ERROR