[Bug] Windows + 150% DPI scaling: Actions Ring does not follow cursor (opens at fixed position)
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 675
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 180
Description
### Pre-flight checklist
- [ ] I searched [existing issues](https://github.com/AprilNEA/OpenLogi/issues?q=is%3Aissue) and this is not a duplicate.
- [ ] I am on the [latest release](https://github.com/AprilNEA/OpenLogi/releases/latest) or a recent `master` build.
- [x] I quit **Logi Options+** before running OpenLogi (the two apps fight over HID++ access and only one can own a receiver at a time).
### Which part of OpenLogi?
GUI (desktop app)
### OpenLogi version
0.7.10
### Operating system
Windows
### OS version & architecture
Windows11
### Device model
MX Master 3s for Business
### How is the device connected?
Logi Bolt receiver
### Affected area(s)
- [ ] Device discovery / detection
- [ ] Button remapping
- [ ] DPI control
- [ ] SmartShift
- [ ] Per-application profiles
- [ ] Battery status
- [ ] Settings / configuration (TOML)
- [ ] Auto-update
- [ ] Menu bar / tray
- [ ] Other
### What happened?
## Environment
- OS: Windows 11 Pro 10.0.26200 (64-bit)
- OpenLogi version: 0.7.10
- Device: MX Master 3S (Bolt receiver, slot 2)
- Display: Intel Arc Graphics, physical 2560×1600, **150% DPI scaling** (logical 1707×1067)
- Single display (primary)
### Steps to reproduce
## Expected behavior
The Actions Ring should open centered on the cursor position.
## Actual behavior
The Actions Ring opens at a **fixed position** (appears to be the primary display center) regardless of where the cursor is when the GestureButton is clicked.
## Root cause analysis (from source)
In `crates/openlogi-overlay/src/platform.rs`:
- `display_containing(x, y)` returns `None` on Windows — only the macOS branch is implemented (`#[cfg(target_os = "macos")]`); the `#[cfg(not(target_os = "macos"))]` branch is a stub returning `None`.
In `crates/openlogi-overlay/src/ring.rs` (`ring_window_options`):
- When `display_containing` returns `None`, the code falls back to scanning `cx.displays()` with `display.bounds().contains(&cursor)`.
- **However, `GetCursorPos()` returns PHYSICAL pixels (e.g. 1528×700 at 150% scaling), while GPUI window bounds use LOGICAL pixels (1707×1067 display space).** The coordinate-space mismatch makes the `contains()` check fail, so it falls back to `primary_display()` center.
- Result: ring opens at primary display center instead of at the cursor.
## Suggested fix
1. Implement `display_containing()` for Windows (e.g. via `MonitorFromPoint` / `GetMonitorInfoW`), and/or
2. Convert `GetCursorPos()` physical coordinates to logical pixels using the DPI scale factor (`GetDpiForSystem` or the monitor's DPI) before feeding them into GPUI's logical coordinate space.
## Related
- #649 (Actions Ring positioning improvements)
- #588 (closed: open ring on display containing cursor)
### Diagnostics report
```markdown
```
### `openlogi list` output
```text
```
### Logs
```shell
```
### macOS permissions (if applicable)
- [ ] OpenLogi has **Accessibility** permission (needed to remap buttons via the event tap).
- [ ] OpenLogi has **Input Monitoring** permission (needed for Bluetooth-direct devices and capture).
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in crates/openlogi-overlay/src/platform.rs, where display_containing(x, y) is stubbed on Windows, then trace its use in ring.rs within ring_window_options. Check how GetCursorPos coordinates relate to GPUI display bounds at 150% scaling. Done means the Actions Ring opens centered on the cursor on the reported Windows 11 single-display setup instead of at the primary-display center.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100