from kmk.common.consts import UnicodeModes from kmk.common.event_defs import (hid_report_event, keycode_down_event, keycode_up_event) from kmk.common.keycodes import Common, Macro, Modifiers from kmk.common.macros.simple import simple_key_sequence IBUS_KEY_COMBO = Modifiers.KC_LCTRL(Modifiers.KC_LSHIFT(Common.KC_U)) def generate_codepoint_keysym_seq(codepoint): # To make MacOS and Windows happy, always try to send # sequences that are of length 4 at a minimum # On Linux systems, we can happily send longer strings. # They will almost certainly break on MacOS and Windows, # but this is a documentation problem more than anything. # Not sure how to send emojis on Mac/Windows like that, # though, since (for example) the Canadian flag is assembled # from two five-character codepoints, 1f1e8 and 1f1e6 seq = [Common.KC_0 for _ in range(max(len(codepoint), 4))] for idx, codepoint_fragment in enumerate(reversed(codepoint)): seq[-(idx + 1)] = getattr(Common, 'KC_{}'.format(codepoint_fragment.upper())) return seq def unicode_sequence(codepoints): def _unicode_sequence(state): if state.unicode_mode == UnicodeModes.IBUS: yield from _ibus_unicode_sequence(codepoints, state) elif state.unicode_mode == UnicodeModes.RALT: yield from _ralt_unicode_sequence(codepoints, state) elif state.unicode_mode == UnicodeModes.WINC: yield from _winc_unicode_sequence(codepoints, state) return Macro(keydown=_unicode_sequence) def _ralt_unicode_sequence(codepoints, state): for codepoint in codepoints: yield keycode_down_event(Modifiers.RALT(no_release=True)) yield from simple_key_sequence(generate_codepoint_keysym_seq(codepoint)).keydown(state) yield keycode_up_event(Modifiers.RALT(no_press=True)) def _ibus_unicode_sequence(codepoints, state): for codepoint in codepoints: yield keycode_down_event(IBUS_KEY_COMBO) yield hid_report_event() yield keycode_up_event(IBUS_KEY_COMBO) yield hid_report_event() seq = generate_codepoint_keysym_seq(codepoint) seq.append(Common.KC_ENTER) yield from simple_key_sequence(seq).keydown(state) def _winc_unicode_sequence(codepoints, state): ''' Send unicode sequence using WinCompose: http://wincompose.info/ https://github.com/SamHocevar/wincompose ''' for codepoint in codepoints: yield keycode_down_event(Modifiers.RALT()) yield keycode_down_event(Common.KC_U()) yield from simple_key_sequence(generate_codepoint_keysym_seq(codepoint)).keydown(state)