keyhac 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. keyhac-2.0.0/LICENSE +21 -0
  2. keyhac-2.0.0/MANIFEST.in +14 -0
  3. keyhac-2.0.0/PKG-INFO +141 -0
  4. keyhac-2.0.0/README.md +110 -0
  5. keyhac-2.0.0/keyhac/__init__.py +70 -0
  6. keyhac-2.0.0/keyhac/__main__.py +4 -0
  7. keyhac-2.0.0/keyhac/_config.py +372 -0
  8. keyhac-2.0.0/keyhac/actions.py +622 -0
  9. keyhac-2.0.0/keyhac/core/__init__.py +0 -0
  10. keyhac-2.0.0/keyhac/core/action.py +121 -0
  11. keyhac-2.0.0/keyhac/core/clipboard_history.py +113 -0
  12. keyhac-2.0.0/keyhac/core/config.py +29 -0
  13. keyhac-2.0.0/keyhac/core/const.py +81 -0
  14. keyhac-2.0.0/keyhac/core/focus.py +130 -0
  15. keyhac-2.0.0/keyhac/core/input.py +203 -0
  16. keyhac-2.0.0/keyhac/core/key.py +144 -0
  17. keyhac-2.0.0/keyhac/core/keymap.py +546 -0
  18. keyhac-2.0.0/keyhac/core/log.py +154 -0
  19. keyhac-2.0.0/keyhac/core/replay.py +80 -0
  20. keyhac-2.0.0/keyhac/core/settings.py +64 -0
  21. keyhac-2.0.0/keyhac/core/vk.py +393 -0
  22. keyhac-2.0.0/keyhac/main.py +181 -0
  23. keyhac-2.0.0/keyhac/platform/__init__.py +0 -0
  24. keyhac-2.0.0/keyhac/platform/base.py +307 -0
  25. keyhac-2.0.0/keyhac/platform/fake.py +99 -0
  26. keyhac-2.0.0/keyhac/platform/mac/__init__.py +26 -0
  27. keyhac-2.0.0/keyhac/platform/mac/apps.py +70 -0
  28. keyhac-2.0.0/keyhac/platform/mac/clipboard.py +27 -0
  29. keyhac-2.0.0/keyhac/platform/mac/focus.py +102 -0
  30. keyhac-2.0.0/keyhac/platform/mac/hook.py +586 -0
  31. keyhac-2.0.0/keyhac/platform/mac/instance.py +76 -0
  32. keyhac-2.0.0/keyhac/platform/mac/loop.py +40 -0
  33. keyhac-2.0.0/keyhac/platform/mac/uielement.py +144 -0
  34. keyhac-2.0.0/keyhac/platform/mac/window.py +214 -0
  35. keyhac-2.0.0/keyhac/platform/win/__init__.py +24 -0
  36. keyhac-2.0.0/keyhac/platform/win/apps.py +86 -0
  37. keyhac-2.0.0/keyhac/platform/win/clipboard.py +95 -0
  38. keyhac-2.0.0/keyhac/platform/win/focus.py +220 -0
  39. keyhac-2.0.0/keyhac/platform/win/hook.py +425 -0
  40. keyhac-2.0.0/keyhac/platform/win/instance.py +98 -0
  41. keyhac-2.0.0/keyhac/platform/win/loop.py +90 -0
  42. keyhac-2.0.0/keyhac/platform/win/uielement.py +547 -0
  43. keyhac-2.0.0/keyhac/platform/win/window.py +350 -0
  44. keyhac-2.0.0/keyhac/ui/__init__.py +0 -0
  45. keyhac-2.0.0/keyhac/ui/assets/MenuExtraTemplate.png +0 -0
  46. keyhac-2.0.0/keyhac/ui/assets/MenuExtraTemplate@2x.png +0 -0
  47. keyhac-2.0.0/keyhac/ui/assets/keyhac.icns +0 -0
  48. keyhac-2.0.0/keyhac/ui/assets/keyhac.ico +0 -0
  49. keyhac-2.0.0/keyhac/ui/balloon.py +59 -0
  50. keyhac-2.0.0/keyhac/ui/chooser.py +138 -0
  51. keyhac-2.0.0/keyhac/ui/console.py +300 -0
  52. keyhac-2.0.0/keyhac/ui/runtime.py +6 -0
  53. keyhac-2.0.0/keyhac/ui/tray.py +55 -0
  54. keyhac-2.0.0/keyhac.egg-info/PKG-INFO +141 -0
  55. keyhac-2.0.0/keyhac.egg-info/SOURCES.txt +59 -0
  56. keyhac-2.0.0/keyhac.egg-info/dependency_links.txt +1 -0
  57. keyhac-2.0.0/keyhac.egg-info/entry_points.txt +2 -0
  58. keyhac-2.0.0/keyhac.egg-info/requires.txt +9 -0
  59. keyhac-2.0.0/keyhac.egg-info/top_level.txt +1 -0
  60. keyhac-2.0.0/pyproject.toml +74 -0
  61. keyhac-2.0.0/setup.cfg +4 -0
