diff --git a/.gitignore b/.gitignore
index 44dcf25..eff77b7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ fenrir.egg-info/
 fenrir_screenreader.egg-info/
 dist/
 build/
+*.kate-swp
+.directory
diff --git a/README.md b/README.md
index 871fcb2..a029197 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,10 @@ This software is licensed under the LGPL v3.
 # installation
 - Archlinux: PKGBUILD in AUR
 - PIP: sudo pip install fenrir-screenreader
-- Manual: run install.sh and uninstall.sh as root
+- Manual:
+ - install "espeak" and "sox" with your package manager
+ - sudo pip install -r requirements.txt 
+ - run install.sh and uninstall.sh as root
 - you also can just run it from Git without installing:
 You can just run the following as root:
 if you are in Fenrir Git rootfolder:
@@ -84,7 +87,21 @@ By default it uses:
 - speech driver: genericDriver (via espeak or espeak-ng, could configured in settings.conf)
 - braille driver: brlttyDriver (WIP)
 - input driver: evdevDriver
+# Configure pulseaudio
+Pulseaudio by default does only play sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
+for this fenrir provides a script to configure pulseaudio to stream the sound played as root to your local user. Last is playing the sound then. This is not a issue of fenrir but this is how pulseaudio works.
 
+just run the configuration scipt twice (once as user, once as root).
+
+Run:
+configure_pulse.sh
+sudo configure_pulse.sh
+
+The script could also be found at /tools/ in git
+
+# localization
+copy fenrir.mo translations file  from fenrir/locale/your_language/LC_MESSAGES/fenrir.mo to /usr/share/locale/your_language/LC_MESSAGES/fenrir.mo
+ 
 # Documentation
 You can see all information on the Wiki:
 https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual
diff --git a/TODO v2.0 b/TODO v2.0
index 4fb0dba..ccac91d 100644
--- a/TODO v2.0	
+++ b/TODO v2.0	
@@ -20,6 +20,8 @@ Cleanups:
     [] replace lines by a list insteed of and \n seperated string. (currently we need to split to often) (Easy for contribution)
 General (Easy for contribution)
   [w] make fenrir runnable without root permissions
+  [] check pythran for performance
+    https://github.com/serge-sans-paille/pythran
   [] make fenrir runable without settingsfile. fallback to defaults
   [] Detect progressbars and just present percent
      |===============            |100%
diff --git a/check-dependencies.py b/check-dependencies.py
index 9c75faf..39c980a 100755
--- a/check-dependencies.py
+++ b/check-dependencies.py
@@ -6,7 +6,7 @@ import os, sys
 # speech: speech-dispatcher
 # sound: sox
 # braille: brltty:
-defaultInstallation = ['FenrirCore','vcsaDriver','brlapiDriver','evdevDriver','genericDriver (speech)', 'genericDriver (sound)']
+defaultInstallation = ['FenrirCore','vcsaDriver','dummyDriver (braille)','evdevDriver','genericDriver (speech)', 'genericDriver (sound)']
 currentInstallation = []
 
 print('checking dependencys...')
@@ -34,6 +34,10 @@ if available:
 # SCREEN
 print('--------------------')
 print('screen driver')
+# dummy and debug
+print('dummyDriver (screen): OK')
+currentInstallation.append('dummyDriver (screen)')
+
 # VCSA (screen driver)
 print('vcsaDriver')
 available = True
@@ -66,6 +70,11 @@ if available:
 # BRAILLE
 print('--------------------')
 print('braille driver')
+# dummy and debug
+print('dummyDriver (braille): OK')
+currentInstallation.append('dummyDriver (braille)')
+print('debugDriver (braille): OK')
+currentInstallation.append('debugDriver (braille)')
 # brltty (braille driver)
 print('brlapiDriver')
 available = True
@@ -81,6 +90,11 @@ if available:
 # INPUT
 print('--------------------')
 print('input driver')
+# dummy and debug
+print('dummyDriver (input): OK')
+currentInstallation.append('dummyDriver (input)')
+print('debugDriver (input): OK')
+currentInstallation.append('debugDriver (input)')
 # evdev (input driver)
 print('evdevDriver')
 available = True
@@ -90,13 +104,13 @@ try:
     print('python3-evdev: OK')
 except:
     print('python3-evdev: FAIL')
-    available = available and False    
+    available = available and False
 try:
     import pyudev
     print('python3-pyudev: OK')
 except:
     print('python3-pyudev: FAIL')
-    available = available and False     
+    available = available and False
 if available:
     currentInstallation.append('evdevDriver')
 # pty emulation (input driver)
@@ -108,19 +122,24 @@ try:
     print('pyte: OK')
 except:
     print('pyte: FAIL')
-    available = available and False    
+    available = available and False
 if available:
-    currentInstallation.append('ptyDriver (Input)')     
+    currentInstallation.append('ptyDriver (Input)')
 # SOUND
 print('--------------------')
 print('sound driver')
+# dummy and debug
+print('dummyDriver (sound): OK')
+currentInstallation.append('dummyDriver (sound)')
+print('debugDriver (sound): OK')
+currentInstallation.append('debugDriver (sound)')
 print('genericDriver (uses sox by default)')
 available = True
 if os.path.exists('/usr/bin/play') and os.path.exists('/usr/bin/sox'):
     print('sox: OK')
 else:
     print('sox: FAIL')
-    available = available and False    
+    available = available and False
 if available:
     currentInstallation.append('genericDriver (sound)')
 print('')
@@ -132,26 +151,31 @@ try:
     print('gi: OK')
 except:
     print('gi: FAIL')
-    available = available and False    
+    available = available and False
 try:
     from gi.repository import GLib 
     print('gi GLib: OK')
 except:
     print('gi GLib: FAIL')
-    available = available and False    
+    available = available and False
 try:
     gi.require_version('Gst', '1.0')
     from gi.repository import Gst
     print('gi Gst: OK')
 except:
-    print('gi Gst: FAIL')   
-    available = available and False     
+    print('gi Gst: FAIL')
+    available = available and False
 if available:
     currentInstallation.append('gstreamerDriver')
 
 # SPEECH
 print('--------------------')
 print('speech driver')
+# dummy and debug
+print('dummyDriver (speech): OK')
+currentInstallation.append('dummyDriver (speech)')
+print('debugDriver (speech): OK')
+currentInstallation.append('debugDriver (speech)')
 # speechd (speech driver)
 print('speechdDriver')
 available = True
@@ -160,7 +184,7 @@ try:
     print('python3-speechd: OK')
 except:
     print('python3-speechd: FAIL')
-    available = available and False    
+    available = available and False
 if available:
     currentInstallation.append('speechdDriver')
 print('')
@@ -172,18 +196,18 @@ try:
     print('python3-espeak: OK')
 except:
     print('python3-espeak: FAIL')
-    available = available and False    
+    available = available and False
 if available:
-    currentInstallation.append('espeakDriver')    
-print('genericDriver (uses espeak by default)')
+    currentInstallation.append('espeakDriver')
+print('genericDriver (uses espeak-ng by default)')
 available = True
-if os.path.exists('/usr/bin/espeak') or os.path.exists('/bin/espeak'):
-    print('espeak: OK')
+if os.path.exists('/usr/bin/espeak-ng') or os.path.exists('/bin/espeak-ng'):
+    print('espeak-ng: OK')
 else:
-    print('espeak: FAIL')
+    print('espeak-ng: FAIL')
     available = available and False    
 if available:
-    currentInstallation.append('genericDriver (speech)')    
+    currentInstallation.append('genericDriver (speech)')
 
 # SUMMERY
 print('====================')
diff --git a/config/keyboard/desktop.conf b/config/keyboard/nvda-desktop.conf
similarity index 67%
rename from config/keyboard/desktop.conf
rename to config/keyboard/nvda-desktop.conf
index 547fd1f..9a0dba3 100644
--- a/config/keyboard/desktop.conf
+++ b/config/keyboard/nvda-desktop.conf
@@ -1,12 +1,13 @@
+KEY_FENRIR,KEY_F1=toggle_tutorial_mode
 KEY_FENRIR,KEY_H=toggle_tutorial_mode
 KEY_CTRL=shut_up
-KEY_FENRIR,KEY_KP9=review_bottom
-KEY_FENRIR,KEY_KP7=review_top
+KEY_SHIFT,KEY_KP9=review_bottom
+KEY_SHIFT,KEY_KP7=review_top
 KEY_KP8=review_curr_line
 KEY_KP7=review_prev_line
 KEY_KP9=review_next_line
-KEY_FENRIR,KEY_KP4=review_line_begin
-KEY_FENRIR,KEY_KP6=review_line_end
+KEY_SHIFT,KEY_KP1=review_line_begin
+KEY_SHIFT,KEY_KP3=review_line_end
 KEY_FENRIR,KEY_KP1=review_line_first_char
 KEY_FENRIR,KEY_KP3=review_line_last_char
 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
@@ -14,33 +15,34 @@ KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
 KEY_KP5=review_curr_word
 KEY_KP4=review_prev_word
 KEY_KP6=review_next_word
-KEY_FENRIR,KEY_SHIFT,KEY_KP5=review_curr_word_phonetic
-KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic
-KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic
+2,KEY_KP5=review_curr_word_phonetic
+2,KEY_KP4=review_prev_word_phonetic
+2,KEY_KP6=review_next_word_phonetic
 KEY_KP2=review_curr_char
 KEY_KP1=review_prev_char
 KEY_KP3=review_next_char
-KEY_FENRIR,KEY_SHIFT,KEY_KP2=review_curr_char_phonetic
-KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic
-KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic
+2,KEY_KP2=review_curr_char_phonetic
+2,KEY_KP1=review_prev_char_phonetic
+2,KEY_KP3=review_next_char_phonetic
 KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
 KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
 KEY_FENRIR,KEY_KPDOT=exit_review
 KEY_KPDOT=cursor_position
 KEY_FENRIR,KEY_I=indent_curr_line
-KEY_FENRIR,KEY_KP5=curr_screen
+KEY_FENRIR,KEY_B=curr_screen
 KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
 KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
-#=cursor_read_to_end_of_line
+KEY_FENRIR,KEY_SHIFT,KEY_PAGEDOWN=cursor_read_to_end_of_line
 #=cursor_column
 #=cursor_lineno
 #=braille_flush
-#=braille_return_to_cursor
+KEY_FENRIR,KEY_CTRL,KEY_T=braille_return_to_cursor
 #=braille_pan_left
 #=braille_pan_right
 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
 KEY_FENRIR,KEY_1=bookmark_1
+KEY_FENRIR,KEY_K=bookmark_1
 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
 KEY_FENRIR,KEY_2=bookmark_2
@@ -61,7 +63,7 @@ KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
 KEY_FENRIR,KEY_7=bookmark_7
 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
-#KEY_FENRIR,KEY_8=bookmark_8
+KEY_FENRIR,KEY_8=bookmark_8
 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
 KEY_FENRIR,KEY_9=bookmark_9
@@ -71,52 +73,56 @@ KEY_FENRIR,KEY_0=bookmark_10
 KEY_FENRIR,KEY_KPSLASH=set_window_application
 2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
 KEY_KPPLUS=last_incoming
-KEY_FENRIR,KEY_F2=toggle_braille
+#=toggle_braille
 KEY_FENRIR,KEY_F3=toggle_sound
 KEY_FENRIR,KEY_F4=toggle_speech
 KEY_KPENTER=temp_disable_speech
-KEY_FENRIR,KEY_CTRL,KEY_P=toggle_punctuation_level
+KEY_FENRIR,KEY_P=toggle_punctuation_level
 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
-KEY_FENRIR,KEY_BACKSLASH=toggle_output
+KEY_FENRIR,KEY_S=toggle_output
 KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons
-key_FENRIR,KEY_KPENTER=toggle_auto_read
+key_FENRIR,KEY_5=toggle_auto_read
 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
 KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking
 KEY_FENRIR,KEY_KPMINUS=toggle_barrier
 KEY_FENRIR,KEY_Q=quit_fenrir
 KEY_FENRIR,KEY_T=time
+KEY_FENRIR,KEY_F12=time
 2,KEY_FENRIR,KEY_T=date
+2,KEY_FENRIR,KEY_F12=date
 KEY_KPSLASH=toggle_auto_indent
-KEY_KPMINUS=attribute_cursor
+KEY_FENRIR,KEY_F=attribute_cursor
 #=toggle_has_attribute
-KEY_FENRIR,KEY_S=spell_check
+KEY_FENRIR,KEY_F7=spell_check
 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
-KEY_FENRIR,KEY_BACKSPACE=forward_keypress
-KEY_FENRIR,KEY_UP=inc_speech_volume
-KEY_FENRIR,KEY_DOWN=dec_speech_volume
-KEY_FENRIR,KEY_RIGHT=inc_speech_rate
-KEY_FENRIR,KEY_LEFT=dec_speech_rate
-KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
-KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
+KEY_FENRIR,KEY_F2=forward_keypress
 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
-KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
+#=clear_clipboard
 KEY_FENRIR,KEY_HOME=first_clipboard
 KEY_FENRIR,KEY_END=last_clipboard
 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
-KEY_FENRIR,KEY_CTRL,KEY_U=copy_last_echo_to_clipboard
+KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=copy_last_echo_to_clipboard
 KEY_FENRIR,KEY_V=paste_clipboard
 KEY_FENRIR,KEY_F5=import_clipboard_from_file
 KEY_FENRIR,KEY_F6=export_clipboard_to_file
 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
-KEY_FENRIR,KEY_X=set_mark
-KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
+KEY_FENRIR,KEY_F9=set_mark
+KEY_FENRIR,KEY_F10=marked_text
+KEY_FENRIR,KEY_F10=toggle_vmenu_mode
+KEY_FENRIR,KEY_SPACE=current_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_SPACE=current_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_RIGHT=next_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_UP=next_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_LEFT=prev_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_DOWN=prev_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_C=save_settings
 # linux specific
-KEY_FENRIR,KEY_F7=import_clipboard_from_x
+#=import_clipboard_from_x
 KEY_FENRIR,KEY_F8=export_clipboard_to_x
-KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
-KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
+KEY_FENRIR,KEY_ALT,KEY_UP=inc_alsa_volume
+KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_alsa_volume
diff --git a/config/keyboard/laptop.conf b/config/keyboard/nvda-laptop.conf
similarity index 65%
rename from config/keyboard/laptop.conf
rename to config/keyboard/nvda-laptop.conf
index 53626b1..dab8d12 100644
--- a/config/keyboard/laptop.conf
+++ b/config/keyboard/nvda-laptop.conf
@@ -1,46 +1,48 @@
+KEY_FENRIR,KEY_F1=toggle_tutorial_mode
 KEY_FENRIR,KEY_H=toggle_tutorial_mode
 KEY_CTRL=shut_up
-KEY_FENRIR,KEY_SHIFT,KEY_O=review_bottom
-KEY_FENRIR,KEY_SHIFT,KEY_U=review_top
-KEY_FENRIR,KEY_I=review_curr_line
+KEY_FENRIR,KEY_CTRL,KEY_END=review_bottom
+KEY_FENRIR,KEY_CTRL,KEY_HOME=review_top
+KEY_FENRIR,KEY_SHIFT,KEY_DOT=review_curr_line
 KEY_FENRIR,KEY_U=review_prev_line
 KEY_FENRIR,KEY_O=review_next_line
-KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin
-KEY_FENRIR,KEY_SHFIT,KEY_L=review_line_end
+KEY_FENRIR,KEY_HOME=review_line_begin
+KEY_FENRIR,KEY_END=review_line_end
 KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
 KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
-KEY_FENRIR,KEY_K=review_curr_word
+KEY_FENRIR,KEY_CTRL,KEY_DOT=review_curr_word
 KEY_FENRIR,KEY_J=review_prev_word
 KEY_FENRIR,KEY_L=review_next_word
-KEY_FENRIR,KEY_ALT,KEY_K=review_curr_word_phonetic
-KEY_FENRIR,KEY_ALT,KEY_J=review_prev_word_phonetic
-KEY_FENRIR,KEY_ALT,KEY_L=review_next_word_phonetic
+2,KEY_FENRIR,KEY_CTRL,KEY_DOT=review_curr_word_phonetic
+2,KEY_FENRIR,KEY_J=review_prev_word_phonetic
+2,KEY_FENRIR,KEY_L=review_next_word_phonetic
 KEY_FENRIR,KEY_COMMA=review_curr_char
 KEY_FENRIR,KEY_M=review_prev_char
 KEY_FENRIR,KEY_DOT=review_next_char
-KEY_FENRIR,KEY_ALT,KEY_COMMA=curr_char_phonetic
-KEY_FENRIR,KEY_ALT,KEY_M=prev_char_phonetic
-KEY_FENRIR,KEY_ALT,KEY_DOT=next_char_phonetic
+2,KEY_FENRIR,KEY_COMMA=curr_char_phonetic
+2,KEY_FENRIR,KEY_M=prev_char_phonetic
+2,KEY_FENRIR,KEY_DOT=next_char_phonetic
 KEY_FENRIR,KEY_CTRL,KEY_I=review_up
 KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
 KEY_FENRIR,KEY_SLASH=exit_review
 KEY_FENRIR,KEY_SHIFT,KEY_DOT=cursor_position
 2,KEY_FENRIR,KEY_I=indent_curr_line
-KEY_FENRIR,KEY_SHIFT,KEY_K=curr_screen
+KEY_FENRIR,KEY_B=curr_screen
 KEY_FENRIR,KEY_SHIFT,KEY_I=curr_screen_before_cursor
 KEY_FENRIR,KEY_SHIFT,KEY_COMMA=curr_screen_after_cursor
-#=cursor_read_to_end_of_line
+KEY_FENRIR,KEY_SHIFT,KEY_PAGEDOWN=cursor_read_to_end_of_line
 #=cursor_column
 #=cursor_lineno
 #=braille_flush
-#=braille_return_to_cursor
+KEY_FENRIR,KEY_CTRL,KEY_T=braille_return_to_cursor
 #=braille_pan_left
 #=braille_pan_right
 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
 KEY_FENRIR,KEY_1=bookmark_1
+KEY_FENRIR,KEY_K=bookmark_1
 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
 KEY_FENRIR,KEY_2=bookmark_2
@@ -71,52 +73,56 @@ KEY_FENRIR,KEY_0=bookmark_10
 KEY_FENRIR,KEY_CTRL,KEY_8=set_window_application
 2,KEY_FENRIR,KEY_CTRL,KEY_8=clear_window_application
 KEY_FENRIR,KEY_SEMICOLON=last_incoming
-KEY_FENRIR,KEY_F2=toggle_braille
+#=toggle_braille
 KEY_FENRIR,KEY_F3=toggle_sound
 KEY_FENRIR,KEY_F4=toggle_speech
 KEY_FENRIR,KEY_ENTER=temp_disable_speech
-KEY_FENRIR,KEY_SHIFT,KEY_CTRL,KEY_P=toggle_punctuation_level
+KEY_FENRIR,KEY_P=toggle_punctuation_level
 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
-KEY_FENRIR,KEY_SHIFT,KEY_ENTER=toggle_output
+KEY_FENRIR,KEY_S=toggle_output
 KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons
-KEY_FENRIR,KEY_ENTER=toggle_auto_read
+KEY_FENRIR,KEY_5=toggle_auto_read
 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
 KEY_FENRIR,KEY_Y=toggle_highlight_tracking
 #=toggle_barrier
 KEY_FENRIR,KEY_Q=quit_fenrir
 KEY_FENRIR,KEY_T=time
+KEY_FENRIR,KEY_F12=time
 2,KEY_FENRIR,KEY_T=date
+2,KEY_FENRIR,KEY_F12=date
 KEY_FENRIR,KEY_BACKSLASH=toggle_auto_indent
-KEY_FENRIR,KEY_MINUS=attribute_cursor
+KEY_FENRIR,KEY_F=attribute_cursor
 #=toggle_has_attribute
-KEY_FENRIR,KEY_S=spell_check
+KEY_FENRIR,KEY_F7=spell_check
 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
-KEY_FENRIR,KEY_BACKSPACE=forward_keypress
-KEY_FENRIR,KEY_UP=inc_speech_volume
-KEY_FENRIR,KEY_DOWN=dec_speech_volume
-KEY_FENRIR,KEY_RIGHT=inc_speech_rate
-KEY_FENRIR,KEY_LEFT=dec_speech_rate
-KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
-KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
+KEY_FENRIR,KEY_F2=forward_keypress
 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
-KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
-KEY_FENRIR,KEY_HOME=first_clipboard
-KEY_FENRIR,KEY_END=last_clipboard
+#=clear_clipboard
+#=first_clipboard
+#=last_clipboard
 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
-KEY_FENRIR,KEY_CTRL,KEY_U=copy_last_echo_to_clipboard
+KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=copy_last_echo_to_clipboard
 KEY_FENRIR,KEY_V=paste_clipboard
 KEY_FENRIR,KEY_F5=import_clipboard_from_file
 KEY_FENRIR,KEY_F6=export_clipboard_to_file
 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
-KEY_FENRIR,KEY_X=set_mark
-KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
+KEY_FENRIR,KEY_F9=set_mark
+KEY_FENRIR,KEY_F10=marked_text
+KEY_FENRIR,KEY_SHIFT,KEY_F10=toggle_vmenu_mode
+KEY_FENRIR,KEY_SPACE=current_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_SPACE=current_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_RIGHT=next_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_UP=next_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_LEFT=prev_quick_menu_entry
+KEY_FENRIR,KEY_CTRL,KEY_DOWN=prev_quick_menu_value
+KEY_FENRIR,KEY_CTRL,KEY_C=save_settings
 # linux specific
-KEY_FENRIR,KEY_F7=import_clipboard_from_x
+#=import_clipboard_from_x
 KEY_FENRIR,KEY_F8=export_clipboard_to_x
-KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
-KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
+KEY_FENRIR,KEY_ALT,KEY_UP=inc_alsa_volume
+KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_alsa_volume
diff --git a/config/keyboard/pty.conf b/config/keyboard/pty.conf
index ba1a23b..871bfd4 100644
--- a/config/keyboard/pty.conf
+++ b/config/keyboard/pty.conf
@@ -1,3 +1,7 @@
+# This file contains terminal escape sequences as shortcut
+# It is used for PTY screen / Input driver (Terminal emulation)
+# ^[ is used as escape
+
 # f1 - fenrir help
 ^[OP=toggle_tutorial_mode
 # double tap control+end read attributes
diff --git a/config/keyboard/pty2.conf b/config/keyboard/pty2.conf
index f53ea06..619bd39 100644
--- a/config/keyboard/pty2.conf
+++ b/config/keyboard/pty2.conf
@@ -1,3 +1,7 @@
+# This file contains terminal escape sequences as shortcut
+# It is used for PTY screen / Input driver (Terminal emulation)
+# ^[ is used as escape
+
 ^[h=toggle_tutorial_mode
 ^[/=shut_up
 ^[[D=shut_up
diff --git a/config/punctuation/de.conf b/config/punctuation/de.conf
index 7e63dfc..cebc180 100644
--- a/config/punctuation/de.conf
+++ b/config/punctuation/de.conf
@@ -46,8 +46,28 @@ _:===:Lienie unten
 [customDict]
 
 [emoticonDict]
-:):===:Grins
-;):===:Zwinker
-XD:===:loool
-:D:===:Lach
-<{-.-}>:===:Raves
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"][\s*|'|"]8\):===:smile with sunglasses
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s*|'|"][O|o][O|o][\s*|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/punctuation/default.conf b/config/punctuation/default.conf
index f290a80..e90d9bf 100644
--- a/config/punctuation/default.conf
+++ b/config/punctuation/default.conf
@@ -4,7 +4,7 @@
 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
 [levelDict]
 none:===:
-some:===:-$~+*-/\@
+some:===:-$~+*-/\@#
 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
 
@@ -46,9 +46,27 @@ _:===:line
 [customDict]
 
 [emoticonDict]
-:):===:smile
-;):===:wink
-XD:===:LOL
-:D:===:laugh
-<{-.-}>:===:Raves
-\o/:===:Hurray
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s+|'|"](Oo)|(oO)[\s+|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/punctuation/en.conf b/config/punctuation/en.conf
index 21e51c0..8656411 100644
--- a/config/punctuation/en.conf
+++ b/config/punctuation/en.conf
@@ -46,8 +46,27 @@ _:===:line
 [customDict]
 
 [emoticonDict]
-:):===:smile
-;):===:twinker
-XD:===:loool
-:D:===:lought
-<{-.-}>:===:Raves
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s+|'|"][O|o][O|o][\s+|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/punctuation/es.conf b/config/punctuation/es.conf
index f95d3c7..0332567 100644
--- a/config/punctuation/es.conf
+++ b/config/punctuation/es.conf
@@ -46,8 +46,28 @@ _:===:subrayado
 [customDict]
 
 [emoticonDict]
-:):===:sonrisa
-;):===:twinker
-XD:===:loool
-:D:===:lought
-<{-.-}>:===:Raves
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"][\s*|'|"]8\):===:smile with sunglasses
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s*|'|"][O|o][O|o][\s*|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/punctuation/fr.conf b/config/punctuation/fr.conf
index ff36dff..7bff0ed 100644
--- a/config/punctuation/fr.conf
+++ b/config/punctuation/fr.conf
@@ -46,8 +46,28 @@ _:===:souligné
 [customDict]
 
 [emoticonDict]
-:):===:sourire
-;):===:clin d'oeil
-XD:===:explosé de rire
-:D:===:rire
-<{-.-}>:===:Raves
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"][\s*|'|"]8\):===:smile with sunglasses
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s*|'|"][O|o][O|o][\s*|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/punctuation/pl.conf b/config/punctuation/pl.conf
index 5935640..3cec60c 100644
--- a/config/punctuation/pl.conf
+++ b/config/punctuation/pl.conf
@@ -46,8 +46,28 @@ _:===:podkreślnik
 [customDict]
 
 [emoticonDict]
-:):===:smile
-;):===:twinker
-XD:===:loool
-:D:===:lought
-<{-.-}>:===:Raves
+# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
+regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
+regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
+regex;[\s*|'|"][\s*|'|"]:-/:===:confused
+regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
+regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
+regex;[\s*|'|"][\s*|'|"]8-X:===:skull
+regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
+regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
+regex;[\s*|'|"][\s*|'|"]:/:===:confused
+regex;[\s*|'|"][\s*|'|"]8\):===:smile with sunglasses
+regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
+regex;[\s*|'|"];\)[\s*|'|"]:===:wink
+regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
+regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
+regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
+# example for arrow left
+#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
+# or
+#([ |^])<-([ ,.!?$]):===:arrow left\2
+regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
+regex;[\s*|'|"][O|o][O|o][\s*|'|"]:===:WTF?
+regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
diff --git a/config/settings/espeak.settings.conf b/config/settings/espeak.settings.conf
index e0b331a..37d42ac 100644
--- a/config/settings/espeak.settings.conf
+++ b/config/settings/espeak.settings.conf
@@ -148,8 +148,11 @@ doubleTapTimeout=0.2
 
 [general]
 debugLevel=0
+# debugMode sets where the debug output should send to:
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
+# debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -161,7 +164,7 @@ clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
 # define the current Fenrir key
 fenrirKeys=KEY_KP0,KEY_META
-scriptKey=KEY_COMPOSE
+scriptKeys=KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat=%A, %B %d, %Y
 autoSpellCheck=True
@@ -195,7 +198,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -219,6 +222,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 enabled=False
 presentTime=True
diff --git a/config/settings/settings-daemon.conf b/config/settings/settings-daemon.conf
index 2d48e90..8532130 100644
--- a/config/settings/settings-daemon.conf
+++ b/config/settings/settings-daemon.conf
@@ -151,10 +151,10 @@ doubleTapTimeout=0.2
 [general]
 debugLevel=0
 # debugMode sets where the debug output should send to:
-# debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -167,12 +167,12 @@ clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
 # define the current Fenrir key
 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
-scriptKey=KEY_COMPOSE
+scriptKeys=KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat=%A, %B %d, %Y
 autoSpellCheck=True
 spellCheckLanguage=en_US
-# path for your scripts "scriptKey" functionality
+# path for your scripts "scriptKeys" functionality
 scriptPath=/usr/share/fenrirscreenreader/scripts
 # overload commands, and create new one without changing Fenrir default
 commandPath=
@@ -205,7 +205,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -229,6 +229,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 # automatic time anouncement
 enabled=False
diff --git a/config/settings/settings-pty.conf b/config/settings/settings-pty.conf
index 2d48e90..8532130 100644
--- a/config/settings/settings-pty.conf
+++ b/config/settings/settings-pty.conf
@@ -151,10 +151,10 @@ doubleTapTimeout=0.2
 [general]
 debugLevel=0
 # debugMode sets where the debug output should send to:
-# debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -167,12 +167,12 @@ clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
 # define the current Fenrir key
 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
-scriptKey=KEY_COMPOSE
+scriptKeys=KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat=%A, %B %d, %Y
 autoSpellCheck=True
 spellCheckLanguage=en_US
-# path for your scripts "scriptKey" functionality
+# path for your scripts "scriptKeys" functionality
 scriptPath=/usr/share/fenrirscreenreader/scripts
 # overload commands, and create new one without changing Fenrir default
 commandPath=
@@ -205,7 +205,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -229,6 +229,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 # automatic time anouncement
 enabled=False
diff --git a/config/settings/settings.conf b/config/settings/settings.conf
index 2d48e90..251c879 100644
--- a/config/settings/settings.conf
+++ b/config/settings/settings.conf
@@ -53,16 +53,17 @@ volume=1.0
 
 # Module is used for Speech-dispatcher, to select the speech module you want to use.
 # Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available.
-# The default is espeak.
-#module=espeak
+# The default is specified in speechd.conf.
+#module=espeak-ng
 
-# Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
-# or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
+# Voice selects the voice you want to use, for example, en-GB-scotland will use the Scotish English voice in Espeak,
+# To find out which voices are available, consult the documentation provided with your selected synthesizer.
 # This also sets the voice used in the generic driver.
-voice=en-us
+# You can add a variant by adding +name onto the end.
+# voice=en-us
 
 # Select the language you want Fenrir to use.
-#language=english-us
+#language=en
 
 # Read new text as it happens?
 autoReadIncoming=True
@@ -78,7 +79,7 @@ autoReadIncoming=True
 # fenrirVolume = is replaced with the current volume
 # fenrirPitch = is replaced with the current pitch
 # fenrirRate = is replaced with the current speed (speech rate)
-genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice -- "fenrirText"
+genericSpeechCommand=espeak-ng -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice -- "fenrirText"
 
 # those are the min and max values of the TTS system that is used in genericSpeechCommand
 fenrirMinVolume=0
@@ -142,7 +143,7 @@ charDeleteEcho=True
 # echo word after pressing space
 wordEcho=False
 # interrupt speech on any keypress
-interruptOnKeyPress=False
+interruptOnKeyPress=True
 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
 interruptOnKeyPressFilter=
 # timeout for double tap in sec
@@ -151,10 +152,10 @@ doubleTapTimeout=0.2
 [general]
 debugLevel=0
 # debugMode sets where the debug output should send to:
-# debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -167,12 +168,12 @@ clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
 # define the current Fenrir key
 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
-scriptKey=KEY_COMPOSE
+scriptKeys=KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat=%A, %B %d, %Y
 autoSpellCheck=True
 spellCheckLanguage=en_US
-# path for your scripts "scriptKey" functionality
+# path for your scripts "scriptKeys" functionality
 scriptPath=/usr/share/fenrirscreenreader/scripts
 # overload commands, and create new one without changing Fenrir default
 commandPath=
@@ -205,7 +206,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -229,6 +230,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 # automatic time anouncement
 enabled=False
diff --git a/config/settings/settings.conf.example b/config/settings/settings.conf.example
index 2c48c35..ac58a76 100644
--- a/config/settings/settings.conf.example
+++ b/config/settings/settings.conf.example
@@ -152,10 +152,10 @@ doubleTapTimeout=0.2
 [general]
 debugLevel=0
 # debugMode sets where the debug output should send to:
-# debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -206,7 +206,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -230,6 +230,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 # automatic time anouncement
 enabled=False
diff --git a/config/settings/speech-dispatcher.settings.conf b/config/settings/speech-dispatcher.settings.conf
index 32337ae..664086c 100644
--- a/config/settings/speech-dispatcher.settings.conf
+++ b/config/settings/speech-dispatcher.settings.conf
@@ -151,10 +151,10 @@ doubleTapTimeout=0.2
 [general]
 debugLevel=0
 # debugMode sets where the debug output should send to:
-# debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
+# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -167,12 +167,12 @@ clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
 # define the current Fenrir key
 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
-scriptKey=KEY_COMPOSE
+scriptKeys=KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat=%A, %B %d, %Y
 autoSpellCheck=True
 spellCheckLanguage=en_US
-# path for your scripts "scriptKey" functionality
+# path for your scripts "scriptKeys" functionality
 scriptPath=/usr/share/fenrirscreenreader/scripts
 # overload commands, and create new one without changing Fenrir default
 commandPath=
@@ -205,7 +205,7 @@ driver=unixDriver
 # tcp port
 port=22447
 # socket filepath
-socketpath=/tmp/
+socketFile=
 # allow settings to overwrite
 enableSettingsRemote=True
 # allow commands to be executed
@@ -229,6 +229,10 @@ enabled=True
 inactiveTimeoutSec=120
 list=
 
+[menu]
+vmenuPath=
+quickMenu=speech#rate;speech#pitch;speech#volume
+
 [time]
 # automatic time anouncement
 enabled=False
diff --git a/debian/changelog b/debian/changelog
index 9f16a23..1a18a91 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,12 +1,16 @@
-fenrir (1.9.5-3) UNRELEASED; urgency=medium
+fenrir (1.9.7.1-1) UNRELEASED; urgency=medium
 
+  [ Samuel Thibault ]
   * watch: Generalize pattern.
   * control: Update alioth list domain.
   * Bump debhelper from 10 to 12.
   * control: Set Rules-Requires-Root to no.
   * control: Bump Standards-Version to 4.6.0 (no change)
 
- -- Samuel Thibault <sthibault@debian.org>  Thu, 19 Sep 2019 01:53:53 +0200
+  [ Debian Janitor ]
+  * New upstream release.
+
+ -- Samuel Thibault <sthibault@debian.org>  Wed, 16 Mar 2022 08:07:15 -0000
 
 fenrir (1.9.5-2) unstable; urgency=medium
 
diff --git a/install.sh b/install.sh
index 9a7a793..db52997 100755
--- a/install.sh
+++ b/install.sh
@@ -17,8 +17,9 @@ install -m755 -d /usr/share/fenrirscreenreader/scripts
 cp -af "config/scripts/wlan__-__key_y.sh" /usr/share/fenrirscreenreader/scripts/
 
 # keyboard
-install -m644 -D "config/keyboard/desktop.conf" /etc/fenrirscreenreader/keyboard/desktop.conf
-install -m644 -D "config/keyboard/laptop.conf" /etc/fenrirscreenreader/keyboard/laptop.conf
+for i in "config/keyboard/"*.conf ; do
+    install -m644 -D "$i" "/etc/fenrirscreenreader/keyboard/${i##*/}"
+done
 
 # punctuation
 install -m755 -d /etc/fenrirscreenreader/punctuation 
@@ -51,9 +52,12 @@ Installation complete.
 install path:/opt/fenrirscreenreader
 settings path:/etc/fenrirscreenreader
 
-To test Fenrir
-sudo systemctl start fenrir
-To have Fenrir start on system boot:
+To test Fenrir:
+sudo fenrir
+
+To have Fenrir start on system boot using systemd:
+download service file: https://raw.githubusercontent.com/chrys87/fenrir/master/autostart/systemd/Arch/fenrir.service
+move the service file to: /etc/systemd/system/fenrir.service
 sudo systemctl enable fenrir
 
 Pulseaudio users may want to run
diff --git a/locale/ru/LC_MESSAGES/fenrir.mo b/locale/ru/LC_MESSAGES/fenrir.mo
new file mode 100644
index 0000000..081a85a
Binary files /dev/null and b/locale/ru/LC_MESSAGES/fenrir.mo differ
diff --git a/locale/ru/LC_MESSAGES/fenrir.po b/locale/ru/LC_MESSAGES/fenrir.po
new file mode 100644
index 0000000..42a8e31
--- /dev/null
+++ b/locale/ru/LC_MESSAGES/fenrir.po
@@ -0,0 +1,1219 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2020-04-19 09:11+0700\n"
+"PO-Revision-Date: 2020-04-19 19:26+07\n"
+"Last-Translator: denis rybin <mejdugorka@yandex.ru>\n"
+"Language-Team: russian \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: ../src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:27
+msgid "adds the current word to the exceptions dictionary"
+msgstr "добавляет текущее слово в словарь исключение"
+
+#: ../src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:34
+#: ../src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:34
+#: ../src/fenrirscreenreader/commands/commands/spell_check.py:35
+msgid "pyenchant is not installed"
+msgstr "pyenchant не установлен"
+
+#: ../src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:49
+msgid "{0} is already in dictionary"
+msgstr "{0} уже находится в словаре"
+
+#: ../src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:52
+msgid "{0} added to dictionary"
+msgstr "{0} добавлено в словарь"
+
+#: ../src/fenrirscreenreader/commands/commands/attribute_cursor.py:18
+#: ../src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py:18
+msgid "Reads attributes of current cursor position"
+msgstr "Читает атрибуты текущей позиции курсора"
+
+#: ../src/fenrirscreenreader/commands/commands/bookmark_1.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_10.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_2.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_3.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_4.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_5.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_6.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_7.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_8.py:19
+#: ../src/fenrirscreenreader/commands/commands/bookmark_9.py:19
+msgid "read Bookmark {0}"
+msgstr "чтение закладки {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/bookmark_1.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_10.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_2.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_3.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_4.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_5.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_6.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_7.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_8.py:24
+#: ../src/fenrirscreenreader/commands/commands/bookmark_9.py:24
+msgid "Bookmark {0} not set"
+msgstr "Закладка {0} не установлена"
+
+#: ../src/fenrirscreenreader/commands/commands/bookmark_1.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_1.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_10.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_10.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_2.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_2.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_3.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_3.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_4.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_4.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_5.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_5.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_6.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_6.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_7.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_7.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_8.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_8.py:30
+#: ../src/fenrirscreenreader/commands/commands/bookmark_9.py:27
+#: ../src/fenrirscreenreader/commands/commands/bookmark_9.py:30
+msgid "Bookmark for application {0} not set"
+msgstr "Закладка для приложения {0} не установлена"
+
+#: ../src/fenrirscreenreader/commands/commands/bookmark_1.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_10.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_2.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_3.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_4.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_5.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_6.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_7.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_8.py:43
+#: ../src/fenrirscreenreader/commands/commands/bookmark_9.py:43
+#: ../src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py:27
+#: ../src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py:30
+#: ../src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py:27
+#: ../src/fenrirscreenreader/commands/commands/indent_curr_line.py:31
+#: ../src/fenrirscreenreader/commands/commands/marked_text.py:33
+#: ../src/fenrirscreenreader/commands/commands/present_first_line.py:25
+#: ../src/fenrirscreenreader/commands/commands/present_last_line.py:25
+#: ../src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_curr_line.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_line_begin.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_next_line.py:29
+#: ../src/fenrirscreenreader/commands/commands/review_next_word.py:29
+#: ../src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_prev_line.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py:27
+#: ../src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py:37
+#: ../src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:59
+msgid "blank"
+msgstr "пусто"
+
+#: ../src/fenrirscreenreader/commands/commands/braille_flush.py:17
+msgid "Clear the Braille device if it is displaying a message"
+msgstr "Очистить устройство Брайля, если оно отображает сообщение."
+
+#: ../src/fenrirscreenreader/commands/commands/braille_pan_left.py:17
+msgid "Move braille view to the left."
+msgstr "Переместить брайлевский вид влево."
+
+#: ../src/fenrirscreenreader/commands/commands/braille_pan_right.py:17
+msgid "Move braille view to the right."
+msgstr "Переместить брайлевский вид вправо."
+
+#: ../src/fenrirscreenreader/commands/commands/braille_return_to_cursor.py:17
+msgid "Set the braille view back to cursor."
+msgstr "Установить брайлевский вид обратно на курсор."
+
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_1.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_10.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_2.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_3.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_4.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_5.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_6.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_7.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_8.py:17
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_9.py:17
+msgid "remove Bookmark {0}"
+msgstr "Удалить закладку {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_1.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_10.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_2.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_3.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_4.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_5.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_6.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_7.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_8.py:24
+#: ../src/fenrirscreenreader/commands/commands/clear_bookmark_9.py:24
+msgid "Bookmark {0} removed for application {1}"
+msgstr "Закладка {0} удалена для приложения {1}"
+
+#: ../src/fenrirscreenreader/commands/commands/clear_clipboard.py:17
+msgid "clears the currently selected clipboard"
+msgstr "Очищает текущий выбранный буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/clear_clipboard.py:21
+msgid "clipboard cleared"
+msgstr "Буфер обмена очищен."
+
+#: ../src/fenrirscreenreader/commands/commands/clear_window_application.py:17
+msgid "Turn off window mode for application"
+msgstr "Отключить режим окна для приложения."
+
+#: ../src/fenrirscreenreader/commands/commands/clear_window_application.py:22
+msgid "Window Mode off for application {0}"
+msgstr "Режим окна выключен для приложения {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/clear_window_application.py:24
+msgid "Not in window Mode"
+msgstr "Не в режиме окна."
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py:18
+msgid "copies last presented text to the clipboard"
+msgstr "Копирует последний представленный текст в буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py:18
+msgid "copies marked text to the currently selected clipboard"
+msgstr "Копирует помеченный текст в выбранный буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py:22
+msgid "One or two marks are needed"
+msgstr "Необходимы одна или две ментки."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_clipboard.py:17
+msgid "speaks the contents of the currently selected clipboard"
+msgstr "Говорит содержимое выбранного буфера обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_clipboard.py:21
+#: ../src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py:28
+#: ../src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py:27
+#: ../src/fenrirscreenreader/commands/commands/first_clipboard.py:21
+#: ../src/fenrirscreenreader/commands/commands/last_clipboard.py:21
+#: ../src/fenrirscreenreader/commands/commands/next_clipboard.py:21
+#: ../src/fenrirscreenreader/commands/commands/paste_clipboard.py:23
+#: ../src/fenrirscreenreader/commands/commands/prev_clipboard.py:21
+msgid "clipboard empty"
+msgstr "Буфер обмена пустой."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_screen.py:17
+msgid "reads the contents of the current screen"
+msgstr "Чтение содержимого текущего экрана."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_screen.py:21
+msgid "screen is empty"
+msgstr "Экран пустой."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py:18
+msgid "reads from the cursor to the bottom of the screen"
+msgstr "Чтение от курсора до конца экрана."
+
+#: ../src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py:18
+msgid "Reads from the top of the screen to the cursor position"
+msgstr "Чтение сначала экрана до курсора."
+
+#: ../src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py:17
+msgid "get current quick menu entry"
+msgstr "Получить текущий быстрый пункт меню"
+
+#: ../src/fenrirscreenreader/commands/commands/current_quick_menu_value.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py:17
+msgid "get current quick menu value"
+msgstr "Получить текущее значение быстрого меню."
+
+#: ../src/fenrirscreenreader/commands/commands/cursor_column.py:17
+msgid "Column number for cursor"
+msgstr "Номер столбца для курсора."
+
+#: ../src/fenrirscreenreader/commands/commands/cursor_lineno.py:17
+msgid "Line number for cursor"
+msgstr "Номер строки для курсора."
+
+#: ../src/fenrirscreenreader/commands/commands/cursor_position.py:17
+msgid "displays the position of the review cursor"
+msgstr "Отображает положение курсора обзора."
+
+#: ../src/fenrirscreenreader/commands/commands/cursor_position.py:23
+msgid "line {0}, column {1}, Terminal {2}"
+msgstr "Строка {0}, столбец {1}, терминал {2}"
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py:18
+msgid "read to end of line, use review cursor if you are in review mode, otherwhise use text cursor"
+msgstr "Чтение до конца строки, используйте курсор обзора, если вы находитесь в режиме просмотра, иначе используйте текстовый курсор."
+
+#: ../src/fenrirscreenreader/commands/commands/date.py:18
+msgid "presents the date"
+msgstr "Сообщить дату."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_alsa_volume.py:24
+msgid "Decrease system volume"
+msgstr "Уменьшить громкость системы."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_alsa_volume.py:28
+#: ../src/fenrirscreenreader/commands/commands/inc_alsa_volume.py:28
+msgid "alsaaudio is not installed"
+msgstr "alsaaudio не установлено"
+
+#: ../src/fenrirscreenreader/commands/commands/dec_alsa_volume.py:36
+#: ../src/fenrirscreenreader/commands/commands/inc_alsa_volume.py:36
+msgid "{0} percent system volume"
+msgstr "Громкость системы {0} процентов."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_sound_volume.py:18
+msgid "decrease sound volume"
+msgstr "Уменьшить громкость звука."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_sound_volume.py:29
+#: ../src/fenrirscreenreader/commands/commands/inc_sound_volume.py:29
+msgid "{0} percent sound volume"
+msgstr "Громкость звука {0} процентов."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_pitch.py:18
+msgid "Decreases the pitch of the speech"
+msgstr "Уменьшить тон речи."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_pitch.py:26
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_pitch.py:27
+msgid "{0} percent speech pitch"
+msgstr "Тон речи {0} процентов."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_rate.py:18
+msgid "Decreases the rate of the speech"
+msgstr "Уменьшить скорость речи."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_rate.py:27
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_rate.py:27
+msgid "{0} percent speech rate"
+msgstr "Скорость речи {0} процентов."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_volume.py:18
+msgid "Decreases the volume of the speech"
+msgstr "Уменьшить громкость речи."
+
+#: ../src/fenrirscreenreader/commands/commands/dec_speech_volume.py:27
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_volume.py:27
+msgid "{0} percent speech volume"
+msgstr "Громкость речи {0} процентов."
+
+#: ../src/fenrirscreenreader/commands/commands/exit_review.py:17
+#: ../src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py:17
+msgid "exits review mode"
+msgstr "Выход из режима просмотра."
+
+#: ../src/fenrirscreenreader/commands/commands/exit_review.py:21
+msgid "Not in Review Mode"
+msgstr "Нет в режиме просмотра."
+
+#: ../src/fenrirscreenreader/commands/commands/exit_review.py:25
+msgid "Exiting Review Mode"
+msgstr "Закрытие режима просмотра."
+
+#: ../src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py:19
+msgid "export the current fenrir clipboard to a file"
+msgstr "Экспортировать текущий буфер обмена Fenrir в файл."
+
+#: ../src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py:34
+msgid "clipboard exported to file"
+msgstr "Буфер обмена экспортирован в файл."
+
+#: ../src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py:20
+msgid "Export current fenrir clipboard to X or GUI clipboard"
+msgstr "Экспорт текущего буфера обмена fenrir в буфер обмена X или GUI"
+
+#: ../src/fenrirscreenreader/commands/commands/first_clipboard.py:17
+msgid "selects the first clipboard"
+msgstr "Выбирает первый буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/forward_keypress.py:17
+msgid "sends the following keypress to the terminal or application"
+msgstr "Отправляет следующее нажатие на терминал или приложение."
+
+#: ../src/fenrirscreenreader/commands/commands/forward_keypress.py:21
+msgid "Forward next keypress"
+msgstr "Переслать следующую клавишу."
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py:19
+msgid "imports text from clipboard file to the clipboard"
+msgstr "импортирует текст из буфера файла в буфер обмена"
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py:27
+msgid "File does not exist"
+msgstr "Файл не существует."
+
+#: ../src/fenrirscreenreader/commands/commands/import_clipboard_from_x.py:21
+msgid "imports the graphical clipboard to Fenrir's clipboard"
+msgstr "Импортирует графический буфер обмена в буфер обмена Фенрира."
+
+#: ../src/fenrirscreenreader/commands/commands/inc_alsa_volume.py:24
+msgid "Increase system volume"
+msgstr "Увеличение громкости системы."
+
+#: ../src/fenrirscreenreader/commands/commands/inc_sound_volume.py:18
+msgid "adjusts the volume for in coming sounds"
+msgstr "Регулирует громкость входящих звуков."
+
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_pitch.py:18
+msgid "Increases the pitch of the speech"
+msgstr "Увеличение тона речи."
+
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_rate.py:18
+msgid "Increase the speech rate"
+msgstr "Увеличение скорости речи."
+
+#: ../src/fenrirscreenreader/commands/commands/inc_speech_volume.py:18
+msgid "Increase the speech volume"
+msgstr "Увеличение громкости речи."
+
+#: ../src/fenrirscreenreader/commands/commands/indent_curr_line.py:18
+msgid "Presents the indentation level for the current line"
+msgstr "Сообщает уровень отступа для текущей строки."
+
+#: ../src/fenrirscreenreader/commands/commands/indent_curr_line.py:33
+msgid "indent {0}"
+msgstr "Отступ {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/last_clipboard.py:17
+msgid "selects the last clipboard"
+msgstr "Выбирает последний буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/last_incoming.py:17
+msgid "Presents the text which was last received"
+msgstr "Сообщать текст, который был получен последним."
+
+#: ../src/fenrirscreenreader/commands/commands/marked_text.py:18
+msgid "Presents the currently selected text that will be copied to the clipboard"
+msgstr "Сообщает текущий выбранный текст, который будет скопирован в буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/marked_text.py:23
+msgid "please set begin and endmark"
+msgstr "Пожалуйста, установите начало и конец."
+
+#: ../src/fenrirscreenreader/commands/commands/next_clipboard.py:17
+msgid "selects the next clipboard"
+msgstr "Выбирает следующий буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/next_clipboard.py:28
+#: ../src/fenrirscreenreader/commands/commands/prev_clipboard.py:28
+msgid "First clipboard "
+msgstr "Первый буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/next_clipboard.py:30
+#: ../src/fenrirscreenreader/commands/commands/prev_clipboard.py:30
+msgid "Last clipboard "
+msgstr "Последний буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py:17
+msgid "get next quick menu entry"
+msgstr "Получить следующий быстрый пункт меню."
+
+#: ../src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py:27
+msgid "Quick menu not available"
+msgstr "Быстрое меню недоступно."
+
+#: ../src/fenrirscreenreader/commands/commands/next_quick_menu_value.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py:17
+msgid "get next quick menu value"
+msgstr "Получить следующее значение быстрого меню."
+
+#: ../src/fenrirscreenreader/commands/commands/paste_clipboard.py:19
+msgid "pastes the text from the currently selected clipboard"
+msgstr "Вставляет текст из текущего выбранного буфера обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/present_first_line.py:18
+msgid "present first line"
+msgstr "Сообщать первую строку."
+
+#: ../src/fenrirscreenreader/commands/commands/present_last_line.py:18
+#: ../src/fenrirscreenreader/commands/commands/review_curr_line.py:18
+msgid "current line"
+msgstr "Текущая строка."
+
+#: ../src/fenrirscreenreader/commands/commands/prev_clipboard.py:17
+msgid "selects the previous clipboard"
+msgstr "Выбирает предыдущий буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py:17
+msgid "get previous quick menu entry"
+msgstr "Получить предыдущий пункт быстрого меню."
+
+#: ../src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py:17
+#: ../src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py:17
+msgid "get previous quick menu value"
+msgstr "Получить предыдущее значение быстрого меню."
+
+#: ../src/fenrirscreenreader/commands/commands/quit_fenrir.py:17
+msgid "exits Fenrir"
+msgstr "Выход из  fenrir."
+
+#: ../src/fenrirscreenreader/commands/commands/remove_marks.py:17
+msgid "Removes marks from selected text"
+msgstr "Удалить метки из выбранного текста."
+
+#: ../src/fenrirscreenreader/commands/commands/remove_marks.py:21
+msgid "Remove marks"
+msgstr "Удалить метки."
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:27
+msgid "removes the current word from the exceptions dictionary"
+msgstr "Удаляет текущее слова из словаря исключений."
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:50
+msgid "{0} is not in the dictionary"
+msgstr "{0} нет в словаре"
+
+#:
+#: ../src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:53
+msgid "{0} removed"
+msgstr "{0} удалено"
+
+#: ../src/fenrirscreenreader/commands/commands/review_bottom.py:17
+msgid "Move review to the bottom of the screen"
+msgstr "Переместить просмотр в конец экрана."
+
+#: ../src/fenrirscreenreader/commands/commands/review_bottom.py:21
+msgid "Bottom"
+msgstr "Конец"
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_char.py:18
+msgid "presents the current character."
+msgstr "Сообщать текущий символ."
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py:18
+msgid "set review and phonetically presents the current character"
+msgstr "Установить обзор и фонетически представлять текущий символ."
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word.py:18
+msgid "current word."
+msgstr "Текущее слово."
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word.py:32
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py:36
+#: ../src/fenrirscreenreader/commands/commands/review_down.py:27
+#: ../src/fenrirscreenreader/commands/commands/review_next_char.py:28
+#: ../src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py:30
+#: ../src/fenrirscreenreader/commands/commands/review_next_line.py:34
+#: ../src/fenrirscreenreader/commands/commands/review_next_word.py:34
+#: ../src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py:36
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char.py:31
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py:30
+#: ../src/fenrirscreenreader/commands/commands/review_prev_line.py:32
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word.py:32
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py:36
+#: ../src/fenrirscreenreader/commands/commands/review_up.py:27
+msgid "end of screen"
+msgstr "Конец экрана."
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word.py:35
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py:39
+#: ../src/fenrirscreenreader/commands/commands/review_next_char.py:31
+#: ../src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py:33
+#: ../src/fenrirscreenreader/commands/commands/review_next_word.py:37
+#: ../src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py:39
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char.py:34
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py:33
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word.py:35
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py:39
+#: ../src/fenrirscreenreader/commands/commands/review_up.py:30
+msgid "line break"
+msgstr "Разрыв строки"
+
+#: ../src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py:19
+msgid "Phonetically spells the current word"
+msgstr "Представляет фонетически  текущее слово"
+
+#: ../src/fenrirscreenreader/commands/commands/review_down.py:18
+msgid "Move review to the character below the current position"
+msgstr "Переместить обзор на символ ниже текущей позиции."
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_begin.py:18
+msgid "set review cursor to begin of current line and display the content"
+msgstr "Установить курсор просмотра в начало текущей строки и отобразить содержимое."
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_begin.py:30
+msgid "beginning of line"
+msgstr "Начало строки"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_end.py:18
+msgid "Move Review to the end of current line and display the content"
+msgstr "Установить курсор просмотра в конец текущей строки и отобразить содержимое."
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_end.py:27
+msgid "end of line"
+msgstr "Конец строки"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_first_char.py:19
+msgid "Move Review to the first character on the line"
+msgstr "Переместить курсор просмотра к первому символу строки"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_first_char.py:26
+msgid "line is empty"
+msgstr "Строка пустая"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_first_char.py:33
+msgid "first character in line indent {0}"
+msgstr "Первый символ в строке {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_last_char.py:18
+msgid "Move Review to the last character on the line"
+msgstr "Переместить курсор к последнему символу на строке"
+
+#: ../src/fenrirscreenreader/commands/commands/review_line_last_char.py:27
+msgid "last character in line"
+msgstr "Последний символ в строке"
+
+#: ../src/fenrirscreenreader/commands/commands/review_next_char.py:18
+msgid "Moves review to the next character "
+msgstr "Переместить курсор просмотра к следующему символу "
+
+#: ../src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py:18
+msgid "phonetically presents the next character and set review to it"
+msgstr "Фонетически представляет следующий символ и устанавливает курсор обзора к нему."
+
+#: ../src/fenrirscreenreader/commands/commands/review_next_line.py:18
+msgid "moves review to the next line "
+msgstr "Переместить курсор просмотра к следующей строке"
+
+#: ../src/fenrirscreenreader/commands/commands/review_next_word.py:18
+msgid "moves review to the next word "
+msgstr "Переместить курсор просмотра к следующему слову"
+
+#: ../src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py:19
+msgid "Phonetically spells the next word and moves review to it"
+msgstr "Фонетически представляет следующее слово и перемещает курсор обзора к нему."
+
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char.py:18
+msgid "moves review to the previous character "
+msgstr "Переместить курсор просмотра к предыдущему символу"
+
+#: ../src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py:18
+msgid "phonetically presents the previous character and set review to it"
+msgstr "Фонетически представляет предыдущий символ и устанавливает курсор обзора к нему."
+
+#: ../src/fenrirscreenreader/commands/commands/review_prev_line.py:18
+msgid "moves review to the previous line "
+msgstr "Переместить курсор просмотра к предыдущей строке"
+
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word.py:18
+msgid "moves review focus to the previous word "
+msgstr "Переместить курсор просмотра к предыдущему слову"
+
+#: ../src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py:19
+msgid "Phonetically spells the previous word and moves review to it"
+msgstr "Фонетически представляет предыдущее слово и перемещает курсор обзора к нему."
+
+#: ../src/fenrirscreenreader/commands/commands/review_top.py:18
+msgid "move review to top of screen"
+msgstr "Переместить курсор просмотра в начало экрана"
+
+#: ../src/fenrirscreenreader/commands/commands/review_top.py:22
+msgid "Top"
+msgstr "Начало"
+
+#: ../src/fenrirscreenreader/commands/commands/review_up.py:18
+msgid "Move review to the character in the line above the current position"
+msgstr "Переместить курсор обзора на символ в строке выше текущей позиции."
+
+#: ../src/fenrirscreenreader/commands/commands/save_settings.py:18
+msgid "Saves your current Fenrir settings so they are the default."
+msgstr "Сохранить текущие настройки fenrir как настройки по умолчанию."
+
+#: ../src/fenrirscreenreader/commands/commands/save_settings.py:22
+msgid "Settings saved."
+msgstr "Настройки сохранены"
+
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_1.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_10.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_2.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_3.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_4.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_5.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_6.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_7.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_8.py:18
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_9.py:18
+msgid "set Bookmark {0}"
+msgstr "Установить закладку {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_1.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_10.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_2.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_3.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_4.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_5.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_6.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_7.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_8.py:22
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_9.py:22
+msgid "No mark found"
+msgstr "Метка не найдена."
+
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_1.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_10.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_2.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_3.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_4.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_5.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_6.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_7.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_8.py:32
+#: ../src/fenrirscreenreader/commands/commands/set_bookmark_9.py:32
+msgid "Bookmark {0} set for application {1}"
+msgstr "Закладка {0} установлена для приложения {1}"
+
+#: ../src/fenrirscreenreader/commands/commands/set_mark.py:17
+msgid "places marks to select text to copy to the clipboard"
+msgstr "Ставит метки для выбора текста для копирования в буфер обмена."
+
+#: ../src/fenrirscreenreader/commands/commands/set_mark.py:21
+msgid "no review cursor"
+msgstr "Нет курсора просмотра"
+
+#: ../src/fenrirscreenreader/commands/commands/set_mark.py:26
+#: ../src/fenrirscreenreader/commands/commands/set_mark.py:28
+msgid "set mark"
+msgstr "Установка метки."
+
+#: ../src/fenrirscreenreader/commands/commands/set_window_application.py:17
+msgid "set Window Mode, needs 2 marks "
+msgstr "Установка режима окна нуждается в двух метках"
+
+#: ../src/fenrirscreenreader/commands/commands/set_window_application.py:22
+msgid "Window Mode on for application {0}"
+msgstr "Режим окна для приложения {0}"
+
+#: ../src/fenrirscreenreader/commands/commands/set_window_application.py:25
+msgid "Set window begin and end marks"
+msgstr "Установка начала и конца окна"
+
+#: ../src/fenrirscreenreader/commands/commands/shut_up.py:17
+msgid "Interrupts the current presentation"
+msgstr "Прерывать текущую речь."
+
+#: ../src/fenrirscreenreader/commands/commands/spell_check.py:26
+msgid "checks the spelling of the current word"
+msgstr "Проверяет написание текущего слова."
+
+#: ../src/fenrirscreenreader/commands/commands/spell_check.py:51
+#: ../src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py:129
+msgid "misspelled"
+msgstr "Орфографическая ошибка"
+
+#: ../src/fenrirscreenreader/commands/commands/spell_check.py:53
+msgid "correct"
+msgstr "Правильно"
+
+#: ../src/fenrirscreenreader/commands/commands/subprocess.py:21
+msgid "script: {0} fullpath: {1}"
+msgstr "Скрипт; {0}, путь {1}"
+
+#: ../src/fenrirscreenreader/commands/commands/subprocess.py:24
+msgid "Script file not found"
+msgstr "Скрипт не найден"
+
+#: ../src/fenrirscreenreader/commands/commands/subprocess.py:27
+msgid "Script source is not a valid file"
+msgstr "Исходник скрипта неправильный файл"
+
+#: ../src/fenrirscreenreader/commands/commands/subprocess.py:30
+msgid "Script file is not executable"
+msgstr "Файл скрипта не исполняемый"
+
+#: ../src/fenrirscreenreader/commands/commands/temp_disable_speech.py:17
+#: ../src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py:17
+#: ../src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py:17
+msgid "disables speech until next keypress"
+msgstr "Отключить речь пока не нажата следующая клавиша"
+
+#: ../src/fenrirscreenreader/commands/commands/time.py:18
+msgid "presents the time"
+msgstr "Сообщить время"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_indent.py:16
+msgid "enables or disables automatic reading of indentation level changes"
+msgstr "включить или отключить чтение изменения уровня отступов."
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_indent.py:21
+msgid "autoindent enabled"
+msgstr "чтение отступов включено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_indent.py:23
+msgid "autoindent disabled"
+msgstr "чтение отступов отключено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_read.py:16
+msgid "enables or disables automatic reading of new text as it appears"
+msgstr "включить или отключить чтения нового текста"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_read.py:21
+msgid "autoread enabled"
+msgstr "Автоматическое чтение нового текста включено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_read.py:23
+msgid "autoread disabled"
+msgstr "Автоматическое чтение нового текста выключено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py:17
+msgid "enables or disables automatic spell checking"
+msgstr "Включить или отключить проверку орфографических ошибок."
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py:22
+msgid "auto spellcheck enabled"
+msgstr "Проверка орфографических ошибок включена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py:24
+msgid "auto spellcheck disabled"
+msgstr "Проверка орфографических ошибок выключена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_time.py:16
+msgid "Enables or disables automatic reading of time after specified intervals"
+msgstr "Включение или выключение автоматического сообщение времени в указанном интервале."
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_time.py:21
+msgid "Automatic time announcement enabled"
+msgstr "Автоматическое сообщение времени включено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_auto_time.py:23
+msgid "Automatic time announcement disabled"
+msgstr "Автоматическое сообщение времени отключено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_barrier.py:16
+msgid "enables or disables the barrier mode"
+msgstr "Включение или отключение режима барьера"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_barrier.py:21
+msgid "barrier mode enabled"
+msgstr "Режим барьера включен"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_barrier.py:23
+msgid "barrier mode disabled"
+msgstr "Режим барьера выключен"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_braille.py:17
+msgid "Enables and disables Braille output"
+msgstr "Включение и отключение устройства Брайля."
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_braille.py:21
+msgid "braille disabled"
+msgstr "Браиль выключен"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_braille.py:24
+msgid "braille enabled"
+msgstr "Браиль включен"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_emoticons.py:16
+msgid "enables or disables announcement of emoticons instead of chars"
+msgstr "Включение или отключение смайлов вместо символов."
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_emoticons.py:21
+msgid "emoticons enabled"
+msgstr "Смайлы включены"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_emoticons.py:23
+msgid "emoticons disabled"
+msgstr "Смайлы выключены"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_has_attribute.py:16
+msgid "enables or disables the announcement of attributes"
+msgstr "Включение или отключение чтения атрибутов"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_has_attribute.py:21
+msgid "announcement of attributes enabled"
+msgstr "Чтение атрибутов включено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_has_attribute.py:23
+msgid "announcement of attributes disabled"
+msgstr "Чтение атрибутов выключено"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py:16
+msgid "enables or disables tracking of highlighted text"
+msgstr "Включает или отключает отслеживание выделенного текста"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py:24
+msgid "highlight tracking"
+msgstr "Отслеживание выделения"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py:26
+msgid "cursor tracking"
+msgstr "Отслеживание курсора"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_output.py:17
+msgid "toggles all output settings"
+msgstr "Переключает все настройки вывода"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_output.py:23
+msgid "Fenrir muted"
+msgstr "Речь fenrir отключена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_output.py:31
+msgid "Fenrir unmuted"
+msgstr "Речь fenrir включена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_punctuation_level.py:23
+msgid "No punctuation found."
+msgstr "Пунктуация не найдена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_sound.py:17
+msgid "enables or disables sound"
+msgstr "Включение или отключение звуковых эффектов"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_sound.py:21
+msgid "sound disabled"
+msgstr "Звуковые эффекты выключены"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_sound.py:24
+msgid "sound enabled"
+msgstr "Звуковые эффекты включены"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_speech.py:17
+msgid "enables or disables speech"
+msgstr "Включение или отключение речи"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_speech.py:22
+msgid "speech disabled"
+msgstr "Речь выключена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_speech.py:25
+#: ../src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py:24
+#: ../src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py:28
+msgid "speech enabled"
+msgstr "Речь включена"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py:18
+msgid "Exiting tutorial mode. To enter tutorial mode again press Fenrir+f1"
+msgstr "Режим обучения закрыт. Чтобы снова войти в режим обучения нажмите fenrir+f1"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py:22
+msgid "Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1."
+msgstr "Включен режим обучения. В этом режиме можно ознакомиться с описанием команд сами команды не выполняются. Перемещаться по списку можно с помощью клавиш стрелок вверх, вниз. Для закрытия нажмите fenrir+f1"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py:18
+msgid "Entering or Leaving v menu mode."
+msgstr "вход и выход из v меню"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py:22
+msgid "Entering v menu."
+msgstr "вход в v меню"
+
+#: ../src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py:24
+msgid "Leaving v menu."
+msgstr "выъход из v меню"
+
+#: ../src/fenrirscreenreader/commands/help/curr_help.py:17
+msgid "get current help message"
+msgstr "Получить текущее сообщение подсказки"
+
+#: ../src/fenrirscreenreader/commands/help/next_help.py:17
+msgid "get next help message"
+msgstr "Получить следующее сообщение подсказки"
+
+#: ../src/fenrirscreenreader/commands/help/prev_help.py:17
+msgid "get prev help message"
+msgstr "Получить предыдущее сообщение подсказки"
+
+#:
+#: ../src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py:46
+msgid "indented "
+msgstr ""
+
+#: ../src/fenrirscreenreader/commands/onHeartBeat/76000-time.py:66
+msgid "Autotime: {0}"
+msgstr "объявление времени {0}"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py:22
+msgid "Capslock on"
+msgstr "Capslock включен"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py:24
+msgid "Capslock off"
+msgstr "Capslock выключен"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py:22
+msgid "Scrolllock on"
+msgstr "Scrolllock включен"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py:24
+msgid "Scrolllock off"
+msgstr "Scrolllock выключен"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py:22
+msgid "Numlock on"
+msgstr "Numlock включен"
+
+#: ../src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py:24
+msgid "Numlock off"
+msgstr "Numlock выключен"
+
+#:
+#: ../src/fenrirscreenreader/commands/onScreenChanged/80000-screen_change_announcement.py:20
+msgid "screen {0}"
+msgstr "Экран {0} "
+
+#:
+#: ../src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py:16
+msgid "enables or disables tracking of highlighted"
+msgstr "Включает или отключает отслеживание выделения"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py:17
+msgid "get current v menu entry"
+msgstr "Получить текущий пункт меню v"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py:17
+msgid "leave v menu submenu"
+msgstr "Выйти v меню подменю"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py:17
+msgid "execute v menu entry"
+msgstr "Выполнить пункт v меню"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py:17
+msgid "enter v menu submenu"
+msgstr "войти в подменю меню"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py:17
+msgid "get next v menu entry"
+msgstr "получить следующий пункт меню v"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py:17
+msgid "get prev v menu entry"
+msgstr "получить предыдущий пункт меню v"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_a.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_b.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_c.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_d.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_e.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_f.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_g.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_h.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_i.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_j.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_k.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_l.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_m.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_n.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_o.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_p.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_q.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_r.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_s.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_t.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_u.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_v.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_w.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_x.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_y.py:17
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_z.py:17
+msgid "search for an menu entry"
+msgstr "поиск пункта меню"
+
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_a.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_b.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_c.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_d.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_e.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_f.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_g.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_h.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_i.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_j.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_k.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_l.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_m.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_n.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_o.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_p.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_q.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_r.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_s.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_t.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_u.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_v.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_w.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_x.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_y.py:23
+#: ../src/fenrirscreenreader/commands/vmenu-navigation/search_z.py:23
+msgid "not found"
+msgstr "Не найдено"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:168
+msgid "bold"
+msgstr "Жирный"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:176
+msgid "italic"
+msgstr "Курсивный"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:184
+msgid "underline"
+msgstr "Подчеркнутый"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:192
+msgid "strikethrough"
+msgstr "Зачеркнутый"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:200
+msgid "reverse"
+msgstr "Обратный"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:208
+msgid "blink"
+msgstr "Мерцание"
+
+#: ../src/fenrirscreenreader/core/attributeManager.py:225
+#: ../src/fenrirscreenreader/core/attributeManager.py:232
+msgid "default"
+msgstr "По умолчанию"
+
+#: ../src/fenrirscreenreader/core/byteManager.py:103
+#: ../src/fenrirscreenreader/core/byteManager.py:105
+msgid "Sticky Mode On"
+msgstr "Режим залипания включен"
+
+#: ../src/fenrirscreenreader/core/byteManager.py:109
+msgid "bypass"
+msgstr ""
+
+#: ../src/fenrirscreenreader/core/fenrirManager.py:26
+msgid "Start Fenrir"
+msgstr "fenrir запущен"
+
+#: ../src/fenrirscreenreader/core/fenrirManager.py:234
+msgid "Quit Fenrir"
+msgstr "выключить fenrir"
+
+#: ../src/fenrirscreenreader/core/helpManager.py:77
+msgid "toggles the tutorial mode"
+msgstr "Переключение в режим обучения"
+
+#: ../src/fenrirscreenreader/core/outputManager.py:297
+msgid "speech temporary disabled"
+msgstr "Речь временно отключена"
+
+#: ../src/fenrirscreenreader/core/quickMenuManager.py:124
+msgid "setting invalid"
+msgstr "Неправильная настройка"
+
+#: ../src/fenrirscreenreader/core/quickMenuManager.py:131
+msgid "setting value invalid"
+msgstr "Значение настройки неправильное"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "black"
+msgstr "черный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "blue"
+msgstr "синий"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "cyan"
+msgstr ""
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "green"
+msgstr "зеленый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "red"
+msgstr "красный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+msgid "white"
+msgstr "белый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Magenta"
+msgstr "пурпурный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:12
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "brown/yellow"
+msgstr "коричневый/желтый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Black"
+msgstr "черный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Blue"
+msgstr "синий"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Cyan"
+msgstr ""
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Dark gray"
+msgstr "темно серый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Green"
+msgstr "зеленый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light blue"
+msgstr "голубой"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light cyan"
+msgstr "светло-голубой"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light gray"
+msgstr "светлосерый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light magenta"
+msgstr "Светло-пурпурный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light red"
+msgstr "розовый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Light yellow"
+msgstr "светло желтый"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "Red"
+msgstr "красный"
+
+#: ../src/fenrirscreenreader/core/screenDriver.py:13
+msgid "White"
+msgstr "белый"
+
+#: ../src/fenrirscreenreader/core/vmenuManager.py:66
+#: ../src/fenrirscreenreader/core/vmenuManager.py:226
+msgid "Menu"
+msgstr "Меню"
+
+#: ../src/fenrirscreenreader/core/vmenuManager.py:234
+msgid "Action"
+msgstr "Действие"
+
diff --git a/play zone/clilauncher.sh b/play zone/clilauncher.sh
new file mode 100755
index 0000000..2373016
--- /dev/null
+++ b/play zone/clilauncher.sh	
@@ -0,0 +1,41 @@
+#!/bin/bash
+# clilauncher.sh
+# Description: Launches xterm with give application and fenrir.
+#
+# Copyright 2019, F123 Consulting, <information@f123.org>
+# Copyright 2019, Storm Dragon, <storm_dragon@linux-a11y.org>
+#
+# This is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this package; see the file COPYING.  If not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+#--code--
+ 
+if [[ $# -lt 1 ]]; then
+    echo "Usage: $0 program to launch args."
+    exit 1
+fi
+
+# Make sure the program being launched exists
+command -v "${1%% *}" &> /dev/null || exit 1
+
+for i in /tmp/fenrirscreenreader-*.sock ; do
+if [[ "$i" != "/tmp/fenrirscreenreader-deamon.sock" ]]; then
+        echo -n "setting set screen#suspendingScreen=pty" | socat - UNIX-CLIENT:$i
+    fi
+done
+
+#/usr/bin/urxvt -name "${1%% *}" -e fenrir -d -s /etc/fenrirscreenreader/settings/xterm.conf -o "general.shell=/usr/bin/${1%% *};remote#socketFile=/tmp/fenrirscreenreader-${1%% *}.sock"
+/usr/bin/urxvt -name "${1%% *}" -e ../src/fenrir -d -s ./xterm.conf -o "general.shell=/usr/bin/${1%% *};remote#socketFile=/tmp/fenrirscreenreader-${1%% *}.sock"
+
diff --git a/play zone/start1.sh b/play zone/start1.sh
new file mode 100755
index 0000000..7276199
--- /dev/null
+++ b/play zone/start1.sh	
@@ -0,0 +1,35 @@
+#!/bin/bash
+# clilauncher.sh
+# Description: Launches xterm with give application and fenrir.
+#
+# Copyright 2019, F123 Consulting, <information@f123.org>
+# Copyright 2019, Storm Dragon, <storm_dragon@linux-a11y.org>
+#
+# This is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this package; see the file COPYING.  If not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+#--code--
+
+rm -rf /tmp/fenrir*
+
+for i in /tmp/fenrirscreenreader-*.sock ; do
+if [[ "$i" != "/tmp/fenrirscreenreader-deamon.sock" ]]; then
+        echo -n "setting set screen#suspendingScreen=pty" | socat - UNIX-CLIENT:$i
+    fi
+done
+
+/usr/bin/urxvt -e ../src/fenrir -s ./xterm.conf -o "general.shell=./waitForKey1;remote#socketFile=/tmp/fenrirscreenreader-waitForKey1.sock"
+
+
diff --git a/play zone/start2.sh b/play zone/start2.sh
new file mode 100755
index 0000000..e627bbe
--- /dev/null
+++ b/play zone/start2.sh	
@@ -0,0 +1,33 @@
+#!/bin/bash
+# clilauncher.sh
+# Description: Launches xterm with give application and fenrir.
+#
+# Copyright 2019, F123 Consulting, <information@f123.org>
+# Copyright 2019, Storm Dragon, <storm_dragon@linux-a11y.org>
+#
+# This is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this package; see the file COPYING.  If not, write to the Free
+# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+#--code--
+ 
+for i in /tmp/fenrirscreenreader-*.sock ; do
+if [[ "$i" != "/tmp/fenrirscreenreader-deamon.sock" ]]; then
+        echo -n "setting set screen#suspendingScreen=pty" | socat - UNIX-CLIENT:$i
+    fi
+done
+
+/usr/bin/urxvt -e ../src/fenrir -d -s ./xterm.conf -o "general.shell=./waitForKey2;remote#socketFile=/tmp/fenrirscreenreader-waitForKey2.sock"
+
+
diff --git a/play zone/waitForKey1 b/play zone/waitForKey1
new file mode 100755
index 0000000..aa59350
--- /dev/null
+++ b/play zone/waitForKey1	
@@ -0,0 +1,14 @@
+#!/bin/bash
+echo "1"
+echo "Press 'q' to exit"
+count=0
+while : ; do
+read -n 1 k <&1
+if [[ $k = q ]] ; then
+printf "\nQuitting from the program\n"
+break
+else
+((count=$count+1))
+echo "Press 'q' to exit"
+fi
+done
diff --git a/play zone/waitForKey2 b/play zone/waitForKey2
new file mode 100755
index 0000000..598e0ae
--- /dev/null
+++ b/play zone/waitForKey2	
@@ -0,0 +1,14 @@
+#!/bin/bash
+echo "2"
+echo "Press 'q' to exit"
+count=0
+while : ; do
+read -n 1 k <&1
+if [[ $k = q ]] ; then
+printf "\nQuitting from the program\n"
+break
+else
+((count=$count+1))
+echo "Press 'q' to exit"
+fi
+done
diff --git a/config/settings/settings.conf.storm b/play zone/xterm.conf
similarity index 92%
rename from config/settings/settings.conf.storm
rename to play zone/xterm.conf
index 1103186..8f950a1 100644
--- a/config/settings/settings.conf.storm
+++ b/play zone/xterm.conf	
@@ -9,16 +9,16 @@ genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine
 
 [speech]
 enabled=True
-#driver=speechdDriver
-driver=genericDriver
+driver=speechdDriver
+#driver=genericDriver
 serverPath=
-rate=0.80
+rate=0.85
 pitch=0.5
 # Pitch for capital letters
 capitalPitch=0.9
-module=espeak
-voice=en-us
-language=english-us
+#module=espeak
+voice=bdl
+#language=en
 volume=1.0
 autoReadIncoming=True
 
@@ -44,9 +44,9 @@ fenrirMinRate=80
 fenrirMaxRate=890
 
 [braille]
-enabled=False
+enabled=True
 driver=dummyDriver
-layout=en
+#layout=en
 # to what should the flush timeout relate to 
 # word = flush after (number of words to display) * seconds
 # char = flush after (number of chars to display) * seconds
@@ -69,17 +69,17 @@ fixCursorOnCell=-1
 # none = no automatic toggle command used
 # review = priority to review
 # last = follow last used cursor
-cursorFollowMode=review
+cursorFollowMode=last
 # number of cells in panning (horizontal)
 # 0 = display size, >0 number of cells
 panSizeHorizontal=0
 
 [screen]
-driver=vcsaDriver
+driver=ptyDriver
 encoding=auto
 screenUpdateDelay=0.05
-suspendingScreen=
-autodetectSuspendingScreen=True
+suspendingScreen=1
+autodetectSuspendingScreen=False
 
 [keyboard]
 driver=evdevDriver
@@ -103,7 +103,7 @@ debugLevel=1
 # debugMode=File writes to debugFile (Default: /var/log/fenrirscreenreader/fenrir.log)
 # debugMode=Print just prints on the screen
 debugMode=File
-debugFile=/var/log/fenrirscreenreader/fenrir.log
+debugFile=
 punctuationProfile=default
 punctuationLevel=some
 respectPunctuationPause=True
@@ -113,8 +113,8 @@ numberOfClipboards=10
 # $user is replaced by username
 clipboardExportPath=/tmp/fenrirClipboard
 emoticons=True
-fenrirKeys=KEY_KP0,KEY_META
-scriptKey=KEY_COMPOSE
+fenrirKeys=KEY_KP0,KEY_CAPSLOCK
+scriptKeys=KEY_META,KEY_COMPOSE
 timeFormat=%H:%M:%P
 dateFormat="%A, %B %d, %Y"
 autoSpellCheck=True
@@ -144,10 +144,10 @@ highlight=False
 
 [remote]
 enable=True
-# driver
-# unixDriver = unix sockets
-# tcpDriver = tcp (localhost only)
-driver=unixDriver
+# connection type
+# unix = unix sockets
+# tcp = tcp (localhost only)
+method=unix
 # tcp port
 port=22447
 # socket filepath
diff --git a/realese nots/1.9.6 b/realese nots/1.9.6
new file mode 100644
index 0000000..9e80bd9
--- /dev/null
+++ b/realese nots/1.9.6	
@@ -0,0 +1,19 @@
+!!!! ATTENTION !!!!
+the speech-dispatcher driver was reworked. the language and voice was swapped.
+this needs some reconfiguration in your settings.conf
+what you have as speech language= needs now to be set to voice=
+!!!! ATTENTION !!!!
+
+1. vMenu
+- it allows to define macros in an menu like structure
+- allows us to create a settings menu
+2. first letter navigation in vMenu
+3. quit command for remote manager for exiting fenrir
+4. "vmenu" command for remote manager for lock an vmenu
+5. "resetvmenu" command for remote manager for release complete vmenu
+6. NVDA compatible keyboard layouts
+7. fixes to speech-dispatcher driver
+8. quickMenu
+
+Bugfixes and Cleanups
+
diff --git a/realese nots/1.9.7 b/realese nots/1.9.7
new file mode 100644
index 0000000..9447937
--- /dev/null
+++ b/realese nots/1.9.7	
@@ -0,0 +1,12 @@
+1. PTY screen driver (leaves experimental state, stable now)
+- lot higher accuracy
+- works with "dialog" now
+- a lot of performance speedup
+- shortcuts are now recognieced more accurate
+2. VCSA screen driver got support for UTF32 using /dev/vcsu (needs Linux >=4.19)
+3. Tutorial mode now creates more userfriendly output of the shortcuts
+4. faster word echo
+5. improved dynamic grab/ ungrab of devices
+6. custom dicts and emojis can now use regex when prefix with regex;
+Bugfixes and Cleanups
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..518049c
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,7 @@
+evdev>=1.1.2
+daemonize>=2.5.0
+dbus-python>=1.2.8
+pyudev>=0.21.0
+pexpect
+pyttsx3
+pyte>=0.7.0
diff --git a/setup.py b/setup.py
index ea1bb2e..61b6a49 100755
--- a/setup.py
+++ b/setup.py
@@ -6,10 +6,10 @@ from shutil import copyfile
 from setuptools import find_packages
 from setuptools import setup
 
-fenrirVersion = '1.9.3'
+fenrirVersion = '1.9.7'
 packageVersion = 'post1'
 
-# handle flags for package manager like yaourt and pacaur.
+# handle flags for package manager like aurman and pacaur.
 forceSettings = False
 if "--force-settings" in sys.argv:
     forceSettings = True
@@ -18,7 +18,7 @@ if "--force-settings" in sys.argv:
 data_files = []
 directories = glob.glob('config/*')
 for directory in directories:
-    files = glob.glob(directory+'/*') 
+    files = glob.glob(directory+'/*')
     destDir = ''
     if 'config/punctuation' in directory :
         destDir = '/etc/fenrirscreenreader/punctuation'
@@ -32,14 +32,14 @@ for directory in directories:
             except:
                 pass
     elif 'config/scripts' in directory:
-        destDir = '/usr/share/fenrirscreenreader/scripts' 
+        destDir = '/usr/share/fenrirscreenreader/scripts'
     if destDir != '':
         data_files.append((destDir, files))
 
-files = glob.glob('config/sound/default/*')                 
-destDir = '/usr/share/sounds/fenrirscreenreader/default'            
+files = glob.glob('config/sound/default/*')
+destDir = '/usr/share/sounds/fenrirscreenreader/default'
 data_files.append((destDir, files))
-files = glob.glob('config/sound//template/*')                 
+files = glob.glob('config/sound//template/*')
 destDir = '/usr/share/sounds/fenrirscreenreader/template'
 data_files.append((destDir, files))
 files = glob.glob('tools/*') 
@@ -57,18 +57,18 @@ setup(
     # description
     description="A TTY Screen Reader for Linux.",
     long_description=read('README.md'),
-    keywords=['screenreader', 'a11y', 'accessibility', 'terminal', 'TTY', 'console'],        
+    keywords=['screenreader', 'a11y', 'accessibility', 'terminal', 'TTY', 'console'],
     license="License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
     url="https://github.com/chrys87/fenrir/",
     download_url = 'https://github.com/chrys87/fenrir/archive/' + fenrirVersion + '.tar.gz',	
     classifiers=[
-        "Programming Language :: Python",        
-        "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",        
+        "Programming Language :: Python",
+        "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
         "Development Status :: 5 - Production/Stable",
         "Topic :: Multimedia :: Sound/Audio :: Speech",
-        "Environment :: Console",        
+        "Environment :: Console",
     ],
-    
+
     # Application author details:
     author="Chrys, Storm_dragon, Jeremiah and others",
     author_email="chrysg@linux-a11y.org",
@@ -83,19 +83,19 @@ setup(
     zip_safe=False,
 
     data_files=data_files,
-    
+
     # Dependent packages (distributions)
     install_requires=[
-        "evdev",
-        "daemonize",
-        "dbus-python",
-        "pyudev",
+        "evdev>=1.1.2",
+        "daemonize>=2.5.0",
+        "dbus-python>=1.2.8",
+        "pyudev>=0.21.0",
         "setuptools",
         "pexpect",
         "pyttsx3",
-        "pyte",
+        "pyte>=0.7.0",
     ],
-    
+
 )
 
 if not forceSettings:
diff --git a/src/fenrirscreenreader/brailleDriver/brlapiDriver.py b/src/fenrirscreenreader/brailleDriver/brlapiDriver.py
index 0958fa9..6961c62 100644
--- a/src/fenrirscreenreader/brailleDriver/brlapiDriver.py
+++ b/src/fenrirscreenreader/brailleDriver/brlapiDriver.py
@@ -16,11 +16,11 @@ class driver(brailleDriver):
         self.env = environment
         try:
             import brlapi
-            self._brl = brlapi.Connection()            
-            self._deviceSize = self._brl.displaySize           
+            self._brl = brlapi.Connection()
+            self._deviceSize = self._brl.displaySize
         except Exception as e:
             print(e)
-            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)                 
+            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
             return
         self._isInitialized = True
 
diff --git a/src/fenrirscreenreader/brailleDriver/debugDriver.py b/src/fenrirscreenreader/brailleDriver/debugDriver.py
index 116cd7d..f90f067 100644
--- a/src/fenrirscreenreader/brailleDriver/debugDriver.py
+++ b/src/fenrirscreenreader/brailleDriver/debugDriver.py
@@ -44,6 +44,6 @@ class driver(brailleDriver):
 
     def shutdown(self):
         if self._isInitialized:
-            self.leveScreen()    
-        self._isInitialized = False        
+            self.leveScreen()
+        self._isInitialized = False
         print('Braille Debug Driver: Shutdown')
diff --git a/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py b/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py
index d0dd515..5b0fdb9 100644
--- a/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py
+++ b/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py
@@ -31,7 +31,6 @@ class command():
     
     def run(self):
         if not initialized:
-           self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) 
            return
         if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
             try:
diff --git a/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py b/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py
index d6918a4..238ae87 100644
--- a/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py
+++ b/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py
@@ -19,6 +19,8 @@ class command():
     
     def run(self):
         lastEcho = self.env['runtime']['outputManager'].getLastEcho()
+        if lastEcho.rstrip() != "":
+            lastEcho = lastEcho.rstrip()
         self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', lastEcho)
         self.env['runtime']['outputManager'].presentText(lastEcho, soundIcon='CopyToClipboard', interrupt=True)
 
diff --git a/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py
new file mode 100644
index 0000000..19a264f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py
@@ -0,0 +1,26 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get current quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+        if menu != '':
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py
new file mode 100644
index 0000000..440d76f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py
@@ -0,0 +1,22 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get current quick menu value')
+    def run(self):
+        value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+        self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/cursor_position.py b/src/fenrirscreenreader/commands/commands/cursor_position.py
index bbb1208..1f123f8 100644
--- a/src/fenrirscreenreader/commands/commands/cursor_position.py
+++ b/src/fenrirscreenreader/commands/commands/cursor_position.py
@@ -20,7 +20,7 @@ class command():
         # Prefer review cursor over text cursor
         cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
 
-        self.env['runtime']['outputManager'].presentText(_("line {0}, column {1}").format(cursorPos['y']+1, cursorPos['x']+1), interrupt=True)
+        self.env['runtime']['outputManager'].presentText(_("line {0}, column {1}, Terminal {2}").format(cursorPos['y']+1, cursorPos['x']+1, self.env['screen']['newTTY']), interrupt=True)
    
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py b/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py
index 2b344bf..fba57a5 100644
--- a/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py
+++ b/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py
@@ -28,7 +28,7 @@ class command():
                 return 
             clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory')                               
             for display in range(10):
-                p = Popen('su ' + self.env['general']['currUser'] + ' -c  "echo -n \\\"' + clipboard.replace('"','\\\\\\"')  +'\\\" | xclip -d :' + str(display) + ' -selection c"' , stdout=PIPE, stderr=PIPE, shell=True)
+                p = Popen('su ' + self.env['general']['currUser'] + ' -c  "cat << \\\"EOF\\\" | xclip -d :' + str(display) + ' -selection clipboard\n' + clipboard + '\nEOF\n"', stdout=PIPE, stderr=PIPE, shell=True)
                 stdout, stderr = p.communicate()
                 self.env['runtime']['outputManager'].interruptOutput()
                 #screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
diff --git a/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py
new file mode 100644
index 0000000..bd5490b
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py
@@ -0,0 +1,29 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get next quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        if self.env['runtime']['quickMenuManager'].nextEntry():
+            menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+            if menu != '':
+                value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+                self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py
new file mode 100644
index 0000000..35e0c57
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get next quick menu value')
+    def run(self):
+        if self.env['runtime']['quickMenuManager'].nextValue():
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py
new file mode 100644
index 0000000..fa93d8b
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py
@@ -0,0 +1,29 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get previous quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        if self.env['runtime']['quickMenuManager'].prevEntry():
+            menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+            if menu != '':
+                value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+                self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py
new file mode 100644
index 0000000..6546cf2
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get previous quick menu value')
+    def run(self):
+        if self.env['runtime']['quickMenuManager'].prevValue():
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/save_settings.py b/src/fenrirscreenreader/commands/commands/save_settings.py
new file mode 100644
index 0000000..1e837eb
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/save_settings.py
@@ -0,0 +1,24 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.core import settingsManager
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return _('Saves your current Fenrir settings so they are the default.')
+    def run(self):
+        settingsFile = self.env['runtime']['settingsManager'].getSettingsFile()
+        self.env['runtime']['settingsManager'].saveSettings(settingsFile)
+        self.env['runtime']['outputManager'].presentText(_("Settings saved."), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/commands/temp_disable_speech.py b/src/fenrirscreenreader/commands/commands/temp_disable_speech.py
index da1701a..c63873d 100644
--- a/src/fenrirscreenreader/commands/commands/temp_disable_speech.py
+++ b/src/fenrirscreenreader/commands/commands/temp_disable_speech.py
@@ -17,11 +17,7 @@ class command():
         return _('disables speech until next keypress') 
     
     def run(self):
-        if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): 
-            self.env['runtime']['outputManager'].presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True)
-            self.env['commandBuffer']['enableSpeechOnKeypress'] = True
-            self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
-            self.env['runtime']['outputManager'].interruptOutput()            
+        self.env['runtime']['outputManager'].tempDisableSpeech()
                
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/commands/toggle_speech.py b/src/fenrirscreenreader/commands/commands/toggle_speech.py
index 9434875..a3d0b23 100644
--- a/src/fenrirscreenreader/commands/commands/toggle_speech.py
+++ b/src/fenrirscreenreader/commands/commands/toggle_speech.py
@@ -18,6 +18,7 @@ class command():
     
     def run(self):
         if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): 
+            self.env['runtime']['outputManager'].interruptOutput()
             self.env['runtime']['outputManager'].presentText(_('speech disabled'), soundIcon='SpeechOff', interrupt=True)
         self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))   
         if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): 
diff --git a/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py b/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py
index 1ac2eb3..2ce9853 100644
--- a/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py
+++ b/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py
@@ -14,11 +14,11 @@ class command():
     def shutdown(self):
         pass 
     def getDescription(self):
-        self.env['runtime']['helpManager'].toggleTutorialMode()            
-        #self.env['runtime']['outputManager'].presentText(,  interrupt=True)       
+        self.env['runtime']['helpManager'].toggleTutorialMode()
         return _('Exiting tutorial mode. To enter tutorial mode again press Fenrir+f1')
     def run(self):
-        self.env['runtime']['helpManager'].toggleTutorialMode()            
-        self.env['runtime']['outputManager'].presentText( _('Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1.'),  interrupt=True)                             
+        self.env['runtime']['helpManager'].toggleTutorialMode()
+        if self.env['runtime']['helpManager'].isTutorialMode():
+            self.env['runtime']['outputManager'].presentText( _('Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1.'),  interrupt=True)                             
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py b/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py
new file mode 100644
index 0000000..6888170
--- /dev/null
+++ b/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py
@@ -0,0 +1,26 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        self.env['runtime']['vmenuManager'].togglelVMenuMode()
+        return _('Entering or Leaving v menu mode.')
+    def run(self):
+        self.env['runtime']['vmenuManager'].togglelVMenuMode()
+        if self.env['runtime']['vmenuManager'].getActive():
+            self.env['runtime']['outputManager'].presentText( _('Entering v menu.'), interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText( _('Leaving v menu.'), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py b/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py
new file mode 100644
index 0000000..dd62c65
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py
@@ -0,0 +1,48 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+
+    def run(self):
+        # enabled?
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
+            return
+        # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now)
+        xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
+        if xMove > 3:
+            return
+        if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
+            if self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_TAB']]:
+                return 
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+            if self.env['runtime']['byteManager'].getLastByteKey() in [b'	', b'\t']:
+                return 
+        # detect deletion or chilling 
+        if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']:
+            return
+        # is there any change?
+        if not self.env['runtime']['screenManager'].isDelta():
+            return
+        # filter unneded space on word begin
+        currDelta = self.env['screen']['newDelta']
+        if len(currDelta.strip()) != len(currDelta) and \
+          currDelta.strip() != '':
+            currDelta = currDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py b/src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py
rename to src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py b/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py
new file mode 100644
index 0000000..1fe6722
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py
@@ -0,0 +1,133 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import os, string
+
+initialized = False
+try:
+    import enchant
+    initialized = True
+except:
+    pass
+    
+class command():
+    def __init__(self):
+        self.language = ''
+        self.spellChecker = ''
+    def initialize(self, environment):
+        self.env = environment
+        self.updateSpellLanguage()
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+      
+    def updateSpellLanguage(self):  
+        if not initialized:
+           return
+        self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
+        self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')      
+
+    def run(self):
+        if not initialized:
+            return        
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'):
+            return
+        if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
+            try:
+                self.updateSpellLanguage()
+            except:
+                return
+
+        # just when horizontal cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+            
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # more than a keyecho?
+        if len(self.env['screen']['newDelta']) > 1:
+            return            
+        # deletion
+        if self.env['runtime']['screenManager'].isNegativeDelta():
+            return             
+        # first place could not be the end of a word
+        if self.env['screen']['newCursor']['x'] == 0:
+            return
+            
+        # get the word (just for speedup only look at current line
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                  
+        # was this a typed word?
+        if self.env['runtime']['screenManager'].isDelta():
+            if not(newContent[self.env['screen']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['oldCursor']['x']):
+                return
+            else:
+                currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~')
+        else:
+        # or just arrow arround?
+            if not newContent[self.env['screen']['newCursor']['x']].isspace():
+                return
+            if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
+              (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
+                return  
+
+        # just on end of word
+        if self.env['screen']['newCursor']['x'] > 0:
+            if not newContent[self.env['screen']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase:
+                return
+        
+        # ignore bash buildins
+        if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\
+          'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']:
+            return
+        # ignore the application name
+        if currWord.upper() == 'FENRIR':
+            return       
+        if currWord[0] =='-':
+            return
+        if currWord[0] == '/':
+            return
+        if currWord[0] == '#':
+            return
+        if currWord.startswith('./'):
+            return               
+        if '@' in currWord and '.' in currWord:
+            return            
+        if currWord[0] == '@':
+            return            
+        if currWord.isnumeric():
+            return            
+        if currWord.isdecimal():
+            return
+        if currWord.isspace():
+            return
+  
+        try:
+            if os.path.exists("/bin/"+currWord):
+                return
+        except:
+            pass
+        try:
+            if os.path.exists("/usr/bin/"+currWord):
+                return            
+        except:
+            pass
+        try:
+            if os.path.exists("/sbin/"+currWord):
+                return            
+        except:
+            pass
+
+        if not self.spellChecker.check(currWord):
+            self.env['runtime']['outputManager'].presentText(_('misspelled'), soundIcon='mispell', interrupt=False, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/65000-char_delete_echo.py b/src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/65000-char_delete_echo.py
rename to src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py b/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py
new file mode 100644
index 0000000..a69f87c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py
@@ -0,0 +1,49 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+    def run(self):
+        # try to detect the tab completion by cursor change
+        xMove = self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']
+        if xMove <= 0:
+            return
+        if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
+            if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_TAB']]):
+                if xMove < 5:
+                    return 
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+            found = False
+            for currByte in self.env['runtime']['byteManager'].getLastByteKey():
+                if currByte == 9:
+                    found = True
+            if not found:
+                if xMove < 5:
+                    return 
+        # is there any change?
+        if not self.env['runtime']['screenManager'].isDelta():
+            return
+        if not xMove == len(self.env['screen']['newDelta']):
+            return
+        # filter unneded space on word begin
+        currDelta = self.env['screen']['newDelta']
+        if len(currDelta.strip()) != len(currDelta) and \
+          currDelta.strip() != '':
+            currDelta = currDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, announceCapital=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py b/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py
rename to src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/55000-present_line_if_cursor_change_vertical.py b/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/55000-present_line_if_cursor_change_vertical.py
rename to src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/77000-has_attribute.py b/src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/77000-has_attribute.py
rename to src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/66000-exit_review_mode.py b/src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/66000-exit_review_mode.py
rename to src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/45000-char_echo.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/45000-char_echo.py
similarity index 95%
rename from src/fenrirscreenreader/commands/onCursorChange/45000-char_echo.py
rename to src/fenrirscreenreader/commands/onCursorChange/orig_sorting/45000-char_echo.py
index 926d8eb..c4cd2ad 100644
--- a/src/fenrirscreenreader/commands/onCursorChange/45000-char_echo.py
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/45000-char_echo.py
@@ -20,7 +20,7 @@ class command():
         # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now)
         xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
         if xMove > 1:
-            return       
+            return
         if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
             return
         # detect deletion or chilling 
diff --git a/src/fenrirscreenreader/commands/onCursorChange/46000-tab_completion.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/46000-tab_completion.py
similarity index 100%
rename from src/fenrirscreenreader/commands/onCursorChange/46000-tab_completion.py
rename to src/fenrirscreenreader/commands/onCursorChange/orig_sorting/46000-tab_completion.py
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/50000-present_char_if_cursor_change_horizontal.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/50000-present_char_if_cursor_change_horizontal.py
new file mode 100644
index 0000000..ecd32a4
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/50000-present_char_if_cursor_change_horizontal.py
@@ -0,0 +1,51 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import char_utils
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return ''           
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
+            return        
+        if self.env['runtime']['screenManager'].isScreenChange():
+            return                 
+        # detect an change on the screen, we just want to cursor arround, so no change should appear
+        if self.env['runtime']['screenManager'].isDelta():
+            return
+        if self.env['runtime']['screenManager'].isNegativeDelta():
+            return
+        # is a vertical change?
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return                        
+        # is it a horizontal change?
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+       
+        # echo word insteed of char 
+        if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
+            if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) != 1:
+                # get the word            
+                newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+                x, y, currWord, endOfScreen, lineBreak = \
+                  word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) 
+                if self.env['screen']['newCursor']['x'] == x:
+                    return            
+        x, y, currChar = char_utils.getCurrentChar(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])     
+        if not currChar.isspace():
+            self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/55000-present_line_if_cursor_change_vertical.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/55000-present_line_if_cursor_change_vertical.py
new file mode 100644
index 0000000..5ccbd0c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/55000-present_line_if_cursor_change_vertical.py
@@ -0,0 +1,59 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import line_utils
+from fenrirscreenreader.utils import word_utils
+
+class command():
+    def __init__(self):
+        self.lastIdent = -1
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return ''        
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
+            return      
+        if self.env['runtime']['screenManager'].isScreenChange():
+            self.lastIdent = 0        
+            return        
+        # this leads to problems in vim -> status line change -> no announcement, so we do check the lengh as hack
+        if self.env['runtime']['screenManager'].isDelta():
+            return
+            
+        # is a vertical change?
+        if not self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return   
+       
+        x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])
+        if currLine.isspace():
+            self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
+        else:
+            # ident
+            currIdent = len(currLine) - len(currLine.lstrip())
+            if self.lastIdent == -1:
+                self.lastIdent = currIdent
+            doInterrupt = True                
+            if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'):
+                if self.lastIdent != currIdent: 
+                    self.env['runtime']['outputManager'].presentText(_('indented ') + str(currIdent) + ' ', interrupt=doInterrupt, flush=False)
+                    doInterrupt = False    
+            # barrier
+            sayLine = currLine        
+            if self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
+                isBarrier, barrierLine = self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
+                if isBarrier:
+                    sayLine = barrierLine
+            # output
+            self.env['runtime']['outputManager'].presentText(sayLine, interrupt=doInterrupt, flush=False)
+            self.lastIdent = currIdent
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/60000-word_echo_type.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/60000-word_echo_type.py
new file mode 100644
index 0000000..57a530f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/60000-word_echo_type.py
@@ -0,0 +1,58 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import string
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'     
+
+    def run(self):
+        # is it enabled?    
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
+            return
+        # is naviation?
+        if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1:
+            return
+        # just when cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # currently writing
+        if self.env['runtime']['screenManager'].isDelta():
+            return            
+        
+        # get the word            
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = \
+          word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                          
+        
+        # is there a word?        
+        if currWord == '':
+            return
+        # at the end of a word        
+        if not newContent[self.env['screen']['newCursor']['x']].isspace():
+            return
+        # at the end of a word        
+        if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
+          (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
+            return    
+
+        self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/61000-word_echo_navigation.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/61000-word_echo_navigation.py
new file mode 100644
index 0000000..08778ce
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/61000-word_echo_navigation.py
@@ -0,0 +1,54 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import string
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'     
+
+    def run(self):
+        # is navigation?    
+        if not abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) > 1:
+            return
+
+        # just when cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # currently writing
+        if self.env['runtime']['screenManager'].isDelta():
+            return            
+        
+        # get the word            
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = \
+          word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                          
+        
+        # is there a word?        
+        if currWord == '':
+            return
+
+        # at the start of a word        
+        if (x + len(currWord) != self.env['screen']['newCursor']['x'])  and \
+          (self.env['screen']['newCursor']['x'] != x):
+            return     
+
+        self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/62000-spell_check.py
similarity index 97%
rename from src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py
rename to src/fenrirscreenreader/commands/onCursorChange/orig_sorting/62000-spell_check.py
index 332e5f1..1fe6722 100644
--- a/src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/62000-spell_check.py
@@ -29,7 +29,6 @@ class command():
       
     def updateSpellLanguage(self):  
         if not initialized:
-           self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True) 
            return
         self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
         self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')      
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/65000-char_delete_echo.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/65000-char_delete_echo.py
new file mode 100644
index 0000000..4128131
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/65000-char_delete_echo.py
@@ -0,0 +1,46 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'        
+
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'):
+            return
+        # detect typing or chilling
+        if self.env['screen']['newCursor']['x'] >= self.env['screen']['oldCursor']['x']:
+            return 
+
+        # More than just a deletion happend
+        if self.env['runtime']['screenManager'].isDelta(ignoreSpace=True):
+            return
+
+        # no deletion
+        if not self.env['runtime']['screenManager'].isNegativeDelta():
+            return           
+
+        # too much for a single backspace...
+        # word begin produce a diff wiht len == 2 |a | others with 1 |a|
+        if len(self.env['screen']['newNegativeDelta']) > 2:
+            return
+                       
+        currNegativeDelta = self.env['screen']['newNegativeDelta']
+        if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \
+          currNegativeDelta.strip() != '':
+            currNegativeDelta = currNegativeDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/66000-exit_review_mode.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/66000-exit_review_mode.py
new file mode 100644
index 0000000..d934fb1
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/66000-exit_review_mode.py
@@ -0,0 +1,26 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('exits review mode')        
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnCursorChange'):
+            return        
+        if self.env['runtime']['cursorManager'].isReviewMode():
+            self.env['runtime']['cursorManager'].clearReviewCursor()
+   
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/77000-has_attribute.py b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/77000-has_attribute.py
new file mode 100644
index 0000000..b367875
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/orig_sorting/77000-has_attribute.py
@@ -0,0 +1,34 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import screen_utils
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return _('Reads attributes of current cursor position')         
+    def run(self):
+        # is it enabled?    
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'):
+            return    
+        # is a vertical change?
+        if not (self.env['runtime']['cursorManager'].isCursorVerticalMove() or\
+          self.env['runtime']['cursorManager'].isCursorHorizontalMove()):
+            return       
+
+        cursorPos = self.env['screen']['newCursor']
+        
+        if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos):
+            return
+        self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/15000-char_echo.py b/src/fenrirscreenreader/commands/onCursorChange/resort/15000-char_echo.py
new file mode 100644
index 0000000..c4cd2ad
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/15000-char_echo.py
@@ -0,0 +1,42 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+
+    def run(self):
+        # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now)
+        xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
+        if xMove > 1:
+            return
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
+            return
+        # detect deletion or chilling 
+        if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']:
+            return
+        # is there any change?
+        if not self.env['runtime']['screenManager'].isDelta():
+            return
+    
+        # filter unneded space on word begin
+        currDelta = self.env['screen']['newDelta']
+        if len(currDelta.strip()) != len(currDelta) and \
+          currDelta.strip() != '':
+            currDelta = currDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/25000-word_echo_type.py b/src/fenrirscreenreader/commands/onCursorChange/resort/25000-word_echo_type.py
new file mode 100644
index 0000000..57a530f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/25000-word_echo_type.py
@@ -0,0 +1,58 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import string
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'     
+
+    def run(self):
+        # is it enabled?    
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
+            return
+        # is naviation?
+        if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1:
+            return
+        # just when cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # currently writing
+        if self.env['runtime']['screenManager'].isDelta():
+            return            
+        
+        # get the word            
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = \
+          word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                          
+        
+        # is there a word?        
+        if currWord == '':
+            return
+        # at the end of a word        
+        if not newContent[self.env['screen']['newCursor']['x']].isspace():
+            return
+        # at the end of a word        
+        if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
+          (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
+            return    
+
+        self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/35000-spell_check.py b/src/fenrirscreenreader/commands/onCursorChange/resort/35000-spell_check.py
new file mode 100644
index 0000000..1fe6722
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/35000-spell_check.py
@@ -0,0 +1,133 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import os, string
+
+initialized = False
+try:
+    import enchant
+    initialized = True
+except:
+    pass
+    
+class command():
+    def __init__(self):
+        self.language = ''
+        self.spellChecker = ''
+    def initialize(self, environment):
+        self.env = environment
+        self.updateSpellLanguage()
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+      
+    def updateSpellLanguage(self):  
+        if not initialized:
+           return
+        self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
+        self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')      
+
+    def run(self):
+        if not initialized:
+            return        
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'):
+            return
+        if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
+            try:
+                self.updateSpellLanguage()
+            except:
+                return
+
+        # just when horizontal cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+            
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # more than a keyecho?
+        if len(self.env['screen']['newDelta']) > 1:
+            return            
+        # deletion
+        if self.env['runtime']['screenManager'].isNegativeDelta():
+            return             
+        # first place could not be the end of a word
+        if self.env['screen']['newCursor']['x'] == 0:
+            return
+            
+        # get the word (just for speedup only look at current line
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                  
+        # was this a typed word?
+        if self.env['runtime']['screenManager'].isDelta():
+            if not(newContent[self.env['screen']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['oldCursor']['x']):
+                return
+            else:
+                currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~')
+        else:
+        # or just arrow arround?
+            if not newContent[self.env['screen']['newCursor']['x']].isspace():
+                return
+            if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
+              (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
+                return  
+
+        # just on end of word
+        if self.env['screen']['newCursor']['x'] > 0:
+            if not newContent[self.env['screen']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase:
+                return
+        
+        # ignore bash buildins
+        if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\
+          'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']:
+            return
+        # ignore the application name
+        if currWord.upper() == 'FENRIR':
+            return       
+        if currWord[0] =='-':
+            return
+        if currWord[0] == '/':
+            return
+        if currWord[0] == '#':
+            return
+        if currWord.startswith('./'):
+            return               
+        if '@' in currWord and '.' in currWord:
+            return            
+        if currWord[0] == '@':
+            return            
+        if currWord.isnumeric():
+            return            
+        if currWord.isdecimal():
+            return
+        if currWord.isspace():
+            return
+  
+        try:
+            if os.path.exists("/bin/"+currWord):
+                return
+        except:
+            pass
+        try:
+            if os.path.exists("/usr/bin/"+currWord):
+                return            
+        except:
+            pass
+        try:
+            if os.path.exists("/sbin/"+currWord):
+                return            
+        except:
+            pass
+
+        if not self.spellChecker.check(currWord):
+            self.env['runtime']['outputManager'].presentText(_('misspelled'), soundIcon='mispell', interrupt=False, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/45000-char_delete_echo.py b/src/fenrirscreenreader/commands/onCursorChange/resort/45000-char_delete_echo.py
new file mode 100644
index 0000000..4128131
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/45000-char_delete_echo.py
@@ -0,0 +1,46 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'        
+
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'):
+            return
+        # detect typing or chilling
+        if self.env['screen']['newCursor']['x'] >= self.env['screen']['oldCursor']['x']:
+            return 
+
+        # More than just a deletion happend
+        if self.env['runtime']['screenManager'].isDelta(ignoreSpace=True):
+            return
+
+        # no deletion
+        if not self.env['runtime']['screenManager'].isNegativeDelta():
+            return           
+
+        # too much for a single backspace...
+        # word begin produce a diff wiht len == 2 |a | others with 1 |a|
+        if len(self.env['screen']['newNegativeDelta']) > 2:
+            return
+                       
+        currNegativeDelta = self.env['screen']['newNegativeDelta']
+        if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \
+          currNegativeDelta.strip() != '':
+            currNegativeDelta = currNegativeDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/50000-present_char_if_cursor_change_horizontal.py b/src/fenrirscreenreader/commands/onCursorChange/resort/50000-present_char_if_cursor_change_horizontal.py
new file mode 100644
index 0000000..ecd32a4
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/50000-present_char_if_cursor_change_horizontal.py
@@ -0,0 +1,51 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import char_utils
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return ''           
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
+            return        
+        if self.env['runtime']['screenManager'].isScreenChange():
+            return                 
+        # detect an change on the screen, we just want to cursor arround, so no change should appear
+        if self.env['runtime']['screenManager'].isDelta():
+            return
+        if self.env['runtime']['screenManager'].isNegativeDelta():
+            return
+        # is a vertical change?
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return                        
+        # is it a horizontal change?
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+       
+        # echo word insteed of char 
+        if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
+            if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) != 1:
+                # get the word            
+                newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+                x, y, currWord, endOfScreen, lineBreak = \
+                  word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) 
+                if self.env['screen']['newCursor']['x'] == x:
+                    return            
+        x, y, currChar = char_utils.getCurrentChar(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])     
+        if not currChar.isspace():
+            self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/55000-tab_completion.py b/src/fenrirscreenreader/commands/onCursorChange/resort/55000-tab_completion.py
new file mode 100644
index 0000000..43b9115
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/55000-tab_completion.py
@@ -0,0 +1,42 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'
+
+    def run(self):
+        # try to detect the tab completion by cursor change
+        xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
+        if xMove == 1:
+            return
+        # is there any change?
+        if not self.env['runtime']['screenManager'].isDelta():
+            return            
+        if not( (xMove > 1) and xMove == len(self.env['screen']['newDelta'])):
+            return                 
+        # detect deletion or chilling 
+        if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']:
+            return
+        
+        # filter unneded space on word begin
+        currDelta = self.env['screen']['newDelta']
+        if len(currDelta.strip()) != len(currDelta) and \
+          currDelta.strip() != '':
+            currDelta = currDelta.strip()
+        self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, announceCapital=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/60000-word_echo_navigation.py b/src/fenrirscreenreader/commands/onCursorChange/resort/60000-word_echo_navigation.py
new file mode 100644
index 0000000..08778ce
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/60000-word_echo_navigation.py
@@ -0,0 +1,54 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import word_utils
+import string
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No Description found'     
+
+    def run(self):
+        # is navigation?    
+        if not abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) > 1:
+            return
+
+        # just when cursor move worddetection is needed
+        if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
+            return
+        # for now no new line
+        if self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return
+        # currently writing
+        if self.env['runtime']['screenManager'].isDelta():
+            return            
+        
+        # get the word            
+        newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
+        x, y, currWord, endOfScreen, lineBreak = \
+          word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)                          
+        
+        # is there a word?        
+        if currWord == '':
+            return
+
+        # at the start of a word        
+        if (x + len(currWord) != self.env['screen']['newCursor']['x'])  and \
+          (self.env['screen']['newCursor']['x'] != x):
+            return     
+
+        self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
+
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/65000-present_line_if_cursor_change_vertical.py b/src/fenrirscreenreader/commands/onCursorChange/resort/65000-present_line_if_cursor_change_vertical.py
new file mode 100644
index 0000000..5ccbd0c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/65000-present_line_if_cursor_change_vertical.py
@@ -0,0 +1,59 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import line_utils
+from fenrirscreenreader.utils import word_utils
+
+class command():
+    def __init__(self):
+        self.lastIdent = -1
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return ''        
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
+            return      
+        if self.env['runtime']['screenManager'].isScreenChange():
+            self.lastIdent = 0        
+            return        
+        # this leads to problems in vim -> status line change -> no announcement, so we do check the lengh as hack
+        if self.env['runtime']['screenManager'].isDelta():
+            return
+            
+        # is a vertical change?
+        if not self.env['runtime']['cursorManager'].isCursorVerticalMove():
+            return   
+       
+        x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])
+        if currLine.isspace():
+            self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
+        else:
+            # ident
+            currIdent = len(currLine) - len(currLine.lstrip())
+            if self.lastIdent == -1:
+                self.lastIdent = currIdent
+            doInterrupt = True                
+            if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'):
+                if self.lastIdent != currIdent: 
+                    self.env['runtime']['outputManager'].presentText(_('indented ') + str(currIdent) + ' ', interrupt=doInterrupt, flush=False)
+                    doInterrupt = False    
+            # barrier
+            sayLine = currLine        
+            if self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
+                isBarrier, barrierLine = self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
+                if isBarrier:
+                    sayLine = barrierLine
+            # output
+            self.env['runtime']['outputManager'].presentText(sayLine, interrupt=doInterrupt, flush=False)
+            self.lastIdent = currIdent
+    def setCallback(self, callback):
+        pass
+
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/85000-has_attribute.py b/src/fenrirscreenreader/commands/onCursorChange/resort/85000-has_attribute.py
new file mode 100644
index 0000000..b367875
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/85000-has_attribute.py
@@ -0,0 +1,34 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import screen_utils
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return _('Reads attributes of current cursor position')         
+    def run(self):
+        # is it enabled?    
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'):
+            return    
+        # is a vertical change?
+        if not (self.env['runtime']['cursorManager'].isCursorVerticalMove() or\
+          self.env['runtime']['cursorManager'].isCursorHorizontalMove()):
+            return       
+
+        cursorPos = self.env['screen']['newCursor']
+        
+        if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos):
+            return
+        self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onCursorChange/resort/95000-exit_review_mode.py b/src/fenrirscreenreader/commands/onCursorChange/resort/95000-exit_review_mode.py
new file mode 100644
index 0000000..d934fb1
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onCursorChange/resort/95000-exit_review_mode.py
@@ -0,0 +1,26 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('exits review mode')        
+    
+    def run(self):
+        if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnCursorChange'):
+            return        
+        if self.env['runtime']['cursorManager'].isReviewMode():
+            self.env['runtime']['cursorManager'].clearReviewCursor()
+   
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py b/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py
new file mode 100644
index 0000000..f995a87
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'
+    def run(self):
+        if self.env['runtime']['helpManager'].isTutorialMode():
+            self.env['runtime']['inputManager'].keyEcho()
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py b/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py
new file mode 100755
index 0000000..d01fd39
--- /dev/null
+++ b/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py
@@ -0,0 +1,34 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+import time
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+        self.lastTime = time.time()
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'
+    def run(self):
+        playSound = False
+        deviceList = self.env['runtime']['inputManager'].getLastDetectedDevices()
+        try:
+            for deviceEntry in deviceList:
+            # dont play sounds for virtual devices
+                playSound = playSound or not deviceEntry['virtual']
+        except:
+            playSound = True
+        if playSound:
+            if time.time() - self.lastTime > 5:
+                self.env['runtime']['outputManager'].playSoundIcon(soundIcon = 'accept', interrupt=True)
+                lastTime = time.time()
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py b/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py
index 1937acf..2363463 100644
--- a/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py
+++ b/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py
@@ -13,13 +13,11 @@ class command():
     def shutdown(self):
         pass 
     def getDescription(self):
-        return _('enables or disables tracking of highlighted')        
-    
+        return _('enables or disables tracking of highlighted')
     def run(self):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
             return
         attributeDelta = self.env['runtime']['attributeManager'].getAttributeDelta()
-        self.env['runtime']['outputManager'].presentText(attributeDelta, soundIcon='', interrupt=True, flush=False)                          
-    
+        self.env['runtime']['outputManager'].presentText(attributeDelta, soundIcon='', interrupt=True, flush=False)
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py b/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py
index 8433283..d94d033 100644
--- a/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py
+++ b/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py
@@ -14,7 +14,7 @@ class command():
     def shutdown(self):
         pass
     def getDescription(self):
-        return ''        
+        return ''
     def run(self):
         if self.env['screen']['newAttribDelta'] != '':
             return  
@@ -31,15 +31,15 @@ class command():
         if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
             if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_UP'],['KEY_DOWN']]):
                 return 
-        if self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
             if not (self.env['runtime']['byteManager'].getLastByteKey() in [b'^[[A',b'^[[B']):
                 return 
-                
+
         prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
-        currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]            
+        currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
         if prevLine == currLine:
             if self.env['screen']['newDelta'] != '':
-                return         
+                return
         if not currLine.isspace():
             currPrompt = currLine.find('$')
             rootPrompt = currLine.find('#')
@@ -47,17 +47,17 @@ class command():
                 if rootPrompt > 0:
                     currPrompt = rootPrompt
                 else:
-                    announce = currLine            
+                    announce = currLine
             if currPrompt > 0:
                 remove_digits = str.maketrans('0123456789', '          ')
                 if prevLine[:currPrompt].translate(remove_digits) == currLine[:currPrompt].translate(remove_digits):
                     announce = currLine[currPrompt+1:]
                 else:
-                    announce = currLine                      
+                    announce = currLine
 
         if currLine.isspace():
             self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
-        else:            
+        else:
             self.env['runtime']['outputManager'].presentText(announce, interrupt=True, flush=False)
         self.env['commandsIgnore']['onScreenUpdate']['CHAR_DELETE_ECHO'] = True
         self.env['commandsIgnore']['onScreenUpdate']['CHAR_ECHO'] = True
diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py
index cc2bc39..e790b2d 100644
--- a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py
+++ b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py
@@ -14,16 +14,16 @@ class command():
     def shutdown(self):
         pass
     def getDescription(self):
-        return 'No Description found'      
+        return 'No Description found'
 
     def run(self):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'):
             return
         # is there something to read?
         if not self.env['runtime']['screenManager'].isDelta(ignoreSpace=True):
-            return      
-        
-        # this must be a keyecho or something      
+            return
+
+        # this must be a keyecho or something
         #if len(self.env['screen']['newDelta'].strip(' \n\t')) <= 1:
         xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
         yMove = abs(self.env['screen']['newCursor']['y'] - self.env['screen']['oldCursor']['y'])
@@ -31,7 +31,7 @@ class command():
         if (xMove >= 1) and xMove == len(self.env['screen']['newDelta']):
         # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2:
             if not '\n' in self.env['screen']['newDelta']:
-                return          
+                return
         #print(xMove, yMove, len(self.env['screen']['newDelta']), len(self.env['screen']['newNegativeDelta']))
         self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=False, flush=False)
 
diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py b/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py
index ed3027d..66d8403 100644
--- a/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py
+++ b/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py
@@ -15,8 +15,7 @@ class command():
     def shutdown(self):
         pass
     def getDescription(self):
-        return 'No Description found'     
-
+        return 'No Description found'
     def run(self):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('promote', 'enabled'):
             return
@@ -25,13 +24,12 @@ class command():
         if int(time.time() - self.env['input']['lastInputTime']) < self.env['runtime']['settingsManager'].getSettingAsInt('promote', 'inactiveTimeoutSec'):
             return
         if len(self.env['runtime']['settingsManager'].getSetting('promote', 'list')) == 0:
-            return       
+            return
         for promote in self.env['runtime']['settingsManager'].getSetting('promote', 'list').split(','):
             if promote in self.env['screen']['newDelta']:    
-                self.env['runtime']['outputManager'].playSoundIcon('PromotedText')        
+                self.env['runtime']['outputManager'].playSoundIcon('PromotedText')
                 self.env['input']['lastInputTime'] = time.time()
                 return
-
     def setCallback(self, callback):
         pass
 
diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py b/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py
index 87d119b..207ed4a 100644
--- a/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py
+++ b/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py
@@ -14,16 +14,13 @@ class command():
     def shutdown(self):
         pass
     def getDescription(self):
-        return 'No Description found'      
-
+        return 'No Description found'
     def run(self):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'):
             return
         if not self.env['runtime']['screenManager'].isDelta(ignoreSpace=True):
-            return      
-
+            return
         self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y'])
-
     def setCallback(self, callback):
         pass
 
diff --git a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py
new file mode 100644
index 0000000..19a264f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py
@@ -0,0 +1,26 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get current quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+        if menu != '':
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py
new file mode 100644
index 0000000..440d76f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py
@@ -0,0 +1,22 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get current quick menu value')
+    def run(self):
+        value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+        self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py
new file mode 100644
index 0000000..bd5490b
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py
@@ -0,0 +1,29 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get next quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        if self.env['runtime']['quickMenuManager'].nextEntry():
+            menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+            if menu != '':
+                value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+                self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py
new file mode 100644
index 0000000..35e0c57
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get next quick menu value')
+    def run(self):
+        if self.env['runtime']['quickMenuManager'].nextValue():
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py
new file mode 100644
index 0000000..fa93d8b
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py
@@ -0,0 +1,29 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get previous quick menu entry')
+    def run(self):
+        menu = ''
+        value = ''
+        if self.env['runtime']['quickMenuManager'].prevEntry():
+            menu = self.env['runtime']['quickMenuManager'].getCurrentEntry()
+            if menu != '':
+                value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+                self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py
new file mode 100644
index 0000000..6546cf2
--- /dev/null
+++ b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get previous quick menu value')
+    def run(self):
+        if self.env['runtime']['quickMenuManager'].prevValue():
+            value = self.env['runtime']['quickMenuManager'].getCurrentValue()
+            self.env['runtime']['outputManager'].presentText(value, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/sayAll/__init__.py b/src/fenrirscreenreader/commands/sayAll/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/__init__.py b/src/fenrirscreenreader/commands/vmenu-navigation/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py
new file mode 100644
index 0000000..140d32e
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py
@@ -0,0 +1,22 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get current v menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].getCurrentEntry()
+        self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py
new file mode 100644
index 0000000..67c41b9
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('leave v menu submenu')
+    def run(self):
+        self.env['runtime']['vmenuManager'].decLevel()
+        text = self.env['runtime']['vmenuManager'].getCurrentEntry()
+        self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py
new file mode 100644
index 0000000..af32cb5
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('execute v menu entry')
+    def run(self):
+        self.env['runtime']['vmenuManager'].executeMenu()
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py
new file mode 100644
index 0000000..342a215
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('enter v menu submenu')
+    def run(self):
+        self.env['runtime']['vmenuManager'].incLevel()
+        text = self.env['runtime']['vmenuManager'].getCurrentEntry()
+        self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py
new file mode 100644
index 0000000..8eb1d40
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get next v menu entry')
+    def run(self):
+        self.env['runtime']['vmenuManager'].nextIndex()
+        text = self.env['runtime']['vmenuManager'].getCurrentEntry()
+        self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py
new file mode 100644
index 0000000..2a9ee97
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py
@@ -0,0 +1,23 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('get prev v menu entry')
+    def run(self):
+        self.env['runtime']['vmenuManager'].prevIndex()
+        text = self.env['runtime']['vmenuManager'].getCurrentEntry()
+        self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py
new file mode 100644
index 0000000..7e4236c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('a')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py
new file mode 100644
index 0000000..5da6a56
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('b')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py
new file mode 100644
index 0000000..1634540
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('c')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py
new file mode 100644
index 0000000..d77b6c1
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('d')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py
new file mode 100644
index 0000000..c0b35e0
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('e')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py
new file mode 100644
index 0000000..cc37e45
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('f')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py
new file mode 100644
index 0000000..fc23572
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('g')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py
new file mode 100644
index 0000000..10fc5fb
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('h')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py
new file mode 100644
index 0000000..e616fbf
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('i')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py
new file mode 100644
index 0000000..92c716c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('j')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py
new file mode 100644
index 0000000..3ced6b7
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('k')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py
new file mode 100644
index 0000000..75e81c1
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('l')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py
new file mode 100644
index 0000000..d143ac7
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('m')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py
new file mode 100644
index 0000000..9ed32f6
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('n')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py
new file mode 100644
index 0000000..b281757
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('o')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py
new file mode 100644
index 0000000..7f5d002
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('p')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py
new file mode 100644
index 0000000..ad0dcdb
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('q')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py
new file mode 100644
index 0000000..43cd84a
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('r')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py
new file mode 100644
index 0000000..22a9b5d
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('s')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py
new file mode 100644
index 0000000..7dbb981
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('t')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py
new file mode 100644
index 0000000..3a4bb39
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('u')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py
new file mode 100644
index 0000000..26a6e16
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('v')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py
new file mode 100644
index 0000000..7e4236c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('a')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py
new file mode 100644
index 0000000..0c45a9f
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('x')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py
new file mode 100644
index 0000000..2656a31
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('y')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py
new file mode 100644
index 0000000..32714e1
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('search for an menu entry')
+    def run(self):
+        text = self.env['runtime']['vmenuManager'].searchEntry('z')
+        if text != '':
+            self.env['runtime']['outputManager'].presentText(text, interrupt=True)
+        else:
+            self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/BYTE/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/BYTE/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/onPlugInputDevice/80000-plugSound.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py
old mode 100755
new mode 100644
similarity index 64%
rename from src/fenrirscreenreader/commands/onPlugInputDevice/80000-plugSound.py
rename to src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py
index 34a6dac..63f33aa
--- a/src/fenrirscreenreader/commands/onPlugInputDevice/80000-plugSound.py
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py
@@ -5,21 +5,17 @@
 # By Chrys, Storm Dragon, and contributers.
 
 from fenrirscreenreader.core import debug
-import time
 
 class command():
     def __init__(self):
         pass
     def initialize(self, environment):
         self.env = environment
-        self.lastTime = time.time()
     def shutdown(self):
         pass
     def getDescription(self):
         return 'No description found'         
     def run(self):
-        if time.time() - self.lastTime > 2:
-            self.env['runtime']['outputManager'].playSoundIcon(soundIcon = 'accept', interrupt=True)     
-            lastTime = time.time()
+        self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True)
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/onPlugInputDevice/50000-UpdateDevices.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py
old mode 100755
new mode 100644
similarity index 79%
rename from src/fenrirscreenreader/commands/onPlugInputDevice/50000-UpdateDevices.py
rename to src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py
index 9d0c067..33c5f26
--- a/src/fenrirscreenreader/commands/onPlugInputDevice/50000-UpdateDevices.py
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py
@@ -16,7 +16,6 @@ class command():
     def getDescription(self):
         return 'No description found'         
     def run(self):
-        pass
-        #self.env['runtime']['inputManager'].updateInputDevices()
+        self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True)
     def setCallback(self, callback):
         pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py
new file mode 100644
index 0000000..57f2f91
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py
new file mode 100644
index 0000000..d4e2d8c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py
new file mode 100644
index 0000000..e754a03
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py
@@ -0,0 +1,30 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+import datetime
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('presents the date')        
+    
+    def run(self):
+        dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
+
+        # get the time formatted
+        dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat)
+
+        # present the time via speak and braile, there is no soundicon, interrupt the current speech
+        self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py
new file mode 100644
index 0000000..fa0ab1c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py
@@ -0,0 +1,25 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+        self.keyMakro = [[1, 'KEY_LEFTCTRL'], [1, 'KEY_G'], [0.05,'sleep'] ,[0, 'KEY_G'], [0, 'KEY_LEFTCTRL']]
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['inputManager'].sendKeys(self.keyMakro)
+    def setCallback(self, callback):
+        pass
+
+
+
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py
new file mode 100644
index 0000000..57efa97
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py
@@ -0,0 +1,22 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+        self.macro = [[1,'KEY_LEFTSHIFT'],[1,'KEY_LEFTCTRL'],[1,'KEY_N'],[0.05,'SLEEP'],[0,'KEY_N'],[0,'KEY_LEFTCTRL'],[0,'KEY_LEFTSHIFT']]
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['inputManager'].sendKeys(self.macro)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py
new file mode 100644
index 0000000..33c5f26
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py
new file mode 100644
index 0000000..57f2f91
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py
new file mode 100644
index 0000000..d4e2d8c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py
new file mode 100644
index 0000000..e754a03
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py
@@ -0,0 +1,30 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+import datetime
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('presents the date')        
+    
+    def run(self):
+        dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
+
+        # get the time formatted
+        dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat)
+
+        # present the time via speak and braile, there is no soundicon, interrupt the current speech
+        self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py
new file mode 100755
index 0000000..a293a07
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8
+from fenrirscreenreader.core import debug
+
+
+class command():
+    def __init__(self):
+        pass
+
+    def initialize(self, environment):
+        self.env = environment
+        self.keyMakro = [[1, 'KEY_LEFTCTRL'],
+                         [1, 'KEY_G'],
+                         [0.05, 'SLEEP'],
+                         [0, 'KEY_G'],
+                         [0, 'KEY_LEFTCTRL']]
+
+    def shutdown(self):
+        pass
+
+    def getDescription(self):
+        return "Learn about the Nano text editor."
+
+    def run(self):
+        self.env['runtime']['outputManager'].presentText(
+            "Okay, loading the information about Nano.", interrupt=True)
+        if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
+            self.env['runtime']['inputManager'].sendKeys(self.keyMakro)
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+            self.env['runtime']['byteManager'].sendBytes(self.byteMakro)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py
new file mode 100644
index 0000000..63f33aa
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py
new file mode 100755
index 0000000..8a2f922
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8
+from fenrirscreenreader.core import debug
+
+
+class command():
+    def __init__(self):
+        pass
+
+    def initialize(self, environment):
+        self.env = environment
+        self.keyMakro = [[1, 'KEY_LEFTCTRL'],
+                         [1, 'KEY_S'],
+                         [0.05, 'SLEEP'],
+                         [0, 'KEY_S'],
+                         [0, 'KEY_LEFTCTRL']]
+
+    def shutdown(self):
+        pass
+
+    def getDescription(self):
+        return "Save your work."
+
+    def run(self):
+        self.env['runtime']['outputManager'].presentText(
+            "Okay, you will now be asked to save your work.", interrupt=True)
+        if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
+            self.env['runtime']['inputManager'].sendKeys(self.keyMakro)
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+            self.env['runtime']['byteManager'].sendBytes(self.byteMakro)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py
new file mode 100644
index 0000000..57f2f91
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py
new file mode 100644
index 0000000..d4e2d8c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py
new file mode 100644
index 0000000..e754a03
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py
@@ -0,0 +1,30 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+import datetime
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('presents the date')        
+    
+    def run(self):
+        dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
+
+        # get the time formatted
+        dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat)
+
+        # present the time via speak and braile, there is no soundicon, interrupt the current speech
+        self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py
new file mode 100644
index 0000000..63f33aa
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py
new file mode 100644
index 0000000..33c5f26
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py
new file mode 100644
index 0000000..57f2f91
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py
new file mode 100644
index 0000000..d4e2d8c
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py
@@ -0,0 +1,21 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py
new file mode 100644
index 0000000..e754a03
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py
@@ -0,0 +1,30 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+import datetime
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+    def shutdown(self):
+        pass 
+    def getDescription(self):
+        return _('presents the date')        
+    
+    def run(self):
+        dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
+
+        # get the time formatted
+        dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat)
+
+        # present the time via speak and braile, there is no soundicon, interrupt the current speech
+        self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True)
+
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/__init__.py
new file mode 100755
index 0000000..e69de29
diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/template.py b/src/fenrirscreenreader/commands/vmenu-profiles/template.py
new file mode 100644
index 0000000..253e249
--- /dev/null
+++ b/src/fenrirscreenreader/commands/vmenu-profiles/template.py
@@ -0,0 +1,29 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+
+class command():
+    def __init__(self):
+        pass
+    def initialize(self, environment):
+        self.env = environment
+        # examples:
+        # self.keyMakro = [[1,'KEY_LEFTCTRL'],[1,'KEY_O'],[0.05,'SLEEP'],[0,'KEY_O'],[0,'KEY_LEFTCTRL']]
+        # self.keyMakro = [[1,'KEY_LEFTSHIFT'],[1,'KEY_LEFTCTRL'],[1,'KEY_N'],[0.05,'SLEEP'],[0,'KEY_N'],[0,'KEY_LEFTCTRL'],[0,'KEY_LEFTSHIFT']]
+        self.keyMakro = []
+        self.byteMakro = []
+    def shutdown(self):
+        pass
+    def getDescription(self):
+        return 'No description found'         
+    def run(self):
+        if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']:
+            self.env['runtime']['inputManager'].sendKeys(self.keyMakro)
+        elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']:
+            self.env['runtime']['byteManager'].sendBytes(self.byteMakro)
+    def setCallback(self, callback):
+        pass
diff --git a/src/fenrirscreenreader/core/attributeManager.py b/src/fenrirscreenreader/core/attributeManager.py
index 986ab4e..3b3cf7e 100644
--- a/src/fenrirscreenreader/core/attributeManager.py
+++ b/src/fenrirscreenreader/core/attributeManager.py
@@ -14,20 +14,20 @@ class attributeManager():
         self.currAttributeDelta = ''
         self.currAttributeCursor = None
         self.prefAttributeCursor = None
-        self.initDefaultAttributes()    
-        self.prevLastCursorAttribute = None            
-        self.currLastCursorAttribute = None            
-        
+        self.initDefaultAttributes()
+        self.prevLastCursorAttribute = None
+        self.currLastCursorAttribute = None
+
     def initialize(self, environment):
-        self.env = environment  
+        self.env = environment
     def shutdown(self):
         pass
     def setLastCursorAttribute(self, lastCursorAttribute):
         self.prevLastCursorAttribute = self.currLastCursorAttribute
-        self.currLastCursorAttribute = lastCursorAttribute     
-    def resetLastCursorAttribute(self, lastCursorAttribute):
+        self.currLastCursorAttribute = lastCursorAttribute
+    def resetLastCursorAttribute(self):
         self.prevLastCursorAttribute = None
-        self.currLastCursorAttribute = None   
+        self.currLastCursorAttribute = None
     def isLastCursorAttributeChange(self):
         if self.prevLastCursorAttribute == None:
             return False
@@ -43,32 +43,33 @@ class attributeManager():
     def resetAttributeAll(self):
         self.resetAttributeDelta()
         self.resetAttributeCursor()
-    def getAttributeDelta(self):       
-        return self.currAttributeDelta        
+    def getAttributeDelta(self):
+        return self.currAttributeDelta
     def resetAttributeDelta(self):
-        self.currAttributeDelta = ''    
-    def setAttributeDelta(self, currAttributeDelta):       
+        self.currAttributeDelta = ''
+    def setAttributeDelta(self, currAttributeDelta):
         self.currAttributeDelta = currAttributeDelta
     def resetAttributeCursor(self):
         self.currAttributeCursor = None
         self.prefAttributeCursor = None
     def setAttributeCursor(self, currAttributeCursor):
-        self.prefAttributeCursor = self.currAttributeCursor        
+        self.prefAttributeCursor = self.currAttributeCursor
         self.currAttributeCursor = currAttributeCursor.copy()
     def resetAttributes(self, currAttributes):
-        self.prevAttributes = None                                    
-        self.currAttributes = currAttributes        
+        self.prevAttributes = None
+        self.currAttributes = currAttributes
     def setAttributes(self, currAttributes):
-        self.prevAttributes = self.currAttributes                                    
+        self.prevAttributes = self.currAttributes
         self.currAttributes = currAttributes.copy()
+
     def getAttributeByXY(self, x, y):
         if not self.currAttributes:
             return None
         if len(self.currAttributes) < y:
             return None
         if len(self.currAttributes[y]) < x - 1:
-            return None    
-        try:    
+            return None
+        try:
             return self.currAttributes[y][x]
         except KeyError:
             try:
@@ -81,7 +82,7 @@ class attributeManager():
             return
         if len(attribute) != 10:
             return
-        self.defaultAttributes.append(attribute)     
+        self.defaultAttributes.append(attribute)
     def initDefaultAttributes(self):
         self.defaultAttributes = [None]
         self.defaultAttributes.append([
@@ -95,7 +96,7 @@ class attributeManager():
             False, # blink
             'default', # fontsize
             'default' # fontfamily
-        ]) #end attribute              
+        ]) #end attribute
     def isDefaultAttribute(self,attribute):
         return attribute in self.defaultAttributes
     def hasAttributes(self, cursor, update=True):
@@ -106,7 +107,7 @@ class attributeManager():
             attribute = self.getAttributeByXY( cursorPos['x'], cursorPos['y'])
             
             if update:
-                self.setLastCursorAttribute(attribute)            
+                self.setLastCursorAttribute(attribute)
             if not self.isLastCursorAttributeChange():
                 return False
 
@@ -134,10 +135,10 @@ class attributeManager():
         # "italics",
         # "underscore",
         # "strikethrough",
-        # "reverse",  
-        # "blink"   
+        # "reverse",
+        # "blink"
         # "fontsieze"
-        # "fontfamily" 
+        # "fontfamily"
         if attributeFormatString == '':
             attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString')
         if not attributeFormatString:
@@ -148,7 +149,7 @@ class attributeManager():
             return ''
         if len(attribute) != 10:
             return ''
-        
+
         # 0 FG color (name)
         try:
             attributeFormatString = attributeFormatString.replace('fenrirFGColor', _(attribute[0]))
@@ -169,9 +170,9 @@ class attributeManager():
             pass
         attributeFormatString = attributeFormatString.replace('fenrirBold', '')
         
-        # 3 italics (True/ False)                                       
+        # 3 italics (True/ False)
         try:
-            if attribute[3]:        
+            if attribute[3]:
                 attributeFormatString = attributeFormatString.replace('fenrirItalics', _('italic'))
         except Exception as e:
             pass
@@ -195,15 +196,15 @@ class attributeManager():
         
         # 6 reverse (True/ False)
         try:
-            if attribute[6]:        
+            if attribute[6]:
                 attributeFormatString = attributeFormatString.replace('fenrirReverse', _('reverse'))
         except Exception as e:
             pass
         attributeFormatString = attributeFormatString.replace('fenrirReverse', '')
         
-        # 7 blink (True/ False)     
+        # 7 blink (True/ False)
         try:
-            if attribute[7]:        
+            if attribute[7]:
                 attributeFormatString = attributeFormatString.replace('fenrirBlink', _('blink'))
         except Exception as e:
             pass
@@ -236,16 +237,16 @@ class attributeManager():
         currCursor = None
         # screen change
         if self.prevAttributes == None:
-            return result,  currCursor                
+            return result,  currCursor
         # no change
         if self.prevAttributes == self.currAttributes:
             return result,  currCursor
         # error case
         if self.currAttributes == None:
-            return result,  currCursor                  
+            return result,  currCursor
         # special case for pty if not text exists.
         if len(self.currAttributes) == 0:
-            return result,  currCursor        
+            return result,  currCursor
         text = self.env['runtime']['screenManager'].getScreenText()
         textLines = text.split('\n')
 
@@ -268,7 +269,7 @@ class attributeManager():
         if line < 0:
             return False   
         if line > len(currAttributes):
-            return False                     
+            return False
         useful = False
         if mode == 'default':
             # non default tracking
@@ -278,12 +279,12 @@ class attributeManager():
             if line == 0:
                 useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line + 2][column][attribute])
             elif line >= len(prevAttributes):
-                useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute])        
+                useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute])
             else:
-                useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute])         
+                useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute])
         elif mode == 'barrier':
             # to be implement
             useful = True
-            
+
         return useful
         
diff --git a/src/fenrirscreenreader/core/barrierManager.py b/src/fenrirscreenreader/core/barrierManager.py
index fa4c2d6..aaa115b 100644
--- a/src/fenrirscreenreader/core/barrierManager.py
+++ b/src/fenrirscreenreader/core/barrierManager.py
@@ -41,37 +41,8 @@ class barrierManager():
                 
         if not isBarrier:
             sayLine = ''   
-        return isBarrier, sayLine               
-              
-    def hasBorder(self, text, xCursor, yCursor, validBorder, barrierPos):
-        # check for corners here
-        lastLineNo = len(text) - 1
-        if yCursor <= 0:
-            if not (text[0][barrierPos] in validBorder):
-                return False    
-            if len(text) > 1:
-                if not (text[1][barrierPos] in validBorder):            
-                    return False    
-            if len(text) > 2:
-                if not (text[2][barrierPos] in validBorder):            
-                    return False                      
-        elif yCursor >= lastLineNo:
-            if not (text[lastLineNo][barrierPos] in validBorder):
-                return False    
-            if len(text) > 1:
-                if not (text[lastLineNo - 1][barrierPos] in validBorder):            
-                    return False    
-            if len(text) > 2:
-                if not (text[lastLineNo - 2][barrierPos] in validBorder):            
-                    return False          
-        else:
-            if not (text[yCursor][barrierPos] in validBorder):
-                return False    
-            if not (text[yCursor - 1][barrierPos] in validBorder):            
-                return False    
-            if not (text[yCursor + 1][barrierPos] in validBorder):            
-                return False  
-        return True
+        return isBarrier, sayLine
+
     def getBarrierText(self, text, xCursor, yCursor):
         line = text[yCursor]
         if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'):
@@ -89,10 +60,7 @@ class barrierManager():
                 offset = xCursor - 1
             start = line[:offset].rfind(b)
             if start != -1:
-                if not self.hasBorder(text, xCursor, yCursor, leftBarriers, start):
-                    start = -1  
-                else:
-                    start += 1  
+                start += 1  
                 break
         if start == -1:
             return False, line                
@@ -101,8 +69,6 @@ class barrierManager():
             end = line[start:].find(b)
             if end != -1:
                 end = start + end  
-                if not self.hasBorder(text, xCursor, yCursor,rightBarriers, end):
-                    end = -1
                 break
         if end == -1:
             return False, line                            
diff --git a/src/fenrirscreenreader/core/byteManager.py b/src/fenrirscreenreader/core/byteManager.py
index ebf57fc..1273e2f 100644
--- a/src/fenrirscreenreader/core/byteManager.py
+++ b/src/fenrirscreenreader/core/byteManager.py
@@ -29,12 +29,39 @@ class byteManager():
             if convertedEscapeSequence[0] == 94 and convertedEscapeSequence[1] ==91:
                 convertedEscapeSequence = b'^[' + convertedEscapeSequence[2:]            
         return convertedEscapeSequence
+    def handleByteStream(self, eventData, sep = b'\x1b'):
+        buffer = eventData
+        # handle prefix
+        endIndex = buffer.find(sep)
+        if endIndex > 0:
+            currSequence = buffer[:endIndex]
+            buffer = buffer[endIndex:]
+            self.handleSingleByteSequence(currSequence)
+        # special handlig for none found (performance)
+        elif endIndex == -1:
+            self.handleSingleByteSequence(buffer)
+            return
+        # handle outstanding sequence
+        while buffer != b'':
+            endIndex = buffer[len(sep):].find(sep)
+            if endIndex == -1:
+                currSequence = buffer
+                buffer = b''
+            else:
+                currSequence = buffer[:endIndex + len(sep)]
+                buffer = buffer[endIndex + len(sep):]
+            self.handleSingleByteSequence(currSequence)
     def handleByteInput(self, eventData):
         if not eventData:
             return
         if eventData == b'':
             return
-
+        try:
+            self.env['runtime']['debug'].writeDebugOut("handleByteInput " + eventData.decode('utf8') ,debug.debugLevel.INFO)
+        except:
+            pass
+        self.handleByteStream(eventData)
+    def handleSingleByteSequence(self, eventData):
         convertedEscapeSequence = self.unifyEscapeSeq(eventData)
 
         if self.switchCtrlModeOnce > 0:
@@ -82,6 +109,8 @@ class byteManager():
             self.env['runtime']['outputManager'].presentText(_('bypass'), soundIcon='PTYBypass', interrupt=True, flush=True)
             return True
         return False          
+    def sendBytes(self, byteMacro):
+        pass
     def detectByteCommand(self, escapeSequence):
         convertedEscapeSequence = self.unifyEscapeSeq(escapeSequence)
         command = self.env['runtime']['inputManager'].getCommandForShortcut(convertedEscapeSequence)
diff --git a/src/fenrirscreenreader/core/commandManager.py b/src/fenrirscreenreader/core/commandManager.py
index 3b31670..90e5f2d 100644
--- a/src/fenrirscreenreader/core/commandManager.py
+++ b/src/fenrirscreenreader/core/commandManager.py
@@ -31,22 +31,50 @@ class commandManager():
     def shutdown(self):
         for commandFolder in self.env['general']['commandFolderList']:    
             self.env['runtime']['commandManager'].shutdownCommands(commandFolder)
-        
+
+    def loadFile(self, filepath = ''):
+        if filepath == '':
+            return None
+        if not os.path.exists(filepath):
+            self.env['runtime']['debug'].writeDebugOut("loadFile: filepath not exists:" + filepath ,debug.debugLevel.WARNING)
+            return None
+        if os.path.isdir(filepath):
+            self.env['runtime']['debug'].writeDebugOut("loadFile: filepath is a directory:" + filepath ,debug.debugLevel.ERROR)
+            return None
+        if not os.access(filepath, os.R_OK):
+            self.env['runtime']['debug'].writeDebugOut("loadFile: filepath not readable:" + filepath ,debug.debugLevel.ERROR)
+            return None
+
+        try:
+            fileName, fileExtension = os.path.splitext(filepath)
+            fileName = fileName.split('/')[-1]
+            if fileName.startswith('__'):
+                return None
+            if fileExtension.lower() == '.py':
+                command_mod = module_utils.importModule(fileName, filepath)
+                command = command_mod.command()
+                command.initialize(self.env)
+                self.env['runtime']['debug'].writeDebugOut("loadFile: Load command:" + filepath ,debug.debugLevel.INFO, onAnyLevel=True)
+                return command
+        except Exception as e:
+            self.env['runtime']['debug'].writeDebugOut("loadFile: Loading command:" + filepath ,debug.debugLevel.ERROR)
+            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)                
+        return None
     def loadCommands(self, section='commands',commandPath=''):
         if commandPath =='':
             commandPath = fenrirPath+ "/commands/"
         if not commandPath.endswith('/'):
-            commandPath += '/'        
+            commandPath += '/'
         commandFolder = commandPath + section +"/"
         if not os.path.exists(commandFolder):
-            self.env['runtime']['debug'].writeDebugOut("commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING)                   
+            self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING)                   
             return   
         if not os.path.isdir(commandFolder):
-            self.env['runtime']['debug'].writeDebugOut("commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR)                                    
-            return      
+            self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR)                                    
+            return
         if not os.access(commandFolder, os.R_OK):
-            self.env['runtime']['debug'].writeDebugOut("commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR)                                    
-            return           
+            self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR)                                    
+            return
         self.env['commands'][section] = {}
         self.env['commandsIgnore'][section] = {}
         commandList = glob.glob(commandFolder+'*')
@@ -66,9 +94,9 @@ class commandManager():
                     self.env['commands'][section][fileName.upper()] = command_mod.command()
                     self.env['commandsIgnore'][section][fileName.upper()[fileName.upper().find('-')+1:]+'_IGNORE'] = False
                     self.env['commands'][section][fileName.upper()].initialize(self.env)
-                    self.env['runtime']['debug'].writeDebugOut("Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)                    
+                    self.env['runtime']['debug'].writeDebugOut("loadCommands: Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)                    
             except Exception as e:
-                self.env['runtime']['debug'].writeDebugOut("Loading command:" + command ,debug.debugLevel.ERROR)
+                self.env['runtime']['debug'].writeDebugOut("loadCommands: Loading command:" + command ,debug.debugLevel.ERROR)
                 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)                
                 continue
     
@@ -118,18 +146,18 @@ class commandManager():
                     if not self.env['runtime']['inputManager'].isValidKey(key.upper()):
                         self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' script:' + fileName ,debug.debugLevel.WARNING)                    
                         invalid = True
-                        break                
+                        break
                     shortcutKeys.append(key.upper())
                 if invalid:
-                    continue                    
+                    continue
                 if not 'KEY_SCRIPT' in shortcutKeys:
-                    shortcutKeys.append('KEY_SCRIPT')                
+                    shortcutKeys.append('KEY_SCRIPT')
                 shortcut.append(1)
                 shortcut.append(sorted(shortcutKeys)) 
-                self.env['bindings'][str(shortcut)] = fileName.upper()                     
+                self.env['bindings'][str(shortcut)] = fileName.upper()
             except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut("Loading script:" + fileName ,debug.debugLevel.ERROR)
-                self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)                
+                self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
                 continue
     def shutdownCommands(self, section):
         for command in sorted(self.env['commands'][section]):
@@ -146,36 +174,36 @@ class commandManager():
             return
         #unload
         oldScript = unLoadScript
-        if self.commandExists(oldScript, trigger):        
+        if self.commandExists(oldScript, trigger):
             try:
                self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.unload:" + trigger + "." + oldScript ,debug.debugLevel.INFO)                 
-               self.env['commands'][trigger][oldScript].unload()                     
+               self.env['commands'][trigger][oldScript].unload()
             except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + oldScript ,debug.debugLevel.ERROR)
                 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) 
         #load
         newScript = loadScript
-        if self.commandExists(newScript, trigger):        
+        if self.commandExists(newScript, trigger):
             try:
                self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.load:" + trigger + "." + newScript ,debug.debugLevel.INFO)                    
-               self.env['commands'][trigger][newScript].load()                                 
+               self.env['commands'][trigger][newScript].load()
             except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + newScript ,debug.debugLevel.ERROR)
-                self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)                 
+                self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
 
     def executeDefaultTrigger(self, trigger, force=False):
         if not force:
             if self.env['runtime']['screenManager'].isSuspendingScreen():
                 return
         for command in sorted(self.env['commands'][trigger]):
-            if self.commandExists(command, trigger):        
+            if self.commandExists(command, trigger):
                 try:
                     if self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE']:
                         self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE'] = False
-                        self.env['runtime']['debug'].writeDebugOut("Ignore trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)                                
+                        self.env['runtime']['debug'].writeDebugOut("Ignore trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)
                     else:
-                        self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)                    
-                        self.env['commands'][trigger][command].run()                    
+                        self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)
+                        self.env['commands'][trigger][command].run()
                 except Exception as e:
                     self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command + str(e) ,debug.debugLevel.ERROR)
 
@@ -185,11 +213,11 @@ class commandManager():
         if self.commandExists(command, section):
             try:
                 if self.env['runtime']['helpManager'].isTutorialMode() and section != 'help':
-                    self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO)                   
+                    self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO)
                     description = self.getCommandDescription(command, section)
-                    self.env['runtime']['outputManager'].presentText(description, interrupt=True)                                       
+                    self.env['runtime']['outputManager'].presentText(description, interrupt=False)
                 else:
-                    self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO)                    
+                    self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO)
                     self.runCommand(command, section)
             except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
@@ -213,11 +241,41 @@ class commandManager():
         self.env['commandInfo']['lastCommandExecutionTime'] = time.time()  
         
     def commandExists(self, command, section = 'commands'):
-        return( command in self.env['commands'][section])
-    def getShortcutForCommand(self, command):
-        shortcut = ''
         try:
-            shortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)]      
+            return( command in self.env['commands'][section])
+        except:
+            return False
+    def getShortcutForCommand(self, command, formatKeys = False):
+        shortcut = []
+        try:
+            rawShortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)]      
+            # prefer numbers for multitap
+            for k in ['2', '3', '4', '5', '6', '7', '8']:
+                if k in rawShortcut:
+                    formattedKey = k
+                    if formatKeys:
+                        formattedKey = formattedKey.lower()
+                        formattedKey += ' times '
+                    shortcut.append(formattedKey)
+                    rawShortcut.remove(k)     
+            # prefer metha keys
+            for k in ['KEY_FENRIR', 'KEY_SCRIPT', 'KEY_CTRL', 'KEY_SHIFT', 'KEY_ALT', 'KEY_META']:
+                if k in rawShortcut:
+                    formattedKey = k
+                    if formatKeys:
+                        formattedKey = formattedKey.lower()
+                        formattedKey = formattedKey.replace('key_kp', ' keypad ')
+                        formattedKey = formattedKey.replace('key_', ' ')
+                    shortcut.append(formattedKey)
+                    rawShortcut.remove(k)
+            # handle other keys
+            for k in rawShortcut:
+                formattedKey = k
+                if formatKeys:
+                    formattedKey = formattedKey.lower()
+                    formattedKey = formattedKey.replace('key_kp', ' keypad ')
+                    formattedKey = formattedKey.replace('key_', ' ')
+                shortcut.append(formattedKey)                
         except:
             pass
         return shortcut      
diff --git a/src/fenrirscreenreader/core/debugManager.py b/src/fenrirscreenreader/core/debugManager.py
index 7e8d01d..cdd12e3 100644
--- a/src/fenrirscreenreader/core/debugManager.py
+++ b/src/fenrirscreenreader/core/debugManager.py
@@ -6,12 +6,14 @@ from datetime import datetime
 import pathlib, os
 
 class debugManager():
-    def __init__(self, fileName = '/var/log/fenrirscreenreader/fenrir.log'):
+    def __init__(self, fileName = ''):
         self._file = None
         self._fileOpened = False
-        self._fileName = fileName
+        self._fileName = '/tmp/fenrir_' + str(os.getpid()) + '_' +  str(datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S')) + '.log'
+        if fileName != '':
+            self._fileName = fileName
     def initialize(self, environment):
-        self.env = environment    
+        self.env = environment
     def shutdown(self):
         self.closeDebugFile()
     def __del__(self):
@@ -27,7 +29,7 @@ class debugManager():
         if self._fileName != '':
             directory = os.path.dirname(self._fileName)
             if not os.path.exists(directory):
-                pathlib.Path(directory).mkdir(parents=True, exist_ok=True)         
+                pathlib.Path(directory).mkdir(parents=True, exist_ok=True)
             try:
                 self._file = open(self._fileName,'a')
                 self._fileOpened = True
diff --git a/src/fenrirscreenreader/core/environment.py b/src/fenrirscreenreader/core/environment.py
index 7b864a2..729aaf2 100644
--- a/src/fenrirscreenreader/core/environment.py
+++ b/src/fenrirscreenreader/core/environment.py
@@ -26,4 +26,5 @@ environment = {
 'output': outputData,
 'soundIcons': {},
 'bindings': {},
+'rawBindings': {},
 }
diff --git a/src/fenrirscreenreader/core/fenrirManager.py b/src/fenrirscreenreader/core/fenrirManager.py
index 48adcf7..4b78b6f 100644
--- a/src/fenrirscreenreader/core/fenrirManager.py
+++ b/src/fenrirscreenreader/core/fenrirManager.py
@@ -38,7 +38,7 @@ class fenrirManager():
         parser.add_argument('-o', '--options', metavar='SECTION#SETTING=VALUE;..', default='', help='Overwrite options in given settings file. Sections, settings and Values are cases sensitive')
         parser.add_argument('-d', '--debug',  action='store_true', help='Turns on Debugmode') 
         parser.add_argument('-p', '--print',  action='store_true', help='Print debug messages on screen')
-        parser.add_argument('-e', '--emulated-pty',  action='store_true', help='Use PTY emulation and escape sequences for input')
+        parser.add_argument('-e', '--emulated-pty',  action='store_true', help='Use PTY emulation and escape sequences for input. Allows to use fenrir on the desktop, in a terminal for X or Wayland')
         parser.add_argument('-E', '--emulated-evdev',  action='store_true', help='Use PTY emulation and evdev for input (single instance)')
         try:
             args = parser.parse_args()
@@ -68,6 +68,10 @@ class fenrirManager():
         else: 
             if self.environment['runtime']['helpManager'].isTutorialMode():
                 self.environment['runtime']['inputManager'].clearEventBuffer()
+                self.environment['runtime']['inputManager'].keyEcho(event['Data'])
+
+            if self.environment['runtime']['vmenuManager'].getActive():
+                self.environment['runtime']['inputManager'].clearEventBuffer()
 
             self.detectShortcutCommand()
 
@@ -76,11 +80,12 @@ class fenrirManager():
             if self.singleKeyCommand:
                 if self.environment['runtime']['inputManager'].noKeyPressed():
                     self.environment['runtime']['inputManager'].clearEventBuffer() 
-            else:              
+            else:
                 self.environment['runtime']['inputManager'].writeEventBuffer()
         if self.environment['runtime']['inputManager'].noKeyPressed():
             self.modifierInput = False
             self.singleKeyCommand = False  
+            self.environment['runtime']['inputManager'].handleDeviceGrab()
         if self.environment['input']['keyForeward'] > 0:
             self.environment['input']['keyForeward'] -=1
         self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
@@ -91,35 +96,44 @@ class fenrirManager():
         if event['Data'] == b'':
             return
         self.environment['runtime']['byteManager'].handleByteInput(event['Data'])
-                   
         self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput')
     def handleExecuteCommand(self, event):  
         if not event['Data']:
-            return          
+            return
         if event['Data'] == '':
             return
         command = event['Data']
 
+        # special modes
         if self.environment['runtime']['helpManager'].isTutorialMode():
             if self.environment['runtime']['commandManager'].commandExists( command, 'help'):
                 self.environment['runtime']['commandManager'].executeCommand( command, 'help')
                 return
-        self.environment['runtime']['commandManager'].executeCommand( command, 'commands')            
+        elif self.environment['runtime']['vmenuManager'].getActive():
+            if self.environment['runtime']['commandManager'].commandExists( command, 'vmenu-navigation'):
+                self.environment['runtime']['commandManager'].executeCommand( command, 'vmenu-navigation')
+                return
+
+        # default
+        self.environment['runtime']['commandManager'].executeCommand( command, 'commands')
     def handleRemoteIncomming(self, event):
         if not event['Data']:
             return
-        self.environment['runtime']['remoteManager'].handleRemoteIncomming(event['Data'])        
-    def handleScreenChange(self, event):   
+        self.environment['runtime']['remoteManager'].handleRemoteIncomming(event['Data'])
+    def handleScreenChange(self, event):
         self.environment['runtime']['screenManager'].hanldeScreenChange(event['Data'])
-        '''        
+        '''
         if self.environment['runtime']['applicationManager'].isApplicationChange():
             self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
             self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
               self.environment['runtime']['applicationManager'].getPrevApplication(), \
-              self.environment['runtime']['applicationManager'].getCurrentApplication())          
-        '''        
-        self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')             
-        self.environment['runtime']['screenDriver'].getCurrScreen()        
+              self.environment['runtime']['applicationManager'].getCurrentApplication())
+        '''
+        if self.environment['runtime']['vmenuManager'].getActive():
+            return
+
+        self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
+        self.environment['runtime']['screenDriver'].getCurrScreen()
     def handleScreenUpdate(self, event):
         #startTime = time.time()
         self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data'])
@@ -128,29 +142,32 @@ class fenrirManager():
             self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
             self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
               self.environment['runtime']['applicationManager'].getPrevApplication(), \
-              self.environment['runtime']['applicationManager'].getCurrentApplication())          
+              self.environment['runtime']['applicationManager'].getCurrentApplication())
         '''
         # timout for the last keypress
         if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
-            self.environment['runtime']['inputManager'].clearLastDeepInput()        
-        # has cursor changed?            
+            self.environment['runtime']['inputManager'].clearLastDeepInput()
+        # has cursor changed?
         if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \
           self.environment['runtime']['cursorManager'].isCursorHorizontalMove():
             self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
         self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
         self.environment['runtime']['inputManager'].clearLastDeepInput()
         #print('handleScreenUpdate:',time.time() - startTime)
-    
     def handlePlugInputDevice(self, event):
+        try:
+            self.environment['runtime']['inputManager'].setLastDetectedDevices(event['Data'])
+        except:
+            pass
         self.environment['runtime']['inputManager'].handlePlugInputDevice(event['Data'])
-        self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)   
-    
+        self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)
+        self.environment['runtime']['inputManager'].setLastDetectedDevices(None)
     def handleHeartBeat(self, event):
         self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat',force=True)  
-        #self.environment['runtime']['outputManager'].brailleText(flush=False)                        
+        #self.environment['runtime']['outputManager'].brailleText(flush=False)
 
 
-    def detectShortcutCommand(self):    
+    def detectShortcutCommand(self):
         if self.environment['input']['keyForeward'] > 0:
             return
         if self.environment['runtime']['inputManager'].isKeyPress():
@@ -161,9 +178,9 @@ class fenrirManager():
                     self.singleKeyCommand = len( self.environment['runtime']['inputManager'].getLastDeepestInput() ) == 1
         # key is already released. we need the old one
         if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
-            shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()                
+            shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
             self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut)
-            
+
         if not self.modifierInput:
             if self.environment['runtime']['inputManager'].isKeyPress():
                 if self.command != '':
@@ -172,23 +189,18 @@ class fenrirManager():
         if not (self.singleKeyCommand or self.modifierInput):
             return
 
-        # fire event    
+        # fire event
         if self.command != '':
-            if self.modifierInput:                    
+            if self.modifierInput:
                 self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
-                self.command = ''                
-            else:        
+                self.command = ''
+            else:
                 if self.singleKeyCommand:
                     if self.environment['runtime']['inputManager'].noKeyPressed():
                         self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
                         self.command = ''
     def setProcessName(self, name = 'fenrir'):
         """Attempts to set the process name to 'fenrir'."""
-
-        #sys.argv[0] = name
-
-        # Disabling the import error of setproctitle.
-        # pylint: disable-msg=F0401
         try:
             from setproctitle import setproctitle
         except ImportError:
@@ -217,13 +229,14 @@ class fenrirManager():
         self.shutdownRequest()
 
     def shutdown(self):
-        self.environment['runtime']['eventManager'].stopMainEventLoop()        
-        self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)       
+        self.environment['runtime']['inputManager'].ungrabAllDevices()
+        self.environment['runtime']['eventManager'].stopMainEventLoop()
+        self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
         self.environment['runtime']['eventManager'].cleanEventQueue()
         time.sleep(0.6)
         for currManager in self.environment['general']['managerList']:
             if self.environment['runtime'][currManager]:
-                self.environment['runtime'][currManager].shutdown()   
+                self.environment['runtime'][currManager].shutdown()
                 del self.environment['runtime'][currManager]
 
         self.environment = None
diff --git a/src/fenrirscreenreader/core/generalData.py b/src/fenrirscreenreader/core/generalData.py
index da2858f..9aac384 100644
--- a/src/fenrirscreenreader/core/generalData.py
+++ b/src/fenrirscreenreader/core/generalData.py
@@ -14,5 +14,5 @@ generalData = {
 'managerList':[ 'attributeManager','punctuationManager', 'byteManager', 'cursorManager', 'applicationManager', 'commandManager'
   , 'screenManager', 'inputManager','outputManager', 'helpManager', 'memoryManager', 'eventManager','processManager', 'debug'],
 'commandFolderList':['commands','onKeyInput', 'onByteInput', 'onCursorChange', 'onScreenUpdate','onScreenChanged','onHeartBeat', 'onPlugInputDevice'
-  ,'onApplicationChange','onSwitchApplicationProfile','help',],
+  ,'onApplicationChange','onSwitchApplicationProfile','help','vmenu-navigation',],
 }
diff --git a/src/fenrirscreenreader/core/helpManager.py b/src/fenrirscreenreader/core/helpManager.py
index 6ec5030..aa1439e 100755
--- a/src/fenrirscreenreader/core/helpManager.py
+++ b/src/fenrirscreenreader/core/helpManager.py
@@ -10,7 +10,7 @@ from fenrirscreenreader.core import debug
 class helpManager():
     def __init__(self):
         self.helpDict = {}
-        self.tutorialListIndex = None          
+        self.tutorialListIndex = None
     def initialize(self, environment):
         self.env = environment
     def shutdown(self):
@@ -18,52 +18,81 @@ class helpManager():
     def toggleTutorialMode(self):
         self.setTutorialMode(not self.env['general']['tutorialMode'])
     def setTutorialMode(self, newTutorialMode):
-        self.env['general']['tutorialMode'] = newTutorialMode        
+        if self.env['runtime']['vmenuManager'].getActive():
+            return
+        self.env['general']['tutorialMode'] = newTutorialMode
         if newTutorialMode:
-            self.createHelpDict()        
+            self.createHelpDict()
             self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_TUTORIAL_MODE'
             self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_HELP'
             self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_HELP'
-            self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP'                                    
+            self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP'
         else:
             try:
-                del(self.env['bindings'][str([1, ['KEY_ESC']])])
-                del(self.env['bindings'][str([1, ['KEY_UP']])])
-                del(self.env['bindings'][str([1, ['KEY_DOWN']])])
-                del(self.env['bindings'][str([1, ['KEY_SPACE']])])
+                self.env['bindings'] = self.env['runtime']['settingsManager'].getBindingBackup()
             except:
-                pass                     
+                pass
     def isTutorialMode(self):
-        return self.env['general']['tutorialMode']        
+        return self.env['general']['tutorialMode']
+    def getFormattedShortcutForCommand(self, command):
+        shortcut = []
+        rawShortcut = []
+        try:
+            rawShortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)]
+            rawShortcut = self.env['rawBindings'][rawShortcut]
+            # prefer numbers for multitap
+            if rawShortcut[0] in range(2, 9):
+                formattedKey = str(rawShortcut[0]) +' times '
+                shortcut.append(formattedKey)
+            # prefer metha keys
+            for k in ['KEY_FENRIR', 'KEY_SCRIPT', 'KEY_CTRL', 'KEY_SHIFT', 'KEY_ALT', 'KEY_META']:
+                if k in rawShortcut[1]:
+                    formattedKey = k
+                    formattedKey = formattedKey.lower()
+                    formattedKey = formattedKey.replace('key_kp', ' keypad ')
+                    formattedKey = formattedKey.replace('key_', ' ')
+                    shortcut.append(formattedKey)
+                    rawShortcut[1].remove(k)
+            # handle other keys
+            for k in rawShortcut[1]:
+                formattedKey = k
+                formattedKey = formattedKey.lower()
+                formattedKey = formattedKey.replace('key_kp', ' keypad ')
+                formattedKey = formattedKey.replace('key_', ' ')
+                shortcut.append(formattedKey)
+        except Exception as e:
+            return ''
+        shortcut = str(shortcut)
+        shortcut = shortcut.replace('[','')
+        shortcut = shortcut.replace(']','')
+        shortcut = shortcut.replace("'",'')
+        return shortcut
+
     def getCommandHelpText(self, command, section = 'commands'):
         commandName = command.lower()
-        commandName = commandName.split('__-__')[0]       
-        commandName = commandName.replace('_',' ')        
+        commandName = commandName.split('__-__')[0]
+        commandName = commandName.replace('_',' ')
         commandName = commandName.replace('_',' ')
         if command == 'TOGGLE_TUTORIAL_MODE':
             commandDescription = _('toggles the tutorial mode')
         else:
-            commandDescription = self.env['runtime']['commandManager'].getCommandDescription( command, section = 'commands')
+            commandDescription = self.env['runtime']['commandManager'].getCommandDescription(command, section = 'commands')
         if commandDescription == '':
             commandDescription = 'no Description available'
-        commandShortcut = self.env['runtime']['commandManager'].getShortcutForCommand( command)
-        commandShortcut = commandShortcut.replace('KEY_',' ')
-        commandShortcut = commandShortcut.replace('[','')        
-        commandShortcut = commandShortcut.replace(']','')        
-        commandShortcut = commandShortcut.replace("'",'')        
+        commandShortcut = self.getFormattedShortcutForCommand(command)
         if commandShortcut == '':
             commandShortcut = 'unbound'
         helptext = commandName + ', Shortcut ' + commandShortcut + ', Description ' + commandDescription
         return helptext
     def createHelpDict(self, section = 'commands'):
-        self.helpDict = {}        
+        self.helpDict = {}
         for command in sorted(self.env['commands'][section].keys()):
-            self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section)            
+            self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section)
         if len(self.helpDict) > 0:
             self.tutorialListIndex = 0
         else:
-            self.tutorialListIndex = None        
-    def getHelpForCurrentIndex(self):            
+            self.tutorialListIndex = None
+    def getHelpForCurrentIndex(self):
         if self.tutorialListIndex == None:
             return '' 
         return self.helpDict[self.tutorialListIndex]
diff --git a/src/fenrirscreenreader/core/inputDriver.py b/src/fenrirscreenreader/core/inputDriver.py
index cb011aa..5f2f65f 100644
--- a/src/fenrirscreenreader/core/inputDriver.py
+++ b/src/fenrirscreenreader/core/inputDriver.py
@@ -11,45 +11,50 @@ class inputDriver():
         self._initialized = False
     def initialize(self, environment):
         self.env = environment
-        self.env['runtime']['inputManager'].setShortcutType('KEY')        
+        self.env['runtime']['inputManager'].setShortcutType('KEY')
         self._isInitialized = True
     def shutdown(self):
         if self._initialized:
-            self.removeAllDevices()    
+            self.removeAllDevices()
         self._isInitialized = False
     def getInputEvent(self):
         time.sleep(0.1)
         return None
     def clearEventBuffer(self):
         if not self._initialized:
-            return    
+            return
         del self.env['input']['eventBuffer'][:]
     def updateInputDevices(self, newDevices = None, init = False):
         if not self._initialized:
-            return    
+            return
     def getLedState(self, led = 0):
         if not self._initialized:
-            return False    
+            return False
         return False
     def toggleLedState(self, led = 0):
         if not self._initialized:
             return
     def grabAllDevices(self):
         if not self._initialized:
-            return
+            return True
+        return True
     def ungrabAllDevices(self):
         if not self._initialized:
-            return
+            return True
+        return True
     def hasIDevices(self):
         if not self._initialized:
             return False
         return True
     def removeAllDevices(self):
         if not self._initialized:
-            return 
+            return
+    def sendKey(self):
+        if not self._initialized:
+            return
     def __del__(self):
         if not self._initialized:
-            return     
+            return
         try:
             self.removeAllDevices()
         except:
diff --git a/src/fenrirscreenreader/core/inputManager.py b/src/fenrirscreenreader/core/inputManager.py
index e451d91..e658463 100644
--- a/src/fenrirscreenreader/core/inputManager.py
+++ b/src/fenrirscreenreader/core/inputManager.py
@@ -6,14 +6,15 @@
 
 from fenrirscreenreader.core import debug
 from fenrirscreenreader.core import inputData
-import os, inspect, time
+import os, inspect, time, traceback
 currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
 fenrirPath = os.path.dirname(currentdir)
 
 class inputManager():
     def __init__(self):
         self.shortcutType = 'KEY'
-        self.executeDeviceGrab = False        
+        self.executeDeviceGrab = False
+        self.lastDetectedDevices = None
     def setShortcutType(self, shortcutType = 'KEY'):
         if shortcutType in ['KEY', 'BYTE']:
             self.shortcutType = shortcutType
@@ -33,6 +34,7 @@ class inputManager():
         self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
         self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
         self.lastDeepestInput = []
+        self.lastEvent = None
         self.env['input']['shortcutRepeat'] = 1
         self.lastInputTime = time.time()
     def shutdown(self):
@@ -47,30 +49,59 @@ class inputManager():
         return event
     def setExecuteDeviceGrab(self, newExecuteDeviceGrab = True):
         self.executeDeviceGrab = newExecuteDeviceGrab
-    def handleDeviceGrab(self):
+    def handleDeviceGrab(self, force = False):
+        if force:
+            self.setExecuteDeviceGrab()
         if not self.executeDeviceGrab:
             return
         if self.env['input']['eventBuffer'] != []:
             return
         if not self.noKeyPressed():
-            return        
+            return
         if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
-            return            
+            self.executeDeviceGrab = False
+            return
         if self.env['runtime']['screenManager'].getCurrScreenIgnored():
-            self.ungrabAllDevices()
+            while not self.ungrabAllDevices():
+                time.sleep(0.25)
+                self.env['runtime']['debug'].writeDebugOut("retry ungrabAllDevices " ,debug.debugLevel.WARNING)
+            self.env['runtime']['debug'].writeDebugOut("All devices ungrabbed" ,debug.debugLevel.INFO)
         else:
-            self.grabAllDevices()
-        self.executeDeviceGrab = False 
+            while not self.grabAllDevices():
+                time.sleep(0.25)
+                self.env['runtime']['debug'].writeDebugOut("retry grabAllDevices" ,debug.debugLevel.WARNING)
+            self.env['runtime']['debug'].writeDebugOut("All devices grabbed" ,debug.debugLevel.INFO)
+        self.executeDeviceGrab = False
+    def sendKeys(self, keyMacro):
+        for e in keyMacro:
+            key = ''
+            value = 0
+            if len(e) != 2:
+                continue
+            if isinstance(e[0], int) and isinstance(e[1], str):
+                key = e[1].upper()
+                value = e[0]
+            elif isinstance(e[1], int) and isinstance(e[0], str):
+                key = e[0].upper()
+                value = e[1]
+            else:
+                continue
+            if key.upper() == 'SLEEP':
+                time.sleep(value)
+            else:
+                self.env['runtime']['inputDriver'].sendKey(key, value)
+    def getLastEvent(self):
+        return self.lastEvent
     def handleInputEvent(self, eventData):
-        #print(eventData)
         if not eventData:
             return
+        self.lastEvent = eventData
         # a hang apears.. try to fix
         if self.env['input']['eventBuffer'] == []:
             if self.env['input']['currInput'] != []:
-                self.env['input']['currInput'] = []        
-                self.env['input']['shortcutRepeat'] = 1                
-        
+                self.env['input']['currInput'] = []
+                self.env['input']['shortcutRepeat'] = 1
+
         self.env['input']['prevInput'] = self.env['input']['currInput'].copy()
         if eventData['EventState'] == 0:
             if eventData['EventName'] in self.env['input']['currInput']:
@@ -79,7 +110,7 @@ class inputManager():
                     self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
                 elif len(self.env['input']['currInput']) == 0:
                     self.env['input']['shortcutRepeat'] = 1 
-                self.lastInputTime = time.time()                                                   
+                self.lastInputTime = time.time()
         elif eventData['EventState'] == 1:
             if not eventData['EventName'] in self.env['input']['currInput']:
                 self.env['input']['currInput'].append(eventData['EventName'])
@@ -92,10 +123,10 @@ class inputManager():
                         self.env['input']['shortcutRepeat'] += 1
                     else:
                         self.env['input']['shortcutRepeat'] = 1
-                self.handleLedStates(eventData)      
+                self.handleLedStates(eventData)
                 self.lastInputTime = time.time()
         elif eventData['EventState'] == 2:
-            self.lastInputTime  = time.time()     
+            self.lastInputTime  = time.time()
 
         self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
         self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
@@ -106,42 +137,42 @@ class inputManager():
         self.env['runtime']['debug'].writeDebugOut("currInput " + str(self.env['input']['currInput'] ) ,debug.debugLevel.INFO)
         if self.noKeyPressed():
             self.env['input']['prevInput'] = []
-            self.handleDeviceGrab()
-            
+
     def handleLedStates(self, mEvent):
         try:
             if mEvent['EventName'] == 'KEY_NUMLOCK':
-                self.env['runtime']['inputDriver'].toggleLedState()             
-            elif mEvent['EventName'] == 'KEY_CAPSLOCK':   
-                self.env['runtime']['inputDriver'].toggleLedState(1)                           
-            elif mEvent['EventName'] == 'KEY_SCROLLLOCK':  
-                self.env['runtime']['inputDriver'].toggleLedState(2)               
+                self.env['runtime']['inputDriver'].toggleLedState()
+            elif mEvent['EventName'] == 'KEY_CAPSLOCK':
+                self.env['runtime']['inputDriver'].toggleLedState(1)
+            elif mEvent['EventName'] == 'KEY_SCROLLLOCK':
+                self.env['runtime']['inputDriver'].toggleLedState(2)
         except:
             pass
     def grabAllDevices(self):
         if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
             try:
-                self.env['runtime']['inputDriver'].grabAllDevices()
+                return self.env['runtime']['inputDriver'].grabAllDevices()
             except Exception as e:
-                pass                
+                return False
+        return True
     def ungrabAllDevices(self):
         if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
             try:
-                self.env['runtime']['inputDriver'].ungrabAllDevices()
+                return self.env['runtime']['inputDriver'].ungrabAllDevices()
             except Exception as e:
-                pass
+                return False
+        return True
     def handlePlugInputDevice(self, eventData):
-        self.env['runtime']['inputManager'].updateInputDevices(eventData)
-            
+        for deviceEntry in eventData:
+            self.updateInputDevices(deviceEntry['device'])
     def updateInputDevices(self, newDevice = None):
         try:
-            self.env['runtime']['inputDriver'].updateInputDevices(newDevice)  
+            self.env['runtime']['inputDriver'].updateInputDevices(newDevice)
         except:
             pass
-        self.setExecuteDeviceGrab()
         try:
             if self.env['runtime']['screenManager']:
-                self.handleDeviceGrab()
+                self.handleDeviceGrab(force = True)
         except:
             pass
     def removeAllDevices(self):
@@ -157,7 +188,7 @@ class inputManager():
             return ''
         eventName = eventName.upper()
         if eventName == 'KEY_LEFTCTRL':
-            eventName = 'KEY_CTRL'         
+            eventName = 'KEY_CTRL'
         elif eventName == 'KEY_RIGHTCTRL':
             eventName = 'KEY_CTRL'
         elif eventName == 'KEY_LEFTSHIFT':
@@ -171,24 +202,24 @@ class inputManager():
         elif eventName == 'KEY_LEFTMETA':
             eventName = 'KEY_META'
         elif eventName == 'KEY_RIGHTMETA':
-            eventName = 'KEY_META'            
+            eventName = 'KEY_META'
         if self.isFenrirKey(eventName):
             eventName = 'KEY_FENRIR'
         if self.isScriptKey(eventName):
-            eventName = 'KEY_SCRIPT'            
+            eventName = 'KEY_SCRIPT'
         return eventName
 
     def clearEventBuffer(self):
         try:
             self.env['runtime']['inputDriver'].clearEventBuffer()
         except Exception as e:
-            pass              
+            pass
     def setLastDeepestInput(self, currentDeepestInput):
         self.lastDeepestInput = currentDeepestInput
     def clearLastDeepInput(self):
-        self.lastDeepestInput = []  
+        self.lastDeepestInput = []
     def getLastInputTime(self):
-        return self.lastInputTime           
+        return self.lastInputTime
     def getLastDeepestInput(self):
         return self.lastDeepestInput 
     def writeEventBuffer(self):
@@ -209,7 +240,7 @@ class inputManager():
         shortcut.append(self.env['input']['shortcutRepeat'])
         shortcut.append(self.getLastDeepestInput())
         return str(shortcut)
-        
+
     def getPrevShortcut(self):
         shortcut = []
         shortcut.append(self.env['input']['shortcutRepeat'])
@@ -221,32 +252,43 @@ class inputManager():
         shortcut.append(self.env['input']['shortcutRepeat'])
         if inputSequence:
             shortcut.append(inputSequence)
-        else:        
+        else:
             shortcut.append(self.env['input']['currInput'])
         if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']):
             if self.env['input']['shortcutRepeat'] > 1  and not self.shortcutExists(str(shortcut)):
                 shortcut = []
                 self.env['input']['shortcutRepeat'] = 1
                 shortcut.append(self.env['input']['shortcutRepeat'])
-                shortcut.append(self.env['input']['currInput'])     
-        self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO)                      
+                shortcut.append(self.env['input']['currInput'])
+        self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO)
         return str(shortcut)
-        
+
     def currKeyIsModifier(self):
         if len(self.getLastDeepestInput()) != 1:
             return False
         return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT')
-    
+
     def isFenrirKey(self, eventName):
         return eventName in self.env['input']['fenrirKey']
-    
+
     def isScriptKey(self, eventName):
         return eventName in self.env['input']['scriptKey']
-    
+
     def getCommandForShortcut(self, shortcut):
         if not self.shortcutExists(shortcut):
             return '' 
         return self.env['bindings'][shortcut]
+    def keyEcho(self, eventData = None):
+        if not eventData:
+            eventData = self.getLastEvent()
+            if not eventData:
+                return
+        keyName = ''
+        if eventData['EventState'] == 1:
+            keyName = eventData['EventName'].lower()
+            if keyName.startswith('key_'):
+                keyName = keyName[4:]
+                self.env['runtime']['outputManager'].presentText(_(keyName), interrupt=True)
 
     def shortcutExists(self, shortcut):
         return(shortcut in self.env['bindings'])
@@ -259,7 +301,7 @@ class inputManager():
                 break
             line = line.replace('\n','')
             if line.replace(" ","") == '':
-                continue            
+                continue
             if line.replace(" ","").startswith("#"):
                 continue
             if line.count("=") != 1:
@@ -278,7 +320,7 @@ class inputManager():
                     shortcutRepeat = int(key)
                 except:
                     if not self.isValidKey(key.upper()):
-                        self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING)                    
+                        self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING)
                         invalid = True
                         break
                     shortcutKeys.append(key.upper()) 
@@ -287,12 +329,17 @@ class inputManager():
             shortcut.append(shortcutRepeat)
             shortcut.append(sorted(shortcutKeys))
             if len(shortcutKeys) != 1 and not 'KEY_FENRIR' in shortcutKeys:
-                self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR)                    
-                continue            
+                self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR)
+                continue
             self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True)    
-            self.env['bindings'][str(shortcut)] = commandName   
+            self.env['bindings'][str(shortcut)] = commandName
+            self.env['rawBindings'][str(shortcut)] = shortcut
         kbConfig.close()
         # fix bindings 
         self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE'
     def isValidKey(self, key):
-        return key in inputData.keyNames        
+        return key in inputData.keyNames
+    def setLastDetectedDevices(self, devices):
+        self.lastDetectedDevices =devices
+    def getLastDetectedDevices(self):
+        return self.lastDetectedDevices
diff --git a/src/fenrirscreenreader/core/outputManager.py b/src/fenrirscreenreader/core/outputManager.py
index e7450fa..bbfdf89 100644
--- a/src/fenrirscreenreader/core/outputManager.py
+++ b/src/fenrirscreenreader/core/outputManager.py
@@ -135,7 +135,12 @@ class outputManager():
             else:
                 displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])    
                 self.env['runtime']['brailleDriver'].writeText('flush'+displayText)                          
-
+    def resetSpeechDriver(self):
+        try:            
+            self.env['runtime']['speechDriver'].reset()
+        except Exception as e:
+            self.env['runtime']['debug'].writeDebugOut("reset " + str(e),debug.debugLevel.ERROR)
+        
     def getBrailleCursor(self):
         if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'REVIEW':
             return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
@@ -263,18 +268,36 @@ class outputManager():
         if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
             self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.speakText",debug.debugLevel.INFO)        
             return False  
-            
+
+        try:
+            e = self.env['soundIcons'][soundIcon]
+        except:
+            self.env['runtime']['debug'].writeDebugOut("SoundIcon doesnt exist: " + soundIcon, debug.debugLevel.WARNING)        
+            return False        
+
         if self.env['runtime']['soundDriver'] == None:
             self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText",debug.debugLevel.ERROR)        
-            return False       
+            return False
+
         try:
             self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume'))
+        except Exception as e:
+            self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::setVolume: " + str(e),debug.debugLevel.ERROR)
+
+        try:
             self.env['runtime']['soundDriver'].playSoundFile(self.env['soundIcons'][soundIcon], interrupt)
             return True
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut("\"playSoundIcon\" in outputManager.speakText ",debug.debugLevel.ERROR)
-            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)            
+            self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::playSoundFile: " + str(e),debug.debugLevel.ERROR)
+            return False
+
         return False
+    def tempDisableSpeech(self):
+        if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): 
+            self.presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True)
+            self.env['commandBuffer']['enableSpeechOnKeypress'] = True
+            self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
+            self.interruptOutput()
     def announceActiveCursor(self, interrupt_p=False):        
         if self.env['runtime']['cursorManager'].isReviewMode():
             self.presentText(' review cursor ', interrupt=interrupt_p)                                
diff --git a/src/fenrirscreenreader/core/processManager.py b/src/fenrirscreenreader/core/processManager.py
index 8681165..b6e6407 100644
--- a/src/fenrirscreenreader/core/processManager.py
+++ b/src/fenrirscreenreader/core/processManager.py
@@ -23,15 +23,15 @@ class processManager():
         
     def terminateAllProcesses(self):
         for proc in self._Processes:
-            try:
-                proc.terminate()
-            except KeyboardInterrupt:
-                pass           
-            except:
-                pass
-            proc.join()                
+            #try:
+            #    proc.terminate()
+            #except KeyboardInterrupt:
+            #    pass
+            #except:
+            #    pass
+            proc.join()
         for t in self._Threads:
-            t.join()         
+            t.join()
     def heartBeatTimer(self, active):
         try:
             time.sleep(0.5)
diff --git a/src/fenrirscreenreader/core/punctuationData.py b/src/fenrirscreenreader/core/punctuationData.py
index 2d55c95..6858e02 100644
--- a/src/fenrirscreenreader/core/punctuationData.py
+++ b/src/fenrirscreenreader/core/punctuationData.py
@@ -6,6 +6,7 @@
 
 from fenrirscreenreader.core import debug
 import string
+from collections import OrderedDict
 
 punctuationData = {
 'LEVELDICT':{
@@ -15,47 +16,7 @@ punctuationData = {
   'all': string.punctuation + ' §',
   },
 'PUNCTDICT':{
-  ' ':'space',
-  '&':'and',
-  "'":"apostrophe",
-  '@':'at',
-  '\\':'backslash',
-  '|':'bar',
-  '!':'bang',
-  '^':'carrot',
-  ':':'colon',
-  ',':'comma',
-  '-':'dash',
-  '$':'dollar',
-  '.':'dot',
-  '>':'greater',
-  '`':'grave',
-  '#':'hash',
-  '{':'left brace',
-  '[':'left bracket',
-  '(':'left paren',
-  '<':'less',
-  '%':'percent',
-  '+':'plus',
-  '?':'question',
-  '"':'quote',
-  ')':'right paren',
-  '}':'right brace',
-  ']':'right bracket',
-  ';':'semicolon',
-  '/':'slash',
-  '*':'star',
-  '~':'tilde',
-  '_':'line',
-  '=':'equals',
   },
-'CUSTOMDICT':{
-  }, 
-'EMOTICONDICT':{
-  ':)':'smiley',
-  ';)':'winking face',
-  'XD':'loool',
-  ':@':'angry face',
-  ':D':'lought'
-  },          
+'CUSTOMDICT':OrderedDict(), 
+'EMOTICONDICT':OrderedDict(),
 }
diff --git a/src/fenrirscreenreader/core/punctuationManager.py b/src/fenrirscreenreader/core/punctuationManager.py
index d665141..72877ae 100644
--- a/src/fenrirscreenreader/core/punctuationManager.py
+++ b/src/fenrirscreenreader/core/punctuationManager.py
@@ -33,15 +33,20 @@ class punctuationManager():
                 del currAllPunctNone[ord(char)]
             except:
                 pass
-        return text.translate(currAllPunctNone)   
-    
+        return text.translate(currAllPunctNone)
     def useCustomDict(self, text, customDict, seperator=''):
         resultText = str(text)
         if customDict:
             for key,item in customDict.items():
-                resultText = resultText.replace(str(key),seperator + str(item) + seperator)
+                try:
+                    regexLbl = 'REGEX;'
+                    if key.upper().startswith(regexLbl) and (len(key) > len(regexLbl)):
+                        resultText = re.sub(str(key[len(regexLbl):]), seperator + str(item) + seperator, resultText)
+                    else:
+                        resultText = resultText.replace(str(key),seperator + str(item) + seperator)
+                except Exception as e:
+                    self.env['runtime']['debug'].writeDebugOut("useCustomDict replace:'"  + key + "' with '" + item +"' failed:" + str(e),debug.debugLevel.ERROR, onAnyLevel=False)
         return resultText
-    
     def usePunctuationDict(self, text, punctuationDict, punctuation):
         resultText = str(text)
 
@@ -49,11 +54,11 @@ class punctuationManager():
             if ' ' in punctuation:
                 resultText = resultText.replace(' ',' ' + punctuationDict[' '] + ' ')
             for key,item in punctuationDict.items():
-                if key in punctuation and key not in ' ':
+                if (punctuation != '' and key in punctuation) and key not in ' ':
                     if self.env['runtime']['settingsManager'].getSetting('general', 'respectPunctuationPause') and \
                       len(key) == 1 and \
                       key in "',.;:?!":
-                        resultText = resultText.replace(str(key),' ' +str(item) + str(key) + ' ')                    
+                        resultText = resultText.replace(str(key),' ' +str(item) + str(key) + ' ')
                     else:
                         resultText = resultText.replace(str(key),' ' +str(item) + ' ')
         return resultText
@@ -96,7 +101,8 @@ class punctuationManager():
             if line.replace(" ","") == '':
                 continue
             if line.replace(" ","").startswith("#"):
-                continue
+                if not line.replace(" ","").startswith("#:===:"):
+                    continue
             if line.replace(" ","").upper().startswith("[") and \
               line.replace(" ","").upper().endswith("DICT]"):
                 currDictName = line[line.find('[') + 1 :line.upper().find('DICT]') + 4].upper()
@@ -114,4 +120,4 @@ class punctuationManager():
                     sepLine[1] = ':===:'
                 self.env['punctuation'][currDictName][sepLine[0]] = sepLine[1]
                 self.env['runtime']['debug'].writeDebugOut("Punctuation: " + currDictName + '.' + str(sepLine[0]) + ' :' + sepLine[1] ,debug.debugLevel.INFO, onAnyLevel=True)    
-        dictConfig.close()        
+        dictConfig.close()
diff --git a/src/fenrirscreenreader/core/quickMenuManager.py b/src/fenrirscreenreader/core/quickMenuManager.py
new file mode 100644
index 0000000..2ac5626
--- /dev/null
+++ b/src/fenrirscreenreader/core/quickMenuManager.py
@@ -0,0 +1,131 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.core.settingsData import settingsData
+
+class quickMenuManager():
+    def __init__(self):
+        self.position = 0
+        self.quickMenu = []
+        self.settings = settingsData
+
+    def initialize(self, environment):
+        self.env = environment
+        self.loadMenu(self.env['runtime']['settingsManager'].getSetting('menu', 'quickMenu'))
+    def shutdown(self):
+        pass
+    def loadMenu(self, menuString):
+        self.position = 0
+        self.quickMenu = []
+        if menuString == '':
+            return
+        entrys = menuString.split(';')
+        for e in entrys:
+            entry = e.split('#')
+            if len(entry) != 2:
+                continue
+            try:
+                t = self.settings[entry[0]][entry[1]]
+            except:
+                print(entry[0],entry[1], 'not found')
+                continue
+            self.quickMenu.append({'section': entry[0], 'setting': entry[1]})
+    def nextEntry(self):
+        if len(self.quickMenu) == 0:
+            return False
+        self.position += 1
+        if self.position >= len(self.quickMenu):
+            self.position = 0
+        return True
+    def prevEntry(self):
+        if len(self.quickMenu) == 0:
+            return False
+        self.position -= 1
+        if self.position < 0:
+            self.position = len(self.quickMenu) - 1
+        return True
+    def nextValue(self):
+        if len(self.quickMenu) == 0:
+            return False
+        section = self.quickMenu[self.position]['section']
+        setting = self.quickMenu[self.position]['setting']
+        valueString = ''
+        try:
+            valueString = self.env['runtime']['settingsManager'].getSetting(section, setting)
+        except:
+            return False
+
+        try:
+            if isinstance(self.settings[section][setting], str):
+                value = str(valueString)
+                return False
+            elif isinstance(self.settings[section][setting], bool):
+                if not valueString in ['True','False']:
+                    return False
+                value = not value
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value))
+            elif isinstance(self.settings[section][setting], int):
+                value = int(valueString)
+                value += 1
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value))
+            elif isinstance(self.settings[section][setting], float):
+                value = float(valueString)
+                value += 0.05
+                if value > 1.0:
+                    value = 1.0
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)[:4])
+        except Exception as e:
+            return False
+        return True
+    def prevValue(self):
+        if len(self.quickMenu) == 0:
+            return False
+        section = self.quickMenu[self.position]['section']
+        setting = self.quickMenu[self.position]['setting']
+        valueString = ''
+        try:
+            valueString = self.env['runtime']['settingsManager'].getSetting(section, setting)
+        except:
+            return False
+        try:
+            if isinstance(self.settings[section][setting], str):
+                value = str(valueString)
+                return False
+            elif isinstance(self.settings[section][setting], bool):
+                if not valueString in ['True','False']:
+                    return False
+                value = not value
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value))
+            elif isinstance(self.settings[section][setting], int):
+                value = int(valueString)
+                value -= 1
+                if value < 0:
+                    value = 0
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value))
+            elif isinstance(self.settings[section][setting], float):
+                value = float(valueString)
+                value -= 0.05
+                if value < 0.0:
+                    value = 0.0
+                self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)[:4])
+        except Exception as e:
+            return False
+        return True
+    def getCurrentEntry(self):
+        if len(self.quickMenu) == 0:
+            return ''
+        try:
+            return _(self.quickMenu[self.position]['section']) + ' ' + _(self.quickMenu[self.position]['setting'])
+        except:
+            return _('setting invalid')
+    def getCurrentValue(self):
+        if len(self.quickMenu) == 0:
+            return ''
+        try:
+            return self.env['runtime']['settingsManager'].getSetting(self.quickMenu[self.position]['section'], self.quickMenu[self.position]['setting'])
+        except:
+            return _('setting value invalid')
diff --git a/src/fenrirscreenreader/core/remoteManager.py b/src/fenrirscreenreader/core/remoteManager.py
index 4ae30b9..612c43e 100644
--- a/src/fenrirscreenreader/core/remoteManager.py
+++ b/src/fenrirscreenreader/core/remoteManager.py
@@ -35,13 +35,19 @@ class remoteManager():
         # command controll
         self.commandConst = 'COMMAND '
         self.sayConst = 'SAY '
+        self.vmenuConst = 'VMENU '
+        self.resetVmenuConst = 'RESETVMENU'
         self.interruptConst = 'INTERRUPT'
+        self.quitAppConst = 'QUITAPPLICATION'
+        self.tempDisableSpeechConst = 'TEMPDISABLESPEECH'
         self.defineWindowConst = 'WINDOW '
         self.resetWindowConst = 'RESETWINDOW'
+        self.setClipboardConst = 'CLIPBOARD '
         # setting controll
         self.settingConst = 'SETTING '
         self.setSettingConst = 'SET '
-        self.saveSettingConst = 'SAVE '
+        self.saveAsSettingConst = 'SAVEAS '
+        self.saveSettingConst = 'SAVE'
         self.resetSettingConst = 'RESET'
     def initialize(self, environment):
         self.env = environment
@@ -59,13 +65,17 @@ class remoteManager():
         if upperSettingsText.startswith(self.setSettingConst):
             parameterText = settingsText[len(self.setSettingConst):]
             self.setSettings(parameterText)
-        # save setting
-        if upperSettingsText.startswith(self.saveSettingConst):
-            parameterText = settingsText[len(self.saveSettingConst):]
+        # save as setting
+        elif upperSettingsText.startswith(self.saveAsSettingConst):
+            parameterText = settingsText[len(self.saveAsSettingConst):]
             self.saveSettings(parameterText)
+        # save setting
+        elif upperSettingsText == self.saveSettingConst:
+            self.saveSettings()
         # reset setting
-        if upperSettingsText.startswith(self.resetSettingConst):
+        elif upperSettingsText == self.resetSettingConst:
             self.resetSettings()
+
     def handleCommandExecution(self, commandText):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableCommandRemote'):
             return
@@ -77,15 +87,42 @@ class remoteManager():
             parameterText = commandText[len(self.sayConst):]
             self.say(parameterText)
         # interrupt
-        if upperCommandText.startswith(self.interruptConst):
+        elif upperCommandText == self.interruptConst:
             self.interruptSpeech()
+        # temp disable speech
+        elif upperCommandText == self.tempDisableSpeechConst:
+            self.tempDisableSpeech()
+        # set vmenu
+        elif upperCommandText.startswith(self.vmenuConst):
+            parameterText = commandText[len(self.vmenuConst):]
+            self.setVMenu(parameterText)
+        # reset vmenu
+        elif upperCommandText == self.resetVmenuConst:
+            self.resetVMenu()
+        # quit fenrir
+        elif upperCommandText == self.quitAppConst:
+            self.quitFenrir()
         # define window
-        if upperCommandText.startswith(self.defineWindowConst):
+        elif upperCommandText.startswith(self.defineWindowConst):
             parameterText = commandText[len(self.defineWindowConst):]
             self.defineWindow(parameterText)
         # reset window
-        if upperCommandText.startswith(self.resetWindowConst):
+        elif upperCommandText == self.resetWindowConst:
             self.resetWindow()
+        # set clipboard
+        elif upperCommandText.startswith(self.setClipboardConst):
+            parameterText = commandText[len(self.setClipboardConst):]
+            self.setClipboard(parameterText)
+    def tempDisableSpeech(self):
+        self.env['runtime']['outputManager'].tempDisableSpeech()
+    def setVMenu(self, vmenu = ''):
+        self.env['runtime']['vmenuManager'].setCurrMenu(vmenu)
+    def resetVMenu(self):
+        self.env['runtime']['vmenuManager'].setCurrMenu()
+    def setClipboard(self, text = ''):
+        self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', text)
+    def quitFenrir(self):
+        self.env['runtime']['eventManager'].stopMainEventLoop()
     def defineWindow(self, windowText):
         start = {}
         end = {}
@@ -111,9 +148,9 @@ class remoteManager():
         self.env['runtime']['outputManager'].speakText(text)
     def interruptSpeech(self):
         self.env['runtime']['outputManager'].interruptOutput()
-    def saveSettings(self, settingConfigPath):
+    def saveSettings(self, settingConfigPath = None):
         if not settingConfigPath:
-            return
+            settingConfigPath = self.env['runtime']['settingsManager'].getSettingsFile()
         if settingConfigPath == '':
             return
         self.env['runtime']['settingsManager'].saveSettings(settingConfigPath)
@@ -121,12 +158,14 @@ class remoteManager():
         self.env['runtime']['settingsManager'].resetSettingArgDict()
     def setSettings(self, settingsArgs):
         self.env['runtime']['settingsManager'].parseSettingArgs(settingsArgs)
+        self.env['runtime']['screenManager'].updateScreenIgnored()
+        self.env['runtime']['inputManager'].handleDeviceGrab(force = True)
     def handleRemoteIncomming(self, eventData):
         if not eventData:
             return
         upperEventData = eventData.upper()
         self.env['runtime']['debug'].writeDebugOut('remoteManager:handleRemoteIncomming: event: ' + str(eventData),debug.debugLevel.INFO)
-        
+
         if upperEventData.startswith(self.settingConst):
             settingsText = eventData[len(self.settingConst):]
             self.handleSettingsChange(settingsText)
diff --git a/src/fenrirscreenreader/core/screenManager.py b/src/fenrirscreenreader/core/screenManager.py
index e3bca0d..7ea496d 100644
--- a/src/fenrirscreenreader/core/screenManager.py
+++ b/src/fenrirscreenreader/core/screenManager.py
@@ -24,15 +24,15 @@ class screenManager():
     def initialize(self, environment):
         self.env = environment
         self.env['runtime']['settingsManager'].loadDriver(\
-          self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver')    
-        self.getCurrScreen()  
+          self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver')
         self.getCurrScreen()
-        self.getSessionInformation()        
+        self.getCurrScreen()
+        self.getSessionInformation()
+        self.updateScreenIgnored()
         self.updateScreenIgnored()
-        self.updateScreenIgnored()      
     def resetScreenText(self, screenText):
         self.prevScreenText = ''
-        self.currScreenText = screenText          
+        self.currScreenText = screenText
     def setScreenText(self, screenText):
         self.prevScreenText = self.currScreenText
         self.currScreenText = screenText
@@ -44,58 +44,54 @@ class screenManager():
         except:
             pass
     def getSessionInformation(self):
-        try:    
+        try:
             self.env['runtime']['screenDriver'].getSessionInformation()
         except:
-            pass        
-            
+            pass
     def shutdown(self):
         self.env['runtime']['settingsManager'].shutdownDriver('screenDriver')
     def isCurrScreenIgnoredChanged(self):
         return self.getCurrScreenIgnored() != self.getPrevScreenIgnored()
     def hanldeScreenChange(self, eventData):
         self.getCurrScreen()
-        self.getSessionInformation()        
-        self.updateScreenIgnored()         
+        self.getSessionInformation()
+        self.updateScreenIgnored()
         if self.isCurrScreenIgnoredChanged():
             self.env['runtime']['inputManager'].setExecuteDeviceGrab()
-        self.env['runtime']['inputManager'].handleDeviceGrab()        
-              
-        if self.isScreenChange():                 
+        self.env['runtime']['inputManager'].handleDeviceGrab()
+        if self.isScreenChange():
             self.changeBrailleScreen() 
-
-        if not self.isSuspendingScreen(self.env['screen']['newTTY']):       
+        if not self.isSuspendingScreen(self.env['screen']['newTTY']):
             self.update(eventData, 'onScreenChange')
             self.env['screen']['lastScreenUpdate'] = time.time()
         else:
-            self.env['runtime']['outputManager'].interruptOutput()        
-                 
+            self.env['runtime']['outputManager'].interruptOutput()
     def handleScreenUpdate(self, eventData):
         self.env['screen']['oldApplication'] = self.env['screen']['newApplication'] 
         self.updateScreenIgnored() 
         if self.isCurrScreenIgnoredChanged():
             self.env['runtime']['inputManager'].setExecuteDeviceGrab()
-        self.env['runtime']['inputManager'].handleDeviceGrab()     
-        if not self.getCurrScreenIgnored():       
+        self.env['runtime']['inputManager'].handleDeviceGrab()
+        if not self.getCurrScreenIgnored():
             self.update(eventData, 'onScreenUpdate')
             #if trigger == 'onUpdate' or self.isScreenChange() \
             #  or len(self.env['screen']['newDelta']) > 6:
-            #    self.env['runtime']['screenDriver'].getCurrApplication() 
+            #    self.env['runtime']['screenDriver'].getCurrApplication()
             self.env['screen']['lastScreenUpdate'] = time.time()
-        elif self.isCurrScreenIgnoredChanged():        
-            self.env['runtime']['outputManager'].interruptOutput()              
+        elif self.isCurrScreenIgnoredChanged():
+            self.env['runtime']['outputManager'].interruptOutput()
     def getCurrScreenIgnored(self):
         return self.currScreenIgnored
     def getPrevScreenIgnored(self):
-        return self.prevScreenIgnored      
+        return self.prevScreenIgnored
     def updateScreenIgnored(self):
-        self.prevScreenIgnored = self.currScreenIgnored              
-        self.currScreenIgnored = self.isSuspendingScreen(self.env['screen']['newTTY'])                            
+        self.prevScreenIgnored = self.currScreenIgnored
+        self.currScreenIgnored = self.isSuspendingScreen(self.env['screen']['newTTY'])
     def update(self, eventData, trigger='onUpdate'):
         # set new "old" values
         self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes']
         self.env['screen']['oldContentText'] = self.env['screen']['newContentText']
-        self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy()   
+        self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy()
         self.env['screen']['oldDelta'] = self.env['screen']['newDelta']
         self.env['screen']['oldNegativeDelta'] = self.env['screen']['newNegativeDelta']
         self.env['screen']['newContentBytes'] = eventData['bytes']
@@ -104,7 +100,7 @@ class screenManager():
         self.env['screen']['lines'] = int( eventData['lines'])
         self.env['screen']['columns'] = int( eventData['columns'])
         self.colums = int( eventData['columns'])
-        self.rows = int( eventData['lines'])        
+        self.rows = int( eventData['lines'])
         self.env['screen']['newCursor']['x'] = int( eventData['textCursor']['x'])
         self.env['screen']['newCursor']['y'] = int( eventData['textCursor']['y'])
         self.env['screen']['newTTY'] = eventData['screen']
@@ -113,16 +109,16 @@ class screenManager():
         # screen change
         if self.isScreenChange():
             self.env['screen']['oldContentBytes'] = b''
-            self.resetScreenText(eventData['text'])            
+            self.resetScreenText(eventData['text'])
             self.env['runtime']['attributeManager'].resetAttributes(eventData['attributes'])
-            self.env['runtime']['attributeManager'].resetAttributeCursor()            
+            self.env['runtime']['attributeManager'].resetAttributeCursor()
             self.env['screen']['oldContentText'] = ''
             self.env['screen']['oldCursor']['x'] = 0
             self.env['screen']['oldCursor']['y'] = 0
-            self.env['screen']['oldDelta'] = ''          
-            self.env['screen']['oldNegativeDelta'] = '' 
+            self.env['screen']['oldDelta'] = ''
+            self.env['screen']['oldNegativeDelta'] = ''
         else:
-            self.setScreenText(eventData['text'])        
+            self.setScreenText(eventData['text'])
             self.env['runtime']['attributeManager'].setAttributes(eventData['attributes'])
         # initialize current deltas
         self.env['screen']['newNegativeDelta'] = ''
@@ -131,10 +127,10 @@ class screenManager():
 
         # changes on the screen
         oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
-        newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))        
+        newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
         typing = False
-        diffList = []        
-        
+        diffList = []
+
         if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']):
             if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '':
                 if oldScreenText == '' and\
@@ -142,7 +138,7 @@ class screenManager():
                     self.env['screen']['newDelta'] = newScreenText
             else:
                 cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y']
-                cursorLineEnd = cursorLineStart  + self.env['screen']['columns']         
+                cursorLineEnd = cursorLineStart  + self.env['screen']['columns']
                 if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) >= 1 and \
                   self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \
                   self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \
@@ -152,14 +148,14 @@ class screenManager():
                     #if cursorLineStart < cursorLineStart + self.env['screen']['newCursor']['x'] - 4:
                     #    cursorLineStartOffset = cursorLineStart + self.env['screen']['newCursor']['x'] - 4
                     if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
-                        cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3                                               
+                        cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
                     oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset] 
                     # oldScreenText = re.sub(' +',' ',oldScreenText)
                     newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
                     #newScreenText = re.sub(' +',' ',newScreenText)
                     diff = self.differ.compare(oldScreenText, newScreenText) 
                     diffList = list(diff)
-                    typing = True                    
+                    typing = True
                     tempNewDelta = ''.join(x[2:] for x in diffList if x[0] == '+')
                     if tempNewDelta.strip() != '':
                         if tempNewDelta != ''.join(newScreenText[self.env['screen']['oldCursor']['x']:self.env['screen']['newCursor']['x']].rstrip()):
@@ -167,13 +163,13 @@ class screenManager():
                             typing = False
                 else:
                     diff = self.differ.compare(oldScreenText.split('\n'),\
-                      newScreenText.split('\n'))                    
+                      newScreenText.split('\n'))
                     diffList = list(diff)
 
                 if not typing:
                     self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
                 else:
-                    self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')             
+                    self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
                 self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
 
         # track highlighted
@@ -181,9 +177,9 @@ class screenManager():
             if self.env['runtime']['attributeManager'].isAttributeChange():
                 if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
                     attributeDelta, attributeCursor = self.env['runtime']['attributeManager'].trackHighlights()
-                    if attributeCursor:                    
+                    if attributeCursor:
                         self.env['runtime']['attributeManager'].setAttributeCursor(attributeCursor)
-                        self.env['runtime']['attributeManager'].setAttributeDelta(attributeDelta)                    
+                        self.env['runtime']['attributeManager'].setAttributeDelta(attributeDelta)
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut('screenManager:update:highlight: ' + str(e),debug.debugLevel.ERROR) 
 
@@ -193,10 +189,10 @@ class screenManager():
         ignoreScreens = []
         fixIgnoreScreens = self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreen')
         if fixIgnoreScreens != '':
-            ignoreScreens.extend(fixIgnoreScreens.split(',')) 
+            ignoreScreens.extend(fixIgnoreScreens.split(','))
         if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectSuspendingScreen'):
             ignoreScreens.extend(self.env['screen']['autoIgnoreScreens'])
-        self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ignore:' + str(ignoreScreens) + ' current:'+ str(screen ), debug.debugLevel.INFO)         
+        self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ignore:' + str(ignoreScreens) + ' current:'+ str(screen ), debug.debugLevel.INFO)
         return (screen in ignoreScreens)
  
     def isScreenChange(self):
@@ -208,7 +204,7 @@ class screenManager():
         if ignoreSpace:
             newDelta = newDelta.strip()
         return newDelta != ''
-    def isNegativeDelta(self):    
+    def isNegativeDelta(self):
         return self.env['screen']['newNegativeDelta'] != ''
     def getWindowAreaInText(self, text):
         if not self.env['runtime']['cursorManager'].isApplicationWindowSet():
@@ -220,7 +216,7 @@ class screenManager():
         for line in windowList:
             windowText += line[self.env['commandBuffer']['windowArea'][currApp]['1']['x']:self.env['commandBuffer']['windowArea'][currApp]['2']['x'] + 1] + '\n'
         return windowText
-    
+
     def injectTextToScreen(self, text, screen = None):
         try:
             self.env['runtime']['screenDriver'].injectTextToScreen(text, screen) 
@@ -240,6 +236,6 @@ class screenManager():
                     self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:leveScreen ' + str(e),debug.debugLevel.ERROR) 
         if not self.isSuspendingScreen():
             try:
-                self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY'])      
-            except Exception as e:                
+                self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY'])
+            except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:enterScreen ' + str(e),debug.debugLevel.ERROR) 
diff --git a/src/fenrirscreenreader/core/settingsData.py b/src/fenrirscreenreader/core/settingsData.py
index d69cc0c..5eceffe 100644
--- a/src/fenrirscreenreader/core/settingsData.py
+++ b/src/fenrirscreenreader/core/settingsData.py
@@ -56,7 +56,7 @@ settingsData = {
 'general':{
   'debugLevel': debug.debugLevel.DEACTIVE,
   'debugMode': 'FILE',
-  'debugFile': '/var/log/fenrirscreenreader/fenrir.log',
+  'debugFile': '',
   'punctuationProfile':'default',
   'punctuationLevel': 'some',
   'respectPunctuationPause':True,
@@ -84,7 +84,7 @@ settingsData = {
   'enabled': True,
   'driver': 'unixDriver',
   'port': 22447,
-  'socketpath':'/tmp/',
+  'socketFile':'',
   'enableSettingsRemote': True,
   'enableCommandRemote': True,
 },
@@ -99,6 +99,10 @@ settingsData = {
   'leaveReviewOnCursorChange': True,
   'leaveReviewOnScreenChange': True,
 },
+'menu':{
+  'vmenuPath': '',
+  'quickMenu': 'speech#rate;speech#pitch;speech#volume',
+},
 'promote':{
   'enabled': True,
   'inactiveTimeoutSec': 120,
diff --git a/src/fenrirscreenreader/core/settingsManager.py b/src/fenrirscreenreader/core/settingsManager.py
index cfff6f4..1d9da48 100644
--- a/src/fenrirscreenreader/core/settingsManager.py
+++ b/src/fenrirscreenreader/core/settingsManager.py
@@ -22,6 +22,7 @@ from fenrirscreenreader.core import punctuationManager
 from fenrirscreenreader.core import cursorManager
 from fenrirscreenreader.core import applicationManager
 from fenrirscreenreader.core import helpManager
+from fenrirscreenreader.core import vmenuManager
 from fenrirscreenreader.core import textManager
 from fenrirscreenreader.core import tableManager
 from fenrirscreenreader.core import byteManager
@@ -29,6 +30,7 @@ from fenrirscreenreader.core import attributeManager
 from fenrirscreenreader.core import barrierManager
 from fenrirscreenreader.core import remoteManager
 from fenrirscreenreader.core import sayAllManager
+from fenrirscreenreader.core import quickMenuManager
 from fenrirscreenreader.core import environment 
 from fenrirscreenreader.core.settingsData import settingsData
 from fenrirscreenreader.core import debug
@@ -38,11 +40,14 @@ class settingsManager():
     def __init__(self):
         self.settings = settingsData
         self.settingArgDict = {}
+        self.bindingsBackup = None
+        self.settingsFile = ''
     def initialize(self, environment):
         self.env = environment
     def shutdown(self):
         pass
-        
+    def getBindingBackup(self):
+        return self.bindingsBackup.copy()
     def loadSoundIcons(self, soundIconPath):
         siConfig = open(soundIconPath + '/soundicons.conf',"r")
         while(True):
@@ -71,14 +76,25 @@ class settingsManager():
             self.env['soundIcons'][soundIcon] = soundIconFile
             self.env['runtime']['debug'].writeDebugOut("SoundIcon: " + soundIcon + '.' + soundIconFile, debug.debugLevel.INFO, onAnyLevel=True)               
         siConfig.close()
-    
+    def getSettingsFile(self):
+        return self.settingsFile
+    def setSettingsFile(self, settingsFile):
+        if not os.path.exists(settingsFile):
+            return
+        if not os.access(settingsFile, os.R_OK):
+            return        
+        self.settingsFile = settingsFile
     def loadSettings(self, settingConfigPath):
         if not os.path.exists(settingConfigPath):
             return False
         if not os.access(settingConfigPath, os.R_OK):
             return False
         self.env['settings'] = ConfigParser()
-        self.env['settings'].read(settingConfigPath)
+        try:
+            self.env['settings'].read(settingConfigPath)
+        except:
+            return False
+        self.setSettingsFile(settingConfigPath)
         return True
     def saveSettings(self, settingConfigPath):
         # set opt dict here
@@ -195,6 +211,7 @@ class settingsManager():
                 self.env['input']['scriptKey'].append(key)
     def resetSettingArgDict(self):
         self.settingArgDict = {}
+        self.env['runtime']['outputManager'].resetSpeechDriver()
     def setOptionArgDict(self, section, setting, value):
         #section = section.lower()
         #setting = setting.lower()
@@ -223,18 +240,32 @@ class settingsManager():
             #self.env['runtime']['debug'].writeDebugOut('settingsManager:setOptionArgDict:Datatype missmatch: '+ section + '#' + setting + '=' +  value + ' Error:' +  str(e), debug.debugLevel.ERROR)
             return
 
-
-
     def parseSettingArgs(self, settingArgs):
         for optionElem in settingArgs.split(';'):
-            if len(optionElem.split('#',1)) != 2:
+            settingValList = []
+            sectionOptionList = []
+            section = ''
+            option = ''
+            value = ''
+            settingValList = optionElem.split('=',1)
+            if len(settingValList) != 2:
+                continue
+            if '#' in settingValList[0]:
+                sectionOptionList = settingValList[0].split('#', 1)
+            elif '.' in settingValList[0]:
+                sectionOptionList = settingValList[0].split('.', 1)
+            elif ',' in settingValList[0]:
+                sectionOptionList = settingValList[0].split(',', 1)
+            elif '!' in settingValList[0]:
+                sectionOptionList = settingValList[0].split('!', 1)
+            else:
                 continue
-            if len(optionElem.split('#',1)[1].split('=',1)) != 2:
+            if len(sectionOptionList) != 2:
                 continue
 
-            section = str(optionElem.split('#',1)[0])
-            option = str(optionElem.split('#',1)[1].split('=',1)[0])
-            value = optionElem.split('#',1)[1].split('=',1)[1]
+            section = str(sectionOptionList[0])
+            option = str(sectionOptionList[1])
+            value = str(settingValList[1])
             self.setOptionArgDict(section, option, value)
 
     def initFenrirConfig(self, cliArgs, fenrirManager = None, environment = environment.environment):
@@ -277,7 +308,6 @@ class settingsManager():
             # TODO needs cleanup use dict
             #self.setOptionArgDict('keyboard', 'keyboardLayout', 'pty')
             self.setSetting('keyboard', 'keyboardLayout', 'pty')
-            self.setSetting('general', 'debugFile', '/tmp/fenrir-pty.log')
         if cliArgs.emulated_evdev:
             self.setSetting('screen', 'driver', 'ptyDriver')
             self.setSetting('keyboard', 'driver', 'evdevDriver')
@@ -383,10 +413,21 @@ class settingsManager():
         environment['runtime']['barrierManager'].initialize(environment)
         environment['runtime']['sayAllManager'] = sayAllManager.sayAllManager()
         environment['runtime']['sayAllManager'].initialize(environment)
+        environment['runtime']['vmenuManager'] = vmenuManager.vmenuManager()
+        environment['runtime']['vmenuManager'].initialize(environment)
+        environment['runtime']['quickMenuManager'] = quickMenuManager.quickMenuManager()
+        environment['runtime']['quickMenuManager'].initialize(environment)
+
+        # only possible after having input and screen managers with clean buffer
+        environment['runtime']['inputManager'].writeEventBuffer()
+        environment['runtime']['inputManager'].handleDeviceGrab(force = True)
+
         environment['runtime']['debug'].writeDebugOut('\/-------environment-------\/',debug.debugLevel.INFO, onAnyLevel=True)
         environment['runtime']['debug'].writeDebugOut(str(environment), debug.debugLevel.INFO, onAnyLevel=True)
         environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/', debug.debugLevel.INFO, onAnyLevel=True)
         environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections) , debug.debugLevel.INFO, onAnyLevel=True)
         environment['runtime']['debug'].writeDebugOut('\/-------self.settingArgDict-------\/',debug.debugLevel.INFO, onAnyLevel=True)
         environment['runtime']['debug'].writeDebugOut(str( self.settingArgDict) ,debug.debugLevel.INFO, onAnyLevel=True)
+        self.bindingsBackup = environment['bindings'].copy()
+
         return environment
diff --git a/src/fenrirscreenreader/core/speechDriver.py b/src/fenrirscreenreader/core/speechDriver.py
index ca4df1d..ca37f5d 100644
--- a/src/fenrirscreenreader/core/speechDriver.py
+++ b/src/fenrirscreenreader/core/speechDriver.py
@@ -8,6 +8,8 @@ from fenrirscreenreader.core import debug
 
 class speechDriver():
     def __init__(self):
+        pass
+    def initialize(self, environment):
         self._isInitialized = False
         self.language = None
         self.voice = None
@@ -15,14 +17,12 @@ class speechDriver():
         self.pitch = None
         self.rate = None
         self.volume = None
-    def initialize(self, environment):
         self.env = environment
-        self._isInitialized = True        
-        
+        self._isInitialized = True
     def shutdown(self):
         if self._isInitialized:
             self.cancel()
-        self._isInitialized = False            
+        self._isInitialized = False
 
     def speak(self,text, queueable=True):
         if not self._isInitialized:
@@ -32,11 +32,11 @@ class speechDriver():
     
     def cancel(self):
         if not self._isInitialized:
-            return     
+            return
 
     def setCallback(self, callback):
         if not self._isInitialized:
-            return        
+            return
         if not callback:
             return
 
@@ -48,7 +48,7 @@ class speechDriver():
         if not self._isInitialized:
             return
         if voice == '':
-            return            
+            return
         self.voice = voice 
 
     def setPitch(self, pitch):
@@ -77,16 +77,18 @@ class speechDriver():
         if not isinstance(module, str):
             return
         if module == '':
-            return            
+            return
         self.module = module
-
+    def reset(self):
+        self.shutdown()
+        self.initialize(self.env)
     def setLanguage(self, language):
         if not self._isInitialized:
             return
         if not isinstance(language, str):
             return
         if language == '':
-            return            
+            return
         self.language = language 
     def setVolume(self, volume):
         if not self._isInitialized:
diff --git a/src/fenrirscreenreader/core/vmenuManager.py b/src/fenrirscreenreader/core/vmenuManager.py
new file mode 100755
index 0000000..a106d23
--- /dev/null
+++ b/src/fenrirscreenreader/core/vmenuManager.py
@@ -0,0 +1,262 @@
+#!/bin/python
+# -*- coding: utf-8 -*-
+
+# Fenrir TTY screen reader
+# By Chrys, Storm Dragon, and contributers.
+
+from fenrirscreenreader.core import debug
+from fenrirscreenreader.utils import module_utils
+import os, inspect, time
+
+currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
+fenrirPath = os.path.dirname(currentdir)
+
+class vmenuManager():
+    def __init__(self):
+        self.menuDict = {}
+        self.currIndex = None
+        self.currMenu = ''
+        self.active = False
+        self.reset = True
+        self.useTimeout = True
+        self.searchText = ''
+        self.lastSearchTime = time.time()
+    def initialize(self, environment):
+        self.env = environment
+        # use default path
+        self.defaultVMenuPath = fenrirPath+ "/commands/vmenu-profiles/" + self.env['runtime']['inputManager'].getShortcutType()
+        # if there is no user configuration
+        if self.env['runtime']['settingsManager'].getSetting('menu', 'vmenuPath') != '':
+            self.defaultVMenuPath = self.env['runtime']['settingsManager'].getSetting('menu', 'vmenuPath')
+            if not self.defaultVMenuPath.endswith('/'):
+                self.defaultVMenuPath += '/'
+            self.defaultVMenuPath += self.env['runtime']['inputManager'].getShortcutType()
+
+        self.createMenuTree()
+        self.closeAfterAction = False
+    def shutdown(self):
+        pass
+    def clearSearchText(self):
+        self.searchText = ''
+    def searchEntry(self, value, forceReset = False):
+        if self.currIndex == None:
+            return ''
+        if self.reset or forceReset:
+            self.clearSearchText()
+        else:
+            if self.useTimeout:
+                if time.time() - self.lastSearchTime > 1:
+                    self.clearSearchText()
+        self.searchText += value.upper()
+        self.lastSearchTime = time.time()
+        startIndex = self.getCurrIndex()
+        while True:
+            if not self.nextIndex():
+                return ''
+            entry = self.getCurrentEntry()
+            if entry.upper().startswith(self.searchText):
+                return entry
+            if startIndex == self.getCurrIndex():
+                return ''
+
+    def setCurrMenu(self, currMenu = ''):
+        self.currIndex = None
+        self.currMenu = ''
+        if currMenu != '':
+            currMenu += ' ' + _('Menu')
+            try:
+                t = self.menuDict[currMenu]
+                l = list(self.menuDict.keys())
+                self.currIndex = [l.index(currMenu)]
+            except Exception as e:
+                print(e)
+                self.currMenu = ''
+                self.currIndex = None
+                return
+            if self.incLevel():
+                self.currMenu = currMenu
+            else:
+                self.currMenu = ''
+                self.currIndex = None
+    def getCurrMenu(self):
+        return self.currMenu
+    def getActive(self):
+        return self.active
+    def togglelVMenuMode(self, closeAfterAction = True):
+        self.setActive(not self.getActive(), closeAfterAction)
+    def setActive(self, active, closeAfterAction = True):
+        if self.env['runtime']['helpManager'].isTutorialMode():
+            return
+        self.active = active
+        if self.active:
+            self.closeAfterAction = closeAfterAction
+            try:
+                self.createMenuTree()
+            except Exception as e:
+                print(e)
+            try:
+                if self.currMenu != '':
+                    self.setCurrMenu(self.currMenu)
+                if self.currIndex == None:
+                    if len(self.menuDict) > 0:
+                        self.currIndex = [0]
+            except Exception as e:
+                print(e)
+            try:
+                # navigation
+                self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_VMENU_MODE'
+                self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_VMENU_ENTRY'
+                self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_VMENU_ENTRY'
+                self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_VMENU_ENTRY'
+                self.env['bindings'][str([1, ['KEY_LEFT']])] = 'DEC_LEVEL_VMENU'
+                self.env['bindings'][str([1, ['KEY_RIGHT']])] = 'INC_LEVEL_VMENU'
+                self.env['bindings'][str([1, ['KEY_ENTER']])] = 'EXEC_VMENU_ENTRY'
+                # search
+                self.env['bindings'][str([1, ['KEY_A']])] = 'SEARCH_A'
+                self.env['bindings'][str([1, ['KEY_B']])] = 'SEARCH_B'
+                self.env['bindings'][str([1, ['KEY_C']])] = 'SEARCH_C'
+                self.env['bindings'][str([1, ['KEY_D']])] = 'SEARCH_D'
+                self.env['bindings'][str([1, ['KEY_E']])] = 'SEARCH_E'
+                self.env['bindings'][str([1, ['KEY_F']])] = 'SEARCH_F'
+                self.env['bindings'][str([1, ['KEY_G']])] = 'SEARCH_G'
+                self.env['bindings'][str([1, ['KEY_H']])] = 'SEARCH_H'
+                self.env['bindings'][str([1, ['KEY_I']])] = 'SEARCH_I'
+                self.env['bindings'][str([1, ['KEY_J']])] = 'SEARCH_J'
+                self.env['bindings'][str([1, ['KEY_K']])] = 'SEARCH_K'
+                self.env['bindings'][str([1, ['KEY_L']])] = 'SEARCH_L'
+                self.env['bindings'][str([1, ['KEY_M']])] = 'SEARCH_M'
+                self.env['bindings'][str([1, ['KEY_N']])] = 'SEARCH_N'
+                self.env['bindings'][str([1, ['KEY_O']])] = 'SEARCH_O'
+                self.env['bindings'][str([1, ['KEY_P']])] = 'SEARCH_P'
+                self.env['bindings'][str([1, ['KEY_Q']])] = 'SEARCH_Q'
+                self.env['bindings'][str([1, ['KEY_R']])] = 'SEARCH_R'
+                self.env['bindings'][str([1, ['KEY_S']])] = 'SEARCH_S'
+                self.env['bindings'][str([1, ['KEY_T']])] = 'SEARCH_T'
+                self.env['bindings'][str([1, ['KEY_U']])] = 'SEARCH_U'
+                self.env['bindings'][str([1, ['KEY_V']])] = 'SEARCH_V'
+                self.env['bindings'][str([1, ['KEY_W']])] = 'SEARCH_W'
+                self.env['bindings'][str([1, ['KEY_X']])] = 'SEARCH_X'
+                self.env['bindings'][str([1, ['KEY_Y']])] = 'SEARCH_Y'
+                self.env['bindings'][str([1, ['KEY_Z']])] = 'SEARCH_Z'
+            except Exception as e:
+                print(e)
+        else:
+            try:
+                self.currIndex = None
+                self.env['bindings'] = self.env['runtime']['settingsManager'].getBindingBackup()
+            except:
+                pass
+    def createMenuTree(self, resetIndex = True):
+        if resetIndex:
+            self.currIndex = None
+        menu = self.fs_tree_to_dict( self.defaultVMenuPath)
+        if menu:
+            self.menuDict = menu
+        # index still valid?
+        if self.currIndex != None:
+            try:
+                r = self.getValueByPath(self.menuDict, self.currIndex)
+                if r == {}:
+                    self.currIndex = None
+            except:
+                self.currIndex = None        
+    def executeMenu(self):
+        if self.currIndex == None:
+            return
+        try:
+            command = self.getValueByPath(self.menuDict, self.currIndex)
+            if not command == None:
+                command.run()
+                if self.closeAfterAction:
+                    self.setActive(False)
+        except Exception as e:
+            try:
+                self.incLevel()
+                text = self.getCurrentEntry()
+                self.env['runtime']['outputManager'].presentText(text, interrupt=True)                
+            except:
+                print(e)
+
+    def incLevel(self):
+        if self.currIndex == None:
+            return False
+        try:
+            r = self.getValueByPath(self.menuDict, self.currIndex +[0])
+            if r == {}:
+                return False
+        except:
+            return False
+        self.currIndex.append(0)
+        return True
+    def decLevel(self):
+        if self.currIndex == None:
+            return False
+        if self.currMenu != '':
+            if len(self.currIndex) <= 2:
+                return False
+        elif len(self.currIndex) == 1:
+            return False
+        self.currIndex = self.currIndex[:len(self.currIndex) - 1]
+        return True
+    def nextIndex(self):
+        if self.currIndex == None:
+            return False
+        if self.currIndex[len(self.currIndex) - 1] + 1 >= len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])):
+           self.currIndex[len(self.currIndex) - 1] = 0 
+        else:
+            self.currIndex[len(self.currIndex) - 1] += 1
+        return True
+    def getCurrIndex(self):
+        if self.currIndex == None:
+            return 0        
+        return self.currIndex[len(self.currIndex) - 1]
+    def prevIndex(self):
+        if self.currIndex == None:
+            return False
+        if self.currIndex[len(self.currIndex) - 1] == 0:
+           self.currIndex[len(self.currIndex) - 1] = len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])) - 1
+        else:
+            self.currIndex[len(self.currIndex) - 1] -= 1
+        return True
+
+    def getCurrentEntry(self):
+        return self.getKeysByPath(self.menuDict, self.currIndex)[self.currIndex[-1]]
+    def fs_tree_to_dict(self, path_):
+        for root, dirs, files in os.walk(path_):
+            tree = {d + ' ' + _('Menu'): self.fs_tree_to_dict(os.path.join(root, d)) for d in dirs if not d.startswith('__')}
+            for f in files:
+                try:
+                    fileName, fileExtension = os.path.splitext(f)
+                    fileName = fileName.split('/')[-1]
+                    if fileName.startswith('__'):
+                        continue
+                    command = self.env['runtime']['commandManager'].loadFile(root + '/' + f)
+                    tree.update({fileName + ' ' + _('Action'): command})
+                except Exception as e:
+                    print(e)
+            return tree  # note we discontinue iteration trough os.walk
+    def getNestedByPath(self, complete, path):
+        path = path.copy()
+        if path != []:
+            index = list(complete.keys())[path[0]]
+            nested = self.getNestedByPath(complete[index], path[1:])
+            return nested
+        else:
+            return complete
+
+
+    def getKeysByPath(self, complete, path):
+        if not isinstance(complete, dict):
+            return[]
+        d = complete
+        for i in path[:-1]:
+            d = d[list(d.keys())[i]]
+        return list(d.keys())
+
+    def getValueByPath(self, complete, path):
+        if not isinstance(complete, dict):
+            return complete
+        d = complete.copy()
+        for i in path:
+            d = d[list(d.keys())[i]]
+        return d
diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py
index e5158ce..f81e596 100644
--- a/src/fenrirscreenreader/fenrirVersion.py
+++ b/src/fenrirscreenreader/fenrirVersion.py
@@ -4,5 +4,5 @@
 # Fenrir TTY screen reader
 # By Chrys, Storm Dragon, and contributers.
 
-version = '1.9.4'
-codename = 'tucher'
+version = '1.9.7'
+codename = 'krug'
diff --git a/src/fenrirscreenreader/inputDriver/debugDriver.py b/src/fenrirscreenreader/inputDriver/debugDriver.py
index d4868bb..fce1325 100644
--- a/src/fenrirscreenreader/inputDriver/debugDriver.py
+++ b/src/fenrirscreenreader/inputDriver/debugDriver.py
@@ -14,14 +14,14 @@ class driver(inputDriver):
         
     def initialize(self, environment):
         self.env = environment
-        self.env['runtime']['inputManager'].setShortcutType('KEY')        
-        self._initialized = True        
-        print('Input Debug Driver: Initialized')    
+        self.env['runtime']['inputManager'].setShortcutType('KEY')
+        self._initialized = True
+        print('Input Debug Driver: Initialized')
         
     def shutdown(self):
         if self._initialized:
-            self.removeAllDevices()       
-        self._initialized = False    
+            self.removeAllDevices()
+        self._initialized = False
         print('Input Debug Driver: Shutdown')
         
     def getInputEvent(self):
@@ -32,32 +32,32 @@ class driver(inputDriver):
         return None
     def writeEventBuffer(self):
         if not self._initialized:
-            return    
+            return
         print('Input Debug Driver: writeEventBuffer')
     def clearEventBuffer(self):
         if not self._initialized:
-            return    
-        del self.env['input']['eventBuffer'][:]            
+            return
+        del self.env['input']['eventBuffer'][:]
         print('Input Debug Driver: clearEventBuffer')
     def updateInputDevices(self, newDevices = None, init = False):
         if not self._initialized:
-            return    
+            return
         print('Input Debug Driver: updateInputDevices') 
     def getLedState(self, led = 0):
         if not self._initialized:
-            return False    
-        return False          
+            return False
+        return False
     def toggleLedState(self, led = 0):
         if not self._initialized:
-            return    
+            return
         print('Input Debug Driver: toggleLedState')
     def grabAllDevices(self):
         if not self._initialized:
-            return    
+            return
         print('Input Debug Driver: grabAllDevices')
     def ungrabAllDevices(self):
         if not self._initialized:
-            return    
+            return
         print('Input Debug Driver: ungrabAllDevices')
         
     def removeAllDevices(self):
@@ -67,6 +67,6 @@ class driver(inputDriver):
     def __del__(self):
         if self._initialized:
             self.removeAllDevices()
-        print('Input Debug Driver: __del__')        
+        print('Input Debug Driver: __del__')
 
 
diff --git a/src/fenrirscreenreader/inputDriver/evdevDriver.py b/src/fenrirscreenreader/inputDriver/evdevDriver.py
index 76338a6..792b07d 100644
--- a/src/fenrirscreenreader/inputDriver/evdevDriver.py
+++ b/src/fenrirscreenreader/inputDriver/evdevDriver.py
@@ -1,6 +1,3 @@
-#!/bin/python
-# -*- coding: utf-8 -*-
-
 # Fenrir TTY screen reader
 # By Chrys, Storm Dragon, and contributers.
 
@@ -10,7 +7,7 @@ _evdevAvailableError = ''
 _udevAvailableError = ''
 try:
     import evdev
-    from evdev import InputDevice, UInput
+    from evdev import InputDevice, UInput, ecodes as e
     _evdevAvailable = True
 
 except Exception as e:
@@ -43,54 +40,67 @@ class driver(inputDriver):
         self.gDevices = {}
         self.iDeviceNo = 0
         self.watchDog = Value(c_bool, True)
+        self.UInputinject = UInput()
     def initialize(self, environment):
         self.env = environment
         self.env['runtime']['inputManager'].setShortcutType('KEY')
         global _evdevAvailable
         global _udevAvailable
-        self._initialized = _evdevAvailable and _udevAvailable
-        if not self._initialized:
-            global _evdevAvailableError
-            global _udevAvailableError
-            currError = ' '
-            if not _evdevAvailable:
-                currError += _evdevAvailableError
-            if not _udevAvailable:
-                currError += ' ' + _udevAvailableError
-            self.env['runtime']['debug'].writeDebugOut('InputDriver:' + currError, debug.debugLevel.ERROR)
-            return  
+        global _evdevAvailableError
+        global _udevAvailableError
+        if not _udevAvailable:
+            self.env['runtime']['debug'].writeDebugOut('InputDriver:' + _udevAvailableError, debug.debugLevel.ERROR)            
+        if not _evdevAvailable:
+            self.env['runtime']['debug'].writeDebugOut('InputDriver:' + _evdevAvailableError, debug.debugLevel.ERROR)
+            return
 
-        self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev)
+        if _udevAvailable:
+            self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev)
         self.env['runtime']['processManager'].addCustomEventThread(self.inputWatchdog)
+        self._initialized = True
+
     def plugInputDeviceWatchdogUdev(self,active , eventQueue):
         context = pyudev.Context()
         monitor = pyudev.Monitor.from_netlink(context)
         monitor.filter_by(subsystem='input')
         monitor.start()
+        ignorePlug = False
         while active.value:
             validDevices = []
             device = monitor.poll(1)
             while device:
                 self.env['runtime']['debug'].writeDebugOut('plugInputDeviceWatchdogUdev:' + str(device), debug.debugLevel.INFO)
                 try:
-                    if not '/sys/devices/virtual/input/' in device.sys_path:
+                    try:
+                        if device.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']:
+                            ignorePlug = True
+                        if device.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']:
+                            ignorePlug = True
+                        if 'BRLTTY' in  device.name.upper():
+                            ignorePlug = True
+                    except Exception as e:
+                        self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev CHECK NAME CRASH: " + str(e),debug.debugLevel.ERROR)
+                    if not ignorePlug:
+                        virtual = '/sys/devices/virtual/input/' in device.sys_path
                         if device.device_node:
-                            validDevices.append(str(device.device_node))
-                except:                    
-                    pass
+                            validDevices.append({'device': device.device_node, 'virtual': virtual})
+                except Exception as e:
+                    self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev APPEND CRASH: " + str(e),debug.debugLevel.ERROR)
                 try:
-                    device = monitor.poll(0.1)                
-                except:                    
+                    pollTimeout = 1
+                    device = monitor.poll(pollTimeout)
+                except:
                     device = None
+                ignorePlug = False
             if validDevices:
                 eventQueue.put({"Type":fenrirEventType.PlugInputDevice,"Data":validDevices})
-        return time.time()       
-         
+        return time.time()
+
     def inputWatchdog(self,active , eventQueue):
         try:
             while active.value:
                 r, w, x = select(self.iDevices, [], [], 0.8)
-                event = None                        
+                event = None
                 foundKeyInSequence = False
                 foreward = False
                 eventFired = False
@@ -137,12 +147,13 @@ class driver(inputDriver):
                     if self.gDevices[iDevice.fd]:
                         self.writeUInput(uDevice, event)
             except Exception as e:
-                pass           
+                pass
 
     def writeUInput(self, uDevice, event):
         if not self._initialized:
-            return    
+            return
         uDevice.write_event(event)
+        time.sleep(0.0000002)
         uDevice.syn()
 
     def updateInputDevices(self, newDevices = None, init = False):
@@ -152,6 +163,8 @@ class driver(inputDriver):
         deviceFileList = None
 
         if newDevices and not init:
+            if not isinstance(newDevices, list):
+                newDevices = [newDevices]
             deviceFileList = newDevices
         else:
             deviceFileList = evdev.list_devices()
@@ -188,10 +201,10 @@ class driver(inputDriver):
                 except:
                     continue
                 try:
-                    if currDevice.name.upper() in ['','SPEAKUP','PY-EVDEV-UINPUT']:
-                        continue                
-                    if currDevice.phys.upper() in ['','SPEAKUP','PY-EVDEV-UINPUT']:
-                        continue                    
+                    if currDevice.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']:
+                        continue
+                    if currDevice.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']:
+                        continue
                     if 'BRLTTY' in  currDevice.name.upper():
                         continue
                 except:
@@ -200,25 +213,25 @@ class driver(inputDriver):
                 if mode in ['ALL','NOMICE']:
                     if eventType.EV_KEY in cap:
                         if 116 in cap[eventType.EV_KEY] and len(cap[eventType.EV_KEY]) < 10:
-                            self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name,debug.debugLevel.INFO)                                                                
+                            self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name,debug.debugLevel.INFO)
                             continue
                         if len(cap[eventType.EV_KEY]) < 60:
-                            self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name,debug.debugLevel.INFO)                                                                                        
-                            continue                                                   
+                            self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name,debug.debugLevel.INFO)
+                            continue
                         if mode == 'ALL':
                             self.addDevice(currDevice)
-                            self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO)                           
+                            self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO)
                         elif mode == 'NOMICE':
                             if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)):
                                 self.addDevice(currDevice)
-                                self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO)                                                
+                                self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO)
                             else:
-                                self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name,debug.debugLevel.INFO)      
+                                self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name,debug.debugLevel.INFO)
                     else:
-                        self.env['runtime']['debug'].writeDebugOut('Device Skipped (no EV_KEY):' + currDevice.name,debug.debugLevel.INFO)                                                                                       
+                        self.env['runtime']['debug'].writeDebugOut('Device Skipped (no EV_KEY):' + currDevice.name,debug.debugLevel.INFO)
                 elif currDevice.name.upper() in mode.split(','):
                     self.addDevice(currDevice)
-                    self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) 
+                    self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO)
             except Exception as e:
                 self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile +' ' + currDevice.name +' '+ str(e),debug.debugLevel.INFO)
         self.iDeviceNo = len(evdev.list_devices())
@@ -231,12 +244,12 @@ class driver(inputDriver):
                     self.iDevicesFD.append(fd)
             for fd in self.iDevicesFD:
                 if not fd in self.iDevices:
-                    self.iDevicesFD.remove(fd)  
+                    self.iDevicesFD.remove(fd)
         except:
             pass
     def mapEvent(self, event):
         if not self._initialized:
-            return None    
+            return None
         if not event:
             return None
         mEvent = inputData.inputEvent
@@ -251,47 +264,51 @@ class driver(inputDriver):
                             mEvent['EventName'] = mEvent['EventName'][0]
             mEvent['EventValue'] = event.code
             mEvent['EventSec'] = event.sec
-            mEvent['EventUsec'] = event.usec                
+            mEvent['EventUsec'] = event.usec
             mEvent['EventState'] = event.value
             mEvent['EventType']  = event.type
             return mEvent
         except Exception as e:
             return None
-       
+
     def getLedState(self, led = 0):
         if not self.hasIDevices():
-            return False    
+            return False
         # 0 = Numlock
         # 1 = Capslock
         # 2 = Rollen
         for fd, dev in self.iDevices.items():
             if led in dev.leds():
                 return True
-        return False          
+        return False
     def toggleLedState(self, led = 0):
         if not self.hasIDevices():
-            return False    
+            return False
         ledState = self.getLedState(led)
         for i in self.iDevices:
             if self.gDevices[i]:
                 # 17 LEDs
-                if 17 in self.iDevices[i].capabilities():            
+                if 17 in self.iDevices[i].capabilities():
                     if ledState == 1:
                         self.iDevices[i].set_led(led , 0)
                     else:
                         self.iDevices[i].set_led(led , 1)
     def grabAllDevices(self):
         if not self._initialized:
-            return
+            return True
+        ok = True
         for fd in self.iDevices:
-            self.grabDevice(fd)  
-
+            if not self.gDevices[fd]:
+                ok = ok and self.grabDevice(fd)
+        return ok
     def ungrabAllDevices(self):
         if not self._initialized:
-            return
+            return True
+        ok = True
         for fd in self.iDevices:
-            self.ungrabDevice(fd)
-
+            if self.gDevices[fd]:
+                ok = ok and self.ungrabDevice(fd)
+        return ok
     def createUInputDev(self, fd):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
             self.uDevices[fd] = None
@@ -303,48 +320,75 @@ class driver(inputDriver):
             self.uDevices[fd] = None
         if self.uDevices[fd] != None:
             return
-        try:      
-            self.uDevices[fd] = UInput.from_device(self.iDevices[fd])            
+        try:
+            self.uDevices[fd] = UInput.from_device(self.iDevices[fd], name='fenrir-uinput', phys='fenrir-uinput')
         except Exception as e:
             try:
-                self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback:  ' + str(e),debug.debugLevel.WARNING)         
+                self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback:  ' + str(e),debug.debugLevel.WARNING)
                 dev = self.iDevices[fd]
                 cap = dev.capabilities()
                 del cap[0]
                 self.uDevices[fd] = UInput(
                   cap,
-                  dev.name,
+                  name = 'fenrir-uinput',
+                  phys = 'fenrir-uinput'
                 )
             except Exception as e:
-                self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible:  ' + str(e),debug.debugLevel.ERROR)         
-                return               
+                self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible:  ' + str(e),debug.debugLevel.ERROR)
+                return
     def addDevice(self, newDevice):
-        self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device added:  ' + str(newDevice.fd) + ' ' +str(newDevice),debug.debugLevel.INFO)      
-        self.iDevices[newDevice.fd] = newDevice  
-        self.gDevices[newDevice.fd] = False                      
-        self.createUInputDev(newDevice.fd)
+        self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device added:  ' + str(newDevice.fd) + ' ' +str(newDevice),debug.debugLevel.INFO)
+        try:
+            self.iDevices[newDevice.fd] = newDevice  
+            self.createUInputDev(newDevice.fd)
+            self.gDevices[newDevice.fd] = False
+        except:
+            # if it doesnt work clean up
+            try:
+                del(self.iDevices[newDevice.fd])
+            except:
+                pass
+            try:
+                del(self.uDevices[newDevice.fd])
+            except:
+                pass
+            try:
+                del(self.gDevices[newDevice.fd])
+            except:
+                pass
     def grabDevice(self, fd):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
-            return
+            return True
         try:
             self.iDevices[fd].grab()
             self.gDevices[fd] = True
-            self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grab device ('+ str(self.iDevices[fd].name) + ')',debug.debugLevel.INFO)            
-        except IOError:            
-            self.gDevices[fd] = True            
+            self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grab device ('+ str(self.iDevices[fd].name) + ')',debug.debugLevel.INFO)
+        except IOError:
+            if not self.gDevices[fd]:
+                return False
+        #    self.gDevices[fd] = True
+        #    #self.removeDevice(fd)
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible:  ' + str(e),debug.debugLevel.ERROR)         
+            self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible:  ' + str(e),debug.debugLevel.ERROR)
+            return False
+        return True
     def ungrabDevice(self,fd):
         if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
-            return      
+            return True
         try:
-            self.gDevices[fd] = False                    
             self.iDevices[fd].ungrab()
+            self.gDevices[fd] = False
             self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrab device ('+ str(self.iDevices[fd].name) + ')',debug.debugLevel.INFO)
-        except:
-            pass    
+        except IOError:
+            if self.gDevices[fd]:
+                return False
+        #    self.gDevices[fd] = False
+        #    #self.removeDevice(fd)
+        except Exception as e:
+            return False
+        return True
     def removeDevice(self,fd):
-        self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed:  ' + str(fd) + ' ' +str(self.iDevices[fd]),debug.debugLevel.INFO)         
+        self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed:  ' + str(fd) + ' ' +str(self.iDevices[fd]),debug.debugLevel.INFO)
         self.clearEventBuffer()
         try:
             self.ungrabDevice(fd)
@@ -365,13 +409,13 @@ class driver(inputDriver):
         try:
             del(self.uDevices[fd])
         except:
-            pass  
+            pass
         try:
             del(self.gDevices[fd])
         except:
-            pass              
+            pass
         self.updateMPiDevicesFD()
-                 
+
     def hasIDevices(self):
         if not self._initialized:
             return False
@@ -379,7 +423,16 @@ class driver(inputDriver):
             return False
         if len(self.iDevices) == 0:
             return False
-        return True    
+        return True
+
+    def sendKey(self, key, state):
+        if not self._initialized:
+            return
+        try:
+            self.UInputinject.write(e.EV_KEY, e.ecodes[key], state)
+            self.UInputinject.syn()
+        except:
+            pass
 
     def removeAllDevices(self):
         if not self.hasIDevices():
@@ -389,5 +442,5 @@ class driver(inputDriver):
             self.removeDevice(fd)
         self.iDevices.clear()
         self.uDevices.clear()
-        self.gDevices.clear()        
+        self.gDevices.clear()
         self.iDeviceNo = 0 
diff --git a/src/fenrirscreenreader/inputDriver/ptyDriver.py b/src/fenrirscreenreader/inputDriver/ptyDriver.py
index c078035..5a2b545 100644
--- a/src/fenrirscreenreader/inputDriver/ptyDriver.py
+++ b/src/fenrirscreenreader/inputDriver/ptyDriver.py
@@ -10,9 +10,9 @@ from fenrirscreenreader.core.inputDriver import inputDriver
 
 class driver(inputDriver):
     def __init__(self):
-        self._isInitialized = False    
+        self._isInitialized = False
         inputDriver.__init__(self)
     def initialize(self, environment):
         self.env = environment
         self.env['runtime']['inputManager'].setShortcutType('BYTE')
-        self._isInitialized = True    
+        self._isInitialized = True
diff --git a/src/fenrirscreenreader/remoteDriver/tcpDriver.py b/src/fenrirscreenreader/remoteDriver/tcpDriver.py
index 9b6e640..3bde7ad 100644
--- a/src/fenrirscreenreader/remoteDriver/tcpDriver.py
+++ b/src/fenrirscreenreader/remoteDriver/tcpDriver.py
@@ -18,30 +18,36 @@ class driver(remoteDriver):
         self.env['runtime']['processManager'].addCustomEventThread(self.watchDog, multiprocess=True)
     def watchDog(self, active, eventQueue):
         # echo "command say this is a test" | nc localhost 22447
-        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        self.fenrirSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.fenrirSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         self.host = '127.0.0.1'
         self.port = self.env['runtime']['settingsManager'].getSettingAsInt('remote', 'port')
-        self.sock.bind((self.host, self.port))
-        self.sock.listen(1)
-        while active.value == 1:
-            client_sock, client_addr = self.sock.accept()
-            if client_sock:
-                # Check if the client is still connected and if data is available:
-                try:
-                    r, w, e = select.select([client_sock,], [], [])
-                except select.error:
-                    return
-                if len(r) > 0:
-                    rawdata = client_sock.recv(8129)
-                    try:
-                        data = rawdata.decode("utf-8").rstrip().lstrip()
-                        eventQueue.put({"Type":fenrirEventType.RemoteIncomming,
-                            "Data": data
-                        })
-                    except:
-                        pass
+        self.fenrirSock.bind((self.host, self.port))
+        self.fenrirSock.listen(1)
+        while active.value:
+            try:
+                r, _, _ = select.select([self.fenrirSock], [], [], 0.8)
+            except select.error:
+                break
+            if r == []:
+                continue
+            if self.fenrirSock in r:
+                client_sock, client_addr = self.fenrirSock.accept()
+            try:
+                rawdata = client_sock.recv(8129)
+            except:
+                pass
+            try:
+                data = rawdata.decode("utf-8").rstrip().lstrip()
+                eventQueue.put({"Type":fenrirEventType.RemoteIncomming,
+                    "Data": data
+                })
+            except:
+                pass
+            try:
                 client_sock.close()
-        if self.sock:
-            self.sock.close()
-            self.sock = None
+            except:
+                pass
+        if self.fenrirSock:
+            self.fenrirSock.close()
+            self.fenrirSock = None
diff --git a/src/fenrirscreenreader/remoteDriver/unixDriver.py b/src/fenrirscreenreader/remoteDriver/unixDriver.py
index 83032e8..b4ba41c 100644
--- a/src/fenrirscreenreader/remoteDriver/unixDriver.py
+++ b/src/fenrirscreenreader/remoteDriver/unixDriver.py
@@ -19,39 +19,49 @@ class driver(remoteDriver):
         self.env['runtime']['processManager'].addCustomEventThread(self.watchDog, multiprocess=True)
     def watchDog(self, active, eventQueue):
         # echo "command say this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
-
-        if self.env['runtime']['settingsManager'].getSetting('screen', 'driver') =='vcsaDriver':
-            socketpath = self.env['runtime']['settingsManager'].getSettingAsInt('remote', 'socketpath') + 'fenrirscreenreader-deamon.sock'
-        else:
-            socketpath = self.env['runtime']['settingsManager'].getSettingAsInt('remote', 'socketpath') + 'fenrirscreenreader-' + str(os.getpid()) + '.sock'
-        if os.path.exists(socketpath):
-            os.remove(socketpath)
-        self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        self.sock.bind(socketpath)
-        self.sock.listen(1)
-        if self.env['runtime']['settingsManager'].getSetting('screen', 'driver') =='vcsaDriver':
-            os.chmod(socketpath, 0o222)
-        while active.value == 1:
-            client_sock, client_addr = self.sock.accept()
-            if client_sock:
-                # Check if the client is still connected and if data is available:
-                try:
-                    r, w, e = select.select([client_sock,], [], [])
-                except select.error:
-                    return
-                if len(r) > 0:
-                    rawdata = client_sock.recv(8129)
-                    try:
-                        data = rawdata.decode("utf-8").rstrip().lstrip()
-                        eventQueue.put({"Type":fenrirEventType.RemoteIncomming,
-                            "Data": data
-                        })
-                    except:
-                        pass
+        socketFile = ''
+        try:
+            socketFile = self.env['runtime']['settingsManager'].getSetting('remote', 'socketFile')
+        except:
+            pass
+        if socketFile == '':
+            if self.env['runtime']['settingsManager'].getSetting('screen', 'driver') =='vcsaDriver':
+                socketFile =  '/tmp/fenrirscreenreader-deamon.sock'
+            else:
+                socketFile = '/tmp/fenrirscreenreader-' + str(os.getppid()) + '.sock'
+        if os.path.exists(socketFile):
+            os.unlink(socketFile)
+        self.fenrirSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+        self.fenrirSock.bind(socketFile)
+        os.chmod(socketFile, 0o222)
+        self.fenrirSock.listen(1)
+        while active.value:
+            # Check if the client is still connected and if data is available:
+            try:
+                r, _, _ = select.select([self.fenrirSock], [], [], 0.8)
+            except select.error:
+                break
+            if r == []:
+                continue
+            if self.fenrirSock in r:
+                client_sock, client_addr = self.fenrirSock.accept()
+            try:
+                rawdata = client_sock.recv(8129)
+            except:
+                pass
+            try:
+                data = rawdata.decode("utf-8").rstrip().lstrip()
+                eventQueue.put({"Type":fenrirEventType.RemoteIncomming,
+                    "Data": data
+                })
+            except:
+                pass
+            try:
                 client_sock.close()
-
-        if os.path.exists(socketpath):
-            os.remove(socketpath)
-        if self.sock:
-            self.sock.close()
-            self.sock = None
+            except:
+                pass
+        if self.fenrirSock:
+            self.fenrirSock.close()
+            self.fenrirSock = None
+        if os.path.exists(socketFile):
+            os.unlink(socketFile)
diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py
index 314abaf..e61ff3f 100644
--- a/src/fenrirscreenreader/screenDriver/ptyDriver.py
+++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py
@@ -4,34 +4,39 @@
 # Fenrir TTY screen reader
 # By Chrys, Storm Dragon, and contributers.
 
-import os, struct, sys, pty, tty, termios, shlex, signal, select, pyte, time, fcntl ,getpass
+import os, struct, sys, pty, tty, termios, shlex, signal, pyte, time, fcntl ,getpass
+from select import select
 from fenrirscreenreader.core import debug
 from fenrirscreenreader.core.eventData import fenrirEventType
 from fenrirscreenreader.core.screenDriver import screenDriver
 from fenrirscreenreader.utils import screen_utils
 
+
+class fenrirScreen(pyte.Screen):
+    def set_margins(self, *args, **kwargs):
+        kwargs.pop("private", None)
+        super(fenrirScreen, self).set_margins(*args, **kwargs)
+
 class Terminal:
     def __init__(self, columns, lines, p_in):
         self.text = ''
         self.attributes = None
-        self.screen = pyte.HistoryScreen(columns, lines)
-        self.screen.set_mode(pyte.modes.LNM)
+        self.screen = fenrirScreen(columns, lines)
         self.screen.write_process_input = \
             lambda data: p_in.write(data.encode())
         self.stream = pyte.ByteStream()
         self.stream.attach(self.screen)
     def feed(self, data):
         self.stream.feed(data)
-            
+
     def updateAttributes(self, initialize = False):
-        buffer = self.screen.buffer    
+        buffer = self.screen.buffer
         lines = None
         if not initialize:
             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()]            
-            
+            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]
@@ -55,26 +60,28 @@ class Terminal:
         if yPos == -1:
             yPos = 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)            
+        self.screen.cursor.y = min(self.screen.cursor.y, self.screen.lines - 1)
     def GetScreenContent(self):
         cursor = self.screen.cursor
         self.text = '\n'.join(self.screen.display)
         self.updateAttributes(self.attributes == None)
-        self.screen.dirty.clear()            
+        self.screen.dirty.clear()
         return {"cursor": (cursor.x, cursor.y),
             'lines': self.screen.lines,
             'columns': self.screen.columns,
             "text": self.text, 
             'attributes': self.attributes.copy(),
-            'screen': 'pty',        
-            'screenUpdateTime': time.time(),                            
+            'screen': 'pty',
+            'screenUpdateTime': time.time(),
         }.copy()
 
 class driver(screenDriver):
     def __init__(self):
-        screenDriver.__init__(self)  
+        screenDriver.__init__(self)
         self.signalPipe = os.pipe()
         self.p_out = None
+        self.terminal = None
+        self.p_pid = -1
         signal.signal(signal.SIGWINCH, self.handleSigwinch)
     def initialize(self, environment):
         self.env = environment
@@ -96,36 +103,40 @@ class driver(screenDriver):
         self.env['screen']['autoIgnoreScreens'] = []
         self.env['general']['prevUser'] = getpass.getuser()
         self.env['general']['currUser'] = getpass.getuser()
-    def readAll(self, fd, timeout = 9999999, interruptFd = None, len = 2048):
-        bytes = b'' 
+    def readAll(self, fd, timeout = 0.3, interruptFd = None, len = 65536):
+        msgBytes = b'' 
         fdList = []
-        fdList += [fd]        
+        fdList += [fd]
         if interruptFd:
             fdList += [interruptFd]
         starttime = time.time()
         while True:
-            # respect timeout but wait a little bit of time to see if something more is here
-            if (time.time() - starttime) >= timeout:
-                break            
-            r = screen_utils.hasMoreWhat(fdList,0)
-            hasmore = fd in r
-            if not hasmore:
-                break
-            # exit on interrupt available
-            if interruptFd in r:
+            r = screen_utils.hasMoreWhat(fdList, 0.0001)
+            # nothing more to read
+            if not fd in r:
                 break
             data = os.read(fd, len)
             if data == b'':
                 raise EOFError
-            bytes += data
-        return bytes      
+            msgBytes += data
+            # exit on interrupt available
+            if interruptFd in r:
+                break
+            # respect timeout but wait a little bit of time to see if something more is here
+            if (time.time() - starttime) >= timeout:
+                break
+        return msgBytes
     def openTerminal(self, columns, lines, command):
         p_pid, master_fd = pty.fork()
         if p_pid == 0:  # Child.
             argv = shlex.split(command)
             env = os.environ.copy()
             #values are VT100,xterm-256color,linux
-            env["TERM"] = 'linux'
+            try: 
+                if env["TERM"] == '':
+                    env["TERM"] = 'linux'
+            except:
+                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)
@@ -141,20 +152,20 @@ class driver(screenDriver):
         lines, columns, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s))
         return lines, columns
     def handleSigwinch(self, *args):
-        os.write(self.signalPipe[1], b'w')        
+        os.write(self.signalPipe[1], b'w')
     def terminalEmulation(self,active , eventQueue):
         try:
-            old_attr = termios.tcgetattr(sys.stdin)    
+            old_attr = termios.tcgetattr(sys.stdin)
             tty.setraw(0)
             lines, columns = self.getTerminalSize(0)
             if self.command == '':
                 self.command = screen_utils.getShell()
-            terminal, p_pid, self.p_out = self.openTerminal(columns, lines, self.command)
+            self.terminal, self.p_pid, self.p_out = self.openTerminal(columns, lines, self.command)
             lines, columns = self.resizeTerminal(self.p_out)
-            terminal.resize(lines, columns)            
+            self.terminal.resize(lines, columns)
             fdList = [sys.stdin, self.p_out, self.signalPipe[0]]
             while active.value:
-                r, _, _ = select.select(fdList, [], [], 1)
+                r, _, _ = select(fdList, [], [], 1)
                 # none
                 if r == []:
                     continue
@@ -162,41 +173,43 @@ class driver(screenDriver):
                 if self.signalPipe[0] in r:
                     os.read(self.signalPipe[0], 1)
                     lines, columns = self.resizeTerminal(self.p_out)
-                    terminal.resize(lines, columns)   
+                    self.terminal.resize(lines, columns)
                 # input
                 if sys.stdin in r:
                     try:
-                        msgBytes = self.readAll(sys.stdin.fileno())
+                        msgBytes = self.readAll(sys.stdin.fileno(), len=4096)
                     except (EOFError, OSError):
-                        active.value = False                    
-                        break                  
+                        eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) 
+                        break
                     if self.shortcutType == 'KEY':
                         try:
                             self.injectTextToScreen(msgBytes)
                         except:
-                            active.value = False                    
+                            eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) 
                             break
-                    else:    
+                    else:
                         eventQueue.put({"Type":fenrirEventType.ByteInput,
-                            "Data":msgBytes })                     
+                            "Data":msgBytes })
                 # output
                 if self.p_out in r:
                     try:
-                        msgBytes = self.readAll(self.p_out.fileno(), timeout=0.001, interruptFd=sys.stdin)
+                        msgBytes = self.readAll(self.p_out.fileno(), interruptFd=sys.stdin.fileno())
                     except (EOFError, OSError):
-                        active.value = False
-                        break    
-                    terminal.feed(msgBytes)                                
-                    os.write(sys.stdout.fileno(), msgBytes)
+                        eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) 
+                        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(msgBytes)
                     eventQueue.put({"Type":fenrirEventType.ScreenUpdate,
-                        "Data":screen_utils.createScreenEventData(terminal.GetScreenContent())
+                        "Data":screen_utils.createScreenEventData(self.terminal.GetScreenContent())
                     })
+                    self.injectTextToScreen(msgBytes, screen=sys.stdout.fileno())
         except Exception as e:  # Process died?
             print(e)
-            active.value = False
+            eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) 
         finally:
-            os.kill(p_pid, signal.SIGTERM)
-            self.p_out.close()    
+            os.kill(self.p_pid, signal.SIGTERM)
+            self.p_out.close()
             termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
             eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) 
             sys.exit(0)
diff --git a/src/fenrirscreenreader/screenDriver/vcsaDriver.py b/src/fenrirscreenreader/screenDriver/vcsaDriver.py
index 85a9f93..ca69653 100644
--- a/src/fenrirscreenreader/screenDriver/vcsaDriver.py
+++ b/src/fenrirscreenreader/screenDriver/vcsaDriver.py
@@ -23,6 +23,7 @@ from struct import unpack_from, unpack, pack
 from fenrirscreenreader.core import debug
 from fenrirscreenreader.core.eventData import fenrirEventType
 from fenrirscreenreader.core.screenDriver import screenDriver
+from fenrirscreenreader.utils import screen_utils
 
 class driver(screenDriver):
     def __init__(self):
@@ -32,7 +33,7 @@ class driver(screenDriver):
         self.charmap = {}
         self.bgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'white'}
         self.fgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'light gray', 8: 'dark gray', 9: 'light blue', 10: 'light green', 11: 'light cyan', 12: 'light red', 13: 'light magenta', 14: 'light yellow', 15: 'white'}
-        self.hichar = None        
+        self.hichar = None
     def initialize(self, environment):
         self.env = environment
         self.env['runtime']['attributeManager'].appendDefaultAttributes([
@@ -46,16 +47,16 @@ class driver(screenDriver):
             False, # blink
             'default', # fontsize
             'default' # fontfamily
-        ]) #end attribute   )
-        self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog, multiprocess=True)        
+        ]) #end attribute )
+        self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog, multiprocess=True)
     def getCurrScreen(self):
         self.env['screen']['oldTTY'] = self.env['screen']['newTTY']
-        try:    
+        try:
             currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r')
             self.env['screen']['newTTY'] = str(currScreenFile.read()[3:-1])
             currScreenFile.close()
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)   
+            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
     def injectTextToScreen(self, text, screen = None):
         useScreen = "/dev/tty" + self.env['screen']['newTTY']
         if screen != None:
@@ -63,12 +64,12 @@ class driver(screenDriver):
         with open(useScreen, 'w') as fd:
             for c in text:
                 fcntl.ioctl(fd, termios.TIOCSTI, c)
-                
+
     def getSessionInformation(self):
-        self.env['screen']['autoIgnoreScreens'] = []         
+        self.env['screen']['autoIgnoreScreens'] = []
         try:
             if not self.sysBus:
-                self.sysBus = dbus.SystemBus()            
+                self.sysBus = dbus.SystemBus()
                 obj  = self.sysBus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
                 inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager')
                 self.ListSessions = inf.get_dbus_method('ListSessions')
@@ -83,105 +84,157 @@ class driver(screenDriver):
                     screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY'))
                     screen = screen[screen.upper().find('TTY') + 3:]
                 if screen == '':
-                    self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR)               
+                    self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR)
                     return
                 if sessionType.upper() != 'TTY':
                     self.env['screen']['autoIgnoreScreens'] += [screen]
                 if screen == self.env['screen']['newTTY'] :
                     if self.env['general']['currUser'] != session[2]:
                         self.env['general']['prevUser'] = self.env['general']['currUser']
-                        self.env['general']['currUser'] = session[2]                                                                
+                        self.env['general']['currUser'] = session[2]
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)               
+            self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)
         #self.env['runtime']['debug'].writeDebugOut('getSessionInformation:'  + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general'])  ,debug.debugLevel.INFO)                           
 
     def updateWatchdog(self,active , eventQueue):
         try:
+            useVCSU = os.access('/dev/vcsu', os.R_OK)
             vcsa = {}
             vcsaDevices = glob.glob('/dev/vcsa*')
-            for vcsaDev in vcsaDevices:
-                index = vcsaDev[9:]
-                vcsa[str(index)] = open(vcsaDev,'rb')
-
+            vcsu = {}
+            vcsuDevices = None
+            lastScreenContent = b''
             tty = open('/sys/devices/virtual/tty/tty0/active','r')
             currScreen = str(tty.read()[3:-1])
             oldScreen = currScreen
+            for vcsaDev in vcsaDevices:
+                index = str(vcsaDev[9:])
+                vcsa[index] = open(vcsaDev,'rb')
+                if index == currScreen:
+                    lastScreenContent = vcsa[index].read()
+            if useVCSU:
+                vcsuDevices = glob.glob('/dev/vcsu*')
+                for vcsuDev in vcsuDevices:
+                    index = str(vcsuDev[9:])
+                    vcsu[index] = open(vcsuDev,'rb')
             self.updateCharMap(currScreen)
             watchdog = select.epoll()
             watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR)
             watchdog.register(tty, select.POLLPRI | select.POLLERR)
-            while active.value == 1:
+            while active.value:
                 changes = watchdog.poll(1)
                 for change in changes:
                     fileno = change[0]
                     event = change[1]
                     if fileno == tty.fileno():
-                        self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO)                             
+                        self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO)
                         tty.seek(0)
-                        currScreen = str(tty.read()[3:-1])        
+                        currScreen = str(tty.read()[3:-1])
                         if currScreen != oldScreen:
                             try:
-                                watchdog.unregister(vcsa[ oldScreen ])              
+                                watchdog.unregister(vcsa[oldScreen])
                             except:
                                 pass
                             try:
-                                watchdog.register(vcsa[ currScreen ], select.POLLPRI | select.POLLERR) 
+                                watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR) 
                             except:
                                 pass
-                            self.updateCharMap(currScreen)                            
+                            self.updateCharMap(currScreen)
                             oldScreen = currScreen
                             try:
-                                vcsa[currScreen].seek(0)                        
-                                lastScreenContent = vcsa[currScreen].read() 
+                                vcsa[currScreen].seek(0)
+                                lastScreenContent = vcsa[currScreen].read()
                             except:
-                                pass                             
+                                pass
+                            vcsuContent = None
+                            if useVCSU:
+                                vcsu[currScreen].seek(0)
+                                vcsuContent = vcsu[currScreen].read()
                             eventQueue.put({"Type":fenrirEventType.ScreenChanged,
-                                "Data":self.createScreenEventData(currScreen,lastScreenContent)                            
+                                "Data":self.createScreenEventData(currScreen, lastScreenContent, vcsuContent)
                             })  
                     else:
-                        self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)                                                 
-                        vcsa[currScreen].seek(0)                                                
+                        self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)
+                        vcsa[currScreen].seek(0)
+                        time.sleep(0.01)
                         dirtyContent = vcsa[currScreen].read()
-                        screenContent = b''
+                        screenContent = dirtyContent
+                        vcsuContent = None
                         timeout = time.time()
-                        while screenContent != dirtyContent:
-                            screenContent = dirtyContent
-                            if time.time() - timeout >= 0.4:
-                                break
-                            time.sleep(0.02)
-                            vcsa[currScreen].seek(0)                             
-                            dirtyContent = vcsa[currScreen].read()
+                        # error case
+                        if screenContent == b'':
+                            continue
+                        if lastScreenContent == b'':
+                            lastScreenContent = screenContent
+                        if (abs( int(screenContent[2]) - int(lastScreenContent[2])) in [1,2]) and \
+                            (int(screenContent[3]) == int(lastScreenContent[3])):
+                            # Skip X Movement
+                            pass
+                        elif (abs( int(screenContent[3]) - int(lastScreenContent[3])) in [1]) and \
+                            (int(screenContent[2]) == int(lastScreenContent[2])):
+                            # Skip Y Movement
+                            pass
+                        else:
+                            # anything else? wait for completion
+                            while True:
+                                screenContent = dirtyContent
+                                time.sleep(0.02)
+                                #r,_,_ = select.select([vcsa[currScreen]], [], [], 0.07)
+                                #if not vcsa[currScreen] in r:
+                                #    break
+                                vcsa[currScreen].seek(0)
+                                dirtyContent = vcsa[currScreen].read()
+                                if screenContent == dirtyContent:
+                                    break
+                                if time.time() - timeout >= 0.1:
+                                    screenContent = dirtyContent
+                                    break
+                        if useVCSU:
+                            vcsu[currScreen].seek(0)
+                            vcsuContent = vcsu[currScreen].read()
+                        lastScreenContent = screenContent
                         eventQueue.put({"Type":fenrirEventType.ScreenUpdate,
-                            "Data":self.createScreenEventData(currScreen,screenContent)
+                            "Data":self.createScreenEventData(currScreen, screenContent, vcsuContent)
                         })
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR)
             time.sleep(0.2)
-            
 
-    def createScreenEventData(self, screen, content):
+    def createScreenEventData(self, screen, vcsaContent, vcsuContent = None):
         eventData = {
-            'bytes': content,
-            'lines': int( content[0]),
-            'columns': int( content[1]),
+            'bytes': vcsaContent,
+            'lines': int( vcsaContent[0]),
+            'columns': int( vcsaContent[1]),
             'textCursor': 
                 {
-                    'x': int( content[2]),
-                    'y': int( content[3])
+                    'x': int( vcsaContent[2]),
+                    'y': int( vcsaContent[3])
                 },
-            'screen': screen,     
-            'screenUpdateTime': time.time(),            
+            'screen': screen,
+            'screenUpdateTime': time.time(),
+            'text': '',
+            'attributes': [],
         }
-        eventData['text'], eventData['attributes'] =\
-          self.autoDecodeVCSA(content[4:], eventData['lines'], eventData['columns'])
-        return eventData.copy()     
+        try:
+            eventData['text'], eventData['attributes'] =\
+              self.autoDecodeVCSA(vcsaContent[4:], eventData['lines'], eventData['columns'])
+        except:
+            pass
+        # VCSU seems to give b'   ' instead of b'\x00\x00\x00' (tsp), deactivated until its fixed
+        if vcsuContent != None:
+            try:
+                vcsuContentAsText = vcsuContent.decode('UTF-32')
+                eventData['text'] = screen_utils.insertNewlines(vcsuContentAsText, eventData['columns'])
+            except:
+                pass
+        return eventData.copy()
     def updateCharMap(self, screen):
         self.charmap = {}
         try:
             tty = open('/dev/tty' + screen, 'rb')
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:' + str(e),debug.debugLevel.ERROR)   
-            return        
+            return
         GIO_UNIMAP = 0x4B66
         VT_GETHIFONTMASK = 0x560D
         himask = array("H", (0,))
@@ -212,9 +265,13 @@ class driver(screenDriver):
         for y in range(rows):
             lineText = ''
             lineAttrib = []
+            blink = 0
+            bold = 0
+            ink = 7
+            paper = 0            
             for x in range(cols):
                 data = allData[i: i + 2]
-                i += 2            
+                i += 2
                 if data == b' \x07':
                     #attr = 7
                     #ink = 7
@@ -234,29 +291,36 @@ class driver(screenDriver):
                     lineAttrib.append(charAttrib)
                     lineText += ' '
                     continue
-                (sh,) = unpack("=H", data)
-                attr = (sh >> 8) & 0xFF
-                ch = sh & 0xFF
-                if self.hichar == 0x100:
-                    attr >>= 1
-                ink = attr & 0x0F
-                paper = (attr>>4) & 0x0F
-                blink = 0
-                if attr & 1: 
-                    blink = 1
-                # blink seems to be set always, ignore for now
-                blink = 0 
-                bold = 0 
-                if attr & 16:
-                    bold = 1
-                #if (ink != 7) or (paper != 0):
-                #    print(ink,paper)
-                if sh & self.hichar:
-                    ch |= 0x100
+                ch = None
                 try:
-                    lineText += self.charmap[ch]            
+                    (sh,) = unpack("=H", data)
+                    attr = (sh >> 8) & 0xFF
+                    ch = sh & 0xFF
+                    try:
+                        if sh & self.hichar:
+                            ch |= 0x100
+                    except:
+                        ch = None                    
+                    if self.hichar == 0x100:
+                        attr >>= 1
+                    ink = attr & 0x0F
+                    paper = (attr>>4) & 0x0F
+                    if attr & 1: 
+                        blink = 1
+                    # blink seems to be set always, ignore for now
+                    blink = 0 
+                    bold = 0 
+                    if attr & 16:
+                        bold = 1
+                    #if (ink != 7) or (paper != 0):
+                    #    print(ink,paper)
+                except:
+                    pass
+                try:
+                    lineText += self.charmap[ch]
                 except KeyError:
                     lineText += '?'
+
                 charAttrib = [
                 self.fgColorValues[ink],
                 self.bgColorValues[paper],
@@ -281,7 +345,7 @@ class driver(screenDriver):
             currScreen = self.env['screen']['newTTY']
             apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)         
+            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
             return
         try:
             for i in apps:
@@ -296,8 +360,7 @@ class driver(screenDriver):
                           not "PS" == i[0]:
                             if "TTY"+currScreen in i[1]:
                                 if self.env['screen']['newApplication'] != i[0]:
-                                    self.env['screen']['newApplication'] = i[0]                        
+                                    self.env['screen']['newApplication'] = i[0]
                                 return
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)    
-        
diff --git a/src/fenrirscreenreader/soundDriver/genericDriver.py b/src/fenrirscreenreader/soundDriver/genericDriver.py
index c599fe9..f39458b 100644
--- a/src/fenrirscreenreader/soundDriver/genericDriver.py
+++ b/src/fenrirscreenreader/soundDriver/genericDriver.py
@@ -28,7 +28,7 @@ class driver(soundDriver):
 
     def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
         if not self._initialized:
-            return    
+            return
         if interrupt:
             self.cancel()
         popenFrequenceCommand = shlex.split(self.frequenceCommand)
@@ -36,28 +36,28 @@ class driver(soundDriver):
             word = word.replace('fenrirVolume', str(self.volume + adjustVolume ))
             word = word.replace('fenrirFreqDuration', str(duration))
             word = word.replace('fenrirFrequence', str(frequence))
-            popenFrequenceCommand[idx] = word        
+            popenFrequenceCommand[idx] = word
         self.proc = subprocess.Popen(popenFrequenceCommand, stdin=None, stdout=None, stderr=None, shell=False)
         self.soundType = 'frequence'
     def playSoundFile(self, filePath, interrupt = True):
         if not self._initialized:
-            return    
+            return
         if interrupt:
             self.cancel()
         popenSoundFileCommand = shlex.split(self.soundFileCommand)
         for idx, word in enumerate(popenSoundFileCommand):
             word = word.replace('fenrirVolume', str(self.volume ))
             word = word.replace('fenrirSoundFile', str(filePath))
-            popenSoundFileCommand[idx] = word                
+            popenSoundFileCommand[idx] = word
         self.proc = subprocess.Popen(popenSoundFileCommand, shell=False)
         self.soundType = 'file'
     def cancel(self):
         if not self._initialized:
-            return    
+            return
         if self.soundType == '':
             return
         if self.soundType == 'file':
             self.proc.kill()
         if self.soundType == 'frequence':
-            self.proc.kill()            
-        self.soundType = ''      
+            self.proc.kill()
+        self.soundType = ''
diff --git a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py
index 9f441cd..c1ea3bd 100644
--- a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py
+++ b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py
@@ -10,11 +10,11 @@ from fenrirscreenreader.core.soundDriver import soundDriver
 
 _gstreamerAvailable = False
 try:
-    import gi        
-    from gi.repository import GLib        
+    import gi
+    from gi.repository import GLib
     gi.require_version('Gst', '1.0')
     from gi.repository import Gst
-    _gstreamerAvailable, args = Gst.init_check(None)   
+    _gstreamerAvailable, args = Gst.init_check(None)
 except Exception as e:
     _gstreamerAvailable = False
     _availableError = str(e)
@@ -28,10 +28,10 @@ class driver(soundDriver):
     def initialize(self, environment):
         self.env = environment
         global _gstreamerAvailable
-        self._initialized = _gstreamerAvailable              
+        self._initialized = _gstreamerAvailable
         if not self._initialized:
             global _availableError
-            self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)                        
+            self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)
             return
         self._player = Gst.ElementFactory.make('playbin', 'player')
         bus = self._player.get_bus()
@@ -48,7 +48,7 @@ class driver(soundDriver):
         self._pipeline.add(self._source)
         self._pipeline.add(self._sink)
         self._source.link(self._sink)
-        self.mainloop = GLib.MainLoop()        
+        self.mainloop = GLib.MainLoop()
         self.thread = threading.Thread(target=self.mainloop.run)
         self.thread.start()
 
@@ -66,7 +66,7 @@ class driver(soundDriver):
         elif message.type == Gst.MessageType.ERROR:
             self._player.set_state(Gst.State.NULL)
             error, info = message.parse_error()
-            self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)                        
+            self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
 
     def _onPipelineMessage(self, bus, message):
         if not self._initialized:
@@ -80,27 +80,26 @@ class driver(soundDriver):
             
     def _onTimeout(self, element):
         if not self._initialized:
-            return    
+            return
         element.set_state(Gst.State.NULL)
 
     def playSoundFile(self, fileName, interrupt=True):
         if not self._initialized:
-            return    
+            return
         if interrupt:
             self.cancel()
+        self._player.set_property('volume', self.volume)
         self._player.set_property('uri', 'file://%s' % fileName)
         self._player.set_state(Gst.State.PLAYING)
 
     def playFrequence(self, frequence, duration, adjustVolume, interrupt=True):
         if not self._initialized:
-            return    
+            return
         if interrupt:
             self.cancel()
-        self._source.set_property('volume', tone.volume)
-        self._source.set_property('freq', tone.frequency)
-        self._source.set_property('wave', tone.wave)
+        self._source.set_property('volume', self.volume)
+        self._source.set_property('freq', frequence)
         self._pipeline.set_state(Gst.State.PLAYING)
-        duration = int(1000 * tone.duration)
         GLib.timeout_add(duration, self._onTimeout, self._pipeline)
 
     def cancel(self, element=None):
diff --git a/src/fenrirscreenreader/speechDriver/debugDriver.py b/src/fenrirscreenreader/speechDriver/debugDriver.py
index 0487642..0f7378e 100644
--- a/src/fenrirscreenreader/speechDriver/debugDriver.py
+++ b/src/fenrirscreenreader/speechDriver/debugDriver.py
@@ -19,7 +19,7 @@ class driver(speechDriver):
     def shutdown(self):
         if self._isInitialized:
             self.cancel()
-        self._isInitialized = False    
+        self._isInitialized = False
         print('Speech Debug Driver: Shutdown')
 
     def speak(self,text, queueable=True):
@@ -33,42 +33,42 @@ class driver(speechDriver):
     def cancel(self):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: Cancel')        
+        print('Speech Debug Driver: Cancel')
 
     def setCallback(self, callback):
-        print('Speech Debug Driver: setCallback')    
+        print('Speech Debug Driver: setCallback')
 
     def clear_buffer(self):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: clear_buffer')    
+        print('Speech Debug Driver: clear_buffer')
 
     def setVoice(self, voice):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: setVoice:' +  str(voice))    
+        print('Speech Debug Driver: setVoice:' +  str(voice))
 
     def setPitch(self, pitch):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: setPitch:' + str(pitch))    
+        print('Speech Debug Driver: setPitch:' + str(pitch))
 
     def setRate(self, rate):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: setRate:' + str(rate))    
+        print('Speech Debug Driver: setRate:' + str(rate))
 
     def setModule(self, module):
         if not self._isInitialized:
-            return 
-        print('Speech Debug Driver: setModule:' + str(module))    
+            return
+        print('Speech Debug Driver: setModule:' + str(module))
 
     def setLanguage(self, language):
         if not self._isInitialized:
             return
-        print('Speech Debug Driver: setLanguage:' + str(language))    
+        print('Speech Debug Driver: setLanguage:' + str(language))
 
     def setVolume(self, volume):
         if not self._isInitialized:
-            return     
+            return
         print('Speech Debug Driver: setVolume:' + str(volume))
diff --git a/src/fenrirscreenreader/speechDriver/emacspeakDriver.py b/src/fenrirscreenreader/speechDriver/emacspeakDriver.py
index 0c7fb35..c03be98 100644
--- a/src/fenrirscreenreader/speechDriver/emacspeakDriver.py
+++ b/src/fenrirscreenreader/speechDriver/emacspeakDriver.py
@@ -15,19 +15,19 @@ class driver(speechDriver):
     def __init__(self):
         speechDriver.__init__(self)
     def initialize(self, environment):
-        self.env = environment        
+        self.env = environment
         try:
             self.server = pexpect.spawn('tclsh ' + self.env['runtime']['settingsManager'].getSetting('speech', 'serverPath'))
-            self._isInitialized = True            
+            self._isInitialized = True
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver:initialize:' + str(e),debug.debugLevel.ERROR)     
+            self.env['runtime']['debug'].writeDebugOut('speechDriver:initialize:' + str(e),debug.debugLevel.ERROR)
 
     def shutdown(self):
         if self.server:
             try:
                 self.server.terminate()
             except Exception as e:
-                self.env['runtime']['debug'].writeDebugOut('speechDriver:shutdown:self.server.terminate():' + str(e),debug.debugLevel.ERROR)    
+                self.env['runtime']['debug'].writeDebugOut('speechDriver:shutdown:self.server.terminate():' + str(e),debug.debugLevel.ERROR)
 
     def speak(self,text, queueable=True):
         if not self._isInitialized:
@@ -45,7 +45,7 @@ class driver(speechDriver):
             cleanText = 'tts_say \"' + cleanText +'\"'
             self.server.sendline(cleanText) 
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver:speak:self.server.sendline():' + str(e),debug.debugLevel.ERROR)            
+            self.env['runtime']['debug'].writeDebugOut('speechDriver:speak:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
     
     def cancel(self):
         if not self._isInitialized:
@@ -54,7 +54,7 @@ class driver(speechDriver):
             self.server.sendline('stop')
         except Exception as e:
             print(e)
-            self.env['runtime']['debug'].writeDebugOut('speechDriver:cancel:self.server.sendline():' + str(e),debug.debugLevel.ERROR)   
+            self.env['runtime']['debug'].writeDebugOut('speechDriver:cancel:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
     
     def setRate(self, rate):
         if not self._isInitialized:
@@ -62,7 +62,7 @@ class driver(speechDriver):
         try:
             self.server.sendline('tts_set_speech_rate ' + str(int(rate * 400)))
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver:setRate:self.server.sendline():' + str(e),debug.debugLevel.ERROR)  
+            self.env['runtime']['debug'].writeDebugOut('speechDriver:setRate:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
     
     def setLanguage(self, language):
         if not self._isInitialized:
diff --git a/src/fenrirscreenreader/speechDriver/espeakDriver.py b/src/fenrirscreenreader/speechDriver/espeakDriver.py
index 4a85f06..49ea350 100644
--- a/src/fenrirscreenreader/speechDriver/espeakDriver.py
+++ b/src/fenrirscreenreader/speechDriver/espeakDriver.py
@@ -14,13 +14,13 @@ class driver(speechDriver):
         self._es = None
 
     def initialize(self, environment):
-        self.env = environment          
+        self.env = environment
         try:
             from espeak import espeak 
             self._es = espeak
             self._isInitialized = True
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)         
+            self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
             self._initialized = False
 
     def speak(self,text, interrupt=True):
@@ -30,10 +30,10 @@ class driver(speechDriver):
             self.cancel()
         if self.language != None:
             if self.language != '':
-                self._es.set_voice(self.language)   
+                self._es.set_voice(self.language)
         elif self.voice != None:
-            if self.voice != '':                
-                self._es.set_voice(self.voice)         
+            if self.voice != '':
+                self._es.set_voice(self.voice)
         self._es.synth(text)
 
     def cancel(self):
diff --git a/src/fenrirscreenreader/speechDriver/genericDriver.py b/src/fenrirscreenreader/speechDriver/genericDriver.py
index 3aaecfb..7b404e4 100644
--- a/src/fenrirscreenreader/speechDriver/genericDriver.py
+++ b/src/fenrirscreenreader/speechDriver/genericDriver.py
@@ -27,11 +27,11 @@ class driver(speechDriver):
         self.speechThread = Thread(target=self.worker)
         self.lock = Lock()
         self.textQueue = speakQueue()
-    def initialize(self, environment):   
+    def initialize(self, environment):
         self.env = environment  
         self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume')
-        self.maxVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxVolume')        
-        self.minPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinPitch')        
+        self.maxVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxVolume')
+        self.minPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinPitch')
         self.maxPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxPitch')
         self.minRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinRate')
         self.maxRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxRate')
@@ -40,23 +40,23 @@ class driver(speechDriver):
         if self.speechCommand == '':
             self.speechCommand = 'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice -- "fenrirText"'
         if False: #for debugging overwrite here
-            #self.speechCommand = 'spd-say --wait -r 100 -i 100  "fenrirText"'  
-            self.speechCommand = 'flite -t "fenrirText"'           
+            #self.speechCommand = 'spd-say --wait -r 100 -i 100  "fenrirText"'
+            self.speechCommand = 'flite -t "fenrirText"'
         
-        self._isInitialized = True   
+        self._isInitialized = True
         if self._isInitialized:
-            self.speechThread.start()   
+            self.speechThread.start()
     def shutdown(self):
         if not self._isInitialized:
             return
-        self.cancel()    
+        self.cancel()
         self.textQueue.put(-1)
 
     def speak(self,text, queueable=True):
         if not self._isInitialized:
             return
-        if not queueable: 
-            self.cancel()        
+        if not queueable:
+            self.cancel()
         utterance = {
           'text': text,
           'volume': self.volume,
@@ -65,7 +65,7 @@ class driver(speechDriver):
           'module': self.module,
           'language': self.language,
           'voice': self.voice,
-        }        
+        }
         self.textQueue.put(utterance.copy())
 
     def cancel(self):
@@ -77,20 +77,20 @@ class driver(speechDriver):
             try:
                 self.proc.terminate()
             except Exception as e:
-                self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)                                
+                self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)
                 try:
                     self.proc.kill()
                 except Exception as e:
-                    self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING)                    
-            self.proc = None            
+                    self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING)
+            self.proc = None
         self.lock.release()
     def setCallback(self, callback):
-        print('SpeechDummyDriver: setCallback')    
+        print('SpeechDummyDriver: setCallback')
 
     def clear_buffer(self):
         if not self._isInitialized:
             return
-        self.textQueue.clear()     
+        self.textQueue.clear()
     
     def setVoice(self, voice):
         if not self._isInitialized:
@@ -137,7 +137,7 @@ class driver(speechDriver):
             if not 'text' in utterance:
                 continue
             if not isinstance(utterance['text'],str):
-                continue            
+                continue
             if utterance['text'] == '':
                 continue
             # check for valid data fields
@@ -178,13 +178,13 @@ class driver(speechDriver):
                 popenSpeechCommand[idx] = word
 
             try:
-                self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + ' '.join(popenSpeechCommand),debug.debugLevel.INFO)                                            
+                self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + ' '.join(popenSpeechCommand),debug.debugLevel.INFO)
                 self.lock.acquire(True)
                 self.proc = Popen(popenSpeechCommand, stdin=None, stdout=None, stderr=None, shell=False)
                 self.lock.release()	
                 self.proc.wait()
             except Exception as e:
-                self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + str(e),debug.debugLevel.ERROR)    
+                self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + str(e),debug.debugLevel.ERROR)
 
             self.lock.acquire(True)
             self.proc = None
diff --git a/src/fenrirscreenreader/speechDriver/pyttsxDriver.py b/src/fenrirscreenreader/speechDriver/pyttsxDriver.py
index 09585cc..e6afb50 100644
--- a/src/fenrirscreenreader/speechDriver/pyttsxDriver.py
+++ b/src/fenrirscreenreader/speechDriver/pyttsxDriver.py
@@ -14,12 +14,12 @@ class driver(speechDriver):
         speechDriver.__init__(self)
         self._engine = None
     def initialize(self, environment):
-        self.env = environment                   
+        self.env = environment
     def shutdown(self):
         if self._isInitialized:
-            self.cancel()            
+            self.cancel()
             self._engine.endLoop()
-        self._initialized = False            
+        self._initialized = False
     def eventLoop(self):
         self._engine.startLoop()
     def startEngine(self):
@@ -28,17 +28,17 @@ class driver(speechDriver):
             if self.module != '':
                 self._engine = pyttsx3.init(self.module)
             else:
-                self._engine = pyttsx3.init()                            
+                self._engine = pyttsx3.init()
             self.eventLoopThread = Thread(target=self.eventLoop)
             self._isInitialized = True
             self.eventLoopThread.start()
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('SpeechDriver:initialize:' + str(e),debug.debugLevel.ERROR)    
+            self.env['runtime']['debug'].writeDebugOut('SpeechDriver:initialize:' + str(e),debug.debugLevel.ERROR)
     
     def speak(self,text, interrupt=True):
         if not self._isInitialized:
             self.startEngine()
-            if not self._isInitialized:            
+            if not self._isInitialized:
                 return
         if not interrupt:
             self.cancel()
@@ -51,15 +51,15 @@ class driver(speechDriver):
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:rate:' + str(e),debug.debugLevel.ERROR) 
         try:
-            self._engine.setProperty('pitch', self.pitch)       
+            self._engine.setProperty('pitch', self.pitch)
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:pitch:' + str(e),debug.debugLevel.ERROR)                                 
+            self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:pitch:' + str(e),debug.debugLevel.ERROR)
         if self.language != None:
             if self.language != '':
                 try:
-                    self._engine.setProperty('voice', self.language)       
+                    self._engine.setProperty('voice', self.language)
                 except Exception as e:
-                    self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:language:' + str(e),debug.debugLevel.ERROR)               
+                    self.env['runtime']['debug'].writeDebugOut('SpeechDriver:speak:language:' + str(e),debug.debugLevel.ERROR)
 
         elif self.voice != None:
             if self.voice != '':
diff --git a/src/fenrirscreenreader/speechDriver/speechdDriver.py b/src/fenrirscreenreader/speechDriver/speechdDriver.py
index b8181a9..e0b5a58 100644
--- a/src/fenrirscreenreader/speechDriver/speechdDriver.py
+++ b/src/fenrirscreenreader/speechDriver/speechdDriver.py
@@ -11,71 +11,89 @@ from fenrirscreenreader.core.speechDriver import speechDriver
 class driver(speechDriver):
     def __init__(self):
         speechDriver.__init__(self)
-        self._sd = None
 
     def initialize(self, environment):
+        self._sd = None
         self.env = environment
+        self._isInitialized = False
+        self.language = ''
+        self.voice = ''
+        self.module = ''
         try:
             import speechd 
             self._sd =  speechd.SSIPClient('fenrir')
             self._punct = speechd.PunctuationMode()
             self._isInitialized = True
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR)                 
-                    
+            self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR)
+
     def shutdown(self):
         if not self._isInitialized:
             return
         self.cancel()
         try:
             self._sd.close()
-        except:
+        except Exception as e:
             pass
-        self._isInitialized = False            
-        
+        self._isInitialized = False
+
     def speak(self,text, queueable=True):
         if not queueable:
-            self.cancel()      
+            self.cancel()
         if not self._isInitialized:
             self.initialize(self.env)
+            if not queueable:
+                self.cancel()
             if not self._isInitialized:
                 return
+
         try:
-            self._sd.set_output_module(self.module)
+            if self.module != '':
+                self._sd.set_output_module(self.module)
         except Exception as e:
             self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR)
-                    
+
+        try:
+            if self.language != '':
+                self._sd.set_language(self.language)
+        except Exception as e:
+            self.env['runtime']['debug'].writeDebugOut('speechDriver set_language:' + str(e),debug.debugLevel.ERROR)
+
+        try:
+            if self.voice != '':
+                self._sd.set_synthesis_voice(self.voice)
+        except Exception as e:
+            self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR)
+
         try:
-            if self.voice:
-                if self.voice != '':
-                    self._sd.set_voice(self.voice)
+            self._sd.set_punctuation(self._punct.NONE)
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR)                
+            self.env['runtime']['debug'].writeDebugOut('speechDriver set_punctuation:' + str(e),debug.debugLevel.ERROR)
+
         try:
-            if self.language != '':        
-                self._sd.set_synthesis_voice(self.language)        
-            self._sd.set_punctuation(self._punct.NONE)              
-            self._sd.speak(text)            
+            self._sd.speak(text)
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver speak:' + str(e),debug.debugLevel.ERROR)                 
+            self.env['runtime']['debug'].writeDebugOut('speechDriver speak:' + str(e),debug.debugLevel.ERROR)
             self._isInitialized = False
 
     def cancel(self):
         if not self._isInitialized:
-            return
+            self.initialize(self.env)
+            if not self._isInitialized:
+                return
         try:
             self._sd.cancel()
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR)                         
-            self._isInitialized = False        
-                               
+            self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR)
+            self._isInitialized = False
+
     def setPitch(self, pitch):
         if not self._isInitialized:
             return
         try:
             self._sd.set_pitch(int(-100 + pitch * 200)) 
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver setPitch:' + str(e),debug.debugLevel.ERROR)                                         
+            self.env['runtime']['debug'].writeDebugOut('speechDriver setPitch:' + str(e),debug.debugLevel.ERROR)
 
     def setRate(self, rate):
         if not self._isInitialized:
@@ -83,12 +101,12 @@ class driver(speechDriver):
         try:
             self._sd.set_rate(int(-100 + rate * 200))
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR)                                                                              
-        
+            self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR)
+
     def setVolume(self, volume):
         if not self._isInitialized:
             return 
-        try:               
+        try:
             self._sd.set_volume(int(-100 + volume * 200))
         except Exception as e:
-            self.env['runtime']['debug'].writeDebugOut('speechDriver setVolume:' + str(e),debug.debugLevel.ERROR)                                                         
+            self.env['runtime']['debug'].writeDebugOut('speechDriver setVolume:' + str(e),debug.debugLevel.ERROR)
diff --git a/src/fenrirscreenreader/utils/line_utils.py b/src/fenrirscreenreader/utils/line_utils.py
index 51fa3f3..a4532fb 100644
--- a/src/fenrirscreenreader/utils/line_utils.py
+++ b/src/fenrirscreenreader/utils/line_utils.py
@@ -11,23 +11,23 @@ def getPrevLine(currX,currY, currText):
     endOfScreen = False
     if currText == '':
         return -1, -1, '', endOfScreen
-    wrappedLines = currText.split('\n')         
+    wrappedLines = currText.split('\n')
     x = currX
     y = currY 
     if y - 1 >= 0:
         y -= 1
     else:
-        endOfScreen = True        
+        endOfScreen = True
     x = 0
     currLine = ''
     if not endOfScreen:
-        currLine = wrappedLines[y]                   
+        currLine = wrappedLines[y]
     return x, y, currLine, endOfScreen
 
 def getCurrentLine(currX,currY, currText):
     if currText == '':
         return -1, -1, ''
-    wrappedLines = currText.split('\n')         
+    wrappedLines = currText.split('\n')
     x = currX
     y = currY
     x = 0
@@ -38,7 +38,7 @@ def getNextLine(currX,currY, currText):
     endOfScreen = False
     if currText == '':
         return -1, -1, '', endOfScreen
-    wrappedLines = currText.split('\n')         
+    wrappedLines = currText.split('\n')
     x = currX
     y = currY
     if y + 1 < len(wrappedLines):
diff --git a/src/fenrirscreenreader/utils/screen_utils.py b/src/fenrirscreenreader/utils/screen_utils.py
index e681006..fbb1ef2 100644
--- a/src/fenrirscreenreader/utils/screen_utils.py
+++ b/src/fenrirscreenreader/utils/screen_utils.py
@@ -5,7 +5,8 @@
 # By Chrys, Storm Dragon, and contributers.
 
 from fenrirscreenreader.core import debug
-import getpass, time, string, select, os
+import getpass, time, string, os
+from select import select
 
 def removeNonprintable(text):
     # Get the difference of all ASCII characters from the set of printable characters
@@ -31,20 +32,22 @@ def createScreenEventData(content):
         'screen': content['screen'],
         'text': content['text'],
         'attributes': content['attributes'],
-        'screenUpdateTime': time.time(),            
+        'screenUpdateTime': time.time(),
     }
     return eventData.copy() 
 
-def hasMore(fd, timetout=0.1):
-    r, _, _ = select.select([fd], [], [], timetout)
-    return (fd in r) 
-def hasMoreWhat(fdList, timetout=0.1):
+def hasMore(fd, timetout=0.05):
+    r, _, _ = select([fd], [], [], timetout)
+    return (fd in r)
+
+def hasMoreWhat(fdList, timetout=0.05):
     if not isinstance(fdList, list):
         return []  
     elif fdList == []:
         return []
-    r, _, _ = select.select(fdList, [], [], timetout)
+    r, _, _ = select(fdList, [], [], timetout)
     return r
+
 def isValidShell(shell = ''):
     if not isinstance(shell, str):
         return False
@@ -58,10 +61,11 @@ def isValidShell(shell = ''):
     except:
             return False
     return True
+
 def getShell():
     try:
         shell = os.environ["FENRIRSHELL"]
-        if isValidShell(shell):                                        
+        if isValidShell(shell):
             return shell
     except:
         pass        
@@ -79,7 +83,7 @@ def getShell():
                     (username, encrypwd, uid, gid, gecos, homedir, shell) = user.split(':')
                     shell = shell.replace('\n','')
                     if username == getpass.getuser():
-                        if isValidShell(shell):                            
+                        if isValidShell(shell):
                             return shell
     except:
         pass
diff --git a/tools/fenrir.pot b/tools/fenrir.pot
index fa90139..2d02e8c 100644
--- a/tools/fenrir.pot
+++ b/tools/fenrir.pot
@@ -5,809 +5,1215 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2017-02-26 22:19+UTC\n"
+"POT-Creation-Date: 2020-04-19 08:56+0700\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=cp1251\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Generated-By: pygettext.py 1.5\n"
 
 
-#: ../src/fenrir/commands/commands/add_word_to_spell_check.py:27
+#: ../src/fenrirscreenreader\commands\commands\add_word_to_spell_check.py:27
 msgid "adds the current word to the exceptions dictionary"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/add_word_to_spell_check.py:34
-#: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:34
-#: ../src/fenrir/commands/commands/spell_check.py:29
-#: ../src/fenrir/commands/commands/spell_check.py:36
+#: ../src/fenrirscreenreader\commands\commands\add_word_to_spell_check.py:34
+#: ../src/fenrirscreenreader\commands\commands\remove_word_from_spell_check.py:34
+#: ../src/fenrirscreenreader\commands\commands\spell_check.py:35
 msgid "pyenchant is not installed"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/add_word_to_spell_check.py:49
-msgid "{0} is already in dict"
+#: ../src/fenrirscreenreader\commands\commands\add_word_to_spell_check.py:49
+msgid "{0} is already in dictionary"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/add_word_to_spell_check.py:52
-msgid "{0} added"
+#: ../src/fenrirscreenreader\commands\commands\add_word_to_spell_check.py:52
+msgid "{0} added to dictionary"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/bookmark_1.py:19
-#: ../src/fenrir/commands/commands/bookmark_10.py:19
-#: ../src/fenrir/commands/commands/bookmark_2.py:19
-#: ../src/fenrir/commands/commands/bookmark_3.py:19
-#: ../src/fenrir/commands/commands/bookmark_4.py:19
-#: ../src/fenrir/commands/commands/bookmark_5.py:19
-#: ../src/fenrir/commands/commands/bookmark_6.py:19
-#: ../src/fenrir/commands/commands/bookmark_7.py:19
-#: ../src/fenrir/commands/commands/bookmark_8.py:19
-#: ../src/fenrir/commands/commands/bookmark_9.py:19
+#: ../src/fenrirscreenreader\commands\commands\attribute_cursor.py:18
+#: ../src/fenrirscreenreader\commands\onCursorChange\85000-has_attribute.py:18
+msgid "Reads attributes of current cursor position"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\bookmark_1.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_10.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_2.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_3.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_4.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_5.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_6.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_7.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_8.py:19
+#: ../src/fenrirscreenreader\commands\commands\bookmark_9.py:19
 msgid "read Bookmark {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/bookmark_1.py:24
-#: ../src/fenrir/commands/commands/bookmark_10.py:24
-#: ../src/fenrir/commands/commands/bookmark_2.py:24
-#: ../src/fenrir/commands/commands/bookmark_3.py:24
-#: ../src/fenrir/commands/commands/bookmark_4.py:24
-#: ../src/fenrir/commands/commands/bookmark_5.py:24
-#: ../src/fenrir/commands/commands/bookmark_6.py:24
-#: ../src/fenrir/commands/commands/bookmark_7.py:24
-#: ../src/fenrir/commands/commands/bookmark_8.py:24
-#: ../src/fenrir/commands/commands/bookmark_9.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_1.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_10.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_2.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_3.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_4.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_5.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_6.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_7.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_8.py:24
+#: ../src/fenrirscreenreader\commands\commands\bookmark_9.py:24
 msgid "Bookmark {0} not set"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/bookmark_1.py:27
-#: ../src/fenrir/commands/commands/bookmark_1.py:30
-#: ../src/fenrir/commands/commands/bookmark_10.py:27
-#: ../src/fenrir/commands/commands/bookmark_10.py:30
-#: ../src/fenrir/commands/commands/bookmark_2.py:27
-#: ../src/fenrir/commands/commands/bookmark_2.py:30
-#: ../src/fenrir/commands/commands/bookmark_3.py:27
-#: ../src/fenrir/commands/commands/bookmark_3.py:30
-#: ../src/fenrir/commands/commands/bookmark_4.py:27
-#: ../src/fenrir/commands/commands/bookmark_4.py:30
-#: ../src/fenrir/commands/commands/bookmark_5.py:27
-#: ../src/fenrir/commands/commands/bookmark_5.py:30
-#: ../src/fenrir/commands/commands/bookmark_6.py:27
-#: ../src/fenrir/commands/commands/bookmark_6.py:30
-#: ../src/fenrir/commands/commands/bookmark_7.py:27
-#: ../src/fenrir/commands/commands/bookmark_7.py:30
-#: ../src/fenrir/commands/commands/bookmark_8.py:27
-#: ../src/fenrir/commands/commands/bookmark_8.py:30
-#: ../src/fenrir/commands/commands/bookmark_9.py:27
-#: ../src/fenrir/commands/commands/bookmark_9.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_1.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_1.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_10.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_10.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_2.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_2.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_3.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_3.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_4.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_4.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_5.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_5.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_6.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_6.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_7.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_7.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_8.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_8.py:30
+#: ../src/fenrirscreenreader\commands\commands\bookmark_9.py:27
+#: ../src/fenrirscreenreader\commands\commands\bookmark_9.py:30
 msgid "Bookmark for application {0} not set"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/bookmark_1.py:43
-#: ../src/fenrir/commands/commands/bookmark_10.py:43
-#: ../src/fenrir/commands/commands/bookmark_2.py:43
-#: ../src/fenrir/commands/commands/bookmark_3.py:43
-#: ../src/fenrir/commands/commands/bookmark_4.py:43
-#: ../src/fenrir/commands/commands/bookmark_5.py:43
-#: ../src/fenrir/commands/commands/bookmark_6.py:43
-#: ../src/fenrir/commands/commands/bookmark_7.py:43
-#: ../src/fenrir/commands/commands/bookmark_8.py:43
-#: ../src/fenrir/commands/commands/bookmark_9.py:43
-#: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:27
-#: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:30
-#: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:27
-#: ../src/fenrir/commands/commands/indent_curr_line.py:31
-#: ../src/fenrir/commands/commands/marked_text.py:33
-#: ../src/fenrir/commands/commands/present_first_line.py:25
-#: ../src/fenrir/commands/commands/present_last_line.py:25
-#: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:27
-#: ../src/fenrir/commands/commands/review_curr_line.py:27
-#: ../src/fenrir/commands/commands/review_curr_word.py:27
-#: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:27
-#: ../src/fenrir/commands/commands/review_line_begin.py:27
-#: ../src/fenrir/commands/commands/review_next_line.py:29
-#: ../src/fenrir/commands/commands/review_next_word.py:29
-#: ../src/fenrir/commands/commands/review_next_word_phonetic.py:27
-#: ../src/fenrir/commands/commands/review_prev_line.py:27
-#: ../src/fenrir/commands/commands/review_prev_word.py:27
-#: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:27
-#: ../src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py:38
-#: ../src/fenrir/commands/onInput/72000-history.py:50
+#: ../src/fenrirscreenreader\commands\commands\bookmark_1.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_10.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_2.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_3.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_4.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_5.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_6.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_7.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_8.py:43
+#: ../src/fenrirscreenreader\commands\commands\bookmark_9.py:43
+#: ../src/fenrirscreenreader\commands\commands\curr_screen_after_cursor.py:27
+#: ../src/fenrirscreenreader\commands\commands\curr_screen_before_cursor.py:30
+#: ../src/fenrirscreenreader\commands\commands\cursor_read_to_end_of_line.py:27
+#: ../src/fenrirscreenreader\commands\commands\indent_curr_line.py:31
+#: ../src/fenrirscreenreader\commands\commands\marked_text.py:33
+#: ../src/fenrirscreenreader\commands\commands\present_first_line.py:25
+#: ../src/fenrirscreenreader\commands\commands\present_last_line.py:25
+#: ../src/fenrirscreenreader\commands\commands\review_curr_char_phonetic.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_curr_line.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_line_begin.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:29
+#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:29
+#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:27
+#: ../src/fenrirscreenreader\commands\onCursorChange\65000-present_line_if_cursor_change_vertical.py:37
+#: ../src/fenrirscreenreader\commands\onScreenUpdate\60000-history.py:59
 msgid "blank"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/braille_flush.py:17
-msgid "flush the braille device if a message is written on"
+#: ../src/fenrirscreenreader\commands\commands\braille_flush.py:17
+msgid "Clear the Braille device if it is displaying a message"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/braille_pan_left.py:17
+#: ../src/fenrirscreenreader\commands\commands\braille_pan_left.py:17
 msgid "Move braille view to the left."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/braille_pan_right.py:17
+#: ../src/fenrirscreenreader\commands\commands\braille_pan_right.py:17
 msgid "Move braille view to the right."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/braille_return_to_cursor.py:17
+#: ../src/fenrirscreenreader\commands\commands\braille_return_to_cursor.py:17
 msgid "Set the braille view back to cursor."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_bookmark_1.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_10.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_2.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_3.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_4.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_5.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_6.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_7.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_8.py:17
-#: ../src/fenrir/commands/commands/clear_bookmark_9.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_1.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_10.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_2.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_3.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_4.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_5.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_6.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_7.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_8.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_9.py:17
 msgid "remove Bookmark {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_bookmark_1.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_10.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_2.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_3.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_4.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_5.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_6.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_7.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_8.py:24
-#: ../src/fenrir/commands/commands/clear_bookmark_9.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_1.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_10.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_2.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_3.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_4.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_5.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_6.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_7.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_8.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_bookmark_9.py:24
 msgid "Bookmark {0} removed for application {1}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_clipboard.py:17
 msgid "clears the currently selected clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_clipboard.py:22
+#: ../src/fenrirscreenreader\commands\commands\clear_clipboard.py:21
 msgid "clipboard cleared"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_window_application.py:17
+#: ../src/fenrirscreenreader\commands\commands\clear_window_application.py:17
 msgid "Turn off window mode for application"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_window_application.py:22
+#: ../src/fenrirscreenreader\commands\commands\clear_window_application.py:22
 msgid "Window Mode off for application {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/clear_window_application.py:24
+#: ../src/fenrirscreenreader\commands\commands\clear_window_application.py:24
 msgid "Not in window Mode"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:18
+#:
+#: ../src/fenrirscreenreader\commands\commands\copy_last_echo_to_clipboard.py:18
+msgid "copies last presented text to the clipboard"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\copy_marked_to_clipboard.py:18
 msgid "copies marked text to the currently selected clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:22
-msgid "one or two marks needed"
+#: ../src/fenrirscreenreader\commands\commands\copy_marked_to_clipboard.py:22
+msgid "One or two marks are needed"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\curr_clipboard.py:17
 msgid "speaks the contents of the currently selected clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_clipboard.py:21
-#: ../src/fenrir/commands/commands/export_clipboard_to_x.py:29
-#: ../src/fenrir/commands/commands/export_clipboard_to_x.py:32
-#: ../src/fenrir/commands/commands/export_clipboard_to_x.py:35
-#: ../src/fenrir/commands/commands/export_clipboard_to_x.py:38
-#: ../src/fenrir/commands/commands/first_clipboard.py:21
-#: ../src/fenrir/commands/commands/last_clipboard.py:21
-#: ../src/fenrir/commands/commands/next_clipboard.py:21
-#: ../src/fenrir/commands/commands/paste_clipboard.py:23
-#: ../src/fenrir/commands/commands/paste_clipboard.py:26
-#: ../src/fenrir/commands/commands/paste_clipboard.py:29
-#: ../src/fenrir/commands/commands/paste_clipboard.py:32
-#: ../src/fenrir/commands/commands/prev_clipboard.py:21
+#: ../src/fenrirscreenreader\commands\commands\curr_clipboard.py:21
+#: ../src/fenrirscreenreader\commands\commands\export_clipboard_to_file.py:28
+#: ../src/fenrirscreenreader\commands\commands\export_clipboard_to_x.py:27
+#: ../src/fenrirscreenreader\commands\commands\first_clipboard.py:21
+#: ../src/fenrirscreenreader\commands\commands\last_clipboard.py:21
+#: ../src/fenrirscreenreader\commands\commands\next_clipboard.py:21
+#: ../src/fenrirscreenreader\commands\commands\paste_clipboard.py:23
+#: ../src/fenrirscreenreader\commands\commands\prev_clipboard.py:21
 msgid "clipboard empty"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_screen.py:17
+#: ../src/fenrirscreenreader\commands\commands\curr_screen.py:17
 msgid "reads the contents of the current screen"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_screen.py:21
+#: ../src/fenrirscreenreader\commands\commands\curr_screen.py:21
 msgid "screen is empty"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:18
+#: ../src/fenrirscreenreader\commands\commands\curr_screen_after_cursor.py:18
 msgid "reads from the cursor to the bottom of the screen"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:18
+#: ../src/fenrirscreenreader\commands\commands\curr_screen_before_cursor.py:18
 msgid "Reads from the top of the screen to the cursor position"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/cursor_column.py:17
-msgid "presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1"
+#: ../src/fenrirscreenreader\commands\commands\current_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\current_quick_menu_entry.py:17
+msgid "get current quick menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\current_quick_menu_value.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\current_quick_menu_value.py:17
+msgid "get current quick menu value"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\cursor_column.py:17
+msgid "Column number for cursor"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/cursor_lineno.py:17
-msgid "presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1"
+#: ../src/fenrirscreenreader\commands\commands\cursor_lineno.py:17
+msgid "Line number for cursor"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/cursor_position.py:17
+#: ../src/fenrirscreenreader\commands\commands\cursor_position.py:17
 msgid "displays the position of the review cursor"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/cursor_position.py:23
-msgid "line {0}, column {1}"
+#: ../src/fenrirscreenreader\commands\commands\cursor_position.py:23
+msgid "line {0}, column {1}, Terminal {2}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:18
+#:
+#: ../src/fenrirscreenreader\commands\commands\cursor_read_to_end_of_line.py:18
 msgid "read to end of line, use review cursor if you are in review mode, otherwhise use text cursor"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/date.py:18
+#: ../src/fenrirscreenreader\commands\commands\date.py:18
 msgid "presents the date"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_sound_volume.py:18
+#: ../src/fenrirscreenreader\commands\commands\dec_alsa_volume.py:24
+msgid "Decrease system volume"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\dec_alsa_volume.py:28
+#: ../src/fenrirscreenreader\commands\commands\inc_alsa_volume.py:28
+msgid "alsaaudio is not installed"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\dec_alsa_volume.py:36
+#: ../src/fenrirscreenreader\commands\commands\inc_alsa_volume.py:36
+msgid "{0} percent system volume"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\dec_sound_volume.py:18
 msgid "decrease sound volume"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_sound_volume.py:29
-#: ../src/fenrir/commands/commands/inc_sound_volume.py:29
+#: ../src/fenrirscreenreader\commands\commands\dec_sound_volume.py:29
+#: ../src/fenrirscreenreader\commands\commands\inc_sound_volume.py:29
 msgid "{0} percent sound volume"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_pitch.py:18
-msgid "decreases the pitch of the speech"
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_pitch.py:18
+msgid "Decreases the pitch of the speech"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_pitch.py:27
-#: ../src/fenrir/commands/commands/inc_speech_pitch.py:27
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_pitch.py:26
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_pitch.py:27
 msgid "{0} percent speech pitch"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_rate.py:18
-msgid "decreases the rate of the speech"
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_rate.py:18
+msgid "Decreases the rate of the speech"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_rate.py:27
-#: ../src/fenrir/commands/commands/inc_speech_rate.py:27
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_rate.py:27
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_rate.py:27
 msgid "{0} percent speech rate"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_volume.py:18
-msgid "decreases the volume of the speech"
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_volume.py:18
+msgid "Decreases the volume of the speech"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/dec_speech_volume.py:27
-#: ../src/fenrir/commands/commands/inc_speech_volume.py:27
+#: ../src/fenrirscreenreader\commands\commands\dec_speech_volume.py:27
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_volume.py:27
 msgid "{0} percent speech volume"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/exit_review.py:17
+#: ../src/fenrirscreenreader\commands\commands\exit_review.py:17
+#: ../src/fenrirscreenreader\commands\onCursorChange\95000-exit_review_mode.py:17
 msgid "exits review mode"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/exit_review.py:21
-msgid "Not in review mode"
+#: ../src/fenrirscreenreader\commands\commands\exit_review.py:21
+msgid "Not in Review Mode"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\exit_review.py:25
+msgid "Exiting Review Mode"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/exit_review.py:25
-msgid "leave review mode"
+#: ../src/fenrirscreenreader\commands\commands\export_clipboard_to_file.py:19
+msgid "export the current fenrir clipboard to a file"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/export_clipboard_to_x.py:21
-msgid "export the current fenrir clipboard to X clipboard"
+#: ../src/fenrirscreenreader\commands\commands\export_clipboard_to_file.py:34
+msgid "clipboard exported to file"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/first_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\export_clipboard_to_x.py:20
+msgid "Export current fenrir clipboard to X or GUI clipboard"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\first_clipboard.py:17
 msgid "selects the first clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/forward_keypress.py:17
-msgid "sends the following keypress to the terminal"
+#: ../src/fenrirscreenreader\commands\commands\forward_keypress.py:17
+msgid "sends the following keypress to the terminal or application"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/forward_keypress.py:21
+#: ../src/fenrirscreenreader\commands\commands\forward_keypress.py:21
 msgid "Forward next keypress"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/inc_sound_volume.py:18
+#:
+#: ../src/fenrirscreenreader\commands\commands\import_clipboard_from_file.py:19
+msgid "imports text from clipboard file to the clipboard"
+msgstr ""
+
+#:
+#: ../src/fenrirscreenreader\commands\commands\import_clipboard_from_file.py:27
+msgid "File does not exist"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\import_clipboard_from_x.py:21
+msgid "imports the graphical clipboard to Fenrir's clipboard"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\inc_alsa_volume.py:24
+msgid "Increase system volume"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\inc_sound_volume.py:18
 msgid "adjusts the volume for in coming sounds"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/inc_speech_pitch.py:18
-msgid "increases the pitch of the speech"
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_pitch.py:18
+msgid "Increases the pitch of the speech"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/inc_speech_rate.py:18
-msgid "increase the speech rate"
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_rate.py:18
+msgid "Increase the speech rate"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/inc_speech_volume.py:18
-msgid "increase the speech volume"
+#: ../src/fenrirscreenreader\commands\commands\inc_speech_volume.py:18
+msgid "Increase the speech volume"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/indent_curr_line.py:18
-msgid "shows the indention level for the current line"
+#: ../src/fenrirscreenreader\commands\commands\indent_curr_line.py:18
+msgid "Presents the indentation level for the current line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/indent_curr_line.py:33
+#: ../src/fenrirscreenreader\commands\commands\indent_curr_line.py:33
 msgid "indent {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/last_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\last_clipboard.py:17
 msgid "selects the last clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/last_incoming.py:17
-msgid "displays the last received text"
+#: ../src/fenrirscreenreader\commands\commands\last_incoming.py:17
+msgid "Presents the text which was last received"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/marked_text.py:18
-msgid "speaks the currently selected text that will be copied to the clipboard"
+#: ../src/fenrirscreenreader\commands\commands\marked_text.py:18
+msgid "Presents the currently selected text that will be copied to the clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/marked_text.py:23
+#: ../src/fenrirscreenreader\commands\commands\marked_text.py:23
 msgid "please set begin and endmark"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/next_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\next_clipboard.py:17
 msgid "selects the next clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/next_clipboard.py:26
+#: ../src/fenrirscreenreader\commands\commands\next_clipboard.py:28
+#: ../src/fenrirscreenreader\commands\commands\prev_clipboard.py:28
 msgid "First clipboard "
 msgstr ""
 
-#: ../src/fenrir/commands/commands/paste_clipboard.py:18
+#: ../src/fenrirscreenreader\commands\commands\next_clipboard.py:30
+#: ../src/fenrirscreenreader\commands\commands\prev_clipboard.py:30
+msgid "Last clipboard "
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\next_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\next_quick_menu_entry.py:17
+msgid "get next quick menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\next_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader\commands\commands\prev_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader\commands\quickMenu\next_quick_menu_entry.py:27
+#: ../src/fenrirscreenreader\commands\quickMenu\prev_quick_menu_entry.py:27
+msgid "Quick menu not available"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\next_quick_menu_value.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\next_quick_menu_value.py:17
+msgid "get next quick menu value"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\paste_clipboard.py:19
 msgid "pastes the text from the currently selected clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/present_first_line.py:18
+#: ../src/fenrirscreenreader\commands\commands\present_first_line.py:18
 msgid "present first line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/present_last_line.py:18
-#: ../src/fenrir/commands/commands/review_curr_line.py:18
+#: ../src/fenrirscreenreader\commands\commands\present_last_line.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_curr_line.py:18
 msgid "current line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/prev_clipboard.py:17
+#: ../src/fenrirscreenreader\commands\commands\prev_clipboard.py:17
 msgid "selects the previous clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/prev_clipboard.py:26
-msgid "Last clipboard "
+#: ../src/fenrirscreenreader\commands\commands\prev_quick_menu_entry.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\prev_quick_menu_entry.py:17
+msgid "get previous quick menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\prev_quick_menu_value.py:17
+#: ../src/fenrirscreenreader\commands\quickMenu\prev_quick_menu_value.py:17
+msgid "get previous quick menu value"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/quit_fenrir.py:17
+#: ../src/fenrirscreenreader\commands\commands\quit_fenrir.py:17
 msgid "exits Fenrir"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/remove_marks.py:17
-msgid "removes marks from selected text"
+#: ../src/fenrirscreenreader\commands\commands\remove_marks.py:17
+msgid "Removes marks from selected text"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/remove_marks.py:21
+#: ../src/fenrirscreenreader\commands\commands\remove_marks.py:21
 msgid "Remove marks"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:27
+#:
+#: ../src/fenrirscreenreader\commands\commands\remove_word_from_spell_check.py:27
 msgid "removes the current word from the exceptions dictionary"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:50
-msgid "{0} is already removed from dict"
+#:
+#: ../src/fenrirscreenreader\commands\commands\remove_word_from_spell_check.py:50
+msgid "{0} is not in the dictionary"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:53
+#:
+#: ../src/fenrirscreenreader\commands\commands\remove_word_from_spell_check.py:53
 msgid "{0} removed"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_bottom.py:17
-msgid "move review to bottom of screen"
+#: ../src/fenrirscreenreader\commands\commands\review_bottom.py:17
+msgid "Move review to the bottom of the screen"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_bottom.py:21
+#: ../src/fenrirscreenreader\commands\commands\review_bottom.py:21
 msgid "Bottom"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_char.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_curr_char.py:18
 msgid "presents the current character."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_curr_char_phonetic.py:18
 msgid "set review and phonetically presents the current character"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_word.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:18
 msgid "current word."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_word.py:32
-#: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:36
-#: ../src/fenrir/commands/commands/review_down.py:27
-#: ../src/fenrir/commands/commands/review_next_char.py:28
-#: ../src/fenrir/commands/commands/review_next_char_phonetic.py:30
-#: ../src/fenrir/commands/commands/review_next_line.py:34
-#: ../src/fenrir/commands/commands/review_next_word.py:34
-#: ../src/fenrir/commands/commands/review_next_word_phonetic.py:36
-#: ../src/fenrir/commands/commands/review_prev_char.py:31
-#: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:30
-#: ../src/fenrir/commands/commands/review_prev_line.py:32
-#: ../src/fenrir/commands/commands/review_prev_word.py:32
-#: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:36
-#: ../src/fenrir/commands/commands/review_up.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:32
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:36
+#: ../src/fenrirscreenreader\commands\commands\review_down.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:28
+#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:30
+#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:34
+#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:34
+#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:36
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:31
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:30
+#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:32
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:32
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:36
+#: ../src/fenrirscreenreader\commands\commands\review_up.py:27
 msgid "end of screen"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_word.py:35
-#: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:39
-#: ../src/fenrir/commands/commands/review_next_char.py:31
-#: ../src/fenrir/commands/commands/review_next_char_phonetic.py:33
-#: ../src/fenrir/commands/commands/review_next_word.py:37
-#: ../src/fenrir/commands/commands/review_next_word_phonetic.py:39
-#: ../src/fenrir/commands/commands/review_prev_char.py:34
-#: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:33
-#: ../src/fenrir/commands/commands/review_prev_word.py:35
-#: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:39
-#: ../src/fenrir/commands/commands/review_up.py:30
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word.py:35
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:39
+#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:31
+#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:33
+#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:37
+#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:39
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:34
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:33
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:35
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:39
+#: ../src/fenrirscreenreader\commands\commands\review_up.py:30
 msgid "line break"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:19
-#: ../src/fenrir/commands/commands/review_next_word_phonetic.py:19
-#: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:19
-msgid "phonetically spells the current word and set review to it"
+#: ../src/fenrirscreenreader\commands\commands\review_curr_word_phonetic.py:19
+msgid "Phonetically spells the current word"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_down.py:18
-msgid "set review cursor to char below the current char and present it."
+#: ../src/fenrirscreenreader\commands\commands\review_down.py:18
+msgid "Move review to the character below the current position"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_begin.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_line_begin.py:18
 msgid "set review cursor to begin of current line and display the content"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_begin.py:30
+#: ../src/fenrirscreenreader\commands\commands\review_line_begin.py:30
 msgid "beginning of line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_end.py:18
-#: ../src/fenrir/commands/commands/review_line_first_char.py:19
-#: ../src/fenrir/commands/commands/review_line_last_char.py:18
-msgid "set review cursor to end of current line and display the content"
+#: ../src/fenrirscreenreader\commands\commands\review_line_end.py:18
+msgid "Move Review to the end of current line and display the content"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_end.py:27
+#: ../src/fenrirscreenreader\commands\commands\review_line_end.py:27
 msgid "end of line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_first_char.py:26
+#: ../src/fenrirscreenreader\commands\commands\review_line_first_char.py:19
+msgid "Move Review to the first character on the line"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\review_line_first_char.py:26
 msgid "line is empty"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_first_char.py:33
-msgid "first char in line indent {0}"
+#: ../src/fenrirscreenreader\commands\commands\review_line_first_char.py:33
+msgid "first character in line indent {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_line_last_char.py:27
-msgid "last char in line"
+#: ../src/fenrirscreenreader\commands\commands\review_line_last_char.py:18
+msgid "Move Review to the last character on the line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_next_char.py:18
-msgid "moves review to the next character and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_line_last_char.py:27
+msgid "last character in line"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_next_char_phonetic.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_next_char.py:18
+msgid "Moves review to the next character "
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\review_next_char_phonetic.py:18
 msgid "phonetically presents the next character and set review to it"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_next_line.py:18
-msgid "moves review to the next line and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_next_line.py:18
+msgid "moves review to the next line "
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\review_next_word.py:18
+msgid "moves review to the next word "
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_next_word.py:18
-msgid "moves review to the next word and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_next_word_phonetic.py:19
+msgid "Phonetically spells the next word and moves review to it"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_prev_char.py:18
-msgid "moves review to the previous character and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char.py:18
+msgid "moves review to the previous character "
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_prev_char_phonetic.py:18
 msgid "phonetically presents the previous character and set review to it"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_prev_line.py:18
-msgid "moves review to the previous line and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_prev_line.py:18
+msgid "moves review to the previous line "
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word.py:18
+msgid "moves review focus to the previous word "
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_prev_word.py:18
-msgid "moves review focus to the previous word and presents it"
+#: ../src/fenrirscreenreader\commands\commands\review_prev_word_phonetic.py:19
+msgid "Phonetically spells the previous word and moves review to it"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_top.py:18
+#: ../src/fenrirscreenreader\commands\commands\review_top.py:18
 msgid "move review to top of screen"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_top.py:22
+#: ../src/fenrirscreenreader\commands\commands\review_top.py:22
 msgid "Top"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/review_up.py:18
-msgid "set review cursor to the char in the line below and present it"
+#: ../src/fenrirscreenreader\commands\commands\review_up.py:18
+msgid "Move review to the character in the line above the current position"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_bookmark_1.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_10.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_2.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_3.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_4.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_5.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_6.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_7.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_8.py:18
-#: ../src/fenrir/commands/commands/set_bookmark_9.py:18
+#: ../src/fenrirscreenreader\commands\commands\save_settings.py:18
+msgid "Saves your current Fenrir settings so they are the default."
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\save_settings.py:22
+msgid "Settings saved."
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_1.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_10.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_2.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_3.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_4.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_5.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_6.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_7.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_8.py:18
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_9.py:18
 msgid "set Bookmark {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_bookmark_1.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_10.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_2.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_3.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_4.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_5.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_6.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_7.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_8.py:22
-#: ../src/fenrir/commands/commands/set_bookmark_9.py:22
-msgid "No Mark found"
-msgstr ""
-
-#: ../src/fenrir/commands/commands/set_bookmark_1.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_10.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_2.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_3.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_4.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_5.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_6.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_7.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_8.py:32
-#: ../src/fenrir/commands/commands/set_bookmark_9.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_1.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_10.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_2.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_3.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_4.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_5.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_6.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_7.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_8.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_9.py:22
+msgid "No mark found"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_1.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_10.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_2.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_3.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_4.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_5.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_6.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_7.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_8.py:32
+#: ../src/fenrirscreenreader\commands\commands\set_bookmark_9.py:32
 msgid "Bookmark {0} set for application {1}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_mark.py:17
+#: ../src/fenrirscreenreader\commands\commands\set_mark.py:17
 msgid "places marks to select text to copy to the clipboard"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_mark.py:21
+#: ../src/fenrirscreenreader\commands\commands\set_mark.py:21
 msgid "no review cursor"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_mark.py:26
-#: ../src/fenrir/commands/commands/set_mark.py:28
+#: ../src/fenrirscreenreader\commands\commands\set_mark.py:26
+#: ../src/fenrirscreenreader\commands\commands\set_mark.py:28
 msgid "set mark"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_window_application.py:17
+#: ../src/fenrirscreenreader\commands\commands\set_window_application.py:17
 msgid "set Window Mode, needs 2 marks "
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_window_application.py:22
+#: ../src/fenrirscreenreader\commands\commands\set_window_application.py:22
 msgid "Window Mode on for application {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/set_window_application.py:25
+#: ../src/fenrirscreenreader\commands\commands\set_window_application.py:25
 msgid "Set window begin and end marks"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/shut_up.py:17
-msgid "interrupts the current presentation"
+#: ../src/fenrirscreenreader\commands\commands\shut_up.py:17
+msgid "Interrupts the current presentation"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/spell_check.py:26
+#: ../src/fenrirscreenreader\commands\commands\spell_check.py:26
 msgid "checks the spelling of the current word"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/spell_check.py:52
-#: ../src/fenrir/commands/onInput/62000-spell_check.py:132
+#: ../src/fenrirscreenreader\commands\commands\spell_check.py:51
+#: ../src/fenrirscreenreader\commands\onCursorChange\35000-spell_check.py:129
 msgid "misspelled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/spell_check.py:54
+#: ../src/fenrirscreenreader\commands\commands\spell_check.py:53
 msgid "correct"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/subprocess.py:21
+#: ../src/fenrirscreenreader\commands\commands\subprocess.py:21
 msgid "script: {0} fullpath: {1}"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/subprocess.py:24
-msgid "scriptfile does not exist"
+#: ../src/fenrirscreenreader\commands\commands\subprocess.py:24
+msgid "Script file not found"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/subprocess.py:27
-msgid "scriptfile is not a file"
+#: ../src/fenrirscreenreader\commands\commands\subprocess.py:27
+msgid "Script source is not a valid file"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/subprocess.py:30
-msgid "scriptfile is not executable"
+#: ../src/fenrirscreenreader\commands\commands\subprocess.py:30
+msgid "Script file is not executable"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/temp_disable_speech.py:17
-#: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:17
+#: ../src/fenrirscreenreader\commands\commands\temp_disable_speech.py:17
+#: ../src/fenrirscreenreader\commands\onByteInput\15000-enable_temp_speech.py:17
+#: ../src/fenrirscreenreader\commands\onKeyInput\15000-enable_temp_speech.py:17
 msgid "disables speech until next keypress"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/temp_disable_speech.py:21
-msgid "speech temporary disabled"
+#: ../src/fenrirscreenreader\commands\commands\time.py:18
+msgid "presents the time"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/time.py:18
-msgid "presents the time"
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_indent.py:16
+msgid "enables or disables automatic reading of indentation level changes"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_indent.py:21
+msgid "autoindent enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_read.py:16
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_indent.py:23
+msgid "autoindent disabled"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_read.py:16
 msgid "enables or disables automatic reading of new text as it appears"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_read.py:21
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_read.py:21
 msgid "autoread enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_read.py:23
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_read.py:23
 msgid "autoread disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:17
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_spell_check.py:17
 msgid "enables or disables automatic spell checking"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:22
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_spell_check.py:22
 msgid "auto spellcheck enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:24
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_spell_check.py:24
 msgid "auto spellcheck disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_time.py:16
-msgid "enables or disables automatic reading of time after an period"
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_time.py:16
+msgid "Enables or disables automatic reading of time after specified intervals"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_time.py:21
+msgid "Automatic time announcement enabled"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_auto_time.py:23
+msgid "Automatic time announcement disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_time.py:21
-msgid "autotime enabled"
+#: ../src/fenrirscreenreader\commands\commands\toggle_barrier.py:16
+msgid "enables or disables the barrier mode"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_auto_time.py:23
-msgid "autotime disabled"
+#: ../src/fenrirscreenreader\commands\commands\toggle_barrier.py:21
+msgid "barrier mode enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_braille.py:17
-msgid "enables and disables output in braille"
+#: ../src/fenrirscreenreader\commands\commands\toggle_barrier.py:23
+msgid "barrier mode disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_braille.py:21
+#: ../src/fenrirscreenreader\commands\commands\toggle_braille.py:17
+msgid "Enables and disables Braille output"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_braille.py:21
 msgid "braille disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_braille.py:24
+#: ../src/fenrirscreenreader\commands\commands\toggle_braille.py:24
 msgid "braille enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_emoticons.py:16
+#: ../src/fenrirscreenreader\commands\commands\toggle_emoticons.py:16
 msgid "enables or disables announcement of emoticons instead of chars"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_emoticons.py:21
+#: ../src/fenrirscreenreader\commands\commands\toggle_emoticons.py:21
 msgid "emoticons enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_emoticons.py:23
+#: ../src/fenrirscreenreader\commands\commands\toggle_emoticons.py:23
 msgid "emoticons disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:16
-#: ../src/fenrir/commands/onInput/56000-highlight_tracking.py:16
-msgid "enables or disables tracking of highlighted"
+#: ../src/fenrirscreenreader\commands\commands\toggle_has_attribute.py:16
+msgid "enables or disables the announcement of attributes"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:24
+#: ../src/fenrirscreenreader\commands\commands\toggle_has_attribute.py:21
+msgid "announcement of attributes enabled"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_has_attribute.py:23
+msgid "announcement of attributes disabled"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_highlight_tracking.py:16
+msgid "enables or disables tracking of highlighted text"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_highlight_tracking.py:24
 msgid "highlight tracking"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:26
+#: ../src/fenrirscreenreader\commands\commands\toggle_highlight_tracking.py:26
 msgid "cursor tracking"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_output.py:17
+#: ../src/fenrirscreenreader\commands\commands\toggle_output.py:17
 msgid "toggles all output settings"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_output.py:23
+#: ../src/fenrirscreenreader\commands\commands\toggle_output.py:23
 msgid "Fenrir muted"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_output.py:31
+#: ../src/fenrirscreenreader\commands\commands\toggle_output.py:31
 msgid "Fenrir unmuted"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_punctuation_level.py:23
+#: ../src/fenrirscreenreader\commands\commands\toggle_punctuation_level.py:23
 msgid "No punctuation found."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_sound.py:17
+#: ../src/fenrirscreenreader\commands\commands\toggle_sound.py:17
 msgid "enables or disables sound"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_sound.py:21
+#: ../src/fenrirscreenreader\commands\commands\toggle_sound.py:21
 msgid "sound disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_sound.py:24
+#: ../src/fenrirscreenreader\commands\commands\toggle_sound.py:24
 msgid "sound enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_speech.py:17
+#: ../src/fenrirscreenreader\commands\commands\toggle_speech.py:17
 msgid "enables or disables speech"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_speech.py:21
+#: ../src/fenrirscreenreader\commands\commands\toggle_speech.py:22
 msgid "speech disabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_speech.py:24
-#: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:28
+#: ../src/fenrirscreenreader\commands\commands\toggle_speech.py:25
+#: ../src/fenrirscreenreader\commands\onByteInput\15000-enable_temp_speech.py:24
+#: ../src/fenrirscreenreader\commands\onKeyInput\15000-enable_temp_speech.py:28
 msgid "speech enabled"
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:18
-msgid "You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again."
+#: ../src/fenrirscreenreader\commands\commands\toggle_tutorial_mode.py:18
+msgid "Exiting tutorial mode. To enter tutorial mode again press Fenrir+f1"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_tutorial_mode.py:22
+msgid "Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1."
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_vmenu_mode.py:18
+msgid "Entering or Leaving v menu mode."
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\commands\toggle_vmenu_mode.py:22
+msgid "Entering v menu."
 msgstr ""
 
-#: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:21
-msgid "you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again."
+#: ../src/fenrirscreenreader\commands\commands\toggle_vmenu_mode.py:24
+msgid "Leaving v menu."
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80000-capslock.py:22
+#: ../src/fenrirscreenreader\commands\help\curr_help.py:17
+msgid "get current help message"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\help\next_help.py:17
+msgid "get next help message"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\help\prev_help.py:17
+msgid "get prev help message"
+msgstr ""
+
+#:
+#: ../src/fenrirscreenreader\commands\onCursorChange\65000-present_line_if_cursor_change_vertical.py:46
+msgid "indented "
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\onHeartBeat\76000-time.py:66
+msgid "Autotime: {0}"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\onKeyInput\80000-capslock.py:22
 msgid "Capslock on"
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80000-capslock.py:24
+#: ../src/fenrirscreenreader\commands\onKeyInput\80000-capslock.py:24
 msgid "Capslock off"
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80300-scrolllock.py:22
+#: ../src/fenrirscreenreader\commands\onKeyInput\80300-scrolllock.py:22
 msgid "Scrolllock on"
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80300-scrolllock.py:24
+#: ../src/fenrirscreenreader\commands\onKeyInput\80300-scrolllock.py:24
 msgid "Scrolllock off"
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80500-numlock.py:22
+#: ../src/fenrirscreenreader\commands\onKeyInput\80500-numlock.py:22
 msgid "Numlock on"
 msgstr ""
 
-#: ../src/fenrir/commands/onInput/80500-numlock.py:24
+#: ../src/fenrirscreenreader\commands\onKeyInput\80500-numlock.py:24
 msgid "Numlock off"
 msgstr ""
 
 #:
-#: ../src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py:20
+#: ../src/fenrirscreenreader\commands\onScreenChanged\80000-screen_change_announcement.py:20
 msgid "screen {0}"
 msgstr ""
 
-#: ../src/fenrir/commands/onScreenUpdate/76000-time.py:66
-msgid "Autotime: {0}"
+#:
+#: ../src/fenrirscreenreader\commands\onScreenUpdate\56000-highlight_tracking.py:16
+msgid "enables or disables tracking of highlighted"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\curr_vmenu_entry.py:17
+msgid "get current v menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\dec_level_vmenu.py:17
+msgid "leave v menu submenu"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\exec_vmenu_entry.py:17
+msgid "execute v menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\inc_level_vmenu.py:17
+msgid "enter v menu submenu"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\next_vmenu_entry.py:17
+msgid "get next v menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\prev_vmenu_entry.py:17
+msgid "get prev v menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_a.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_b.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_c.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_d.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_e.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_f.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_g.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_h.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_i.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_j.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_k.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_l.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_m.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_n.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_o.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_p.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_q.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_r.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_s.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_t.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_u.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_v.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_w.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_x.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_y.py:17
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_z.py:17
+msgid "search for an menu entry"
+msgstr ""
+
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_a.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_b.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_c.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_d.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_e.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_f.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_g.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_h.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_i.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_j.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_k.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_l.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_m.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_n.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_o.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_p.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_q.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_r.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_s.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_t.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_u.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_v.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_w.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_x.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_y.py:23
+#: ../src/fenrirscreenreader\commands\vmenu-navigation\search_z.py:23
+msgid "not found"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:168
+msgid "bold"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:176
+msgid "italic"
 msgstr ""
 
-#: ../src/fenrir/fenrir.py:24
+#: ../src/fenrirscreenreader\core\attributeManager.py:184
+msgid "underline"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:192
+msgid "strikethrough"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:200
+msgid "reverse"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:208
+msgid "blink"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\attributeManager.py:225
+#: ../src/fenrirscreenreader\core\attributeManager.py:232
+msgid "default"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\byteManager.py:103
+#: ../src/fenrirscreenreader\core\byteManager.py:105
+msgid "Sticky Mode On"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\byteManager.py:109
+msgid "bypass"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\fenrirManager.py:26
 msgid "Start Fenrir"
 msgstr ""
 
-#: ../src/fenrir/fenrir.py:99
+#: ../src/fenrirscreenreader\core\fenrirManager.py:234
 msgid "Quit Fenrir"
 msgstr ""
 
+#: ../src/fenrirscreenreader\core\helpManager.py:77
+msgid "toggles the tutorial mode"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\outputManager.py:297
+msgid "speech temporary disabled"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\quickMenuManager.py:124
+msgid "setting invalid"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\quickMenuManager.py:131
+msgid "setting value invalid"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "black"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "blue"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "cyan"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "green"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "red"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+msgid "white"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Magenta"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:12
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "brown/yellow"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Black"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Blue"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Cyan"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Dark gray"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Green"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light blue"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light cyan"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light gray"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light magenta"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light red"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Light yellow"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "Red"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\screenDriver.py:13
+msgid "White"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\vmenuManager.py:66
+#: ../src/fenrirscreenreader\core\vmenuManager.py:226
+msgid "Menu"
+msgstr ""
+
+#: ../src/fenrirscreenreader\core\vmenuManager.py:234
+msgid "Action"
+msgstr ""
+
diff --git a/tools/generate_translations.sh b/tools/generate_translations.sh
index e881d32..0cce67d 100644
--- a/tools/generate_translations.sh
+++ b/tools/generate_translations.sh
@@ -1,3 +1,2 @@
 #!/usr/bin/env bash
-
-pygettext3 -d fenrir ../src/fenrir/*.py ../src/fenrir/*/*.py ../src/fenrir/*/*/*.py
+sudo pygettext3 -d fenrir ../src/fenrirscreenreader/*.py ../src/fenrirscreenreader/*/*.py ../src/fenrirscreenreader/*/*/*.py