Skip to content

Commit e298aaf

Browse files
committed
Merge branch 'main' into add-clipboard-widget
merge-main-into-widget-branch
2 parents f299d7b + b8eb3f4 commit e298aaf

171 files changed

Lines changed: 26322 additions & 13170 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@ updates:
99
timezone: "Etc/UTC"
1010
assignees:
1111
- "amnweb"
12-
allow:
13-
- dependency-name: "pyqt6"
14-
- dependency-name: "pillow"
15-
- dependency-name: "pycaw"
16-
- dependency-name: "cx-freeze"
17-
- dependency-name: "holidays"
18-
- dependency-name: "icoextract"
12+
groups:
13+
winrt:
14+
patterns:
15+
- "winrt*"
1916
commit-message:
2017
prefix: "chore"
2118
include: "scope"

docs/CLI.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ The YASB CLI is a command line interface that allows you to interact with the YA
1515
- `hide-bar` - Hide the status bar.
1616
- `show-bar` - Show the status bar.
1717
- `toggle-bar` - Toggle the visibility of the status bar.
18-
- `toggle-widget` - Toggle the visibility of specific widget.
1918
- `update` - Update aplicattion to the latest version.
2019
- `set-channel` - Set the update channel (stable, dev).
2120
- `log` - Show the status bar logs in the terminal.
@@ -78,25 +77,8 @@ To toggle the visibility of the status bar on a specific screen, use the followi
7877
yasbc toggle-bar --screen <screen_name>
7978
```
8079

81-
## Toggle Widget Visibility
82-
To toggle the visibility of a specific widget on screen, use the following command:
83-
```bash
84-
yasbc toggle-widget launchpad --screen 'DELL P2419H (2)'
85-
```
86-
To toggle the visibility of a specific widget on screen where is mouse cursor, use the following command:
87-
```bash
88-
yasbc toggle-widget launchpad --follow-mouse
89-
```
90-
To toggle the visibility of a specific widget on screens where is focused window, use the following command:
91-
```bash
92-
yasbc toggle-widget launchpad --follow-focused
93-
```
94-
9580
## Switch Update Channel
9681
To switch the update channel to dev, use the following command:
9782
```bash
9883
yasbc set-channel dev
9984
```
100-
101-
> [!NOTE]
102-
> The `toggle-widget` command is not available for all widgets, it is only available for widgets that support toggling visibility. On each widget page, you can find information about the widget and whether it supports toggling visibility.

docs/Keybindings.md

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
# Keybindings
2+
3+
YASB supports global keyboard shortcuts (hotkeys) to trigger widget actions. Keybindings are configured per-widget in the widget's `options` section. This feature uses native Windows low-level keyboard hooks and requires no third-party dependencies.
4+
5+
## Overview
6+
7+
- **Per-widget instance**: Keybindings are tied to the specific widget name in your config (e.g., `clock` vs `clock_2`)
8+
- **Multiple keybindings**: A single widget can have multiple keybindings for different actions
9+
- **Screen-aware**: Hotkeys trigger the widget on the currently focused screen
10+
- **Zero overhead**: If no keybindings are defined, no hotkey listener is started
11+
12+
## Configuration
13+
14+
Add a `keybindings` list to any widget's options. Each keybinding requires:
15+
- `keys`: The key combination (e.g., `"win+c"`, `"ctrl+shift+f1"`)
16+
- `action`: The callback action to trigger (e.g., `"toggle_calendar"`, `"toggle_label"`)
17+
18+
### Basic Example
19+
20+
```yaml
21+
clock:
22+
type: "yasb.clock.ClockWidget"
23+
options:
24+
label: "{%H:%M}"
25+
keybindings:
26+
- keys: "win+c"
27+
action: "toggle_calendar"
28+
- keys: "ctrl+shift+t"
29+
action: "toggle_label"
30+
```
31+
32+
### Multiple Widgets Example
33+
34+
```yaml
35+
clock:
36+
type: "yasb.clock.ClockWidget"
37+
options:
38+
keybindings:
39+
- keys: "win+c"
40+
action: "toggle_calendar"
41+
42+
volume:
43+
type: "yasb.volume.VolumeWidget"
44+
options:
45+
keybindings:
46+
- keys: "win+v"
47+
action: "toggle_menu"
48+
```
49+
50+
## Supported Keys
51+
52+
### Modifier Keys
53+
54+
| Key Name | Description |
55+
|----------|-------------|
56+
| `win`, `windows`, `super`, `meta` | Either Windows key (left or right) |
57+
| `lwin`, `leftwin`, `left_win` | Left Windows key only |
58+
| `rwin`, `rightwin`, `right_win` | Right Windows key only |
59+
| `alt` | Either Alt key (left or right) |
60+
| `lalt`, `leftalt`, `left_alt` | Left Alt key only |
61+
| `ralt`, `rightalt`, `right_alt` | Right Alt key only |
62+
| `ctrl`, `control` | Either Control key (left or right) |
63+
| `lctrl`, `leftctrl`, `left_ctrl` | Left Control key only |
64+
| `rctrl`, `rightctrl`, `right_ctrl` | Right Control key only |
65+
| `shift` | Shift key |
66+
67+
### Function Keys
68+
69+
| Key Name | Description |
70+
|----------|-------------|
71+
| `f1` - `f24` | Function keys F1 through F24 |
72+
73+
### Letter and Number Keys
74+
75+
| Key Name | Description |
76+
|----------|-------------|
77+
| `a` - `z` | Letter keys (case-insensitive) |
78+
| `0` - `9` | Number keys |
79+
80+
### Special Keys
81+
82+
| Key Name | Aliases | Description |
83+
|----------|---------|-------------|
84+
| `space` | | Spacebar |
85+
| `tab` | | Tab key |
86+
| `enter`, `return` | | Enter/Return key |
87+
| `esc`, `escape` | | Escape key |
88+
| `backspace` | | Backspace key |
89+
| `delete`, `del` | | Delete key |
90+
| `insert`, `ins` | | Insert key |
91+
| `home` | | Home key |
92+
| `end` | | End key |
93+
| `pageup`, `pgup` | | Page Up key |
94+
| `pagedown`, `pgdn` | | Page Down key |
95+
| `pause` | | Pause key |
96+
| `capslock`, `caps` | | Caps Lock key |
97+
| `numlock` | | Num Lock key |
98+
| `scrolllock` | | Scroll Lock key |
99+
| `printscreen`, `prtsc` | | Print Screen key |
100+
101+
### Arrow Keys
102+
103+
| Key Name | Description |
104+
|----------|-------------|
105+
| `left` | Left arrow |
106+
| `up` | Up arrow |
107+
| `right` | Right arrow |
108+
| `down` | Down arrow |
109+
110+
### Numpad Keys
111+
112+
| Key Name | Description |
113+
|----------|-------------|
114+
| `numpad0` - `numpad9` | Numpad number keys |
115+
| `multiply` | Numpad * |
116+
| `add` | Numpad + |
117+
| `subtract` | Numpad - |
118+
| `decimal` | Numpad . |
119+
| `divide` | Numpad / |
120+
121+
### Punctuation and Symbol Keys
122+
123+
| Key Name | Description |
124+
|----------|-------------|
125+
| `semicolon` | ; key |
126+
| `equal`, `equals` | = key |
127+
| `comma` | , key |
128+
| `minus` | - key |
129+
| `period` | . key |
130+
| `slash` | / key |
131+
| `backquote`, `grave` | \` key |
132+
| `bracketleft` | [ key |
133+
| `bracketright` | ] key |
134+
| `backslash` | \\ key |
135+
| `quote` | ' key |
136+
137+
## Win Key Specificity
138+
139+
YASB supports distinguishing between the left and right Windows keys:
140+
141+
| Configuration | Behavior |
142+
|--------------|----------|
143+
| `"win+c"` | Triggered by **either** left or right Win key + C |
144+
| `"lwin+c"` | Triggered **only** by left Win key + C |
145+
| `"rwin+c"` | Triggered **only** by right Win key + C |
146+
147+
### Example: Different Actions for Left/Right Win
148+
149+
```yaml
150+
clock:
151+
type: "yasb.clock.ClockWidget"
152+
options:
153+
keybindings:
154+
- keys: "lwin+c"
155+
action: "toggle_calendar"
156+
- keys: "rwin+c"
157+
action: "toggle_label"
158+
```
159+
160+
## Alt/Ctrl Key Specificity
161+
162+
Similarly, you can distinguish between left and right Alt or Ctrl keys:
163+
164+
| Configuration | Behavior |
165+
|--------------|----------|
166+
| `"alt+x"` | Triggered by **either** left or right Alt key + X |
167+
| `"lalt+x"` | Triggered **only** by left Alt key + X |
168+
| `"ralt+x"` | Triggered **only** by right Alt key + X |
169+
| `"ctrl+x"` | Triggered by **either** left or right Ctrl key + X |
170+
| `"lctrl+x"` | Triggered **only** by left Ctrl key + X |
171+
| `"rctrl+x"` | Triggered **only** by right Ctrl key + X |
172+
173+
### Example: Left Alt vs Right Alt
174+
175+
```yaml
176+
volume:
177+
type: "yasb.volume.VolumeWidget"
178+
options:
179+
keybindings:
180+
- keys: "lalt+v"
181+
action: "toggle_menu"
182+
- keys: "ralt+v"
183+
action: "toggle_mute"
184+
```
185+
186+
## Extra Modifier Rejection
187+
188+
YASB uses **exact modifier matching**. If you register `alt+x`, pressing `ctrl+alt+x` will **not** trigger it because Ctrl is an extra modifier that wasn't specified.
189+
190+
| Registered | User Presses | Result |
191+
|------------|--------------|--------|
192+
| `alt+x` | Alt + X | Triggers |
193+
| `alt+x` | Ctrl + Alt + X | Blocked (extra Ctrl) |
194+
| `ctrl+alt+x` | Ctrl + Alt + X | Triggers |
195+
| `ctrl+alt+x` | Ctrl + Alt + Shift + X | Blocked (extra Shift) |
196+
197+
This prevents accidental triggers when using similar hotkeys in other applications.
198+
199+
## Limitations
200+
201+
### No Multi-Key Combos
202+
203+
YASB only supports **modifier + single key** combinations. You cannot bind multiple non-modifier keys together:
204+
205+
| Configuration | Valid |
206+
|--------------|-------|
207+
| `"alt+a"` | Yes |
208+
| `"ctrl+shift+f1"` | Yes |
209+
| `"a+b"` | No - two non-modifier keys |
210+
| `"ctrl+a+b"` | No - two non-modifier keys |
211+
212+
### Modifier-Only Hotkeys Not Supported
213+
214+
You cannot use a modifier key alone as a hotkey:
215+
216+
| Configuration | Valid |
217+
|--------------|-------|
218+
| `"ctrl"` | No - no main key |
219+
| `"alt+shift"` | No - no main key |
220+
| `"win+a"` | Yes |
221+
222+
### Press Order Matters
223+
224+
Hotkeys are triggered when the **main key** is pressed while modifiers are held. This means:
225+
226+
- Hold Alt, then press X → Triggers `alt+x`
227+
- Hold X, then press Alt → Does NOT trigger `alt+x`
228+
229+
This is standard behavior for all hotkey systems (Windows `RegisterHotKey`, AutoHotkey, etc.).
230+
231+
## Available Actions
232+
233+
Each widget has its own set of available callback actions. Common actions include:
234+
235+
| Action | Description |
236+
|--------|-------------|
237+
| `toggle_label` | Toggle between primary and alternate label |
238+
| `toggle_menu` | Show/hide the widget's menu |
239+
| `update_label` | Force refresh the widget label |
240+
| `do_nothing` | No action (useful for disabling) |
241+
242+
Refer to individual widget documentation for widget-specific actions. For example, the Clock widget supports:
243+
- `toggle_calendar` - Show/hide calendar popup
244+
- `toggle_label` - Toggle between label formats
245+
- `next_timezone` - Cycle to next timezone
246+
- `context_menu` - Show context menu
247+
248+
## Screen Targeting
249+
250+
When a hotkey is triggered, YASB determines which screen's widget should respond based on:
251+
1. The currently focused window's screen
252+
2. If no window is focused, falls back to the primary screen
253+
254+
This means pressing `win+c` will toggle the calendar on the monitor where you're currently working.
255+
256+
## Conflict Handling
257+
258+
If the same key combination is assigned to multiple widgets, YASB will:
259+
1. Log a warning message indicating the conflict
260+
2. Use the **last** defined keybinding (later widgets override earlier ones)
261+
262+
```
263+
WARNING: Hotkey conflict: 'win+c' is already assigned to 'yasb.clock.ClockWidget',
264+
overriding with 'yasb.volume.VolumeWidget'
265+
```
266+
267+
To avoid conflicts, use unique key combinations for each widget action.
268+
269+
## Troubleshooting
270+
271+
### Hotkey Not Working
272+
273+
1. **Check the logs**: Enable debug logging to see if the hotkey is being registered
274+
2. **Verify key names**: Ensure you're using supported key names from the tables above
275+
3. **Check for conflicts**: Another application might be using the same hotkey
276+
4. **Elevated apps**: If an elevated (admin) application has focus, hotkeys may not be captured due to Windows UIPI security. This is normal - hotkeys will work again once a non-elevated window has focus
277+
278+
### Hotkey Conflicts with Windows
279+
280+
Some key combinations are reserved by Windows and may not work:
281+
- `win+l` (Lock screen)
282+
- `ctrl+alt+del` (Security options)
283+
284+
Consider using alternative combinations or disabling the Windows shortcuts via Group Policy if needed.
285+
286+
### Keybinding Not in Config
287+
288+
If you don't define any `keybindings` in your widget options, the hotkey listener won't start at all. When keybindings are configured, the listener uses a low-level keyboard hook which has negligible overhead.

0 commit comments

Comments
 (0)