|
2 | 2 |
|
3 | 3 | Turn your Copilot key into a customizable launcher on Linux. |
4 | 4 |
|
5 | | -Press → menu → run anything instantly. |
6 | | ---- |
| 5 | +Press the Copilot/F23 key, pick an action, and launch apps, websites, files, or system commands instantly. |
7 | 6 |
|
8 | | -<img width="1488" height="656" alt="image" src="https://github.com/user-attachments/assets/2eac6d8d-46c6-4262-9c26-d98f351b4c49" /> |
| 7 | + |
9 | 8 |
|
10 | | -here are the pdfs repo for CP - [My CP Notes Repo](https://github.com/codeafridi/Competitive-programming-notes) |
| 9 | +## Features |
11 | 10 |
|
12 | | -## Features |
| 11 | +- Opens a launcher menu from the Copilot/F23 key |
| 12 | +- Runs apps, websites, files, folders, and system commands |
| 13 | +- Configurable with simple JSON |
| 14 | +- Runs as a background user service |
| 15 | +- Supports `rofi-wayland`, `wofi`, `fuzzel`, and `rofi` |
13 | 16 |
|
14 | | -- Press Copilot key → instantly open a menu |
15 | | -- Launch apps, browser, or system actions |
16 | | -- Fully customizable using a simple config file |
17 | | -- Runs in the background automatically |
18 | | -- Works across different Linux setups |
19 | | - |
20 | | ---- |
21 | | - |
22 | | -## Installation |
| 17 | +## Install From Source |
23 | 18 |
|
24 | 19 | ```bash |
25 | | -git clone https://github.com/yourname/keypilot |
26 | | -cd keypilot |
| 20 | +git clone https://github.com/codeafridi/CopilotKey-Linux.git |
| 21 | +cd CopilotKey-Linux |
27 | 22 | chmod +x install.sh |
28 | 23 | ./install.sh |
29 | 24 | ``` |
30 | 25 |
|
31 | | -Run the script as your normal user, not with `sudo`. It will ask for sudo only |
32 | | -when it needs to install packages or update input-device permissions. |
33 | | - |
34 | | -The installer: |
| 26 | +Run the script as your normal user, not with `sudo`. It asks for `sudo` only when it needs to install system packages or update input-device permissions. |
35 | 27 |
|
36 | | -- installs Python/system dependencies |
37 | | -- creates a local `.venv` |
38 | | -- installs Python packages into that `.venv` |
39 | | -- installs a menu launcher (`rofi-wayland` when available, otherwise `rofi`) |
40 | | -- adds your user to the `input` group |
41 | | -- enables the `keypilot` user service |
| 28 | +After installation, log out and log back in. This is required so Linux applies the new `input` group permission to your desktop session. |
42 | 29 |
|
43 | | -After installation, **log out and log back in** or reboot. This is required so |
44 | | -Linux applies the new `input` group permission to your desktop session. |
45 | | - |
46 | | -Then start/restart KeyPilot: |
| 30 | +Then start KeyPilot: |
47 | 31 |
|
48 | 32 | ```bash |
49 | 33 | systemctl --user restart keypilot |
50 | 34 | ``` |
51 | 35 |
|
52 | | ---- |
| 36 | +## Install From A Debian Package |
53 | 37 |
|
54 | | -## Usage |
| 38 | +Build a local `.deb` package: |
55 | 39 |
|
56 | | -Just press the **Copilot key**. |
| 40 | +```bash |
| 41 | +chmod +x packaging/deb/build-deb.sh |
| 42 | +packaging/deb/build-deb.sh 0.1.0 |
| 43 | +``` |
| 44 | + |
| 45 | +Install it on Ubuntu/Debian: |
57 | 46 |
|
58 | | -A menu will appear where you can: |
59 | | -- Open terminal |
60 | | -- Open browser |
61 | | -- Run custom actions |
| 47 | +```bash |
| 48 | +sudo apt install ./dist/keypilot_0.1.0_all.deb |
| 49 | +``` |
62 | 50 |
|
63 | | -To check whether the background service is running: |
| 51 | +Then enable permissions and the user service: |
64 | 52 |
|
65 | 53 | ```bash |
66 | | -systemctl --user status keypilot |
| 54 | +sudo usermod -aG input "$USER" |
67 | 55 | ``` |
68 | 56 |
|
69 | | -To watch logs while pressing the Copilot key: |
| 57 | +Log out and log back in, then run: |
70 | 58 |
|
71 | 59 | ```bash |
72 | | -journalctl --user -u keypilot -f |
| 60 | +mkdir -p ~/.config/keypilot |
| 61 | +cp /etc/keypilot/config.json ~/.config/keypilot/config.json |
| 62 | +systemctl --user daemon-reload |
| 63 | +systemctl --user enable --now keypilot |
73 | 64 | ``` |
74 | 65 |
|
75 | | ---- |
| 66 | +## Usage |
76 | 67 |
|
77 | | -## Customization |
| 68 | +Press the Copilot key. A menu appears with your configured actions. |
78 | 69 |
|
79 | | -Edit `config.json` to change what the key does. |
| 70 | +Check whether the service is running: |
80 | 71 |
|
81 | | -Example: |
| 72 | +```bash |
| 73 | +systemctl --user status keypilot |
| 74 | +``` |
82 | 75 |
|
83 | | -```json |
84 | | -{ |
85 | | - "KEY_F23": { |
86 | | - "type": "menu", |
87 | | - "options": [ |
88 | | - { "label": "Terminal", "action": "terminal" }, |
89 | | - { "label": "Browser", "action": "browser" } |
90 | | - ] |
91 | | - } |
92 | | -} |
| 76 | +Watch logs while pressing the key: |
| 77 | + |
| 78 | +```bash |
| 79 | +journalctl --user -u keypilot -f |
93 | 80 | ``` |
94 | | -## Adding More Menu Options |
95 | 81 |
|
96 | | -You can add as many options as you want to the menu. |
| 82 | +## Configuration |
97 | 83 |
|
98 | | -Just edit `config.json` and add more items inside the `options` list. |
| 84 | +Edit: |
| 85 | + |
| 86 | +```bash |
| 87 | +~/.config/keypilot/config.json |
| 88 | +``` |
| 89 | + |
| 90 | +Example: |
99 | 91 |
|
100 | | -### Example |
101 | 92 | ```json |
102 | 93 | { |
103 | 94 | "KEY_F23": { |
104 | 95 | "type": "menu", |
105 | 96 | "options": [ |
106 | | - { "label": "Terminal", "action": "terminal" }, |
107 | | - { "label": "Browser", "action": "browser" }, |
108 | | - { "label": "Shutdown", "action": "shutdown" }, |
109 | | - { "label": "Files", "action": "files" }, |
110 | | - { "label": "VS Code", "action": "code" } |
| 97 | + { |
| 98 | + "label": "Terminal", |
| 99 | + "action": "terminal" |
| 100 | + }, |
| 101 | + { |
| 102 | + "label": "GitHub", |
| 103 | + "command": ["xdg-open", "https://github.com"] |
| 104 | + }, |
| 105 | + { |
| 106 | + "label": "VS Code", |
| 107 | + "command": ["code"] |
| 108 | + } |
111 | 109 | ] |
112 | 110 | } |
113 | 111 | } |
114 | 112 | ``` |
115 | | -### Important |
116 | | - |
117 | | -If you add a new action in `config.json`, you also need to add it in the code. |
118 | | - |
119 | | -Open `keypilot.py` and find the `run_action()` function. |
120 | 113 |
|
121 | | -### Actions Guide (Apps, Websites, Files, System Commands) |
| 114 | +Each menu option supports either: |
122 | 115 |
|
123 | | -Every action is executed using: |
124 | | - |
125 | | -```python |
126 | | -subprocess.Popen(["command", "arg1", "arg2"]) |
127 | | -``` |
128 | | - |
129 | | ---- |
130 | | - |
131 | | -## Quick Rules |
132 | | - |
133 | | -- **App** → `["app-name"]` |
134 | | -- **Website** → `["xdg-open", "https://..."]` |
135 | | -- **File/Folder** → `["xdg-open", "path"]` |
136 | | -- **System command** → `["command", "argument"]` |
137 | | -- **Search (optional)** → `["xdg-open", "https://google.com/search?q=..."]` |
138 | | - |
139 | | ---- |
140 | | - |
141 | | -## Common Examples |
142 | | - |
143 | | -| Category | What you want to do | Example code | |
144 | | -|--------------|----------------------------|--------------| |
145 | | -| App | Open terminal | `["gnome-terminal"]` | |
146 | | -| App | Open VS Code | `["code"]` | |
147 | | -| App | Open Firefox | `["firefox"]` | |
148 | | -| App | Open file manager | `["nautilus"]` | |
149 | | -| Website | Open Google | `["xdg-open", "https://google.com"]` | |
150 | | -| Website | Open YouTube | `["xdg-open", "https://youtube.com"]` | |
151 | | -| File/Folder | Open current folder | `["xdg-open", "."]` | |
152 | | -| File/Folder | Open Downloads | `["xdg-open", "~/Downloads"]` | |
153 | | -| File | Open a PDF | `["xdg-open", "file.pdf"]` | |
154 | | -| System | Shutdown | `["systemctl", "poweroff"]` | |
155 | | -| System | Restart | `["systemctl", "reboot"]` | |
156 | | -| System | Lock screen | `["loginctl", "lock-session"]` | |
157 | | -| System | Logout | `["gnome-session-quit", "--logout"]` | |
158 | | -| Search | Google search | `["xdg-open", "https://google.com/search?q=linux"]` | |
159 | | -| Custom | Run script | `["bash", "script.sh"]` | |
160 | | -| Custom | Python script | `["python3", "file.py"]` | |
161 | | - |
162 | | ---- |
163 | | - |
164 | | -## Example in `run_action()` |
165 | | - |
166 | | -```python |
167 | | -def run_action(action): |
168 | | - if action == "terminal": |
169 | | - subprocess.Popen(["gnome-terminal"]) |
170 | | - elif action == "browser": |
171 | | - subprocess.Popen(["xdg-open", "https://google.com"]) |
172 | | - elif action == "shutdown": |
173 | | - subprocess.Popen(["systemctl", "poweroff"]) |
174 | | - elif action == "code": |
175 | | - subprocess.Popen(["code"]) |
176 | | -``` |
| 116 | +- `action`: a built-in KeyPilot action |
| 117 | +- `command`: a command array, for example `["xdg-open", "https://example.com"]` |
177 | 118 |
|
178 | | ---- |
| 119 | +Built-in actions: |
179 | 120 |
|
180 | | -## Important |
| 121 | +- `terminal` |
| 122 | +- `browser` |
| 123 | +- `shutdown` |
181 | 124 |
|
182 | | -- Always use `["command", "arg"]` format |
183 | | -- Do NOT write commands as a single string |
184 | | -- Use `xdg-open` for anything that should open with default apps |
185 | | - |
186 | | ---- |
187 | | - |
188 | | -Thats it. you can launch anything. |
189 | | -After changing the service file or reinstalling dependencies, run: |
190 | | - |
191 | | -```bash |
192 | | -./install.sh |
193 | | -systemctl --user restart keypilot |
194 | | -``` |
195 | | - |
196 | | ---- |
| 125 | +Use `command` for everything else. KeyPilot does not run commands through a shell, so write each command and argument as a separate JSON string. |
197 | 126 |
|
198 | 127 | ## Requirements |
199 | 128 |
|
200 | 129 | - Linux |
201 | 130 | - Python 3 |
202 | | -- `python3-venv` |
203 | | -- one supported menu launcher: |
204 | | - - `rofi-wayland` recommended for Wayland |
| 131 | +- `evdev` |
| 132 | +- `xdg-open` |
| 133 | +- One menu launcher: |
| 134 | + - `rofi-wayland` recommended for GNOME/Wayland |
205 | 135 | - `wofi` |
206 | 136 | - `fuzzel` |
207 | | - - `rofi` for X11 |
208 | | - |
209 | | ---- |
210 | | - |
211 | | -## Notes |
212 | | - |
213 | | -- Uses low-level input (`/dev/input`) → permissions handled in install script |
214 | | -- The installer uses a local `.venv`, so it avoids Python's |
215 | | - `externally-managed-environment` / PEP 668 error. |
216 | | -- KeyPilot tries menu launchers in this order: `rofi-wayland`, `wofi`, |
217 | | - `fuzzel`, then `rofi`. |
218 | | -- On GNOME Wayland, classic `/usr/bin/rofi` may crash. Install `rofi-wayland` |
219 | | - or `wofi`, then restart the service. |
220 | | - |
221 | | ---- |
222 | | - |
223 | | -## Troubleshooting |
224 | | - |
225 | | -### Service says "No suitable input device found" |
226 | | - |
227 | | -Check your active groups: |
228 | | - |
229 | | -```bash |
230 | | -id -nG | grep -w input |
231 | | -``` |
232 | | - |
233 | | -If nothing prints, log out completely and log back in, or reboot. Then run: |
| 137 | + - `rofi` |
234 | 138 |
|
235 | | -```bash |
236 | | -systemctl --user reset-failed keypilot |
237 | | -systemctl --user restart keypilot |
238 | | -journalctl --user -u keypilot -n 30 --no-pager |
239 | | -``` |
240 | | - |
241 | | -When it works, the logs should contain something like: |
242 | | - |
243 | | -```text |
244 | | -[KeyPilot] Using F23 device: /dev/input/event3 (...) |
245 | | -[KeyPilot] Listening... |
246 | | -``` |
247 | | - |
248 | | -### Ubuntu reports that rofi crashed |
249 | | - |
250 | | -If you see an Ubuntu crash dialog for `/usr/bin/rofi`, install a Wayland-friendly |
251 | | -launcher: |
| 139 | +## Permissions |
252 | 140 |
|
253 | | -```bash |
254 | | -sudo apt install rofi-wayland |
255 | | -``` |
256 | | - |
257 | | -If that package is not available: |
258 | | - |
259 | | -```bash |
260 | | -sudo apt install wofi |
261 | | -``` |
262 | | - |
263 | | -Then restart KeyPilot: |
264 | | - |
265 | | -```bash |
266 | | -systemctl --user restart keypilot |
267 | | -``` |
| 141 | +KeyPilot reads low-level keyboard events from `/dev/input`. On Ubuntu, the installer adds your user to the `input` group so the user service can read the Copilot/F23 key. |
268 | 142 |
|
269 | | ---- |
| 143 | +This is powerful access. Only install KeyPilot from source you trust. |
270 | 144 |
|
271 | | -## Why this exists |
| 145 | +## Packaging Roadmap |
272 | 146 |
|
273 | | -On Linux, the Copilot key is useless. |
| 147 | +- `.deb` package for Ubuntu/Debian |
| 148 | +- AUR package for Arch Linux |
| 149 | +- Snap package for Ubuntu App Center |
| 150 | +- Optional GNOME extension later, if deeper GNOME integration becomes useful |
274 | 151 |
|
275 | | -KeyPilot turns it into something actually useful. |
| 152 | +## License |
276 | 153 |
|
277 | | -Works on X11 and can work on Wayland when a Wayland-friendly menu launcher is |
278 | | -installed. |
| 154 | +MIT |
0 commit comments