# Lepton Immersive Mode Implementation: A Technical Deep Dive

> Explore Lepton's immersive mode implementation. Discover how IPC messages, Redux state, and CSS class changes create a seamless full-screen experience in this technical deep dive.

- Repository: [CosmoX/Lepton](https://github.com/hackjutsu/lepton)
- Tags: deep-dive
- Published: 2026-02-23

---

**Lepton's immersive mode works by sending an IPC message from the Electron main process to the renderer, which toggles a Redux state flag that triggers CSS class changes and conditional rendering to expand the snippet view to full screen.**

Lepton, an open-source snippet manager built by hackjutsu, features an immersive mode that maximizes the code viewing area by hiding chrome elements. This article examines the technical implementation of Lepton's immersive mode, detailing how Electron IPC, Redux state management, and React components coordinate to create a distraction-free coding environment.

## Triggering Immersive Mode via IPC

The immersive mode can be activated through three entry points in the Electron main process: the application menu, the Touch Bar, or a keyboard shortcut. Each trigger sends the same IPC channel message `'immersive-mode'` to the renderer process.

### Menu and Touch Bar Integration

In [`main.js`](https://github.com/hackjutsu/Lepton/blob/main/main.js), the menu item and Touch Bar button both invoke `mainWindow.send('immersive-mode')` when clicked:

```javascript
// main.js – menu definition (lines 71-73)
{
  label: 'Immersive Mode',
  accelerator: shortcuts.keyImmersiveMode,
  click: (item, mainWindow) => mainWindow && mainWindow.send('immersive-mode')
}

// main.js – Touch Bar button (lines 15-20)
new TouchBarButton({
  label: "Immersive",
  icon: makeIcon("immersive"),
  click: () => mainWindow.send("immersive-mode")
})

```

### Keyboard Shortcuts Configuration

The default shortcut **⌘/Ctrl + I** is defined in [`configs/defaultConfig.js`](https://github.com/hackjutsu/Lepton/blob/main/configs/defaultConfig.js) at line 44:

```json
"keyImmersiveMode": "CommandOrControl+I"

```

## Redux State Management

Once the renderer receives the IPC message, it validates the UI state and updates the Redux store to reflect the new immersive mode status.

### IPC Listener and Action Dispatching

In [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js) (lines 44-69), the `ipcRenderer` listens for the `'immersive-mode'` event. It checks that no modal dialogs are open using `allDialogsClosed()`, then toggles the current state and dispatches the `updateImmersiveModeStatus` action:

```javascript
ipcRenderer.on('immersive-mode', data => {
  const { immersiveMode } = reduxStore.getState()
  const dialogs = [/* …list of open modal flags… */]
  if (allDialogsClosed(dialogs)) {
    const newStatus = immersiveMode === 'ON' ? 'OFF' : 'ON'
    reduxStore.dispatch(updateImmersiveModeStatus(newStatus))
  }
})

```

The action creator is defined in [`app/actions/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/actions/index.js) (lines 90-95):

```javascript
export function updateImmersiveModeStatus (status) {
  return { type: UPDATE_IMMERSIVE_MODE_STATUS, payload: status }
}

```

### Reducer Implementation

The [`app/reducers/reducer_immersive_mode.js`](https://github.com/hackjutsu/Lepton/blob/main/app/reducers/reducer_immersive_mode.js) file manages the state slice, defaulting to `'OFF'` and updating to the action payload when `UPDATE_IMMERSIVE_MODE_STATUS` is received:

```javascript
export default function (state = 'OFF', action) {
  switch (action.type) {
    case UPDATE_IMMERSIVE_MODE_STATUS:
      return action.payload
    default:
      return state
  }
}

```

This reducer is combined into the root reducer in [`app/reducers/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/reducers/index.js) (line 17) under the key `immersiveMode`:

```javascript
import immersiveMode from './reducer_immersive_mode'
export default combineReducers({
  // …other slices…
  immersiveMode,
})

```

## UI Component Adaptations

React components subscribe to the `immersiveMode` state and adjust their rendering and styling accordingly.

### Conditional Rendering Logic

In [`app/containers/appContainer/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/appContainer/index.js) (lines 37-40), the container selects between immersive and normal rendering paths:

```jsx
{ immersiveMode === 'ON'
  ? this.renderActiveImmersiveSection()
  : this.renderActiveNormalSection() }

```

Similarly, [`app/containers/snippetPanel/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/snippetPanel/index.js) (lines 27-30) switches CSS classes based on the mode:

```jsx
<div className={ immersiveMode === 'ON' ? 'snippet-panel-immersive' : 'snippet-panel' }>
  …
</div>

```

### CSS Styling for Full-Screen View

The immersive styling is defined in [`app/containers/snippetPanel/index.scss`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/snippetPanel/index.scss) (lines 12-21). The `.snippet-panel-immersive` class extends the base panel and expands to full viewport width while applying minimal font styling:

```scss
.snippet-panel-immersive {
  @extend .snippet-panel;
  width: 100%;

  .font-style-base { … }
}

```

These CSS rules hide sidebars, remove scrollbars, and create the distraction-free environment characteristic of immersive mode.

## Exiting Immersive Mode

Users can exit immersive mode by pressing **Esc**, which is registered as `'back-to-normal-mode'` in [`main.js`](https://github.com/hackjutsu/Lepton/blob/main/main.js), or by toggling the menu item again. Both methods send the same `'immersive-mode'` IPC channel, triggering the toggle logic in [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js) to set the Redux state back to `'OFF'`.

## Code Examples

### Manually Toggling Immersive Mode from a Custom Button

To programmatically toggle immersive mode from a React component:

```javascript
import { updateImmersiveModeStatus } from '../actions'
import { useDispatch, useSelector } from 'react-redux'

function ImmersiveToggle() {
  const dispatch = useDispatch()
  const mode = useSelector(state => state.immersiveMode)

  const toggle = () => {
    const newMode = mode === 'ON' ? 'OFF' : 'ON'
    dispatch(updateImmersiveModeStatus(newMode))
  }

  return <button onClick={toggle}>
    {mode === 'ON' ? 'Leave Immersive' : 'Enter Immersive'}
  </button>
}

```

### Listening for Mode Changes in Components

Subscribe to state changes to conditionally render UI elements:

```javascript
import { useSelector } from 'react-redux'

function Header() {
  const immersive = useSelector(state => state.immersiveMode)
  return (
    <header className={immersive === 'ON' ? 'hidden' : ''}>
      {/* normal header content */}
    </header>
  )
}

```

### Customizing the Keyboard Shortcut

Modify [`configs/defaultConfig.js`](https://github.com/hackjutsu/Lepton/blob/main/configs/defaultConfig.js) to change the shortcut (e.g., to `Ctrl+Shift+I`):

```json
"keyImmersiveMode": "CommandOrControl+Shift+I"

```

No additional code changes are required; the main process reads this configuration at startup.

## Summary

- **IPC Communication**: Immersive mode is triggered via the `'immersive-mode'` channel sent from [`main.js`](https://github.com/hackjutsu/Lepton/blob/main/main.js) (menu, Touch Bar, or shortcut) to the renderer process.
- **Redux State**: The `immersiveMode` state slice defaults to `'OFF'` in [`app/reducers/reducer_immersive_mode.js`](https://github.com/hackjutsu/Lepton/blob/main/app/reducers/reducer_immersive_mode.js) and toggles via the `updateImmersiveModeStatus` action.
- **UI Adaptation**: Components in [`app/containers/appContainer/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/appContainer/index.js) and [`app/containers/snippetPanel/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/snippetPanel/index.js) conditionally render immersive layouts using the `.snippet-panel-immersive` CSS class defined in [`index.scss`](https://github.com/hackjutsu/Lepton/blob/main/index.scss).
- **Exit Mechanism**: Pressing **Esc** or re-toggling the menu sends the same IPC message to set the state back to `'OFF'`.

## Frequently Asked Questions

### How does Lepton's immersive mode handle keyboard shortcuts?

Lepton registers the immersive mode shortcut in [`configs/defaultConfig.js`](https://github.com/hackjutsu/Lepton/blob/main/configs/defaultConfig.js) using Electron's accelerator format (`CommandOrControl+I`). The main process reads this configuration at startup and binds it to the menu item in [`main.js`](https://github.com/hackjutsu/Lepton/blob/main/main.js). When pressed, the shortcut triggers the same `'immersive-mode'` IPC message as the menu or Touch Bar buttons.

### What prevents immersive mode from activating when dialogs are open?

In [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js), the IPC listener checks the `allDialogsClosed()` function before dispatching the Redux action. This validation ensures that modal dialogs (such as settings or confirmation dialogs) block the immersive mode toggle, preventing UI conflicts and maintaining focus on the active modal.

### Can I customize the immersive mode styling?

Yes, the immersive appearance is controlled by SCSS in [`app/containers/snippetPanel/index.scss`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/snippetPanel/index.scss). The `.snippet-panel-immersive` class extends the base panel styles and sets `width: 100%` while hiding sidebars. You can modify these styles or the conditional class logic in [`app/containers/snippetPanel/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/containers/snippetPanel/index.js) to adjust the full-screen layout.

### How does the application exit immersive mode?

Exiting immersive mode uses the same mechanism as entering it. Pressing **Esc** (registered as `'back-to-normal-mode'` in [`main.js`](https://github.com/hackjutsu/Lepton/blob/main/main.js)) or selecting the immersive mode menu item again sends the `'immersive-mode'` IPC channel. The toggle logic in [`app/index.js`](https://github.com/hackjutsu/Lepton/blob/main/app/index.js) then flips the Redux state from `'ON'` back to `'OFF'`, causing components to revert to their standard layouts.