# How Fluxer Handles macOS Dock Badges and Accessibility Permissions in Electron

> Learn how Fluxer manages macOS dock badges and accessibility permissions in Electron using isolated IPC handlers and platform checks for cross-platform compatibility. Discover the technical details.

- Repository: [Fluxer/fluxer](https://github.com/fluxerapp/fluxer)
- Tags: internals
- Published: 2026-03-17

---

**Fluxer isolates macOS-specific dock badges, bounce notifications, and accessibility permissions in dedicated IPC handlers within the main process, exposing them to the renderer through a typed preload bridge while using platform checks to ensure cross-platform compatibility.**

Fluxer is an Electron-based desktop application that provides deep integration with macOS system features. Understanding how Fluxer handles macOS-specific features like dock badge updates and accessibility permissions reveals the architecture patterns used to maintain clean separation between platform-specific code and cross-platform business logic.

## Architecture Overview for macOS Features

All macOS-specific functionality in Fluxer is isolated within the main process and exposed to the renderer through a secure preload bridge. The architecture relies on three key components:

- **Main Process Handlers**: Located in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx), these handlers contain the platform-specific implementations using Electron's native APIs.
- **Preload Bridge**: Defined in [`fluxer_desktop/src/preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/preload/index.tsx), this bridge securely exposes IPC methods to the renderer process without exposing the full Node.js API.
- **Platform Guards**: All macOS-specific code paths check `process.platform === 'darwin'` before executing, ensuring the application runs safely on Windows and Linux.

## Implementing macOS Dock Badges in Fluxer

The dock badge feature allows Fluxer to display notification counts and attention states on the macOS dock icon. This implementation uses Electron's `app.dock` API exclusively on macOS while providing fallbacks for other platforms.

### Setting the Dock Badge Count

When the renderer needs to update the badge count, it invokes `electronApi.setBadgeCount(count)` through the preload bridge. The main process handler in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx) processes this request:

```typescript
// In fluxer_desktop/src/main/IpcHandlers.tsx
ipcMain.on('set-badge-count', (event, payload) => {
  const count = payload?.count ?? 0;
  const label = payload?.text ?? String(count);
  
  if (process.platform === 'darwin' && app.dock) {
    // macOS-specific: Use app.dock.setBadge
    app.dock.setBadge(count > 0 ? label : '');
  } else if (process.platform === 'win32') {
    // Windows fallback: Use overlay icon
    setWindowsBadgeOverlay(count);
  } else {
    // Linux/generic fallback
    app.setBadgeCount(count);
  }
});

```

The preload bridge in [`fluxer_desktop/src/preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/preload/index.tsx) exposes this functionality:

```typescript
// In fluxer_desktop/src/preload/index.tsx
setBadgeCount: (count: number, text?: string) => {
  ipcRenderer.send('set-badge-count', { count, text });
}

```

### Bouncing the Dock Icon for Attention

Fluxer implements the macOS dock bounce feature to alert users of critical events. The renderer invokes `electronApi.bounceDock(type)` where type can be `'informational'` or `'critical'`.

The main process handler routes this to `app.dock.bounce()`:

```typescript
// In fluxer_desktop/src/main/IpcHandlers.tsx
ipcMain.handle('bounce-dock', (event, type) => {
  if (process.platform === 'darwin' && app.dock) {
    return app.dock.bounce(type); // Returns bounce ID
  }
  return null;
});

```

To cancel an active bounce, the renderer calls `electronApi.cancelBounceDock(id)`:

```typescript
// Cancellation handler
ipcMain.handle('cancel-bounce-dock', (event, id) => {
  if (process.platform === 'darwin' && app.dock && id !== null) {
    app.dock.cancelBounce(id);
  }
});

```

## Managing macOS Accessibility Permissions

Fluxer requires accessibility permissions for certain automation features on macOS. The application uses Electron's `systemPreferences` module to check and request these permissions without crashing on other platforms.

### Checking Trusted Accessibility Client Status

The renderer checks permission status via `electronApi.checkAccessibility(prompt)`. The preload bridge forwards this to the main process:

```typescript
// In fluxer_desktop/src/preload/index.tsx
checkAccessibility: (prompt: boolean) => 
  ipcRenderer.invoke('check-accessibility', prompt)

```

The main process handler in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx) implements platform-specific logic:

