labelmanager.py (screenkey-1.4) | : | labelmanager.py (screenkey-1.5) | ||
---|---|---|---|---|
# "screenkey" is distributed under GNU GPLv3+, WITHOUT ANY WARRANTY. | # "screenkey" is distributed under GNU GPLv3+, WITHOUT ANY WARRANTY. | |||
# Copyright(c) 2010-2012: Pablo Seminario <pabluk@gmail.com> | # Copyright(c) 2010-2012: Pablo Seminario <pabluk@gmail.com> | |||
# Copyright(c) 2015-2016: wave++ "Yuri D'Elia" <wavexx@thregr.org> | # Copyright(c) 2015-2016: wave++ "Yuri D'Elia" <wavexx@thregr.org> | |||
# Copyright(c) 2019-2020: Yuto Tokunaga <yuntan.sub1@gmail.com> | # Copyright(c) 2019-2020: Yuto Tokunaga <yuntan.sub1@gmail.com> | |||
from . import inputlistener | ||||
from .inputlistener import InputListener, InputType | from .inputlistener import InputListener, InputType | |||
from gi.repository import GLib | from gi.repository import GLib | |||
from collections import namedtuple | from collections import namedtuple | |||
from datetime import datetime | from datetime import datetime | |||
# Key replacement data: | # Key replacement data: | |||
# | # | |||
# bk_stop: stops backspace processing in baked mode, but not full mode | # bk_stop: stops backspace processing in baked mode, but not full mode | |||
skipping to change at line 57 | skipping to change at line 58 | |||
'Up': KeyRepl(True, True, False, _('↑')), | 'Up': KeyRepl(True, True, False, _('↑')), | |||
'Left': KeyRepl(True, True, False, _('←')), | 'Left': KeyRepl(True, True, False, _('←')), | |||
'Right': KeyRepl(True, True, False, _('→')), | 'Right': KeyRepl(True, True, False, _('→')), | |||
'Down': KeyRepl(True, True, False, _('↓')), | 'Down': KeyRepl(True, True, False, _('↓')), | |||
'Prior': KeyRepl(True, True, True, _('PgUp')), | 'Prior': KeyRepl(True, True, True, _('PgUp')), | |||
'Next': KeyRepl(True, True, True, _('PgDn')), | 'Next': KeyRepl(True, True, True, _('PgDn')), | |||
'Home': KeyRepl(True, True, True, _('Home')), | 'Home': KeyRepl(True, True, True, _('Home')), | |||
'End': KeyRepl(True, True, True, _('End')), | 'End': KeyRepl(True, True, True, _('End')), | |||
'Insert': KeyRepl(False, True, True, _('Ins')), | 'Insert': KeyRepl(False, True, True, _('Ins')), | |||
'Delete': KeyRepl(True, False, True, _('Del')), | 'Delete': KeyRepl(True, False, True, _('Del')), | |||
'KP_End': KeyRepl(False, False, True, _('(1)')), | 'KP_End': KeyRepl(False, False, True, _('1ᴷᴾ')), | |||
'KP_Down': KeyRepl(False, False, True, _('(2)')), | 'KP_Down': KeyRepl(False, False, True, _('2ᴷᴾ')), | |||
'KP_Next': KeyRepl(False, False, True, _('(3)')), | 'KP_Next': KeyRepl(False, False, True, _('3ᴷᴾ')), | |||
'KP_Left': KeyRepl(False, False, True, _('(4)')), | 'KP_Left': KeyRepl(False, False, True, _('4ᴷᴾ')), | |||
'KP_Begin': KeyRepl(False, False, True, _('(5)')), | 'KP_Begin': KeyRepl(False, False, True, _('5ᴷᴾ')), | |||
'KP_Right': KeyRepl(False, False, True, _('(6)')), | 'KP_Right': KeyRepl(False, False, True, _('6ᴷᴾ')), | |||
'KP_Home': KeyRepl(False, False, True, _('(7)')), | 'KP_Home': KeyRepl(False, False, True, _('7ᴷᴾ')), | |||
'KP_Up': KeyRepl(False, False, True, _('(8)')), | 'KP_Up': KeyRepl(False, False, True, _('8ᴷᴾ')), | |||
'KP_Prior': KeyRepl(False, False, True, _('(9)')), | 'KP_Prior': KeyRepl(False, False, True, _('9ᴷᴾ')), | |||
'KP_Insert': KeyRepl(False, False, True, _('(0)')), | 'KP_Insert': KeyRepl(False, False, True, _('0ᴷᴾ')), | |||
'KP_Delete': KeyRepl(False, False, True, _('(.)')), | 'KP_Delete': KeyRepl(False, False, True, _('(.)')), | |||
'KP_Add': KeyRepl(False, False, True, _('(+)')), | 'KP_Add': KeyRepl(False, False, True, _('(+)')), | |||
'KP_Subtract': KeyRepl(False, False, True, _('(-)')), | 'KP_Subtract': KeyRepl(False, False, True, _('(-)')), | |||
'KP_Multiply': KeyRepl(False, False, True, _('(*)')), | 'KP_Multiply': KeyRepl(False, False, True, _('(*)')), | |||
'KP_Divide': KeyRepl(False, False, True, _('(/)')), | 'KP_Divide': KeyRepl(False, False, True, _('(/)')), | |||
'KP_Enter': KeyRepl(True, False, False, _('⏎')), | 'KP_Enter': KeyRepl(True, False, False, _('⏎')), | |||
'KP_1': KeyRepl(False, False, True, _('1ᴷᴾ')), | ||||
'KP_2': KeyRepl(False, False, True, _('2ᴷᴾ')), | ||||
'KP_3': KeyRepl(False, False, True, _('3ᴷᴾ')), | ||||
'KP_4': KeyRepl(False, False, True, _('4ᴷᴾ')), | ||||
'KP_5': KeyRepl(False, False, True, _('5ᴷᴾ')), | ||||
'KP_6': KeyRepl(False, False, True, _('6ᴷᴾ')), | ||||
'KP_7': KeyRepl(False, False, True, _('7ᴷᴾ')), | ||||
'KP_8': KeyRepl(False, False, True, _('8ᴷᴾ')), | ||||
'KP_9': KeyRepl(False, False, True, _('9ᴷᴾ')), | ||||
'KP_0': KeyRepl(False, False, True, _('0ᴷᴾ')), | ||||
'Num_Lock': KeyRepl(False, True, True, _('NumLck')), | 'Num_Lock': KeyRepl(False, True, True, _('NumLck')), | |||
'Scroll_Lock': KeyRepl(False, True, True, _('ScrLck')), | 'Scroll_Lock': KeyRepl(False, True, True, _('ScrLck')), | |||
'Pause': KeyRepl(False, True, True, _('Pause')), | 'Pause': KeyRepl(False, True, True, _('Pause')), | |||
'Break': KeyRepl(False, True, True, _('Break')), | 'Break': KeyRepl(False, True, True, _('Break')), | |||
'Print': KeyRepl(False, True, True, _('Print')), | 'Print': KeyRepl(False, True, True, _('Print')), | |||
'Multi_key': KeyRepl(False, True, True, _('Compose')), | 'Multi_key': KeyRepl(False, True, True, _('Compose')), | |||
# Multimedia keys | # Multimedia keys | |||
'XF86AudioMute': KeyRepl(True, True, True, [ReplData(_('\uf026'), 'Font Awesome 5 Free', None), | 'XF86AudioMute': KeyRepl(True, True, True, [ReplData(_('\uf026'), 'Font Awesome 5 Free', None), | |||
ReplData(_('\uf026'), 'FontAwesome', None), | ReplData(_('\uf026'), 'FontAwesome', None), | |||
skipping to change at line 196 | skipping to change at line 207 | |||
self.font_families = {x.get_name() for x in pango_ctx.list_families()} | self.font_families = {x.get_name() for x in pango_ctx.list_families()} | |||
self.update_replacement_map() | self.update_replacement_map() | |||
def __del__(self): | def __del__(self): | |||
self.stop() | self.stop() | |||
def start(self): | def start(self): | |||
self.stop() | self.stop() | |||
compose = (self.key_mode == 'composed') | compose = (self.key_mode == 'composed') | |||
translate = (self.key_mode in ['composed', 'translated']) | translate = (self.key_mode in ['composed', 'translated']) | |||
self.kl = InputListener(self.key_press, self.btn_press, | self.kl = InputListener(self.event_handler, | |||
InputType.keyboard | InputType.button, compose, | InputType.keyboard | InputType.button, | |||
translate) | compose, translate) | |||
self.kl.start() | self.kl.start() | |||
self.logger.debug("Thread started.") | self.logger.debug("Thread started.") | |||
def stop(self): | def stop(self): | |||
if self.kl: | if self.kl: | |||
self.kl.stop() | self.kl.stop() | |||
self.logger.debug("Thread stopped.") | self.logger.debug("Thread stopped.") | |||
self.kl.join() | self.kl.join() | |||
self.kl = None | self.kl = None | |||
skipping to change at line 307 | skipping to change at line 318 | |||
# always show some return symbol at the last line | # always show some return symbol at the last line | |||
markup += self.replace_syms['Return'].repl | markup += self.replace_syms['Return'].repl | |||
if recent: | if recent: | |||
markup += '</u>' | markup += '</u>' | |||
self.logger.debug("Label updated: %s." % repr(markup)) | self.logger.debug("Label updated: %s." % repr(markup)) | |||
self.label_listener(markup, synthetic) | self.label_listener(markup, synthetic) | |||
def queue_update(self): | def queue_update(self): | |||
self.update_text(True) | self.update_text(True) | |||
def key_press(self, event): | def event_handler(self, event): | |||
if event is None: | if event is None: | |||
self.logger.debug("inputlistener failure: {}".format(str(self.kl.err or))) | self.logger.debug("inputlistener failure: {}".format(str(self.kl.err or))) | |||
self.label_listener(None, None) | self.label_listener(None, None) | |||
return | return | |||
if isinstance(event, inputlistener.KeyData): | ||||
self.key_press(event) | ||||
elif isinstance(event, inputlistener.ButtonData): | ||||
self.btn_press(event) | ||||
else: | ||||
self.logger.error("unhandled event type {}".format(type(event))) | ||||
def key_press(self, event): | ||||
if event.symbol is None: | if event.symbol is None: | |||
# TODO: Investigate what causes this to happen. | # TODO: Investigate what causes this to happen. | |||
# I caught it once in pdb, but in this function, not in inputlistene r, | # I caught it once in pdb, but in this function, not in inputlistene r, | |||
# and KeyData doesn't contain enough info. | # and KeyData doesn't contain enough info. | |||
return | return | |||
symbol = event.symbol.decode() | symbol = event.symbol.decode() | |||
if self.enabled: | if self.enabled: | |||
for mod, button_id in zip(['ctrl', 'alt', 'shift'], range(8, 11)): | for mod, button_id in zip(['ctrl', 'alt', 'shift'], range(8, 11)): | |||
if symbol in MODS_SYMS[mod]: | if symbol in MODS_SYMS[mod]: | |||
skipping to change at line 502 | skipping to change at line 522 | |||
def key_keysyms_mode(self, event): | def key_keysyms_mode(self, event): | |||
symbol = event.symbol.decode() | symbol = event.symbol.decode() | |||
if symbol in REPLACE_SYMS: | if symbol in REPLACE_SYMS: | |||
value = symbol | value = symbol | |||
else: | else: | |||
value = event.string or symbol | value = event.string or symbol | |||
self.data.append(KeyData(datetime.now(), True, True, True, True, value)) | self.data.append(KeyData(datetime.now(), True, True, True, True, value)) | |||
return True | return True | |||
# callback for mouse button presses | ||||
def btn_press(self, event): | def btn_press(self, event): | |||
if not self.enabled: | if not self.enabled: | |||
return False | return False | |||
if event.pressed: | if event.pressed: | |||
action = "pressed" | action = "pressed" | |||
else: | else: | |||
action = "released" | action = "released" | |||
self.logger.debug("Mouse button %d %s" % (event.btn, action)) | self.logger.debug("Mouse button %d %s" % (event.btn, action)) | |||
self.image_listener( | # possible event.btn values: | |||
ButtonData(datetime.now(), event.btn, event.pressed) | # 1 = LMB, 2 = MMB (wheel click), 3 = RMB, 4/5 = wheel up/down, | |||
) | # 6/7 = wheel left/right, 8+ extra buttons (e. g. thumb buttons) | |||
if event.btn > 7: | ||||
# image_listener can only handle common buttons, redirect thumb butt | ||||
ons etc. to label | ||||
if not event.pressed: | ||||
return False | ||||
# what we refer to as "Mouse 4" has an internal value of 8, | ||||
# so we subtract 4 from the btn value | ||||
markup = GLib.markup_escape_text("M{}".format(event.btn - 4)) | ||||
# show as label, treated the same as keyboard button presses | ||||
self.data.append(KeyData(datetime.now(), False, True, | ||||
True, True, markup)) | ||||
self.update_text() | ||||
else: | ||||
# show event in image | ||||
self.image_listener( | ||||
ButtonData(datetime.now(), event.btn, event.pressed) | ||||
) | ||||
End of changes. 9 change blocks. | ||||
15 lines changed or deleted | 35 lines changed or added |