KDE Plasma KWin Tiling — reimagined for macOS
A tiling window manager that brings the flexibility of KDE Plasma's KWin Tiling to macOS. Design your tile layout visually, drop windows in with Shift+Drag, and resize by dragging boundaries — no config files needed.
Existing macOS tiling WMs force you into fixed layouts or text-based configs. KTApple takes the approach KDE Plasma got right: a visual editor where you design the layout you want.
| KTApple | yabai | AeroSpace | Amethyst | Rectangle | |
|---|---|---|---|---|---|
| Visual Tile Editor | Yes | — | — | — | — |
| Free Tile Placement | Yes | BSP only | i3 tree | Fixed | Presets |
| Shift+Drop Placement | Yes | Zones | — | — | Snap |
| Gap-Drag Resize | Yes | — | — | — | — |
| No SIP Required | Yes | Partial | Yes | Yes | Yes |
| GUI Settings | Yes | CLI | TOML | GUI | GUI |
brew tap m96-chan/homebrew-tap
brew install --cask --no-quarantine ktapple- Grab the
.dmgfrom Releases - Move
KTApple.appto/Applications - Remove quarantine:
xattr -cr /Applications/KTApple.app - Grant Accessibility permission in System Settings > Privacy & Security > Accessibility
Note
KTApple is ad-hoc signed (no Apple Developer Program). Gatekeeper bypass via xattr -cr or Homebrew --no-quarantine is required.
Split, resize, and delete tiles through an interactive GUI. Layouts are stored in normalized 0.0–1.0 coordinates — resolution-independent and portable.
┌────────────┬──────────┐
│ │ Top-R │
│ Left ├──────────┤
│ (60%) │ Bottom-R │
│ │ (40%) │
└────────────┴──────────┘
Hold Shift while dragging any window. A tile highlight appears — release to snap the window into place.
Drag the boundary line between any two tiles. Both adjacent windows resize in real time.
| Shortcut | Action |
|---|---|
| ⌃⌥T | Open tile editor |
| ⌃⌥ + Arrow | Move focus |
| ⌃⌥⇧ + Arrow | Move window |
| ⌃⌥F | Toggle float |
| ⌃⌥M | Toggle maximize |
| ⌃⌥= / - | Expand / shrink tile |
KTApple
├── TileManager Per-display tile tree management
├── TileEditor Visual tile editor (SwiftUI)
├── WindowManager Window ops via Accessibility API
├── HotkeyManager Global shortcut registration
├── DragDropHandler Shift+Drag detection & tile snapping
├── GapResizeHandler Boundary drag-resize handling
├── LayoutStore JSON layout persistence
└── DisplayObserver Monitor hotplug observation
Tile Tree Structure
Tiles follow the same tree model as KWin:
RootTile (Screen)
├── Tile (Left, 60%)
│ ├── Tile (Top-Left)
│ └── Tile (Bottom-Left)
└── Tile (Right, 40%)
├── Tile (Top-Right)
└── Tile (Bottom-Right)
Each node carries:
- proportion — Size relative to siblings (0.0–1.0)
- layoutDirection — Horizontal / Vertical
- children — Arbitrary child count
- windowIDs — Assigned windows
macOS API Usage
| Layer | API |
|---|---|
| Window Operations | AXUIElement (Accessibility API) |
| Window Enumeration | CGWindowListCopyWindowInfo |
| Global Events | CGEvent Tap / NSEvent.addGlobalMonitorForEvents |
| Hotkeys | Carbon.HIToolbox (RegisterEventHotKey) |
| Display Monitoring | CGDisplayRegisterReconfigurationCallback |
| UI | SwiftUI |
- macOS 14.0+ (Sonoma)
- Swift 6 / Xcode 16+ (to build from source)
- Accessibility permission
- No SIP disable required
| Guide | Description |
|---|---|
| Getting Started | Installation, setup, first steps |
| Keyboard Shortcuts | Full shortcut reference |
| Architecture | Internals for contributors |
Contributions are welcome! Please open an issue first to discuss what you'd like to change.
git clone https://github.com/m96-chan/KTApple.git
cd KTApple
swift build
swift test