configs

configs
git clone https://git.prime8.dev/configs.git
Log | Files | Refs | README

commit ab203592b6089d8fc214261aea97990eae1335fd
parent b55c411ff049c6b5e33045d681657ef826067858
Author: Damian Myrda <damian@prime8.dev>
Date:   Tue,  7 Apr 2026 12:11:21 -0500

update toshy keymap config internals

Diffstat:
Mprograms/toshy/toshy_config.py | 770++++++++++++++++++++++++++++++++++++-------------------------------------------
1 file changed, 351 insertions(+), 419 deletions(-)

diff --git a/programs/toshy/toshy_config.py b/programs/toshy/toshy_config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -__version__ = '20260101' +__version__ = '20260404' ############################################################################### ############################ Welcome to Toshy! ############################ ### @@ -26,8 +26,11 @@ import asyncio import inspect import subprocess +# Removing problematic types before they get deprecated: +# from typing import Any, Callable, Optional, Union, List, Dict, Tuple +from typing import Any from subprocess import DEVNULL -from typing import Any, Callable, Optional, Union, List, Dict, Tuple +from collections.abc import Callable from xwaykeyz.config_api import * from xwaykeyz.lib.key_context import KeyContext @@ -92,8 +95,8 @@ try: ########################################################################### # # Virtualized (left) Control key (in Terminals) - LC_aliases: List[str] = Modifier.L_CONTROL.aliases - LC_keys: List[Key] = Modifier.L_CONTROL.keys + LC_aliases: 'list[str]' = Modifier.L_CONTROL.aliases + LC_keys: 'list[Key]' = Modifier.L_CONTROL.keys # use slice assignment instead of insert() LC_aliases[:0] = ['VLCtrl', 'VirtLCtrl'] # debug(f"{LC_aliases = }") @@ -119,8 +122,8 @@ try: ########################################################################### # Virtualized Option/Alt keys (left/right) - LA_aliases: List[str] = Modifier.L_ALT.aliases - LA_keys: List[Key] = Modifier.L_ALT.keys + LA_aliases: 'list[str]' = Modifier.L_ALT.aliases + LA_keys: 'list[Key]' = Modifier.L_ALT.keys # use slice assignment instead of insert() LA_aliases[:0] = ['VLOpt', 'VirtLOpt'] # debug(f"{LA_aliases = }") @@ -136,8 +139,8 @@ try: ########################################################################### # Virtualized Command key (all keyboard types) - R_CONTROL_aliases: List[str] = Modifier.R_CONTROL.aliases - R_CONTROL_keys: List[Key] = Modifier.R_CONTROL.keys + R_CONTROL_aliases: 'list[str]' = Modifier.R_CONTROL.aliases + R_CONTROL_keys: 'list[Key]' = Modifier.R_CONTROL.keys # use slice assignment instead of insert() R_CONTROL_aliases[:0] = ['VCmd', 'VirtCmd'] # debug(f"{R_CONTROL_aliases = }") @@ -164,7 +167,9 @@ sys.path.insert(0, current_folder_path) from toshy_common.env_context import EnvironmentInfo from toshy_common.machine_context import get_machine_id_hash from toshy_common.notification_manager import NotificationManager +from toshy_common.runtime_utils import sanitize_text from toshy_common.settings_class import Settings +from toshy_common.terminal_utils import print_pango_text assets_path = os.path.join(current_folder_path, 'assets') icon_file_active = os.path.join(assets_path, "toshy_app_icon_rainbow.svg") @@ -233,7 +238,7 @@ DE_MAJ_VER = None WINDOW_MGR = None env_ctxt_getter = EnvironmentInfo() -env_ctxt: Dict[str, str] = env_ctxt_getter.get_env_info() +env_ctxt: 'dict[str, str]' = env_ctxt_getter.get_env_info() DISTRO_ID = locals().get('OVERRIDE_DISTRO_ID') or env_ctxt.get('DISTRO_ID', 'keymissing') DISTRO_VER = locals().get('OVERRIDE_DISTRO_VER') or env_ctxt.get('DISTRO_VER', 'keymissing') @@ -331,8 +336,6 @@ MACHINE_ID = get_machine_id_hash() # Establish important global variables here -STARTUP_TIMESTAMP = time.time() # only gets evaluated once for each run of keymapper - # Variable to hold the keyboard type KBTYPE = None @@ -408,7 +411,7 @@ def negRgx(rgx_str): return neg_rgx_str -def create_list_of_dicts(lst: List[str]): +def create_list_of_dicts(lst: 'list[str]'): """ Convert a simple list of class names into a list of dictionaries, each dictionary containing a single key 'clas' with the regex pattern @@ -522,8 +525,6 @@ transmissionStr = toRgxStr(transmissions) # different WM_NAME than client windows. See `remotes_lod` below.) remotes = [ "Anydesk", - "cs2", - "csgo", "Gnome-boxes", "gnome-connections", "org.gnome.Boxes", @@ -966,238 +967,24 @@ def isDoubleTap(dt_combo): return _isDoubleTap -total_matchProps_iterations = 0 -MAX_MATCHPROPS_ITERATIONS = 1000 -MAX_MATCHPROPS_ITERATIONS_REACHED = False -MATCHPROPS_FULL_DEBUG = False # Set True to disable short-circuits and enable full debug logging - - -# Correct syntax to reject all positional parameters: put `*,` at beginning -def matchProps(*, - # string parameters (positive matching) - clas: str = None, name: str = None, devn: str = None, - # string parameters (negative matching) - not_clas: str = None, not_name: str = None, not_devn: str = None, - # bool parameters - numlk: bool = None, capslk: bool = None, cse: bool = None, - # list of dicts of parameters (positive) - lst: List[Dict[str, Union[str, bool]]] = None, - # list of dicts of parameters (negative) - not_lst: List[Dict[str, Union[str, bool]]] = None, - dbg: str = None, # debugging info (such as: which modmap/keymap?) -) -> Callable[[KeyContext], bool]: - """ - ### Match all given properties to current window context. \n - - Parameters must be _named_, no positional arguments. \n - - All parameters optional, but at least one must be given. \n - - Defaults to case insensitive matching of: \n - - WM_CLASS, WM_NAME, device_name \n - - To negate/invert regex pattern match use: \n - - `not_clas` `not_name` `not_devn` params or... \n - - "^(?:(?!^pattern$).)*$" \n - - To force case insensitive pattern match use: \n - - "^(?i:pattern)$" or... \n - - "^(?i)pattern$" \n - - ### Accepted Parameters: \n - `clas` = WM_CLASS (regex/string) [xprop WM_CLASS] \n - `name` = WM_NAME (regex/string) [xprop _NET_WM_NAME] \n - `devn` = Device Name (regex/string) [xwaykeyz --list-devices] \n - `not_clas` = `clas` but inverted, matches when "not" \n - `not_name` = `name` but inverted, matches when "not" \n - `not_devn` = `devn` but inverted, matches when "not" \n - `numlk` = Num Lock LED state (bool) \n - `capslk` = Caps Lock LED state (bool) \n - `cse` = Case Sensitive matching (bool) \n - `lst` = List of dicts of the above arguments \n - `not_lst` = `lst` but inverted, matches when "not" \n - `dbg` = Debugging info (string) \n - - ### Negative match parameters: - - `not_clas`|`not_name`|`not_devn` \n - Parameters take same regex patterns as `clas`|`name`|`devn` \n - but result in a True condition only if pattern is NOT found. \n - Negative parameters cannot be used together with the normal \n - positive matching equivalent parameter in same instance. \n - - ### List of Dicts parameter: `lst`|`not_lst` - A [list] of {dicts} with each dict containing 1 to 6 of the \n - named parameters above, to be processed recursively as args. \n - A dict can also contain a single `lst` or `not_lst` argument. \n - - ### Debugging info parameter: `dbg` - A string that will print as part of logging output. Use to \n - help identify origin of logging output. \n - - \n - """ - # Reference for successful negative lookahead pattern, and - # explanation of why it works: - # https://stackoverflow.com/questions/406230/\ - # regular-expression-to-match-a-line-that-doesnt-contain-a-word - - global MAX_MATCHPROPS_ITERATIONS_REACHED - global total_matchProps_iterations - - # Return `False` immediately if screen does not have focus (e.g. Synergy), - # but only after the guard clauses have had a chance to evaluate on - # all possible uses of the function that may exist in the config. - if MAX_MATCHPROPS_ITERATIONS_REACHED and not cnfg.screen_has_focus: - # return False # Returning a boolean here causes as exception. Must return a callable! - return lambda _: False - - if total_matchProps_iterations >= MAX_MATCHPROPS_ITERATIONS: - MAX_MATCHPROPS_ITERATIONS_REACHED = True - bypass_guard_clauses = True - else: - total_matchProps_iterations += 1 - current_timestamp = time.time() - - # 'STARTUP_TIMESTAMP' is a global variable, set when config is executed - time_elapsed = current_timestamp - STARTUP_TIMESTAMP - - # Bypass all guard clauses if more than a few seconds have passed since keymapper - # started and loaded the config file. Inputs never change until keymapper - # restarts and reloads the config file, so we don't need to keep checking. - bypass_guard_clauses = time_elapsed > 6 - - logging_enabled = False - - allowed_params = (clas, name, devn, not_clas, not_name, not_devn, - numlk, capslk, cse, lst, not_lst, dbg) - lst_dct_params = (clas, name, devn, not_clas, not_name, not_devn, - numlk, capslk, cse) - string_params = (clas, name, devn, not_clas, not_name, not_devn, dbg) - - # This was using up a lot of CPU time, actually. Bad idea. - # dct_param_strs = list(inspect.signature(matchProps).parameters.keys()) - - # Static list of parameter names. Using this instead of `inspect` cuts CPU - # usage considerably, for reasons I don't yet understand. Apparently the - # keymapper is actually running the entire function again on each key - # press and release, rather than just re-evaluating the inner closure. - dct_param_strs = [ - 'clas', 'name', 'devn', 'not_clas', 'not_name', 'not_devn', - 'numlk', 'capslk', 'cse', 'lst', 'not_lst', 'dbg' - ] - - if not MAX_MATCHPROPS_ITERATIONS_REACHED or not bypass_guard_clauses: - if all([x is None for x in allowed_params]): - raise ValueError(f"\n\n(EE) matchProps(): Received no valid argument\n") - if any([x not in (True, False, None) for x in (numlk, capslk, cse)]): - raise TypeError(f"\n\n(EE) matchProps(): Params 'numlk|capslk|cse' are bools\n") - if any([x is not None and not isinstance(x, str) for x in string_params]): - raise TypeError( f"\n\n(EE) matchProps(): These parameters must be strings:" - f"\n\t'clas|name|devn|not_clas|not_name|not_devn|dbg'\n") - if clas and not_clas or name and not_name or devn and not_devn or lst and not_lst: - raise ValueError( f"\n\n(EE) matchProps(): Do not mix positive and " - f"negative match params for same property\n") - - # consolidate positive and negative matching params into new vars - # only one should be in use at a time (checked above) - _lst = not_lst if lst is None else lst - _clas = not_clas if clas is None else clas - _name = not_name if name is None else name - _devn = not_devn if devn is None else devn - - # process lists of conditions - if _lst is not None: - - if not MAX_MATCHPROPS_ITERATIONS_REACHED or not bypass_guard_clauses: - if any([x is not None for x in lst_dct_params]): - raise TypeError(f"\n\n(EE) matchProps(): Param 'lst|not_lst' must be used alone\n") - if not isinstance(_lst, list) or not all(isinstance(item, dict) for item in _lst): - raise TypeError( - f"\n\n(EE) matchProps(): Param 'lst|not_lst' wants a [list] of {{dicts}}\n") - # verify that every {dict} in [list of dicts] only contains valid parameter names - for dct in _lst: - for param in list(dct.keys()): - if param not in dct_param_strs: - error(f"matchProps(): Invalid parameter: '{param}'") - error(f"Invalid parameter is in this dict: \n\t{dct}") - error(f"Dict is in this list:") - for item in _lst: - print(f"\t{item}") - raise ValueError( - f"\n(EE) matchProps(): Invalid parameter found in dict in list. " - f"See log output before traceback.\n") - - def _matchProps_Lst(ctx: KeyContext): - if not cnfg.screen_has_focus: - return False - if not_lst is not None: - if logging_enabled: print(f"## _matchProps_Lst()[not_lst] ## {dbg=}") - return not any(matchProps(**dct)(ctx) for dct in not_lst) - else: - if logging_enabled: print(f"## _matchProps_Lst()[lst] ## {dbg=}") - return any(matchProps(**dct)(ctx) for dct in lst) - - return _matchProps_Lst # outer function returning inner function - - # compile case insensitive regex object for given params, unless cse=True - if _clas is not None: clas_rgx = re.compile(_clas, 0 if cse else re.I) - if _name is not None: name_rgx = re.compile(_name, 0 if cse else re.I) - if _devn is not None: devn_rgx = re.compile(_devn, 0 if cse else re.I) - - def _matchProps(ctx: KeyContext): - if not cnfg.screen_has_focus: - return False - - nt_err = 'ERR: matchProps: NoneType in ctx.' - - # Full debug mode: use original cond_list approach for complete visibility - if MATCHPROPS_FULL_DEBUG: - cond_list = [] - if numlk is not None: - cond_list.append(numlk is ctx.numlock_on) - if capslk is not None: - cond_list.append(capslk is ctx.capslock_on) - if _devn is not None: - devn_match = re.search(devn_rgx, ctx.device_name or nt_err + 'device_name') - cond_list.append(not devn_match if not_devn is not None else devn_match) - if _clas is not None: - clas_match = re.search(clas_rgx, ctx.wm_class or nt_err + 'wm_class') - cond_list.append(not clas_match if not_clas is not None else clas_match) - if _name is not None: - name_match = re.search(name_rgx, ctx.wm_name or nt_err + 'wm_name') - cond_list.append(not name_match if not_name is not None else name_match) - print(f'#### CND_LST ({all(cond_list)}) #### {dbg=}') - for elem in cond_list: - print('##', re.sub(r'^.*span=.*\), ', '', str(elem)).replace('>','')) - print('-------------------------------------------------------------------') - return all(cond_list) - - # Optimized path: short-circuit on first failure - # Order: cheapest checks first, then most selective (devn), then clas, then name - - # Bool checks - nearly free (identity comparison) - if numlk is not None and numlk is not ctx.numlock_on: - return False - if capslk is not None and capslk is not ctx.capslock_on: - return False - - # Device check - most selective, eliminates most keystrokes from other devices - if _devn is not None: - devn_match = re.search(devn_rgx, ctx.device_name or nt_err + 'device_name') - # XOR: fail if (negative match requested) == (match found) - if (not_devn is not None) == bool(devn_match): - return False - - # Class check - moderately selective, often complex regex patterns - if _clas is not None: - clas_match = re.search(clas_rgx, ctx.wm_class or nt_err + 'wm_class') - if (not_clas is not None) == bool(clas_match): - return False - - # Name check - least commonly used - if _name is not None: - name_match = re.search(name_rgx, ctx.wm_name or nt_err + 'wm_name') - if (not_name is not None) == bool(name_match): - return False - - return True - - return _matchProps # outer function returning inner function - +### Hoisted matchProps closures — factory runs once here, not on every key event ### +hmp_is_remote = matchProps(clas=remoteStr) # Only needed for diagnostic dlg +hmp_not_remote = matchProps(not_clas=remoteStr) +hmp_is_terminal = matchProps(clas=termStr) +hmp_not_term_or_remote = matchProps(not_clas=terms_and_remotes_Str) +hmp_not_vscode_or_remote = matchProps(not_clas=vscodes_and_remotes_Str) +hmp_is_vscode = matchProps(clas=vscodeStr) +hmp_numlk_off = matchProps(numlk=False) +hmp_is_browser = matchProps(clas=browsers_allStr) +hmp_is_chrome_browser = matchProps(clas=browsers_chromeStr) +hmp_is_firefox_browser = matchProps(clas=browsers_firefoxStr) +hmp_is_filemanager = matchProps(clas=filemanagerStr) + +# Hoisted list-of-dicts calls — pre-build inner closures at load time +_dialog_escape_closures = [matchProps(**dct) for dct in dialogs_Escape_lod] +hmp_is_dialog_escape = lambda ctx: any(c(ctx) for c in _dialog_escape_closures) +_dialog_closewin_closures = [matchProps(**dct) for dct in dialogs_CloseWin_lod] +hmp_is_dialog_closewin = lambda ctx: any(c(ctx) for c in _dialog_closewin_closures) # Boolean variable to toggle Enter key state between F2 and Enter # True = Enter key sends F2, False = Enter key sends Enter @@ -1361,13 +1148,13 @@ def notify_context(): ctx_devn = ctx.device_name # ------ following are all True/False - ctx_term = matchProps(clas=termStr )(ctx) - ctx_rmte = matchProps(clas=remoteStr )(ctx) - ctx_fmgr = matchProps(clas=filemanagerStr )(ctx) - ctx_brws = matchProps(clas=browsers_allStr )(ctx) - ctx_vscd = matchProps(clas=vscodeStr )(ctx) + ctx_term = hmp_is_terminal(ctx) + ctx_rmte = hmp_is_remote(ctx) + ctx_fmgr = hmp_is_filemanager(ctx) + ctx_brws = hmp_is_browser(ctx) + ctx_vscd = hmp_is_vscode(ctx) - if matchProps(lst=dialogs_CloseWin_lod)(ctx) or matchProps(lst=dialogs_Escape_lod)(ctx): + if hmp_is_dialog_closewin(ctx) or hmp_is_dialog_escape(ctx): ctx_dlgs = True else: ctx_dlgs = False @@ -1404,15 +1191,18 @@ def notify_context(): f"</tt>" ) + # Sanitize Unicode characters in dialog text if locale does not support + sane_message = sanitize_text(message) + zenity_cmd_lst = [ zenity_cmd, '--info', '--no-wrap', '--title=Toshy Context Info', - '--text=' + message ] + '--text=' + sane_message ] # insert the icon argument if it's supported if zenity_icon_option is not None: zenity_cmd_lst.insert(3, zenity_icon_option) - kdialog_cmd_lst = [kdialog_cmd, '--msgbox', message, '--title', 'Toshy Context Info'] + kdialog_cmd_lst = [kdialog_cmd, '--msgbox', sane_message, '--title', 'Toshy Context Info'] # Add icon if needed: kdialog_cmd_lst += ['--icon', '/path/to/icon'] # Figure out why icon argument doesn't work. Need a proper icon theme folder? # DONE: Figured out that Kdialog does not support custom icons at all! @@ -1423,11 +1213,81 @@ def notify_context(): elif dialog_cmd == zenity_cmd: subprocess.Popen(zenity_cmd_lst, cwd=icons_dir, stderr=DEVNULL, stdout=DEVNULL) + # Also print out the diagnostics to the terminal, in case the dialog doesn't work. + # Trim the last 4 lines (dialog-only hints) for terminal output + term_message = nwln_str.join(message.split(nwln_str)[:-4]) + print(f"\n{'=' * 50}") + print(f" Toshy Context Info (diagnostic dialog content)") + print(f"{'=' * 50}") + print_pango_text(term_message, nwln_str) + print() # separate from following lines + # Optionally, also send a system notification: # ntfy.send_notification(message) return _notify_context +### XKB OPTIONS CHECK ### + +from toshy_common.xkb_check import XKBOptionsCheck + +_xkb_checker = XKBOptionsCheck() +_xkb_has_issues = _xkb_checker.check_for_issues() + +if _xkb_has_issues: + _xkb_sep = '!' * 72 + print() # blank line in logging + error(f'\n' + f'{_xkb_sep}\n' + f'{_xkb_sep}\n' + f'\n' + f' WARNING: XKB configuration issue detected!\n' + f'\n' + f' Your system has XKB options that reassign modifier keys\n' + f' Toshy depends on. This WILL cause shortcuts like\n' + f' Cmd+C, Cmd+V, Cmd+X, Cmd+A, Cmd+F, etc. to FAIL.\n' + f'\n' + f' Run this command for details and fix instructions:\n' + f'\n' + f' toshy-xkb-check\n' + f'\n' + f'{_xkb_sep}\n' + f'{_xkb_sep}\n' + ) + + ntfy.send_notification( + message = 'XKB config issue detected! ' + 'Modifier key shortcuts will not work correctly. ' + 'Run "toshy-xkb-check" in a terminal for details.', + urgency = 'critical', + ) + + if zenity_cmd: + try: + _xkb_dialog_text = ( + 'WARNING: XKB configuration issue detected!\n' + '\n' + 'Your system has XKB options that reassign modifier\n' + 'keys Toshy depends on. This WILL cause shortcuts\n' + 'like copy, paste, cut, select-all, and find to FAIL.\n' + '\n' + 'Run this command in a terminal for details:\n' + '\n' + ' toshy-xkb-check' + ) + _xkb_dialog_cmd = [zenity_cmd, '--warning', + '--title=Toshy XKB Warning', + f'--text={_xkb_dialog_text}', + '--width=450'] + if zenity_icon_option: + _xkb_dialog_cmd.append(zenity_icon_option) + subprocess.Popen(_xkb_dialog_cmd, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + except Exception: + pass # dialog is best-effort, don't block config loading + + def is_pre_GNOME_45(de_ver): """Utility function to check if GNOME version is older than GNOME 45""" if DESKTOP_ENV != 'gnome': @@ -1587,12 +1447,12 @@ def process_multitap_command(command, ctx): # Per-combo state tracking using action tuple as key -tap_states: Dict[tuple, Dict[str, Any]] = {} +tap_states: 'dict[tuple, dict[str, Any]]' = {} -event_loop: Optional[asyncio.AbstractEventLoop] = None +event_loop: 'asyncio.AbstractEventLoop | None' = None -def get_loop() -> Optional[asyncio.AbstractEventLoop]: +def get_loop() -> 'asyncio.AbstractEventLoop | None': global event_loop if event_loop is None or event_loop.is_closed(): try: @@ -1640,13 +1500,13 @@ def multitap_config(tap_interval=None, min_tap_delay=None): f"adjusted to {_MULTITAP_CONFIG['min_tap_delay']:.3f}s") -def isMultiTap( tap_1_action: Optional[Callable] = None, - tap_2_action: Optional[Callable] = None, - tap_3_action: Optional[Callable] = None, - tap_4_action: Optional[Callable] = None, - tap_5_action: Optional[Callable] = None, +def isMultiTap( tap_1_action: 'Callable | None' = None, + tap_2_action: 'Callable | None' = None, + tap_3_action: 'Callable | None' = None, + tap_4_action: 'Callable | None' = None, + tap_5_action: 'Callable | None' = None, tap_interval: float = None, - min_tap_delay: float = None) -> Callable: + min_tap_delay: float = None): # returns Callable """ Multi-tap handler that supports 1-5 taps with asyncio. @@ -1790,7 +1650,7 @@ def isMultiTap( tap_1_action: Optional[Callable] = None, state = tap_states[action_key] # Cancel any pending finalization - finalize_handle: Optional[asyncio.Handle] = state['finalize_handle'] + finalize_handle: 'asyncio.Handle | None' = state['finalize_handle'] if finalize_handle is not None: finalize_handle.cancel() state['finalize_handle'] = None @@ -1868,7 +1728,7 @@ def get_iEF2_context(): application does not match on the file manager app class string""" def _get_iEF2_context(ctx: KeyContext): global _enter_is_F2, _enter_F2_last_app_class - if not _enter_is_F2 and not matchProps(clas=filemanagerStr)(ctx): + if not _enter_is_F2 and not hmp_is_filemanager(ctx): debug("Resetting Enter-to-rename state variable to True.") _enter_is_F2 = True _enter_F2_last_app_class = None @@ -1912,7 +1772,7 @@ modmap("Cond modmap - Media Arrows Fix",{ }, when = lambda ctx: cnfg.media_arrows_fix and cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -1944,7 +1804,7 @@ exclude_kpad_devs_UserCustom_lod = locals().get('exclude_kpad_devs_UserCustom_lo # Ensure the NEW variable exists and is a list before attempting to access it # (Existing users MIGHT NOT have it in the marked slice above) -exclude_kpad_devs_UserCustom_lst = locals().get('exclude_kpad_devs_UserCustom_lod', []) +exclude_kpad_devs_UserCustom_lst = locals().get('exclude_kpad_devs_UserCustom_lst', []) DEPRECATED_exclude_kpad_devs_UserCustom_lst = [ device['devn'] for device in exclude_kpad_devs_UserCustom_lod @@ -1959,6 +1819,9 @@ exclude_kpad_devs_lst = [ ] exclude_kpad_devs_Str = toRgxStr(exclude_kpad_devs_lst) +# Hoist placed here because exclude_kpad_devs_Str is defined above +hmp_not_kpad_devs = matchProps(not_devn=exclude_kpad_devs_Str) + modmap("Cond modmap - Forced Numpad feature",{ # Make numpad be a numpad regardless of Numlock state (like an Apple keyboard in macOS) Key.KP1: Key.KEY_1, @@ -1976,8 +1839,8 @@ modmap("Cond modmap - Forced Numpad feature",{ }, when = lambda ctx: cnfg.forced_numpad and cnfg.screen_has_focus and - matchProps(not_devn=exclude_kpad_devs_Str)(ctx) and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_kpad_devs(ctx) and + hmp_not_remote(ctx) ) @@ -2001,9 +1864,9 @@ modmap("Cond modmap - GTK3 numpad nav keys fix", { }, when = lambda ctx: not cnfg.forced_numpad and cnfg.screen_has_focus and - matchProps(numlk=False)(ctx) and - matchProps(not_devn=exclude_kpad_devs_Str)(ctx) and - matchProps(not_clas=remoteStr)(ctx) + hmp_numlk_off(ctx) and + hmp_not_kpad_devs(ctx) and + hmp_not_remote(ctx) ) @@ -2019,7 +1882,7 @@ multipurpose_modmap("Enter2Cmd", { }, when = lambda ctx: cnfg.Enter2Ent_Cmd and cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) multipurpose_modmap("Caps2Esc - not Chromebook kbd", { @@ -2028,7 +1891,7 @@ multipurpose_modmap("Caps2Esc - not Chromebook kbd", { cnfg.Caps2Esc_Cmd and cnfg.screen_has_focus and not isKBtype('Chromebook')(ctx) and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) multipurpose_modmap("Caps2Esc - Chromebook kbd", { @@ -2037,7 +1900,7 @@ multipurpose_modmap("Caps2Esc - Chromebook kbd", { cnfg.Caps2Esc_Cmd and cnfg.screen_has_focus and isKBtype('Chromebook')(ctx) and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -2067,7 +1930,7 @@ modmap("Cond modmap - GUI - Caps2Cmd - not Cbk kdb", { cnfg.Caps2Cmd and cnfg.screen_has_focus and not isKBtype('Chromebook')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Caps2Cmd - Cbk kdb", { Key.LEFT_META: Key.RIGHT_CTRL, # Caps2Cmd - Chromebook @@ -2075,7 +1938,7 @@ modmap("Cond modmap - GUI - Caps2Cmd - Cbk kdb", { cnfg.Caps2Cmd and cnfg.screen_has_focus and isKBtype('Chromebook')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - IBM kbd - multi_lang OFF", { # - IBM @@ -2085,7 +1948,7 @@ modmap("Cond modmap - GUI - IBM kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('IBM', map='mmap GUI IBM ML-OFF')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - IBM kbd", { # - IBM @@ -2095,7 +1958,7 @@ modmap("Cond modmap - GUI - IBM kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('IBM', map='mmap GUI IBM')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Cbk kbd - multi_lang OFF", { # - Chromebook @@ -2105,7 +1968,7 @@ modmap("Cond modmap - GUI - Cbk kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Chromebook', map='mmap GUI Cbk ML-OFF')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Cbk kbd", { # - Chromebook @@ -2114,7 +1977,7 @@ modmap("Cond modmap - GUI - Cbk kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Chromebook', map='mmap GUI Cbk')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Win kbd - multi_lang OFF", { # - Default Mac/Win @@ -2126,7 +1989,7 @@ modmap("Cond modmap - GUI - Win kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Windows', map='mmap GUI Win ML-OFF')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Win kbd", { # - Default Mac/Win @@ -2137,7 +2000,7 @@ modmap("Cond modmap - GUI - Win kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Windows', map='mmap GUI Win')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Mac kbd - multi_lang OFF", { # - Mac Only @@ -2147,7 +2010,7 @@ modmap("Cond modmap - GUI - Mac kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Apple', map='mmap GUI Apple ML-OFF')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) modmap("Cond modmap - GUI - Mac kbd", { # - Mac Only @@ -2156,7 +2019,7 @@ modmap("Cond modmap - GUI - Mac kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Apple', map='mmap GUI Apple')(ctx) and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) @@ -2168,7 +2031,7 @@ modmap("Cond modmap - Terms - IBM kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('IBM', map='mmap terms IBM ML-OFF')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - IBM kbd", { # - IBM @@ -2180,7 +2043,7 @@ modmap("Cond modmap - Terms - IBM kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('IBM', map='mmap terms IBM')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Cbk kbd - multi_lang OFF", { # - Chromebook @@ -2189,7 +2052,7 @@ modmap("Cond modmap - Terms - Cbk kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Chromebook', map='mmap terms Cbk ML-OFF')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Cbk kbd", { # - Chromebook @@ -2201,7 +2064,7 @@ modmap("Cond modmap - Terms - Cbk kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Chromebook', map='mmap terms Cbk')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Win kbd - multi_lang OFF", { # - Default Mac/Win @@ -2213,7 +2076,7 @@ modmap("Cond modmap - Terms - Win kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Windows', map='mmap terms Win ML-OFF')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Win kbd", { # - Default Mac/Win @@ -2224,7 +2087,7 @@ modmap("Cond modmap - Terms - Win kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Windows', map='mmap terms Win')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Mac kbd - multi_lang OFF", { # - Mac Only @@ -2235,7 +2098,7 @@ modmap("Cond modmap - Terms - Mac kbd - multi_lang OFF", { not cnfg.multi_lang and cnfg.screen_has_focus and isKBtype('Apple', map='mmap terms Apple ML-OFF')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) modmap("Cond modmap - Terms - Mac kbd", { # - Mac Only @@ -2247,7 +2110,7 @@ modmap("Cond modmap - Terms - Mac kbd", { }, when = lambda ctx: cnfg.screen_has_focus and isKBtype('Apple', map='mmap terms Apple')(ctx) and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) @@ -3574,7 +3437,7 @@ keymap("OptSpecialChars - ABC", { }, when = lambda ctx: cnfg.screen_has_focus and cnfg.optspec_layout == 'ABC' and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) @@ -3725,7 +3588,7 @@ keymap("OptSpecialChars - US", { }, when = lambda ctx: cnfg.screen_has_focus and cnfg.optspec_layout == 'US' and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) @@ -3776,7 +3639,7 @@ keymap("User hardware keys", { # C("Shift-LC-Space"): None, # block the default general terminals shortcut for input switching # }, when = lambda ctx: # cnfg.screen_has_focus and -# matchProps(clas=termStr)(ctx) +# hmp_is_terminal(ctx) # ) # keymap("User overrides general", { # C("Super-Space"): [iEF2NT(),C("THE-REAL-COMBO-FOR-SOME-LAUNCHER")], # Spotlight equivalent @@ -3786,7 +3649,7 @@ keymap("User hardware keys", { # C("Shift-RC-Space"): [bind,C("THE-REAL-COMBO-FOR-REVERSE-INPUT-SWITCHING")], # input switch reverse (OPTIONAL) # }, when = lambda ctx: # cnfg.screen_has_focus and -# matchProps(clas=remoteStr)(ctx) +# hmp_is_remote(ctx) # ) @@ -3804,6 +3667,7 @@ keymap("User hardware keys", { ################################################################################### # Miscellaneous apps that need a few fixes +hmp_is_thunderbird = matchProps(clas="^thunderbird.*$|^org.mozilla.thunderbird$") keymap("Thunderbird email client", { C("Alt-RC-I"): C("Shift-C-I"), # Dev tools # Enable Cmd+Option+Left/Right for tab navigation @@ -3811,8 +3675,9 @@ keymap("Thunderbird email client", { C("RC-Alt-Right"): [bind,C("C-Page_Down")], # Go to next tab (macOS Thunderbird tab nav shortcut) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^thunderbird.*$|^org.mozilla.thunderbird$")(ctx) ) + hmp_is_thunderbird(ctx) ) +hmp_is_angry_ipscan = matchProps(clas="^Angry.*IP.*Scanner$") keymap("Angry IP Scanner", { C("RC-comma"): C("Shift-C-P"), # Open preferences C("RC-i"): C("Alt-Enter"), # Get info (details) @@ -3820,15 +3685,18 @@ keymap("Angry IP Scanner", { C("Shift-RC-i"): C("C-i"), # Invert selection }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Angry.*IP.*Scanner$")(ctx) ) + hmp_is_angry_ipscan(ctx) ) +hmp_is_transmission = matchProps(clas=transmissionStr) keymap("Transmission bittorrent client", { C("RC-i"): C("Alt-Enter"), # Open properties (Get Info) dialog C("RC-comma"): [C("Alt-e"),C("p")], # Open preferences (settings) dialog }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=transmissionStr)(ctx) ) + hmp_is_transmission(ctx) ) +_jdownloader_closures = [matchProps(**dct) for dct in JDownloader_lod] +hmp_is_jdownloader = lambda ctx: any(c(ctx) for c in _jdownloader_closures) keymap("JDownloader", { # Fixes for tab navigation done here instead of in the main tab nav fix keymaps, # because we have to use a "list of dicts" to match some JDownloader windows. @@ -3842,25 +3710,28 @@ keymap("JDownloader", { C("RC-Comma"): C("C-P"), # Open preferences (settings) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(lst=JDownloader_lod)(ctx) ) + hmp_is_jdownloader(ctx) ) +hmp_is_totem = matchProps(clas="^totem$") keymap("Totem video player", { C("RC-dot"): C("C-q"), # Stop (quit player, there is no "Stop" function) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^totem$")(ctx) ) + hmp_is_totem(ctx) ) +hmp_is_eog = matchProps(clas="^eog$") keymap("GNOME image viewer", { C("RC-i"): C("Alt-Enter"), # Image properties }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^eog$")(ctx) ) + hmp_is_eog(ctx) ) +hmp_is_libreoffice_writer = matchProps(clas="^libreoffice-writer$") keymap("LibreOffice Writer", { C("RC-comma"): C("Alt-F12"), # Tools > Options (preferences dialog) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^libreoffice-writer$")(ctx) ) + hmp_is_libreoffice_writer(ctx) ) @@ -3880,15 +3751,17 @@ keymap("LibreOffice Writer", { # Keybindings overrides for Caja # (overrides some bindings from general file manager code block below) +hmp_is_caja = matchProps(clas="^caja$") keymap("Overrides for Caja - Finder Mods", { C("RC-Super-o"): C("Shift-C-Enter"), # Open in new tab # C("RC-Super-o"): C("Shift-C-W"), # Open in new window }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^caja$")(ctx) ) + hmp_is_caja(ctx) ) # Keybindings overrides for COSMIC Files # (overrides some bindings from general file manager code block below) +hmp_is_cosmic_files = matchProps(clas="^com.system76.CosmicFiles$") keymap("Overrides for COSMIC Files - Finder Mods", { # No shortcuts yet to change the view modes? # TODO: Add Grid/List view mode shortcuts when available (if different from general FMs) @@ -3902,10 +3775,11 @@ keymap("Overrides for COSMIC Files - Finder Mods", { C("Alt-Enter"): C("Space"), # Get info (properties) [Linux shortcut] }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^com.system76.CosmicFiles$")(ctx) ) + hmp_is_cosmic_files(ctx) ) # Keybindings overrides for DDE (Deepin) File Manager # (overrides some bindings from general file manager code block below) +hmp_is_dde_filemgr = matchProps(clas="^dde-file-manager$") keymap("Overrides for DDE File Manager - Finder Mods", { C("RC-i"): C("C-i"), # File properties dialog (Get Info) C("RC-comma"): None, # Disable preferences shortcut (no shortcut available) @@ -3916,11 +3790,12 @@ keymap("Overrides for DDE File Manager - Finder Mods", { C("Shift-RC-Right"): [bind,C("C-Tab")], # Go to next tab }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^dde-file-manager$")(ctx) ) + hmp_is_dde_filemgr(ctx) ) ########################## DOLPHIN KEYMAPS - BEGIN ########################## # Keybindings overrides for Dolphin (KDE file manager) # (overrides some bindings from general file manager code block below) +hmp_is_dolphin = matchProps(clas="^dolphin$|^org.kde.dolphin$") keymap("Overrides for Dolphin - Finder Mods pre-KF6", { # KDE Frameworks 6 assigns F10 to "Open Main Manu" so this is only valid for KF5 now @@ -3929,7 +3804,7 @@ keymap("Overrides for Dolphin - Finder Mods pre-KF6", { }, when = lambda ctx: cnfg.screen_has_focus and DESKTOP_ENV == 'kde' and DE_MAJ_VER in ['5', '4', '3'] and - matchProps(clas="^dolphin$|^org.kde.dolphin$")(ctx) + hmp_is_dolphin(ctx) ) # Dolphin dialog names where Enter should always be Enter (not F2/Enter toggle) @@ -3942,11 +3817,12 @@ dlgs_Dolphin_Enter_is_Enter = [ # Convert list to regex pattern string dlgs_Dolphin_Enter_is_Enter_Str = toRgxStr(dlgs_Dolphin_Enter_is_Enter) +hmp_is_dolphin_dialogs = matchProps(clas="^dolphin$|^org.kde.dolphin$", name=dlgs_Dolphin_Enter_is_Enter_Str) keymap("Overrides for Dolphin dialogs - Finder Mods", { C("Enter"): C("Enter"), # Override Enter to be Enter (never F2) for dialogs }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^dolphin$|^org.kde.dolphin$", name=dlgs_Dolphin_Enter_is_Enter_Str)(ctx) + hmp_is_dolphin_dialogs(ctx) ) keymap("Overrides for Dolphin - Finder Mods", { @@ -3962,7 +3838,7 @@ keymap("Overrides for Dolphin - Finder Mods", { C("RC-comma"): C("Shift-C-comma"), # Open preferences dialog }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^dolphin$|^org.kde.dolphin$")(ctx) ) + hmp_is_dolphin(ctx) ) # ########################### DOLPHIN KEYMAPS - END ########################### @@ -3970,15 +3846,17 @@ keymap("Overrides for Dolphin - Finder Mods", { # Keybindings overrides for elementary OS Files (Pantheon) # (overrides some bindings from general file manager code block below) +hmp_is_elementary_files = matchProps(clas="^io.elementary.files$") keymap("Overrides for Pantheon - Finder Mods", { C("RC-Super-o"): C("Shift-Enter"), # Open folder in new tab C("RC-comma"): None, # Disable preferences shortcut since none available }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^io.elementary.files$")(ctx) ) + hmp_is_elementary_files(ctx) ) # Keybindings overrides for Krusader (alternative/old KDE file manager) # (overrides some bindings from general file manager code block below) +hmp_is_krusader = matchProps(clas="^org.kde.krusader$|^krusader$") keymap("Overrides for Krusader - Finder Mods", { C("Shift-RC-Dot"): C("Alt-Dot"), # Toggle hidden files visibility ("dot" files) # C("RC-n"): None, # Enable this to block Cmd+N (new window is not possible?) @@ -3991,16 +3869,17 @@ keymap("Overrides for Krusader - Finder Mods", { # C("RC-Backspace"): C("Delete"), # Delete file/folder (no auto-confirm) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^org.kde.krusader$|^krusader$")(ctx) ) + hmp_is_krusader(ctx) ) # Keybindings overrides for Nautilus # (overrides some bindings from general file manager code block below) +hmp_is_nautilus_archive = matchProps(clas="^org.gnome.nautilus$|^nautilus$", name="Create Archive") keymap("Overrides for Nautilus Create Archive dialog - Finder Mods", { C("Enter"): C("Enter"), # Use Enter as Enter in the Create Archive dialog }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^org.gnome.nautilus$|^nautilus$", name="Create Archive")(ctx) ) - + hmp_is_nautilus_archive(ctx) ) +hmp_is_nautilus = matchProps(clas="^org.gnome.nautilus$|^nautilus$") keymap("Overrides for Nautilus - Finder Mods", { # Optional "new window at home folder" in Nautilus # C("RC-N"): C("C-Alt-Space"), # macOS Finder search window shortcut Cmd+Option+Space @@ -4014,23 +3893,26 @@ keymap("Overrides for Nautilus - Finder Mods", { C("RC-F"): C("C-F"), # Don't toggle Enter key, pass Cmd+F }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^org.gnome.nautilus$|^nautilus$")(ctx) ) + hmp_is_nautilus(ctx) ) # Keybindings overrides for Nemo # (overrides some bindings from general file manager code block below) +hmp_is_nemo = matchProps(clas="^nemo$") keymap("Overrides for Nemo - Finder Mods", { C("RC-Backspace"): iEF2(C("Delete"), False), # Set Enter to Enter for Cmd+Delete confirmation }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^nemo$")(ctx) ) + hmp_is_nemo(ctx) ) # Keybindings overrides for PCManFM and PCManFM-Qt # (overrides some bindings from general file manager code block below) +hmp_is_pcmanfm_qt_desktop = matchProps(clas="^pcmanfm-qt$", name="^pcmanfm-desktop.*$") keymap("Overrides for PCManFM-Qt - Finder Mods - LXQt desktop", { C("Enter"): C("Enter"), # Use Enter as Enter on the LXQt desktop }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^pcmanfm-qt$", name="^pcmanfm-desktop.*$")(ctx) ) + hmp_is_pcmanfm_qt_desktop(ctx) ) +hmp_is_pcmanfm_qt = matchProps(clas="^pcmanfm-qt$") keymap("Overrides for PCManFM-Qt - Finder Mods", { C("RC-Backspace"): C("Delete"), # Move to Trash (delete, bypass dialog) # Change folder view @@ -4040,16 +3922,20 @@ keymap("Overrides for PCManFM-Qt - Finder Mods", { C("RC-KEY_4"): [C("Alt-V"), sleep(0.1), C("V"), sleep(0.1), C("T")], # View as Thumbnails }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^pcmanfm-qt$")(ctx) ) + hmp_is_pcmanfm_qt(ctx) ) +hmp_is_pcmanfm_any = matchProps(clas="^pcmanfm$|^pcmanfm-qt$") keymap("Overrides for PCManFM - Finder Mods", { C("RC-KEY_2"): C("C-KEY_4"), # View as List (Detailed) [Not in PCManFM-Qt] C("RC-Backspace"): [C("Delete"),C("Space")], # Move to Trash (delete, bypass dialog) C("RC-F"): C("C-F"), # Don't toggle Enter key state, pass Cmd+F (Ctrl+F) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^pcmanfm$|^pcmanfm-qt$")(ctx) ) + hmp_is_pcmanfm_any(ctx) ) +# Keybindings overrides for Peony-Qt +# (overrides some bindings from general file manager code block below) +hmp_is_peony_qt = matchProps(clas="^peony-qt$") keymap("Overrides for Peony-Qt - Finder Mods", { C("RC-Comma"): None, # Block Cmd+Comma (doesn't work in Peony) C("RC-Equal"): C("Shift-C-Equal"), # Enlarge icons @@ -4059,18 +3945,19 @@ keymap("Overrides for Peony-Qt - Finder Mods", { C("Shift-RC-Right"): [bind,C("C-Tab")], # Go to next tab }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^peony-qt$")(ctx) ) + hmp_is_peony_qt(ctx) ) # Keybindings overrides for SpaceFM # (overrides some bindings from general file manager code block below) +hmp_is_spacefm_findfiles = matchProps(clas="^SpaceFM$", name="Find Files") keymap("Overrides for SpaceFM Find Files dialog - Finder Mods", { C("Enter"): C("Enter"), # Use Enter as Enter in the Find dialog C("Esc"): C("Alt-F4"), # Close Find Files dialog with Escape C("RC-W"): C("Alt-F4"), # Close Find Files dialog with Cmd+W }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^SpaceFM$", name="Find Files")(ctx) ) - + hmp_is_spacefm_findfiles(ctx) ) +hmp_is_spacefm = matchProps(clas="^spacefm$") keymap("Overrides for SpaceFM - Finder Mods", { C("RC-Page_Up"): [bind,C("C-Shift-Tab")], # Go to prior tab C("RC-Page_Down"): [bind,C("C-Tab")], # Go to next tab @@ -4087,17 +3974,18 @@ keymap("Overrides for SpaceFM - Finder Mods", { # SpaceFM is doing some nasty binding that blocks all shortcuts, including Alt+Tab, while any menu is open. }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^spacefm$")(ctx) ) + hmp_is_spacefm(ctx) ) # Keybindings overrides for Thunar # (overrides some bindings from general file manager code block below) +hmp_is_thunar = matchProps(clas="^thunar$") keymap("Overrides for Thunar - Finder Mods", { C("RC-Super-o"): C("Shift-C-P"), # Open in new tab C("RC-comma"): [C("Alt-E"),C("E")], # Overrides "Open preferences dialog" shortcut below C("RC-F"): C("C-F"), # Don't toggle Enter key, pass Cmd+F (Ctrl+F) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^thunar$")(ctx) ) + hmp_is_thunar(ctx) ) # Keybindings overrides for GNOME XDG "Save As" and "Open File" dialogs file_open_save_dialogs = [ @@ -4106,6 +3994,10 @@ file_open_save_dialogs = [ name: "^Open File$|^Save As$" }, ] + +# Hoisted list-of-dicts call to matchProps() +_xdg_file_dialog_closures = [matchProps(**dct) for dct in file_open_save_dialogs] +hmp_is_xdg_file_dialog = lambda ctx: any(c(ctx) for c in _xdg_file_dialog_closures) keymap("XDG file dialogs", { C("RC-Left"): C("Alt-Left"), # Go Back C("RC-Right"): C("Alt-Right"), # Go Forward @@ -4113,7 +4005,7 @@ keymap("XDG file dialogs", { C("RC-Down"): C("Enter"), # Go Down dir (open folder/file) [universal] }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(lst=file_open_save_dialogs)(ctx) + hmp_is_xdg_file_dialog(ctx) ) #################################################################################################### @@ -4196,7 +4088,7 @@ keymap("General File Managers - Finder Mods", { C("Shift-RC-Enter"): C("Enter"), # alternative "Enter" key for unusual cases }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=filemanagerStr)(ctx) ) + hmp_is_filemanager(ctx) ) @@ -4243,23 +4135,26 @@ keymap("Firefox Browsers Overrides", { }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=browsers_firefoxStr)(ctx) ) + hmp_is_firefox_browser(ctx) ) -# Zotero is a Firefox based research app +# Zotero is a Firefox-based research app +hmp_is_zotero = matchProps(clas="^.*Zotero.*$") keymap("Zotero", { # (override the Shift+Opt+Cmd+I,I diagnostic dialog shortcut in Zotero) C("Shift-Alt-RC-i"): C("Shift-Alt-C-i"), # Import from clipboard }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^.*Zotero.*$")(ctx) ) + hmp_is_zotero(ctx) ) + +# Vivaldi is a Chromium-based web browser +hmp_is_vivaldi_settings = matchProps(clas="^Vivaldi.*$", name="^Vivaldi Settings:.*Vivaldi$") keymap("Vivaldi browser - Settings dialog", { C("Esc"): C("Alt-F4"), # Close Settings dialog with Escape }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Vivaldi.*$", name="^Vivaldi Settings:.*Vivaldi$")(ctx) ) - -# Vivaldi is a Chromium based web browser + hmp_is_vivaldi_settings(ctx) ) +hmp_is_vivaldi_browser = matchProps(clas="^Vivaldi.*$") keymap("Overrides for Vivaldi browser", { # These get caught by the shell in KDE Plasma!!! (Show Desktop and Go to Desktop 1 shortcuts): @@ -4281,14 +4176,24 @@ keymap("Overrides for Vivaldi browser", { }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Vivaldi.*$")(ctx) ) + hmp_is_vivaldi_browser(ctx) ) # Falkon is a Chromium based web browser +hmp_is_falkon_browser = matchProps(clas="^org.kde.falkon$|^Falkon$") keymap("Overrides for Falkon browser", { C("RC-comma"): C("Shift-C-comma"), # Open preferences (Settings) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^org.kde.falkon$|^Falkon$")(ctx) ) + hmp_is_falkon_browser(ctx) ) + +# Brave is a Chromium-based web browser +hmp_is_brave_browser = matchProps(clas="^brave-browser$") +keymap("Brave Browser Overrides", { + # This won't do anything unless Brave's "Exit" shortcut is set to use Ctrl+Q + C("RC-q"): C("RC-q"), # Quit Brave browser with Cmd+Q +}, when = lambda ctx: + cnfg.screen_has_focus and + hmp_is_brave_browser(ctx) ) keymap("Chrome Browsers Overrides", { # C("C-comma"): [C("Alt-e"), C("s"),C("Enter")], # Open preferences (Settings) @@ -4306,7 +4211,7 @@ keymap("Chrome Browsers Overrides", { C("Shift-RC-j"): C("C-J"), # Show Downloads view }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=browsers_chromeStr)(ctx) ) + hmp_is_chrome_browser(ctx) ) # Keybindings for General Web Browsers keymap("General Web Browsers", { @@ -4333,7 +4238,7 @@ keymap("General Web Browsers", { }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=browsers_allStr)(ctx) ) + hmp_is_browser(ctx) ) @@ -4351,6 +4256,7 @@ keymap("General Web Browsers", { # Keybindings for IntelliJ +hmp_is_jetbrains = matchProps(clas="^jetbrains-(?!.*toolbox).*$") keymap("Jetbrains", { # General C("C-Key_0"): C("Alt-Key_0"), # Open corresponding tool window @@ -4441,7 +4347,7 @@ keymap("Jetbrains", { C("Super-c"): C("C-c"), # Sigints - interrupt }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^jetbrains-(?!.*toolbox).*$")(ctx) ) + hmp_is_jetbrains(ctx) ) keymap("Wordwise - not vscode", { # Wordwise remaining - for Everything but VS Code @@ -4466,7 +4372,7 @@ keymap("Wordwise - not vscode", { # }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=vscodes_and_remotes_Str)(ctx) + hmp_not_vscode_or_remote(ctx) ) # Keybindings for VS Code and variants @@ -4477,7 +4383,7 @@ keymap("VSCodes overrides for Chromebook/IBM - Sublime", { cnfg.ST3_in_VSCode and ( isKBtype('Chromebook', map="vscodes ovr cbook - sublime")(ctx) or isKBtype('IBM', map="vscodes ovr ibm - sublime")(ctx) ) and - matchProps(clas=vscodeStr)(ctx) + hmp_is_vscode(ctx) ) keymap("VSCodes overrides for not Chromebook/IBM - Sublime", { C("Super-C-g"): C("C-f2"), # Default - Sublime - find_all_under @@ -4486,7 +4392,7 @@ keymap("VSCodes overrides for not Chromebook/IBM - Sublime", { cnfg.ST3_in_VSCode and not ( isKBtype('Chromebook', map="vscodes ovr not cbook - sublime")(ctx) or isKBtype('IBM', map="vscodes ovr not ibm - sublime")(ctx) ) and - matchProps(clas=vscodeStr)(ctx) + hmp_is_vscode(ctx) ) keymap("VSCodes overrides for Chromebook/IBM", { C("Alt-c"): C("C-c"), # Chromebook/IBM - Terminal - Sigint @@ -4495,7 +4401,7 @@ keymap("VSCodes overrides for Chromebook/IBM", { cnfg.screen_has_focus and ( isKBtype('Chromebook', map="vscodes ovr cbook")(ctx) or isKBtype('IBM', map="vscodes ovr ibm")(ctx) ) and - matchProps(clas=vscodeStr)(ctx) + hmp_is_vscode(ctx) ) keymap("VSCodes overrides for not Chromebook/IBM", { C("Super-c"): C("C-c"), # Default - Terminal - Sigint @@ -4504,7 +4410,7 @@ keymap("VSCodes overrides for not Chromebook/IBM", { cnfg.screen_has_focus and not ( isKBtype('Chromebook', map="vscodes ovr not cbook")(ctx) or isKBtype('IBM', map="vscodes ovr not ibm")(ctx) ) and - matchProps(clas=vscodeStr)(ctx) + hmp_is_vscode(ctx) ) keymap("VSCodes", { # C("Super-Space"): C("C-Space"), # Basic code completion (conflicts with input switching) @@ -4581,10 +4487,11 @@ keymap("VSCodes", { C("C-Shift-g"): C("Shift-f3"), # find_prev }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=vscodeStr)(ctx) + hmp_is_vscode(ctx) ) # Keybindings for Sublime Text +hmp_is_sublime_text = matchProps(clas=sublimeStr) keymap("Sublime Text overrides for Chromebook/IBM", { C("Alt-c"): C("C-c"), # Chromebook/IBM - Terminal - Sigint C("Alt-x"): C("C-x"), # Chromebook/IBM - Terminal - Exit nano @@ -4594,7 +4501,7 @@ keymap("Sublime Text overrides for Chromebook/IBM", { cnfg.screen_has_focus and ( isKBtype('Chromebook', map="sublime ovr cbook")(ctx) or isKBtype('IBM', map="sublime ovr ibm")(ctx) ) and - matchProps(clas=sublimeStr)(ctx) + hmp_is_sublime_text(ctx) ) keymap("Sublime Text overrides for not Chromebook/IBM", { # C("Super-c"): C("C-c"), # Default - Terminal - Sigint @@ -4605,7 +4512,7 @@ keymap("Sublime Text overrides for not Chromebook/IBM", { cnfg.screen_has_focus and not ( isKBtype('Chromebook', map="sublime ovr not cbook")(ctx) or isKBtype('IBM', map="sublime ovr not ibm")(ctx) ) and - matchProps(clas=sublimeStr)(ctx) + hmp_is_sublime_text(ctx) ) keymap("Sublime Text", { # C("Super-c"): C("C-c"), # Default - Terminal - Sigint @@ -4676,28 +4583,32 @@ keymap("Sublime Text", { # C(""): C(""), # }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=sublimeStr)(ctx) ) + hmp_is_sublime_text(ctx) ) +hmp_is_kate = matchProps(clas="^org.kde.kate$") keymap("Kate Advanced Text Editor", { C("RC-Comma"): C("Shift-C-Comma"), # Open settings/preferences C("RC-g"): C("F3"), # Find next C("Super-g"): C("C-g"), # Go to line }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^org.kde.kate$")(ctx) ) + hmp_is_kate(ctx) ) +hmp_is_xed = matchProps(clas="^xed$") keymap("Linux Mint xed text editor", { C("RC-T"): C("C-N"), # Open new tab (new file) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^xed$")(ctx) ) + hmp_is_xed(ctx) ) +hmp_is_kwrite_close_dlg = matchProps(clas="^kwrite$|^org.kde.Kwrite$", name="^Close Document.*KWrite$") keymap("KWrite text editor - Close Document dialog", { C("RC-d"): C("Alt-d"), # [D]iscard file without saving (from Close Document dialog) C("RC-s"): C("Alt-s"), # Save file (from Close Document dialog) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^kwrite$|^org.kde.Kwrite$", name="^Close Document.*KWrite$")(ctx) ) + hmp_is_kwrite_close_dlg(ctx) ) +hmp_is_kwrite = matchProps(clas="^kwrite$|^org.kde.Kwrite$") keymap("KWrite text editor", { C("RC-comma"): C("Shift-C-comma"), # Open preferences dialog C("RC-t"): C("C-n"), # New tab (new document appears in tab) @@ -4708,14 +4619,15 @@ keymap("KWrite text editor", { C("RC-Backspace"): C("C-k"), # Delete line (Cmd+Delete) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^kwrite$|^org.kde.Kwrite$")(ctx) ) + hmp_is_kwrite(ctx) ) +hmp_is_gnome_text_editor = matchProps(clas="^gnome-text-editor$|^org.gnome.TextEditor$") keymap("GNOME Text Editor", { C("RC-Slash"): None, # Block Cmd+Slash from doing "Select All" C("RC-Alt-f"): C("C-h"), # Search and replace within the document }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^gnome-text-editor$|^org.gnome.TextEditor$")(ctx) ) + hmp_is_gnome_text_editor(ctx) ) ########################### DIALOG FIXES ########################### @@ -4746,7 +4658,7 @@ keymap("Cmd+W dialog fix - send Escape", { C("RC-W"): iEF2(C("Esc"), True), }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(lst=dialogs_Escape_lod)(ctx) + hmp_is_dialog_escape(ctx) ) # This keymap for Manjaro GNOME will override the same shortcut from the keymap just below it, @@ -4756,14 +4668,14 @@ if DISTRO_ID == 'manjaro' and DESKTOP_ENV == 'gnome': C("RC-W"): iEF2(C("Super-Q"), True), }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(lst=dialogs_CloseWin_lod)(ctx) + hmp_is_dialog_closewin(ctx) ) keymap("Cmd+W dialog fix - Alt+F4", { C("RC-W"): iEF2(C("Alt-F4"), True), }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(lst=dialogs_CloseWin_lod)(ctx) + hmp_is_dialog_closewin(ctx) ) @@ -4800,6 +4712,7 @@ tab_UI_fix_CtrlAltPgUp_lst = [ tab_UI_fix_CtrlAltPgUp_Str = toRgxStr(tab_UI_fix_CtrlAltPgUp_lst) # Tab navigation overrides for tabbed UI apps that use Ctrl+Shift+Tab/Ctrl+Tab instead of Ctrl+PgUp/PgDn +hmp_is_tab_UI_fix_CtrlShiftTab = matchProps(clas=tab_UI_fix_CtrlShiftTab_Str) keymap("Tab Nav fix for apps that use Ctrl+Shift+Tab/Ctrl+Tab", { C("Shift-RC-Left_Brace"): [bind,C("C-Shift-Tab")], # Tab nav: Go to prior tab (left) C("Shift-RC-Right_Brace"): [bind,C("C-Tab")], # Tab nav: Go to next tab (right) @@ -4807,18 +4720,20 @@ keymap("Tab Nav fix for apps that use Ctrl+Shift+Tab/Ctrl+Tab", { C("Shift-RC-Right"): [bind,C("C-Tab")], # Tab nav: Go to next tab (right) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=tab_UI_fix_CtrlShiftTab_Str)(ctx) + hmp_is_tab_UI_fix_CtrlShiftTab(ctx) ) # Tab navigation overrides for tabbed UI apps that use Ctrl+Alt+PgUp/PgDn instead of Ctrl+PgUp/PgDn +hmp_is_tab_UI_fix_CtrlAltPgUp = matchProps(clas=tab_UI_fix_CtrlAltPgUp_Str) keymap("Tab Nav fix for apps that use Ctrl+Alt+PgUp/PgDn", { C("Shift-RC-Left_Brace"): [bind,C("C-Alt-Page_Up")], # Go to prior tab (Left) C("Shift-RC-Right_Brace"): [bind,C("C-Alt-Page_Down")], # Go to next tab (Right) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=tab_UI_fix_CtrlAltPgUp_Str)(ctx) + hmp_is_tab_UI_fix_CtrlAltPgUp(ctx) ) +hmp_is_term_konsole = matchProps(clas="^konsole$|^org.kde.Konsole$") keymap("Konsole tab switching", { # Ctrl Tab - In App Tab Switching C("Shift-LC-Tab") : [bind,C("Shift-Left")], @@ -4829,8 +4744,9 @@ keymap("Konsole tab switching", { C("Shift-RC-Right_Brace"): [bind,C("Shift-Right")], # Go to next tab (Right) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^konsole$|^org.kde.Konsole$")(ctx) ) + hmp_is_term_konsole(ctx) ) +hmp_is_term_elem_term_kitty = matchProps(clas="^Io.elementary.terminal$|^kitty$") keymap("Elementary Terminal tab switching", { # Ctrl Tab - In App Tab Switching C("Shift-LC-Tab") : [bind,C("Shift-C-Left")], # Go to prior tab (Left) @@ -4838,7 +4754,7 @@ keymap("Elementary Terminal tab switching", { C("LC-Tab") : [bind,C("Shift-C-Right")], # Go to next tab (Right) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Io.elementary.terminal$|^kitty$")(ctx) ) + hmp_is_term_elem_term_kitty(ctx) ) @@ -4854,28 +4770,30 @@ keymap("Elementary Terminal tab switching", { ### ### ########################################################################################## + +hmp_is_term_alacritty = matchProps(clas="^alacritty$") keymap("Alacritty terminal", { C("RC-K"): C("C-L"), # clear log }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^alacritty$")(ctx) ) - + hmp_is_term_alacritty(ctx) ) +hmp_is_term_contour = matchProps(clas="^contour$") keymap("Contour terminal overrides", { C("RC-minus"): C("Shift-C-minus"), # Decrease font size (override general terminals remap) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^contour$")(ctx) ) - + hmp_is_term_contour(ctx) ) +hmp_is_term_cosmic_term = matchProps(clas="^com.system76.CosmicTerm$") keymap("COSMIC Terminal overrides", { # There are already tab nav fixes in the usual place. C("RC-equal"): C("C-equal"), # Increase font size (override general terminals remap) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^com.system76.CosmicTerm$")(ctx) ) - + hmp_is_term_cosmic_term(ctx) ) +hmp_is_term_deepin_term = matchProps(clas="^deepin-terminal$") keymap("Deepin Terminal overrides", { C("RC-w"): C("Alt-w"), # Close only current tab, instead of all other tabs C("RC-j"): None, # Block Cmd+J from remapping to vertical split (Ctrl+Shift+J) @@ -4883,8 +4801,9 @@ keymap("Deepin Terminal overrides", { C("RC-equal"): C("C-equal"), # Increase font size/zoom in }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^deepin-terminal$")(ctx) ) + hmp_is_term_deepin_term(ctx) ) +hmp_is_term_ghostty = matchProps(clas="^.*ghostty.*$") keymap("Ghostty terminal overrides", { C("RC-Equal"): C( "C-Equal" @@ -4895,23 +4814,25 @@ keymap("Ghostty terminal overrides", { C("RC-K"): C("C-L"), # clear log }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^.*ghostty.*$")(ctx) + hmp_is_term_ghostty(ctx) ) +hmp_is_term_hyper_term = matchProps(clas="^hyper$") keymap("Hyper terminal tab switching", { C("RC-Equal"): C("C-Equal"), # Increase font size [override general terminals remap] C("Shift-LC-Tab"): [bind,C("Shift-C-Tab")], # Tab nav: Go to prior tab (left) [override general remap] C("LC-Tab"): [bind,C("C-Tab")], # Tab nav: Go to next tab (right) [override general remap] }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^hyper$")(ctx) ) + hmp_is_term_hyper_term(ctx) ) +hmp_is_term_kitty = matchProps(clas="^kitty$") keymap("Kitty terminal - not tab nav", { C("RC-L"): C("C-L"), # Clear log C("RC-K"): C("C-L"), # Clear log (macOS) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^kitty$")(ctx) ) + hmp_is_term_kitty(ctx) ) keymap("Konsole terminal - not tab nav", { C("RC-comma"): C("Shift-C-comma"), # Open Preferences dialog @@ -4919,8 +4840,9 @@ keymap("Konsole terminal - not tab nav", { C("RC-K"): C("Shift-C-K"), # Clear Scrollback and Reset }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Konsole$|^org.kde.Konsole$")(ctx) ) + hmp_is_term_konsole(ctx) ) +hmp_is_term_terminology = matchProps(clas="^terminology$") keymap("Terminology terminal", { C("RC-w"): C("Shift-C-End"), # Close focused tab C("RC-c"): C("Alt-w"), # Copy selection to primary buffer @@ -4930,8 +4852,9 @@ keymap("Terminology terminal", { C("RC-Equal"): C("C-Alt-Equal"), # Increase font size }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^terminology$")(ctx) ) + hmp_is_term_terminology(ctx) ) +hmp_is_term_wave = matchProps(clas="^Wave$") keymap("Wave terminal", { C("RC-t"): C("Alt-t"), # Open a new tab C("RC-n"): C("Alt-n"), # Open a new terminal block @@ -4940,13 +4863,14 @@ keymap("Wave terminal", { C("Shift-RC-w"): C("Shift-Alt-w"), # Close the current tab }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^Wave$")(ctx) ) + hmp_is_term_wave(ctx) ) +hmp_is_term_xfce4_term = matchProps(clas="^xfce4-terminal$") keymap("Xfce4 terminal", { C("RC-comma"): [C("Alt-e"), sleep(0.1), C("e")], # Open Preferences dialog }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas="^xfce4-terminal$")(ctx) ) + hmp_is_term_xfce4_term(ctx) ) # Overrides to General Terminals shortcuts for specific distros (or are they really just desktop environments?) @@ -4956,7 +4880,7 @@ if DISTRO_ID in ['fedora', 'almalinux'] and DESKTOP_ENV == 'gnome': C("RC-H"): C("Super-h"), # Hide Window/Minimize app (gnome/fedora) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DISTRO_ID == 'pop': @@ -4965,7 +4889,7 @@ if DISTRO_ID == 'pop': C("LC-Left"): [bind,C("Super-C-Down")], # SL - Change workspace (pop) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DISTRO_ID in ['ubuntu', 'fedora'] and DESKTOP_ENV == 'gnome': @@ -4975,7 +4899,7 @@ if DISTRO_ID in ['ubuntu', 'fedora'] and DESKTOP_ENV == 'gnome': C("LC-Left"): [bind,C("Super-Page_Down")], # SL - Change workspace (ubuntu/fedora) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) @@ -4987,7 +4911,7 @@ if DESKTOP_ENV == 'budgie': C("LC-Left"): [bind,C("C-Alt-Left")], # Default SL - Change workspace (budgie) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) # On Pop!_OS 22.04, System76 seems to have changed the name of the DE from 'cosmic' to 'pop'. @@ -4997,7 +4921,7 @@ if DESKTOP_ENV in ['cosmic', 'pop']: C("LC-RC-F"): C("Super-M"), # Maximize window toggle (overrides General terminals) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DESKTOP_ENV == 'gnome': @@ -5007,7 +4931,7 @@ if DESKTOP_ENV == 'gnome': C("Shift-LC-Space"): [bind,C("Super-Shift-Space")], # keyboard input source (layout) switching (reverse) (gnome) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DESKTOP_ENV == 'kde': @@ -5028,7 +4952,7 @@ if DESKTOP_ENV == 'kde': }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DESKTOP_ENV == 'pantheon': @@ -5037,7 +4961,7 @@ if DESKTOP_ENV == 'pantheon': C("LC-Left"): [bind,C("Super-Left")], # SL - Change workspace (elementary) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DESKTOP_ENV == 'sway': @@ -5045,7 +4969,7 @@ if DESKTOP_ENV == 'sway': C("RC-Q"): C("Shift-C-Q"), # Override sway GenGUI Cmd+Q }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) if DESKTOP_ENV == 'xfce': @@ -5056,7 +4980,7 @@ if DESKTOP_ENV == 'xfce': C("LC-Left"): [bind,C("C-Alt-End")], # SL - Change workspace xfce4 }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) @@ -5135,7 +5059,7 @@ keymap("General Terminals", { }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(clas=termStr)(ctx) + hmp_is_terminal(ctx) ) @@ -5157,7 +5081,7 @@ keymap("Cmd+Dot not in terminals", { C("RC-Dot"): C("Esc"), # Mimic macOS Cmd+dot = Escape key (not in terminals) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=terms_and_remotes_Str)(ctx) + hmp_not_term_or_remote(ctx) ) @@ -5173,7 +5097,7 @@ keymap("GenGUI overrides: Chromebook/IBM", { cnfg.screen_has_focus and ( isKBtype('Chromebook', map="gengui ovr cbook")(ctx) or isKBtype('IBM', map="gengui ovr ibm")(ctx) ) and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) keymap("GenGUI overrides: not Chromebook", { # In-App Tab switching @@ -5183,7 +5107,7 @@ keymap("GenGUI overrides: not Chromebook", { }, when = lambda ctx: cnfg.screen_has_focus and not isKBtype('Chromebook', map="gengui ovr not cbook")(ctx) and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -5194,7 +5118,7 @@ if DISTRO_ID in ['almalinux', 'rhel', 'rocky'] and DESKTOP_ENV == 'xfce': C("RC-Space"): [iEF2NT(),C("Alt-F3")], # Launch App Finder xfce4 (AlmaLinux/Rocky) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'debian' and DESKTOP_ENV == 'xfce': @@ -5202,7 +5126,7 @@ if DISTRO_ID == 'debian' and DESKTOP_ENV == 'xfce': C("RC-Space"): [iEF2NT(),C("Alt-F1")], # Launch Application Menu xfce4 (Debian) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID in ['fedora', 'almalinux'] and DESKTOP_ENV == 'gnome': @@ -5213,7 +5137,7 @@ if DISTRO_ID in ['fedora', 'almalinux'] and DESKTOP_ENV == 'gnome': C("Super-Left"): [bind,C("Super-Page_Down")], # SL - Change workspace (ubuntu/fedora) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'manjaro' and DESKTOP_ENV == 'gnome': @@ -5221,7 +5145,7 @@ if DISTRO_ID == 'manjaro' and DESKTOP_ENV == 'gnome': C("RC-Q"): C("Super-Q"), # Close window }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'manjaro' and DESKTOP_ENV == 'xfce': @@ -5229,7 +5153,7 @@ if DISTRO_ID == 'manjaro' and DESKTOP_ENV == 'xfce': C("RC-Space"): [iEF2NT(),C("Alt-F1")], # Open Whisker Menu with Cmd+Space }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'manjaro': @@ -5237,7 +5161,7 @@ if DISTRO_ID == 'manjaro': C("Super-RC-f"): C("Super-PAGE_UP"), # SL- Maximize app manjaro }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'mint' and DESKTOP_ENV == 'xfce': @@ -5245,7 +5169,7 @@ if DISTRO_ID == 'mint' and DESKTOP_ENV == 'xfce': C("RC-Space"): [iEF2NT(),C("Super-Space")], # Launch Application Menu xfce4 (Linux Mint) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'neon': @@ -5255,7 +5179,7 @@ if DISTRO_ID == 'neon': # SL - Default SL - Change workspace (kde_neon) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'pop': @@ -5267,7 +5191,7 @@ if DISTRO_ID == 'pop': C("RC-Q"): C("Super-q"), # SL - Close Apps (pop) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DISTRO_ID == 'ubuntu': @@ -5277,7 +5201,7 @@ if DISTRO_ID == 'ubuntu': C("Super-Left"): [bind,C("Super-Page_Down")], # SL - Change workspace (ubuntu) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -5291,7 +5215,7 @@ if DESKTOP_ENV == 'budgie': C("RC-H"): C("Super-h"), # Minimize app (gnome/budgie/popos/fedora) not-deepin }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'cinnamon': @@ -5299,7 +5223,7 @@ if DESKTOP_ENV == 'cinnamon': C("RC-Space"): [iEF2NT(),C("C-Esc")], # Right click, configure Mint menu shortcut to Ctrl+Esc }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) # On Pop!_OS 22.04, System76 seems to have changed the name of the DE from 'cosmic' to 'pop'. @@ -5313,7 +5237,7 @@ if DESKTOP_ENV in ['cosmic', 'pop']: C("Super-RC-F"): C("Super-M"), # Maximize window toggle (overrides General GUI) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'dde': @@ -5321,7 +5245,7 @@ if DESKTOP_ENV == 'dde': C("RC-Space"): [iEF2NT(),Key.LEFT_META], # Open Launcher menu (Deeping Desktop Environment) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'deepin': @@ -5330,7 +5254,7 @@ if DESKTOP_ENV == 'deepin': C("Alt-RC-Space"): C("Super-e"), # Open Finder - (deepin) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'enlightenment': @@ -5340,7 +5264,7 @@ if DESKTOP_ENV == 'enlightenment': C("RC-Space"): [iEF2NT(),C("C-Alt-Space")], # enlightenment main menu (override in "User Apps" slice if necessary) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'gnome': @@ -5350,7 +5274,7 @@ if DESKTOP_ENV == 'gnome': C("RC-Space"): [iEF2NT(),C("Super-s")], # Override GNOME 45+ Shift+Ctrl+Space remap }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) keymap("GenGUI overrides: GNOME", { C("RC-Space"): [iEF2NT(),C("Shift-C-Space")], # Show GNOME overview/app launcher @@ -5363,7 +5287,7 @@ if DESKTOP_ENV == 'gnome': C("RC-Shift-Key_5"): C("Print"), # Take a screenshot interactively (gnome) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'hyprland': @@ -5372,7 +5296,7 @@ if DESKTOP_ENV == 'hyprland': C("RC-Space"): [C("Super-d"), iEF2NT()], # Open Launcher with Cmd+Space }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'icewm': @@ -5380,7 +5304,7 @@ if DESKTOP_ENV == 'icewm': C("RC-Space"): [iEF2NT(),Key.LEFT_META], # IceWM: Win95Keys=1 (Meta shows menu) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'kde': @@ -5415,7 +5339,7 @@ if DESKTOP_ENV == 'kde': }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'mate' and DISTRO_ID == 'mint': @@ -5424,7 +5348,7 @@ if DESKTOP_ENV == 'mate' and DISTRO_ID == 'mint': C("RC-Space"): [iEF2NT(), C("Alt-Space")], # Open Mint app menu }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'mate' and DISTRO_ID == 'ubuntu': @@ -5433,7 +5357,7 @@ if DESKTOP_ENV == 'mate' and DISTRO_ID == 'ubuntu': C("RC-Space"): [iEF2NT(), Key.LEFT_META], # Open Brisk Menu Launcher }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'miracle-wm': @@ -5442,7 +5366,15 @@ if DESKTOP_ENV == 'miracle-wm': C("RC-Space"): [C("Super-d"), iEF2NT()], # Open Launcher with Cmd+Space }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) + ) + +if DESKTOP_ENV == 'nebide': + keymap("GenGUI overrides: NebiDE", { + C("RC-Space"): [iEF2NT(),Key.LEFT_META], # Open Launcher with Cmd+Space + }, when = lambda ctx: + cnfg.screen_has_focus and + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'pantheon': @@ -5453,7 +5385,7 @@ if DESKTOP_ENV == 'pantheon': C("Super-RC-f"): C("Super-Up"), # Maximize app elementary }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'sway': @@ -5462,7 +5394,7 @@ if DESKTOP_ENV == 'sway': C("RC-Q"): C("C-Q"), # Override General GUI Alt+F4 remap }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'trinity': @@ -5470,7 +5402,7 @@ if DESKTOP_ENV == 'trinity': C("RC-Space"): [iEF2NT(),Key.LEFT_META], # Trinity desktop (Q4OS) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'unity': @@ -5478,7 +5410,7 @@ if DESKTOP_ENV == 'unity': C("RC-Space"): [iEF2NT(),Key.LEFT_META], # Trinity desktop (Q4OS) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'xfce' and DISTRO_ID == 'zorin': @@ -5486,7 +5418,7 @@ if DESKTOP_ENV == 'xfce' and DISTRO_ID == 'zorin': C("RC-Space"): [iEF2NT(),C("Alt-Pause")], # "Launch and switch applications" (Xfce on Zorin) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) if DESKTOP_ENV == 'xfce': @@ -5502,7 +5434,7 @@ if DESKTOP_ENV == 'xfce': C("RC-Shift-Key_5"): C("Shift-Print"), # Take a screenshot interactively (xfce4) }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -5579,7 +5511,7 @@ keymap("General GUI", { }, when = lambda ctx: cnfg.screen_has_focus and - matchProps(not_clas=remoteStr)(ctx) + hmp_not_remote(ctx) ) @@ -5611,11 +5543,11 @@ keymap("Diagnostics (isMultiTap)", { C("Enter"), C("Enter")], ), -}, when = lambda ctx: ctx is ctx) +}, when = lambda _: True is True) # keymap("Diagnostics (isDoubleTap)", { # C("Shift-Alt-RC-i"): isDoubleTap(notify_context), # Diagnostic dialog (primary) # C("Shift-Alt-RC-h"): isDoubleTap(notify_context), # Diagnostic dialog (alternate) # C("Shift-Alt-RC-t"): isDoubleTap(macro_tester), # Type out test macro -# }, when = lambda ctx: ctx is ctx ) +# }, when = lambda _: True is True)