```typescript
ipcMain.handle('check-accessibility', (event, prompt) => {
  if (process.platform === 'darwin') {
    // Check if Fluxer is a trusted accessibility client
    return systemPreferences.isTrustedAccessibilityClient(prompt);
  }
  // Always return true on Windows/Linux where this concept doesn't exist
  return true;
});

```

When `prompt` is `true`, macOS displays the system dialog requesting permission if access hasn't been granted.

### Opening System Preferences Programmatically

If accessibility permissions are denied, Fluxer guides users to the correct system preferences pane. The renderer invokes `electronApi.openAccessibilitySettings()`:

```typescript
// Preload exposure
openAccessibilitySettings: () => 
  ipcRenderer.invoke('open-accessibility-settings')

```

The main process opens the Security & Privacy preferences directly:

```typescript
ipcMain.handle('open-accessibility-settings', () => {
  if (process.platform === 'darwin') {
    shell.openExternal(
      'x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility'
    );
  }
});

```

This deep link opens the Accessibility tab within Security & Privacy, eliminating manual navigation for users.

## Cross-Platform Safety and Fallbacks

Fluxer's architecture ensures macOS-specific code never executes on incompatible platforms. Every handler checks `process.platform === 'darwin'` before accessing `app.dock` or `systemPreferences`.

For dock badges:

- **macOS**: Uses `app.dock.setBadge()` with string labels
- **Windows**: Falls back to `setWindowsBadgeOverlay()` with overlay icons
- **Linux**: Uses generic `app.setBadgeCount()`

For accessibility:

- **macOS**: Checks `systemPreferences.isTrustedAccessibilityClient()`
- **Other platforms**: Returns `true` immediately, treating the feature as always available

This pattern keeps the renderer code clean—UI components call the same API regardless of platform, while the main process handles platform differentiation.

## Summary

- Fluxer implements macOS dock badges and accessibility permissions through isolated IPC handlers in the main process ([`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx)).
- The preload bridge ([`fluxer_desktop/src/preload/index.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/preload/index.tsx)) securely exposes these capabilities to the renderer using `ipcRenderer` and `ipcMain`.
- Dock badges use `app.dock.setBadge()` on macOS, with automatic fallbacks to Windows overlay icons and Linux generic counts.
- Accessibility permissions rely on `systemPreferences.isTrustedAccessibilityClient()` to check trusted status and `shell.openExternal()` to direct users to system preferences.
- Platform guards (`process.platform === 'darwin'`) ensure macOS-specific APIs never execute on Windows or Linux, maintaining cross-platform stability.

## Frequently Asked Questions

### How does Fluxer update the macOS dock badge count?

Fluxer updates the dock badge by sending an IPC message from the renderer to the main process via `electronApi.setBadgeCount()`. The main process handler in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx) checks if `process.platform === 'darwin'` and calls `app.dock.setBadge()` with the count or custom text. On other platforms, it falls back to Windows overlay icons or the generic `app.setBadgeCount()` API.

### What Electron API does Fluxer use to check accessibility permissions?

Fluxer uses `systemPreferences.isTrustedAccessibilityClient()` from Electron's `systemPreferences` module to check accessibility permissions on macOS. This call is wrapped in an IPC handler in [`fluxer_desktop/src/main/IpcHandlers.tsx`](https://github.com/fluxerapp/fluxer/blob/main/fluxer_desktop/src/main/IpcHandlers.tsx) that returns `true` immediately on Windows and Linux where accessibility permissions don't apply. When called with the `prompt` parameter set to `true`, macOS automatically displays the permission dialog if access hasn't been granted.

### Can Fluxer bounce the dock icon to notify users of urgent events?

Yes, Fluxer supports dock bouncing through `electronApi.bounceDock(type)` where type can be `'informational'` (bounces once) or `'critical'` (bounces until the app is activated). The main process calls `app.dock.bounce(type)` and returns a bounce ID that can be used with `electronApi.cancelBounceDock(id)` to programmatically stop the bounce before user interaction.

### How does Fluxer handle these macOS features on Windows and Linux?

Fluxer uses platform guards (`process.platform === 'darwin'`) in all IPC handlers to ensure macOS-specific code only executes on macOS. For dock badges, Windows uses overlay icons via `setWindowsBadgeOverlay()` while Linux uses `app.setBadgeCount()`. For accessibility, non-macOS platforms immediately return `true` since the permission concept doesn't exist, allowing the UI to function without platform-specific branching logic in the renderer.