A lightweight desktop app that auto-focuses Dofus Retro game windows when it's your character's turn in combat, and lets you switch accounts via a radial overlay. Built for multi-account players.
- Dofus Retro sends a system notification when a game event occurs (turn start, group invite, trade request, private message)
- FocusRetro intercepts the notification banner via OS APIs (Accessibility on macOS, WinRT/notification database on Windows)
- The character name is extracted and matched to the corresponding game window
- The game window is brought to the foreground automatically
No game client modification is needed.
- Auto-focus on turn: Switches to the correct game window when your turn starts
- Group invite handling: Focuses the recipient's window when one of your characters sends a group invite (restricted to known accounts)
- Trade request handling: Focuses the recipient's window when one of your characters sends a trade request (restricted to known accounts)
- Private messages: Captures incoming PMs and displays them in a dedicated Messages tab with HTML item links cleaned up
- Account detection: Detects all open Dofus Retro windows by parsing window titles
- Account management: Reorder accounts via drag & drop, assign icons and colors, designate a principal account
- Radial character selector: Hold a configurable hotkey to open a radial overlay centered on the cursor — move the mouse to the desired character slice and release to focus that account. Works on both macOS and Windows
- Configurable global hotkeys: Default bindings — customizable in Settings:
F1— Focus previous accountF2— Focus next accountF3— Focus principal account- Arrow keys also supported for previous/next navigation
- Hotkeys work everywhere: Uses low-level event hooks (
CGEventTapon macOS,WH_KEYBOARD_LLon Windows) so hotkeys fire even when Dofus (Wine) has focus - System tray: Dynamic icon (active/paused), shows principal account name, account count, toggle autoswitch, show/hide window, quit
- Translations: English, French, Spanish — auto-detects system language on first launch
- Persistent settings: All preferences (toggles, hotkeys, language, account profiles/order) saved to
~/Library/Application Support/com.focusretro.desktop/config.json(macOS) or%APPDATA%\com.focusretro.desktop\config.json(Windows) - Independent toggles: Each feature (autoswitch, group invite, trade, PM) can be enabled/disabled independently
- macOS 12+ (Monterey or later)
- Accessibility permission must be granted:
- System Settings → Privacy & Security → Accessibility → Enable FocusRetro
- Windows 10 1903+ or Windows 11
- Windows 11 / Windows 10 with notification access granted: uses WinRT
UserNotificationListener(event-driven + poll backup). You will be prompted on first launch. - Windows 10 fallback: if
UserNotificationListeneraccess is not available or not granted, FocusRetro automatically falls back to polling the Windows notification database (wpndatabase.db) directly — no permission required.
# Clone the repository
git clone https://github.com/alacroix/focusretro.git
cd focusretro
# Install dependencies
npm install
# Run in development mode
npm run tauri dev
# Build for production
npm run tauri build
# Format all code (Prettier + cargo fmt)
npm run format
# Lint all code (ESLint + prettier --check + cargo clippy)
npm run lintThe built application will be in src-tauri/target/release/bundle/.
The offline variant disables the auto-updater entirely — no outbound HTTP connections at all:
VITE_UPDATER=false npx tauri build --config src-tauri/offline.conf.json -- --no-default-featuresKey differences vs the standard build:
offline.conf.jsonsetsplugins.updater = nullandbundle.createUpdaterArtifacts = false--no-default-featuresdisables theauto_updateCargo feature (removestauri-plugin-updater)VITE_UPDATER=falsehides update-related UI in the frontend
FocusRetro requires Accessibility permission. This is used to:
- Read notification banners — An
AXObserverwatches the NotificationCenter process for new notification windows and reads their text content - Focus game windows —
AXUIElementAPIs raise specific Dofus Retro windows - Simulate keypresses —
CGEventAPIs simulate key events (e.g. Enter key for hotkey actions) - Global hotkeys — A
CGEventTaplistens for keyboard events system-wide so hotkeys work even when another app is focused
When you first launch, you'll be prompted to grant Accessibility permission. If not, go to:
System Settings → Privacy & Security → Accessibility
FocusRetro reads toast notifications from Dofus Retro using one of three modes, selected automatically at runtime:
| Mode | When | How |
|---|---|---|
event |
Win11 / Win10 with access granted | WinRT UserNotificationListener event-driven + 200ms poll backup |
poll |
Access granted, events unavailable (unpackaged app) | WinRT GetNotificationsAsync polled every 100ms |
poll-db |
Win10, access not granted | Polls %LOCALAPPDATA%\Microsoft\Windows\Notifications\wpndatabase.db (SQLite) every 200ms — no permission required |
On first launch on Windows 11 (or Windows 10 with a compatible build), you will be prompted to grant notification access. If you decline or the API is unavailable (Windows 10), the DB fallback kicks in automatically.
No other special permissions are needed — window focus and key simulation use standard Win32 APIs.
src-tauri/src/
├── lib.rs # App setup, tray icon, tray menu
├── commands.rs # Tauri IPC commands
├── state.rs # Shared app state (toggles, accounts, messages, hotkeys, language, persistence)
├── radial.rs # Radial overlay geometry (segment hit-test, selection resolution, focus dispatch)
├── core/
│ ├── autoswitch.rs # Main autoswitch controller
│ ├── accounts.rs # Account detection
│ └── parser.rs # Notification parser (turn, invite, trade, PM)
└── platform/
├── mod.rs # Platform traits (WindowManager, NotificationListener)
├── macos/
│ ├── hotkeys.rs # CGEventTap global hotkey listener
│ ├── window.rs # CGWindowList + AXUIElement + CGEvent
│ ├── notifications.rs # AXObserver on NotificationCenter
│ └── permissions.rs # Accessibility permission checks
└── windows/
│ ├── hotkeys.rs # WH_KEYBOARD_LL global hotkey listener
│ ├── window.rs # EnumWindows + HWND-direct focus (AttachThreadInput/SetActiveWindow) + SendInput
│ └── notifications.rs # WinRT UserNotificationListener (event/poll) + wpndatabase.db poll fallback (Win10)
src/
├── i18n.ts # i18next initialization (en/fr/es)
├── locales/ # Translation JSON files
├── App.tsx # Main layout with tabs
├── components/
│ ├── AccountList.tsx # Account list with drag & drop, icons, colors
│ ├── MessageList.tsx # PM display
│ ├── RadialSelector.tsx # Radial account picker overlay (SVG wheel)
│ └── Settings.tsx # Toggles, hotkey config, language selector
└── lib/
└── commands.ts # Typed Tauri invoke wrappers
| Event | Body pattern | Action |
|---|---|---|
| Turn | FR: C'est à <name> de jouer / EN: <name> 's turn to play / ES: le toca jugar a <name> |
Focus the named character's window |
| Group invite | FR: <name> t'invite à rejoindre son groupe / EN: You are invited to join <name>'s group / ES: <name> te invita a unirte a su grupo |
Focus the receiver's window (inviter must be a known account) |
| Trade | FR: <name> te propose de faire un échange / EN: <name> offers a trade / ES: <name> te propone realizar un intercambio |
Focus the receiver's window (requester must be a known account) |
| Private message | FR: de <name> : <msg> / EN: from <name> : <msg> / ES: desde <name> : <msg> |
Store and display in Messages tab (no focus) |
| Platform | Status |
|---|---|
| macOS | Supported |
| Windows | Supported |
Each release ships two variants per platform:
| Variant | File suffix | Auto-updater |
|---|---|---|
| Standard | (none) | Yes — checks GitHub on launch |
| Offline | _offline |
No — zero outbound HTTP |
The offline variant is built with --no-default-features (disables tauri-plugin-updater). It makes no network connections whatsoever. Both variants are attested by GitHub Actions.
macOS binaries are signed with an ad-hoc identity (-). They are not notarized, so Gatekeeper will block the app when downloaded from the internet. To run it:
xattr -d com.apple.quarantine /Applications/Focus\ Retro.appOr right-click the app → Open → Open anyway.
TODO: set up proper Apple Developer signing + notarization for a smoother install experience.
Windows binaries are currently unsigned. SmartScreen will warn on first install — click "More info → Run anyway".
TODO: set up signing via Azure Artifact Signing (~$10/month, requires registered organization) or SignPath Foundation (free for OSS). See .github/workflows/release.yml and src-tauri/tauri.conf.json — the signCommand config is already in place, just needs credentials.
Only download FocusRetro from the official repository: github.com/alacroix/focusretro. Third-party sites have been known to redistribute modified Dofus community tools containing malware.
Every release asset is attested by GitHub Actions. You can verify a binary before running it:
gh attestation verify <file> --repo alacroix/focusretroExample:
gh attestation verify Focus.Retro_<version>_aarch64.dmg --repo alacroix/focusretroA valid attestation confirms the file was built automatically from source — no human intervention.
FocusRetro is an open-source utility for players of Dofus Retro.
This project is not affiliated with or endorsed by Ankama. Dofus is a trademark of Ankama.
MIT