Island Shape Modes
Island Shape Modes
Info
eIsland supports two visual shape modes โ Notch and Pill โ that change the island's appearance, dimensions, position, and interaction behavior. This document covers the architecture, configuration, and behavioral differences between the two modes.
Overview
The island can operate in two distinct visual modes:
| Mode | Appearance | Position | Default |
|---|---|---|---|
| Notch | Rectangular notch pinned to the top edge | Fixed at screen top | Yes |
| Pill | Rounded capsule floating below the top edge | Draggable, offset from top | No |
Tips
The shape mode persists across sessions via the island-shape-mode.json config file. The default mode is Notch.
Dimension Comparison
The shape mode affects the height of every island state. Widths remain the same in both modes.
Primary States
| State | Width | Notch Height | Pill Height | Pill Border Radius |
|---|---|---|---|---|
idle | 260 px | 42 px | 52 px | 21 px |
hover | 500 px | 60 px | 72 px | 30 px |
expanded | 860 px | 150 px | 164 px | 26 px |
maxExpand | 860 px | 400 px | 416 px | 26 px |
Content States
| State | Width | Notch Height | Pill Height | Pill Border Radius |
|---|---|---|---|---|
notification | 500 px (content: 480 px in pill) | 88 px | 100 px | 44 px |
lyrics | 500 px | 42 px | 52 px | 21 px |
lyricsTranslation | 500 px | 60 px | 72 px | 30 px |
Note
In pill mode, the notification shell remains 500 px wide, but the inner .notification-content container is constrained to 480 px via CSS (src/renderer/styles/notification/notification-content.css). This creates a subtle inset effect within the pill shape.
AI & Input States
| State | Width | Notch Height | Pill Height | Pill Border Radius |
|---|---|---|---|---|
agent | 500 px | 88 px | 100 px | 44 px |
stt | 500 px | 88 px | 100 px | 44 px |
cli | 500 px | 88 px | 100 px | 44 px |
agentVoiceInput | 500 px | 42 px | 52 px | 21 px |
Note
In pill mode, both agent and stt states constrain their inner content containers to 80 px height via CSS (src/renderer/styles/agent/agent.css and src/renderer/styles/stt/stt.css). This prevents the content from overflowing the pill shape.
Full-Screen States
All full-screen states (guide, login, register, resetPassword, setPassword, bindOAuth, bindEmail, payment, announcement) share the same dimensions in both modes (860ร400 px), but pill mode adds a 26 px border radius.
Note
The pill mode constants are defined in src/main/config/storeConfig.ts as PILL_* prefixed exports. The notch mode uses the base constants without a prefix.
Behavioral Differences
Positioning
| Behavior | Notch | Pill |
|---|---|---|
| Vertical anchor | Pinned to screen top (workArea.y) | Offset from top (default workArea.y + 46 + user offset) |
| Horizontal center | Uses initial center X | Uses current window center X |
| User repositioning | Not supported | Draggable in idle, lyrics, lyricsTranslation, agentVoiceInput states |
Important
When switching from pill to notch, the window animates upward to the top edge. When switching from notch to pill, the window animates downward to the pill offset position.
Interaction Mode
| Feature | Notch | Pill |
|---|---|---|
| Hover trigger | Mouse enter auto-expands | Click-to-hover (hover disabled) |
| Idle drag | Not supported | Supported (grab cursor) |
| Active drag cursor | N/A | grabbing cursor on mouse down |
Warning
In pill mode, hover-to-expand is disabled. Users must click the island to trigger the hover state. This prevents accidental expansions when the floating pill is near other UI elements.
CSS Class System
The shape mode is applied as a CSS class on the island shell element:
<div class="island-shell shape-{mode} {state} ...">| Mode | CSS Class | Example |
|---|---|---|
| Notch | shape-notch | <div class="island-shell shape-notch hover"> |
| Pill | shape-pill | <div class="island-shell shape-pill notification"> |
Tips
The CSS class is generated by useIslandShellPresentation hook, which combines shape-${shapeMode} with the current state class name. All pill-specific styles are scoped under .island-shell.shape-pill in src/renderer/styles/shell/shell.css.
CSS Custom Property
A dedicated CSS custom property is available for pill-mode theming:
--color-island-pill: oklch(0.65 0.12 250);Defined in src/renderer/styles/reset/reset.css.
Toggle Mechanism
The shape mode can be toggled through three methods:
Guide Step
During the first-run guide, a dedicated Island Shape step presents two cards with SVG previews:
- Notch โ Anchored at the top, mimicking a notch screen
- Pill โ Floating capsule shape, more dynamic
Each card includes a visual preview of the shape rendered inside a miniature screen outline. Selecting a card immediately applies the shape and broadcasts the change to all windows.
Settings UI
Located in Settings > App > Interaction > Island Shape, the UI presents two radio buttons:
- Notch โ Pins to screen top
- Pill โ Floating capsule shape
Selecting a radio button triggers an immediate hot-switch โ the island animates to the new shape without restarting.
Global Hotkey
A configurable keyboard shortcut toggles between notch and pill modes. The hotkey can be set in Settings > Shortcuts > Toggle Shape Mode.
Note
All three methods (guide, settings UI, hotkey) trigger the same internal flow: write config โ broadcast change โ notify renderer โ animate transition. The guide and settings page both listen to onSettingsChanged for cross-window sync โ changing the shape in one window updates the selection in the other.
IPC Flow
The shape mode uses a multi-layer IPC architecture:
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ Renderer โโโโโโบโ Preload โโโโโโบโ Main IPC โโโโโโบโ Config File โ
โ (store) โ โ (bridge) โ โ (island.ts) โ โ (JSON) โ
โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโ broadcastSettingChange โโโโโโโโโโโค
โ โ
โโโโโโโโโ island:shape-mode:changed โโโโโโโโค
โ โ
โ (animated transition) โ
โผ โผ
CSS class switch Window bounds updateIPC Channels
| Channel | Direction | Purpose |
|---|---|---|
island:shape-mode:get | Renderer โ Main | Read current shape mode |
island:shape-mode:set | Renderer โ Main | Write new shape mode |
island:shape-mode (broadcast) | Main โ All Renderers | Notify all windows of change |
island:shape-mode:changed | Main โ Renderer | Trigger animated transition with target bounds |
toggle-shape-mode-hotkey:get | Renderer โ Main | Read configured hotkey |
toggle-shape-mode-hotkey:set | Renderer โ Main | Set new hotkey |
Important
The island:shape-mode:changed event includes the target (x, y) bounds so the renderer can animate the window position smoothly during the transition.
Animated Transitions
When the shape mode changes, the renderer performs an animated transition managed by useIslandSettingsSync.
Important
The main process computes targetX based on islandWidth (260 px, the idle width). However, lyrics, lyricsTranslation, and agentVoiceInput states use a wider window (500 px). The transition logic accounts for this width mismatch to prevent diagonal drift during mode switches.
Idle-Size States
The isIdleSize group includes idle (260 px wide) and the 500 px-wide content states (lyrics, lyricsTranslation, agentVoiceInput). The transition behavior differs based on the actual window width.
Pill โ Notch (idle โ 260 px)
- Animate window position (X and Y) to notch target
- Switch CSS class to
shape-notch - Resize window to notch dimensions
Pill โ Notch (lyrics / lyricsTranslation / agentVoiceInput โ 500 px)
- Compute corrected target X from notch-mode center and actual window width
- Animate window diagonally (X and Y) to notch target โ avoids two-step repositioning
- Switch CSS class to
shape-notch - Resize window to notch dimensions
Notch โ Pill (idle โ 260 px)
- Resize window to pill dimensions
- Switch CSS class to
shape-pill - Animate window position downward to pill Y offset
Notch โ Pill (lyrics / lyricsTranslation / agentVoiceInput โ 500 px)
- Resize window (width unchanged at 500 px, height adjusts)
- Switch CSS class to
shape-pill - Animate window vertically downward (dx = 0, horizontal center preserved)
Non-Idle States
Pill โ Notch
- Switch CSS class to
shape-notch - Let the current state's expand handler set correct position
Notch โ Pill
- Switch CSS class to
shape-pill - Resize window to pill dimensions
- Animate window downward by
pillNotchDeltaY(46 px)
Source Files
| Layer | File | Responsibility |
|---|---|---|
| Config constants | src/main/config/storeConfig.ts | PILL_* constants, store key, read/write functions |
| Main IPC | src/main/ipc/settings/island.ts | island:shape-mode:get/set handlers |
| Window sizing | src/main/ipc/window/window.ts | getEffectiveCenterX, getEffectiveY, getHeight |
| Main window | src/main/window/mainWindow.ts | notifyShapeModeChanged, getInitialIslandBounds |
| Hotkey service | src/main/services/hotkeyService.ts | Toggle shape mode global shortcut |
| Preload bridge | src/preload/index.ts | shapeModeGet, shapeModeSet, onShapeModeChanged |
| Store type | src/renderer/store/types/index.ts | IslandShapeMode type definition |
| Store slice | src/renderer/store/slices/islandSlice.ts | shapeMode state, setShapeMode action |
| Settings sync | src/renderer/components/hooks/useIslandSettingsSync.ts | Init fetch, broadcast listener, animated transitions |
| Shell class | src/renderer/components/hooks/useIslandShellPresentation.ts | shape-${shapeMode} CSS class generation |
| Drag support | src/renderer/components/hooks/useIslandDrag.ts | Pill-only drag in idle/lyrics states |
| Hover interaction | src/renderer/components/hooks/useIslandHoverInteraction.ts | Pill forces click-to-hover |
| Shell CSS | src/renderer/styles/shell/shell.css | .shape-pill.* dimension and radius rules |
| Settings UI | src/renderer/components/.../BehaviorSettingsPage.tsx | Notch/Pill radio buttons |
| Guide step | src/renderer/components/.../DynamicIslandGuidePages/shape/ | Shape selection with SVG previews |
| Guide CSS | src/renderer/styles/guide/shape.css | Card layout and preview styles |
| STT pill CSS | src/renderer/styles/stt/stt.css | .stt-content height constraint in pill mode |
| Agent pill CSS | src/renderer/styles/agent/agent.css | .agent-content height constraint in pill mode |
Details
Test Coverage: Shape mode IPC registration is verified in src/main/ipc/settings/test/island.test.ts. Window handler tests mock readIslandShapeModeConfig and all PILL_* constants in src/main/ipc/window/test/windowHandlers.test.ts.
Changelog
bb5b2-on