keyhac-2.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 craftware
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # Sdist contents (the wheel is governed by pyproject.toml's packages /
2
+ # package-data). setuptools already ships the keyhac package sources, the
3
+ # keyhac.ui assets declared as package-data, README, LICENSE and
4
+ # pyproject.toml; the lines below prune everything not needed to install and
5
+ # run Keyhac. Same scheme as XeFM's MANIFEST.in.
6
+
7
+ # Development trees and build byproducts — kept out of the sdist.
8
+ prune tests
9
+ prune doc
10
+ prune art
11
+ prune tools
12
+ prune macos_app
13
+ prune windows_app
14
+ global-exclude __pycache__ *.py[cod] .DS_Store
keyhac-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: keyhac
3
+ Version: 2.0.0
4
+ Summary: Keyhac 2 - Python-scriptable keyboard customization tool for Windows and macOS
5
+ Author: craftware
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/crftwr/keyhac2
8
+ Project-URL: Repository, https://github.com/crftwr/keyhac2
9
+ Project-URL: Issues, https://github.com/crftwr/keyhac2/issues
10
+ Keywords: keyboard,hotkey,keymap,macro,remap,customization
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: MacOS X
13
+ Classifier: Environment :: Win32 (MS Windows)
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Utilities
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: puikit>=1.0.8
25
+ Requires-Dist: pyobjc-framework-Cocoa>=10; sys_platform == "darwin"
26
+ Requires-Dist: pyobjc-framework-Quartz>=10; sys_platform == "darwin"
27
+ Requires-Dist: pyobjc-framework-ApplicationServices>=10; sys_platform == "darwin"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # Keyhac 2
33
+
34
+ Python-scriptable keyboard customization for **Windows and macOS**.
35
+
36
+ Keyhac installs a system-wide keyboard hook and lets you script what your keys do in
37
+ Python. You write one file, `~/.keyhac/config.py`, and it runs unchanged on both OSes —
38
+ remapping keys, binding keys to Python functions, and driving windows, applications and
39
+ the clipboard from the keyboard.
40
+
41
+ Keyhac 2 is the successor to both
42
+ [Keyhac for Windows](https://github.com/crftwr/keyhac) and
43
+ [Keyhac for macOS](https://github.com/crftwr/keyhac-mac), rebuilt as one shared codebase.
44
+ Its UI is built on [PuiKit](https://github.com/crftwr/puikit).
45
+
46
+ ## Features
47
+
48
+ - **Key remapping**: key → key, key → key sequence, key → Python function.
49
+ - **Per-application key tables**: match by app name, window title, Win32 window class,
50
+ or the full accessibility focus path (AX on macOS, UI Automation on Windows) — down to
51
+ "only in this app's text editor pane".
52
+ - **User modifiers**: turn any key into a modifier of your own (User0–User3), invisible
53
+ to applications.
54
+ - **One-shot modifiers**: tap a modifier alone for one action, hold it to modify.
55
+ - **Multi-stroke key tables**: Emacs-style prefix keys, with a balloon showing the
56
+ armed prefix.
57
+ - **Clipboard history**: persistent history in a popup chooser — type to filter,
58
+ Enter pastes into the app you came from. Plus fixed snippets and scriptable
59
+ clipboard-transform tools.
60
+ - **Window control**: move, snap/tile, minimize, activate and launch applications,
61
+ multi-monitor aware.
62
+ - **Keyboard macros**: record and replay keys.
63
+ - **Mouse output**: send clicks, wheel scrolls and pointer moves from key bindings.
64
+ - **Console window**: live log, last-key and focus-path inspector — see exactly what to
65
+ bind. Runs from the system tray (Windows) / menu-bar extra (macOS).
66
+
67
+ ## Screenshots
68
+
69
+ | Console (macOS) | Console (Windows) |
70
+ |---|---|
71
+ | ![Keyhac console window on macOS: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector](doc/images/console-mac.jpg) | ![Keyhac console window on Windows: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector](doc/images/console-win.jpg) |
72
+
73
+ | Menu-bar extra (macOS) | Task tray (Windows) |
74
+ |---|---|
75
+ | ![Keyhac menu-bar extra on macOS with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac](doc/images/menubar-extra-icon-mac.jpg) | ![Keyhac task-tray icon on Windows with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac](doc/images/tasktray-icon-win.jpg) |
76
+
77
+ ## Install
78
+
79
+ Download from [Releases](https://github.com/crftwr/keyhac2/releases):
80
+
81
+ - **macOS 15+** — `Keyhac-<version>-macos.dmg`: drag Keyhac.app into Applications and
82
+ launch it. Grant the Accessibility permission when prompted (required for the
83
+ keyboard hook).
84
+ - **Windows 10/11 (x64)** — `Keyhac-<version>-win64.zip`: unzip anywhere and run
85
+ `Keyhac.exe`.
86
+
87
+ Details, data locations and privacy notes: [doc/installation.md](doc/installation.md).
88
+
89
+ ## Quick start
90
+
91
+ On first run Keyhac creates `~/.keyhac/config.py` from a fully commented template.
92
+ Open it from the tray / menu-bar icon ("Edit Config"), edit, then "Reload Config".
93
+ A config defines one function:
94
+
95
+ ```python
96
+ from keyhac import *
97
+
98
+ def configure(keymap):
99
+ kt = keymap.define_keytable(focus_path_pattern="*") # active everywhere
100
+
101
+ kt["Fn-J"] = "Left" # key -> key
102
+ kt["Fn-A"] = "Home", "Shift-End" # key -> sequence
103
+
104
+ def hello(): # key -> Python function
105
+ print("Hello from config.py")
106
+ kt["Fn-H"] = hello
107
+
108
+ kt["Fn-V"] = ShowClipboardHistory() # clipboard history popup
109
+
110
+ kt_browser = keymap.define_keytable(app="chrome|Safari") # per-app table
111
+ kt_browser["Fn-R"] = "Cmd-R"
112
+ ```
113
+
114
+ The full reference is [doc/configuration.md](doc/configuration.md); the shipped
115
+ template ([keyhac/_config.py](keyhac/_config.py)) is a working tour of every feature.
116
+
117
+ ## Documentation
118
+
119
+ - [Installation](doc/installation.md) — install, permissions, data files, privacy.
120
+ - [Configuration](doc/configuration.md) — the complete config.py reference.
121
+ - [Migrating from Keyhac for macOS](doc/migration-from-keyhac-mac.md) — mostly drop-in.
122
+ - [Migrating from Keyhac for Windows](doc/migration-from-keyhac-win.md) — API renamed;
123
+ translation table.
124
+ - [Developer documentation](doc/dev/) — architecture, platform layer, packaging,
125
+ testing. Project guide for coding agents: [CLAUDE.md](CLAUDE.md).
126
+
127
+ ## Running from source
128
+
129
+ ```sh
130
+ python3 -m venv .venv
131
+ .venv/bin/pip install -e ".[dev]"
132
+ .venv/bin/python -m pytest # engine + unit tests, no permissions needed
133
+ .venv/bin/python -m keyhac # run (macOS: needs Accessibility permission)
134
+ ```
135
+
136
+ `python -m keyhac -d` enables debug logging, `--no-ui` runs headless (hook + engine
137
+ only), `--config PATH` uses an alternate config file (its data files live beside it).
138
+
139
+ ## License
140
+
141
+ MIT — see [LICENSE](LICENSE).
keyhac-2.0.0/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # Keyhac 2
2
+
3
+ Python-scriptable keyboard customization for **Windows and macOS**.
4
+
5
+ Keyhac installs a system-wide keyboard hook and lets you script what your keys do in
6
+ Python. You write one file, `~/.keyhac/config.py`, and it runs unchanged on both OSes —
7
+ remapping keys, binding keys to Python functions, and driving windows, applications and
8
+ the clipboard from the keyboard.
9
+
10
+ Keyhac 2 is the successor to both
11
+ [Keyhac for Windows](https://github.com/crftwr/keyhac) and
12
+ [Keyhac for macOS](https://github.com/crftwr/keyhac-mac), rebuilt as one shared codebase.
13
+ Its UI is built on [PuiKit](https://github.com/crftwr/puikit).
14
+
15
+ ## Features
16
+
17
+ - **Key remapping**: key → key, key → key sequence, key → Python function.
18
+ - **Per-application key tables**: match by app name, window title, Win32 window class,
19
+ or the full accessibility focus path (AX on macOS, UI Automation on Windows) — down to
20
+ "only in this app's text editor pane".
21
+ - **User modifiers**: turn any key into a modifier of your own (User0–User3), invisible
22
+ to applications.
23
+ - **One-shot modifiers**: tap a modifier alone for one action, hold it to modify.
24
+ - **Multi-stroke key tables**: Emacs-style prefix keys, with a balloon showing the
25
+ armed prefix.
26
+ - **Clipboard history**: persistent history in a popup chooser — type to filter,
27
+ Enter pastes into the app you came from. Plus fixed snippets and scriptable
28
+ clipboard-transform tools.
29
+ - **Window control**: move, snap/tile, minimize, activate and launch applications,
30
+ multi-monitor aware.
31
+ - **Keyboard macros**: record and replay keys.
32
+ - **Mouse output**: send clicks, wheel scrolls and pointer moves from key bindings.
33
+ - **Console window**: live log, last-key and focus-path inspector — see exactly what to
34
+ bind. Runs from the system tray (Windows) / menu-bar extra (macOS).
35
+
36
+ ## Screenshots
37
+
38
+ | Console (macOS) | Console (Windows) |
39
+ |---|---|
40
+ | ![Keyhac console window on macOS: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector](doc/images/console-mac.jpg) | ![Keyhac console window on Windows: keyboard-hook toggle, log level selector, live key-event log, last-key and focus-path inspector](doc/images/console-win.jpg) |
41
+
42
+ | Menu-bar extra (macOS) | Task tray (Windows) |
43
+ |---|---|
44
+ | ![Keyhac menu-bar extra on macOS with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac](doc/images/menubar-extra-icon-mac.jpg) | ![Keyhac task-tray icon on Windows with its menu open: Open Console, Edit Config, Reload Config, Keyboard Hook, Quit Keyhac](doc/images/tasktray-icon-win.jpg) |
45
+
46
+ ## Install
47
+
48
+ Download from [Releases](https://github.com/crftwr/keyhac2/releases):
49
+
50
+ - **macOS 15+** — `Keyhac-<version>-macos.dmg`: drag Keyhac.app into Applications and
51
+ launch it. Grant the Accessibility permission when prompted (required for the
52
+ keyboard hook).
53
+ - **Windows 10/11 (x64)** — `Keyhac-<version>-win64.zip`: unzip anywhere and run
54
+ `Keyhac.exe`.
55
+
56
+ Details, data locations and privacy notes: [doc/installation.md](doc/installation.md).
57
+
58
+ ## Quick start
59
+
60
+ On first run Keyhac creates `~/.keyhac/config.py` from a fully commented template.
61
+ Open it from the tray / menu-bar icon ("Edit Config"), edit, then "Reload Config".
62
+ A config defines one function:
63
+
64
+ ```python
65
+ from keyhac import *
66
+
67
+ def configure(keymap):
68
+ kt = keymap.define_keytable(focus_path_pattern="*") # active everywhere
69
+
70
+ kt["Fn-J"] = "Left" # key -> key
71
+ kt["Fn-A"] = "Home", "Shift-End" # key -> sequence
72
+
73
+ def hello(): # key -> Python function
74
+ print("Hello from config.py")
75
+ kt["Fn-H"] = hello
76
+
77
+ kt["Fn-V"] = ShowClipboardHistory() # clipboard history popup
78
+
79
+ kt_browser = keymap.define_keytable(app="chrome|Safari") # per-app table
80
+ kt_browser["Fn-R"] = "Cmd-R"
81
+ ```
82
+
83
+ The full reference is [doc/configuration.md](doc/configuration.md); the shipped
84
+ template ([keyhac/_config.py](keyhac/_config.py)) is a working tour of every feature.
85
+
86
+ ## Documentation
87
+
88
+ - [Installation](doc/installation.md) — install, permissions, data files, privacy.
89
+ - [Configuration](doc/configuration.md) — the complete config.py reference.
90
+ - [Migrating from Keyhac for macOS](doc/migration-from-keyhac-mac.md) — mostly drop-in.
91
+ - [Migrating from Keyhac for Windows](doc/migration-from-keyhac-win.md) — API renamed;
92
+ translation table.
93
+ - [Developer documentation](doc/dev/) — architecture, platform layer, packaging,
94
+ testing. Project guide for coding agents: [CLAUDE.md](CLAUDE.md).
95
+
96
+ ## Running from source
97
+
98
+ ```sh
99
+ python3 -m venv .venv
100
+ .venv/bin/pip install -e ".[dev]"
101
+ .venv/bin/python -m pytest # engine + unit tests, no permissions needed
102
+ .venv/bin/python -m keyhac # run (macOS: needs Accessibility permission)
103
+ ```
104
+
105
+ `python -m keyhac -d` enables debug logging, `--no-ui` runs headless (hook + engine
106
+ only), `--config PATH` uses an alternate config file (its data files live beside it).
107
+
108
+ ## License
109
+
110
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,70 @@
1
+ """Keyhac 2 - Python-scriptable keyboard customization for Windows and macOS.
2
+
3
+ Configuration files do `from keyhac import *` and get the user-facing API.
4
+ """
5
+
6
+ __version__ = "2.0.0"
7
+
8
+ from keyhac.core.keymap import Keymap
9
+ from keyhac.core.key import KeyCondition, KeyTable
10
+ from keyhac.core.focus import FocusCondition
11
+ from keyhac.core.input import InputContext
12
+ from keyhac.core.log import getLogger, Console
13
+ from keyhac.core.action import (
14
+ ThreadedAction, LaunchApplication, InputText,
15
+ StartRecordingKeys, StopRecordingKeys, ToggleRecordingKeys,
16
+ PlaybackRecordedKeys,
17
+ )
18
+ from keyhac.core.clipboard_history import ClipboardHistory
19
+ from keyhac.actions import (
20
+ ActivateWindow,
21
+ MouseButtonClick,
22
+ MouseButtonDown,
23
+ MouseButtonUp,
24
+ MouseHorizontalWheel,
25
+ MouseMove,
26
+ MouseWheel,
27
+ MoveWindow,
28
+ SnapWindow,
29
+ ChooserAction,
30
+ DateTimeSnippet,
31
+ ShowClipboardHistory,
32
+ ShowClipboardSnippets,
33
+ ShowClipboardTools,
34
+ )
35
+ from keyhac.platform.base import Focus, KeyEvent
36
+
37
+ __all__ = [
38
+ "Keymap",
39
+ "KeyTable",
40
+ "KeyCondition",
41
+ "FocusCondition",
42
+ "InputContext",
43
+ "Focus",
44
+ "KeyEvent",
45
+ "ThreadedAction",
46
+ "LaunchApplication",
47
+ "InputText",
48
+ "StartRecordingKeys",
49
+ "StopRecordingKeys",
50
+ "ToggleRecordingKeys",
51
+ "PlaybackRecordedKeys",
52
+ "ClipboardHistory",
53
+ "ChooserAction",
54
+ "MouseButtonClick",
55
+ "MouseButtonDown",
56
+ "MouseButtonUp",
57
+ "MouseHorizontalWheel",
58
+ "MouseMove",
59
+ "MouseWheel",
60
+ "MoveWindow",
61
+ "SnapWindow",
62
+ "ActivateWindow",
63
+ "ShowClipboardHistory",
64
+ "ShowClipboardSnippets",
65
+ "ShowClipboardTools",
66
+ "DateTimeSnippet",
67
+ "getLogger",
68
+ "Console",
69
+ "__version__",
70
+ ]
@@ -0,0 +1,4 @@
1
+ from keyhac.main import main
2
+ import sys
3
+
4
+ sys.exit(main())