|
| 1 | +# WinMacKeys |
| 2 | + |
| 3 | +> Mac-style keyboard tweaks for Windows 11 — switch input language with **Caps Lock**, optional **Ctrl ⇄ Win** swap, and a Mac-style **region screenshot** chord. |
| 4 | +
|
| 5 | +[](https://github.com/ushakov-d/winmac-keys/actions/workflows/ci.yml) |
| 6 | +[](https://github.com/ushakov-d/winmac-keys/releases) |
| 7 | +[](LICENSE) |
| 8 | + |
| 9 | +🇷🇺 [Документация на русском](README.ru.md) |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## Features |
| 14 | + |
| 15 | +| Feature | Default | What it does | |
| 16 | +| --- | --- | --- | |
| 17 | +| **Language switch** | `Caps Lock` | One key toggles the input language. `Shift+Caps Lock` keeps the normal Caps Lock. | |
| 18 | +| **Ctrl ⇄ Win swap** | off | Make the bottom-row modifiers feel like macOS. `off` / `left` / `full`. | |
| 19 | +| **Region screenshot** | `Ctrl+Shift+Win+4` | Maps a Mac-style chord to the Windows region capture (`Win+Shift+S`). Handy for Keychron Mac macro keys. | |
| 20 | +| **Custom remaps** | off | Remap any key to any key, e.g. `CapsLock = Escape`, via `[remap]`. | |
| 21 | +| **App / URL launcher** | off | Bind a hotkey to launch an app, file or URL via `[run]`. | |
| 22 | +| **Hyper key** | off | Turn a key into `Ctrl+Alt+Shift+Win` and bind `hyper + X` shortcuts. | |
| 23 | +| **Mac text navigation** | off | `Win+←/→` = Home/End, `Win+↑/↓` = doc start/end, `Alt+←/→` = word. | |
| 24 | + |
| 25 | +Everything is driven by a small INI file, so each feature can be turned on/off without touching code. |
| 26 | + |
| 27 | +> Windows has **no built-in option** to switch the input language with Caps Lock — that is the main reason this tool exists. |
| 28 | +
|
| 29 | +## Why a tool and not just registry tweaks? |
| 30 | + |
| 31 | +The native Windows language-switch hotkeys are limited to `Alt+Shift`, `Ctrl+Shift`, the grave accent and `Win+Space`. Caps Lock is simply not an option in the OS UI. WinMacKeys adds that (and a couple of related niceties) as a tiny [AutoHotkey v2](https://www.autohotkey.com/) layer. |
| 32 | + |
| 33 | +## How it works |
| 34 | + |
| 35 | +Under the hood it's a tiny [AutoHotkey v2](https://www.autohotkey.com/) script that intercepts key presses and substitutes the action you configured. All settings live in a plain `config.ini` — change a value, hit **Reload** in the tray menu, done; you never edit code. The installer copies the program, creates the config and registers a **logon Scheduled Task** so it starts with Windows; the uninstaller removes everything. No AutoHotkey installed? Each release ships a standalone `.exe` that runs without dependencies. |
| 36 | + |
| 37 | +In one line: *a thin layer over Windows that puts Mac-style habits (Caps = language, Ctrl↔Win, a screenshot chord, plus your own remaps) onto the keyboard and starts itself at logon.* |
| 38 | + |
| 39 | +## Install |
| 40 | + |
| 41 | +### Option A — from a release (recommended) |
| 42 | + |
| 43 | +1. Download the latest `WinMacKeys-vX.Y.Z.zip` from [Releases](https://github.com/ushakov-d/winmac-keys/releases) and unzip it. |
| 44 | +2. In the unzipped folder, run: |
| 45 | + |
| 46 | + ```powershell |
| 47 | + powershell -ExecutionPolicy Bypass -File .\install.ps1 |
| 48 | + ``` |
| 49 | + |
| 50 | +The release bundles a standalone `WinMacKeys.exe`, so **AutoHotkey is not required**. |
| 51 | + |
| 52 | +### Option B — from source |
| 53 | + |
| 54 | +```powershell |
| 55 | +git clone https://github.com/ushakov-d/winmac-keys.git |
| 56 | +cd winmac-keys |
| 57 | +powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 |
| 58 | +``` |
| 59 | + |
| 60 | +From source the installer will install AutoHotkey v2 via `winget` if it is missing. |
| 61 | + |
| 62 | +The installer: |
| 63 | + |
| 64 | +- copies the program to `%LOCALAPPDATA%\Programs\WinMacKeys`, |
| 65 | +- writes a default config to `%APPDATA%\WinMacKeys\config.ini` (never overwrites an existing one), |
| 66 | +- registers a **logon Scheduled Task** so it starts automatically (one UAC prompt), |
| 67 | +- starts it right away. |
| 68 | + |
| 69 | +Run with `-NoAutostart` to skip the Scheduled Task. |
| 70 | + |
| 71 | +## Configuration |
| 72 | + |
| 73 | +Every feature is switched on/off in this one text file — **no code changes**. Each `[section]` is independent: set `enabled = true/false` (or `mode = ...` for the swap); the `[remap]`, `[run]` and `[hyper_run]` sections are just lists of lines, and an **empty section means off**. Defaults: language switch and region screenshot **on**, everything else **off**. |
| 74 | + |
| 75 | +Edit `%APPDATA%\WinMacKeys\config.ini`, then pick **Reload** from the tray menu — changes apply instantly. |
| 76 | + |
| 77 | +```ini |
| 78 | +[language] |
| 79 | +; method: altshift | ctrlshift | winspace |
| 80 | +enabled = true |
| 81 | +hotkey = CapsLock |
| 82 | +method = altshift |
| 83 | +shift_toggles_capslock = true |
| 84 | + |
| 85 | +[swap_ctrl_win] |
| 86 | +; mode: off | left | full |
| 87 | +mode = off |
| 88 | + |
| 89 | +[screenshot] |
| 90 | +; hotkeys: semicolon-separated list; ^=Ctrl +=Shift #=Win (^+#4 = Ctrl+Shift+Win+4) |
| 91 | +enabled = true |
| 92 | +hotkeys = ^+#4 |
| 93 | + |
| 94 | +[remap] |
| 95 | +; one "from = to" per line |
| 96 | +CapsLock = Escape |
| 97 | + |
| 98 | +[run] |
| 99 | +; "hotkey = command" |
| 100 | +#t = wt.exe |
| 101 | +^!c = https://www.google.com |
| 102 | + |
| 103 | +[hyper] |
| 104 | +; turn a key into Ctrl+Alt+Shift+Win, then bind hyper+X in [hyper_run] |
| 105 | +enabled = false |
| 106 | +key = CapsLock |
| 107 | + |
| 108 | +[hyper_run] |
| 109 | +; <key> = command (fires while the hyper key is held) |
| 110 | +e = explorer.exe |
| 111 | + |
| 112 | +[mac_text_nav] |
| 113 | +; Win = Cmd. NOTE: overrides Win+Arrow window snapping while enabled |
| 114 | +enabled = false |
| 115 | +``` |
| 116 | + |
| 117 | +See [`config/winmac-keys.example.ini`](config/winmac-keys.example.ini) for the fully commented reference. New sections (`remap`, `run`, `hyper`, `mac_text_nav`) ship **disabled/empty**, so they change nothing until you opt in. |
| 118 | + |
| 119 | +> Put comments on their own line (starting with `;`), not after a value — Windows INI keeps everything after `=` as the value. Hotkeys use [AutoHotkey modifier syntax](https://www.autohotkey.com/docs/v2/Hotkeys.htm): `^` Ctrl, `!` Alt, `+` Shift, `#` Win. |
| 120 | +
|
| 121 | +## Tray menu |
| 122 | + |
| 123 | +A tray icon provides **Suspend hotkeys**, **Edit config**, **Reload** and **Exit**. |
| 124 | +To run without a tray icon, add `#NoTrayIcon` to the top of `WinMacKeys.ahk` (source build). |
| 125 | + |
| 126 | +## Uninstall |
| 127 | + |
| 128 | +```powershell |
| 129 | +powershell -ExecutionPolicy Bypass -File .\uninstall.ps1 |
| 130 | +# add -RemoveConfig to also delete your config.ini |
| 131 | +``` |
| 132 | + |
| 133 | +## How autostart works |
| 134 | + |
| 135 | +A per-user **Scheduled Task** (`AtLogon`, 5-second delay, highest privileges) launches the app. This is more reliable than the Startup folder, and running elevated lets the remaps work even in elevated windows. The task principal is keyed by **SID**, so it keeps working if the account is renamed. |
| 136 | + |
| 137 | +## Notes & limitations |
| 138 | + |
| 139 | +- **Unsigned executable.** The released `.exe` is not code-signed, so SmartScreen may warn on first run (*More info → Run anyway*). Each release ships a `.sha256` checksum; or run from source if you prefer. |
| 140 | +- **Ctrl ⇄ Win swap** moves `Ctrl+C/V/Z` onto the former Win key — that is the point of the swap, but it surprises people, so it is **off by default**. |
| 141 | +- **Administrator step.** Registering the logon task needs one UAC prompt. Use an account that is a local administrator (typical on personal PCs); if you elevate with a *different* admin account, the task is registered for that account. Use `-NoAutostart` to skip it entirely. |
| 142 | +- Works with Cyrillic / spaced user names (paths are resolved from environment variables and files are written as UTF-8). See **Compatibility** below. |
| 143 | + |
| 144 | +## Compatibility |
| 145 | + |
| 146 | +- **Tested on:** Windows 11 Pro **25H2** (build 26200.8457), x64 — with AutoHotkey **v2.0.26** and Windows PowerShell **5.1**. |
| 147 | +- **Should also work on:** Windows 10 and 11 (x64). AutoHotkey v2 runs on Windows 7+ and the features rely on standard OS shortcuts, so other recent builds are expected to work — just not verified by us yet. |
| 148 | +- **Requirements:** |
| 149 | + - `Win+Shift+S` region screenshot needs the Snipping Tool (Windows 10 1809+, standard on 10/11). |
| 150 | + - Installing **from source** uses `winget` to fetch AutoHotkey (Windows 10 1709+ / App Installer). The release `.exe` needs neither winget nor AutoHotkey. |
| 151 | + - 64-bit Windows (the bundled build is x64); Windows PowerShell 5.1 (ships with Windows) or newer. |
| 152 | + |
| 153 | +## Build locally |
| 154 | + |
| 155 | +```powershell |
| 156 | +# requires AutoHotkey v2 + Ahk2Exe |
| 157 | +Ahk2Exe.exe /in src\WinMacKeys.ahk /out dist\WinMacKeys.exe /base AutoHotkey64.exe |
| 158 | +``` |
| 159 | + |
| 160 | +CI builds the `.exe` and publishes a release automatically when a `vX.Y.Z` tag is pushed. |
| 161 | + |
| 162 | +## License |
| 163 | + |
| 164 | +[MIT](LICENSE) |
0 commit comments