Kotlin Window Management is a library that wraps OS-specific window management APIs into an idiomatic Kotlin interface.
The library serves as a foundation for the UI framework used in Air and will later provide an OS integration layer for Compose for Desktop.
- Provide a simple Kotlin API for OS features needed to build desktop applications
- Support all major desktop platforms: Linux (both X11 and Wayland), macOS and Windows
- Flatten OS quirks or at least document them
- Provide a safe API. Incorrect usage of the API should lead to Kotlin exceptions but not crashes
- Provide rendering contexts compatible with Skia, e.g., via skiko
- Make it Kotlin Multiplatform in the future
- Providing bindings for Android or iOS, they are too different from desktop
- Bindings for browser APIs
- API alignment across platforms. Desktop platforms differ in their capabilities; we do not intend to hide these differences
✅ - implemented
🚧 - in progress, partially implemented
❌ - not implemented yet
➖ - not applicable
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Run event loop | ✅ | ✅ | ✅ | ✅ |
| Invoke on Main thread | ✅ | ✅ | ✅ | ✅ |
| List screens | ✅ | ✅ | ✅ | |
| Terminate application | ✅ | ✅ | ✅ | ✅ |
| Show notification | ✅ | ✅ | ❌ | ✅ |
| System tray | ❌ | ❌ | ❌ | ❌ |
| Application icon | ✅ | ➖ | 🚧 | ❌ |
| Application menu | ✅ | ❌ | ➖ | ❌ |
| Accessibility | ❌ | ❌ | ❌ | ❌ |
| File choose dialog | ✅ | ✅ | 🚧 | 🚧 |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Position | ✅ | ➖ (startMove) |
✅ | ❌ (startMove) |
| Size | ✅ | ➖ (startResize) |
✅ | ❌ (startResize) |
| Max/Min size | ✅ | ✅ | ✅ | 🚧 (setMinSize) |
| Content size | ✅ | ➖ | ✅ | ❌ |
| Current screen | ✅ | ✅ | ✅ | ❌ |
| Full screen | ✅ | ✅ | ❌ | ✅ |
| Maximize/Minimize | ✅ | ✅ | ✅ | ✅ |
| Request focus | ✅ | ✅ | 🚧 | ✅ |
| Set cursor icon | ✅ | ✅ | ✅ | ✅ |
| Transparency | ✅ | ✅ | ✅ | ✅ |
| Background effects | ✅ | ❌ | ✅ | ❌ |
| Close window | ✅ | ✅ | ✅ | ✅ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Metal | ✅ | ➖ | ➖ | ➖ |
| ANGLE | ❌ | ❌ | ✅(DX11) | ❌ |
| DirectX12 | ➖ | ➖ | ❌ | ➖ |
| OpenGL | ➖ | ✅ | ❌ | ✅ |
| Vulkan | ❌ | ❌ | ❌ | ❌ |
| Software | ❌ | ✅ | ✅(WARP) | ❌ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| KeyDown | ✅ | ✅ | ✅ | ✅ |
| KeyUp | ✅ | ✅ | ✅ | ✅ |
| ModifiersChanged | ✅ | ✅ | ➖ | ✅ |
| MouseMoved | ✅ | ✅ | ✅ | ✅ |
| MouseDragged | ✅ | ❌ | ❌ | ❌ |
| MouseEntered | ✅ | ✅ | ✅ | ✅ |
| MouseExited | ✅ | ✅ | ✅ | ✅ |
| MouseDown | ✅ | ✅ | ✅ | ✅ |
| MouseUp | ✅ | ✅ | ✅ | ✅ |
| ScrollWheel | ✅ | ✅ | ✅ | ✅ |
| WindowSizeChange | ✅ | ✅ | ✅ | ✅ |
| WindowResize | ✅ | ✅ | ✅ | ✅ |
| WindowMove | ✅ | ➖ | ✅ | ❌ |
| WindowFocusChange | ✅ | ✅ | ✅ | ✅ |
| WindowCloseRequest | ✅ | ✅ | ✅ | ✅ |
| WindowFullScreenToggle | ✅ | ✅ | ❌ | ✅ |
| WindowChangedOcclusionState | ✅ | ❌ | 🚧 | ❌ |
| DisplayConfigurationChange | ✅ | ✅ | 🚧 | ❌ |
| ApplicationOpenURL | ✅ | ✅ | ✅ | ✅ |
| ApplicationAppearanceChange | ✅ | ✅ | ✅ | ✅ |
| ApplicationDidFinishLaunching | ✅ | ✅ | ✅* | ✅ |
* On Windows, a callback is currently enqueued before starting the event loop. This may be replaced with an ApplicationDidFinishLaunching event in the future.
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| isDark/isLight | ✅ | ✅ | ✅ | ✅ |
| Sync with OS | ✅ | ✅ | ✅ | ✅ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Custom text input context | ✅ | ✅ | ❌ | ✅ |
| Order emoji popup | ✅ | ➖ | ❌ | ❌ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Simple text copy/paste | ✅ | ✅ | 🚧 | ✅ |
| Copy files | ✅ | ✅ | 🚧 | ✅ |
| System defined clipboard types | ✅ | ➖ | ❌ | ✅ |
| Custom binary clipboard content | ✅ | ✅ | ❌ | ✅ |
| Lazy fetch of clipboard content | ❌ | ✅ | ❌ | ✅ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| ScreenId | ✅ | ✅ | ➖ | ✅ |
| IsPrimary | ✅ | ❌ | ✅ | ❌ |
| Name | ✅ | ✅ | ✅ | ✅ |
| Origin | ✅ | ✅ | ✅ | ✅ |
| Size | ✅ | ✅ | ✅ | ✅ |
| Scale | ✅ | ✅ | ✅ | ✅ |
| FPS | ✅ | ✅ | ✅ | ✅ |
| Color space | ❌ | ❌ | ❌ | ❌ |
| Persistent identity | ✅ | 🚧 | ❌ | ❌ |
| MacOS | Wayland | Windows | X11 | |
|---|---|---|---|---|
| Window as drag target | ✅ | ✅ | ❌ | ✅ |
| Drag entered | ✅ | ✅ | ❌ | ✅ |
| Drag updated | ✅ | ✅ | ❌ | ✅ |
| Drag exited | ✅ | ✅ | ❌ | ✅ |
| Drag performed | ✅ | ✅ | ❌ | ✅ |
| Drag source | ✅ | ✅ | ❌ | ✅ |
Many libraries tackle the same problem from different angles, but each makes slightly different trade-offs compared to KDT.
To name a few: