or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-integration.mdindex.mdmaterial-design.mdresource-management.mdstate-management.mdui-components.mdwindow-management.md

window-management.mddocs/

0

# Window Management

1

2

Window management in Compose Multiplatform for WASM/JS centers around the `CanvasBasedWindow` function, which creates the main application window that renders to an HTML5 Canvas element. This approach provides full control over the rendering surface while integrating seamlessly with web browsers.

3

4

## Core Window Management

5

6

### CanvasBasedWindow

7

8

The primary function for creating WASM/JS applications.

9

10

```kotlin { .api }

11

@OptIn(ExperimentalComposeUiApi::class)

12

fun CanvasBasedWindow(

13

canvasElementId: String? = null,

14

title: String = "Compose Application",

15

content: @Composable () -> Unit

16

)

17

```

18

19

**Parameters:**

20

- `canvasElementId`: ID of the HTML canvas element to render into. If null, uses default "ComposeTarget"

21

- `title`: Window title (affects browser tab title)

22

- `content`: Composable content to display in the window

23

24

**Usage:**

25

```kotlin { .api }

26

@OptIn(ExperimentalComposeUiApi::class)

27

fun main() {

28

CanvasBasedWindow("MyCanvas") {

29

MaterialTheme {

30

Text("Hello WASM!")

31

}

32

}

33

}

34

```

35

36

### Canvas Element Setup

37

38

The HTML document must contain a canvas element with the specified ID:

39

40

```html

41

<!DOCTYPE html>

42

<html>

43

<head>

44

<title>My Compose App</title>

45

<meta charset="UTF-8">

46

</head>

47

<body>

48

<canvas id="MyCanvas"></canvas>

49

<script src="your-app.js"></script>

50

</body>

51

</html>

52

```

53

54

## Application Lifecycle

55

56

### Initialization Sequence

57

58

1. **WASM Module Loading**: Browser loads and initializes the WASM module

59

2. **Canvas Acquisition**: Application locates and binds to the canvas element

60

3. **Compose Runtime Setup**: Initializes the Compose runtime system

61

4. **Content Rendering**: Begins rendering the composable content

62

63

### Main Function Pattern

64

65

```kotlin { .api }

66

@OptIn(ExperimentalComposeUiApi::class)

67

fun main() {

68

// Optional: Configure resources before window creation

69

configureWebResources {

70

resourcePathMapping { path -> "./$path" }

71

}

72

73

// Create the main application window

74

CanvasBasedWindow(

75

canvasElementId = "ComposeTarget",

76

title = "My Application"

77

) {

78

// Your application content

79

App()

80

}

81

}

82

```

83

84

## Window Configuration

85

86

### Canvas Element Targeting

87

88

**Default Behavior:**

89

```kotlin { .api }

90

CanvasBasedWindow("ComposeTarget") { /* content */ }

91

```

92

93

**Custom Canvas ID:**

94

```kotlin { .api }

95

CanvasBasedWindow("myCustomCanvas") { /* content */ }

96

```

97

98

**Auto-Detection (null ID):**

99

```kotlin { .api }

100

CanvasBasedWindow(canvasElementId = null) { /* content */ }

101

// Uses default "ComposeTarget" ID

102

```

103

104

### Title Management

105

106

The title parameter affects:

107

- Browser tab title

108

- Window identification in browser developer tools

109

- Accessibility tools

110

111

```kotlin { .api }

112

CanvasBasedWindow(

113

canvasElementId = "app",

114

title = "My WASM Application - ${BuildConfig.VERSION}"

115

) {

116

// Application content

117

}

118

```

119

120

## Experimental APIs

121

122

### ExperimentalComposeUiApi

123

124

All window management functions require the experimental API opt-in:

125

126

```kotlin { .api }

127

@file:OptIn(ExperimentalComposeUiApi::class)

128

129

import androidx.compose.ui.ExperimentalComposeUiApi

130

```

131

132

This annotation indicates that WASM support is experimental and APIs may change.

133

134

## Canvas Integration

135

136

### Canvas Properties

137

138

The canvas element receives these properties:

139

- **Full event handling**: Mouse, keyboard, touch events

140

- **Automatic sizing**: Canvas resizes with browser window

141

- **High DPI support**: Automatic pixel density detection

142

- **Focus management**: Keyboard focus and tab navigation

143

144

### CSS Styling

145

146

Style the canvas element for proper display:

147

148

```css

149

#ComposeTarget {

150

width: 100vw;

151

height: 100vh;

152

display: block;

153

margin: 0;

154

padding: 0;

155

}

156

157

body {

158

margin: 0;

159

padding: 0;

160

overflow: hidden;

161

}

162

```

163

164

## Error Handling

165

166

### Common Issues

167

168

**Canvas Not Found:**

169

```

170

Error: Canvas element with ID 'ComposeTarget' not found

171

```

172

- Ensure canvas element exists in HTML

173

- Verify ID matches exactly (case-sensitive)

174

- Check that script loads after canvas element

175

176

**WASM Initialization Failure:**

177

```

178

Error: Failed to instantiate WebAssembly module

179

```

180

- Verify browser supports WASM GC

181

- Check MIME type configuration

182

- Ensure WASM file is served correctly

183

184

**Resource Loading Issues:**

185

```

186

Error: Failed to load application resources

187

```

188

- Configure web resources before window creation

189

- Check resource path mappings

190

- Verify CORS configuration

191

192

### Debug Strategies

193

194

**Canvas Detection:**

195

```kotlin { .api }

196

// Check if canvas exists before creating window

197

val canvas = document.getElementById("ComposeTarget")

198

if (canvas == null) {

199

console.error("Canvas element not found!")

200

return

201

}

202

203

CanvasBasedWindow("ComposeTarget") { /* content */ }

204

```

205

206

**Console Logging:**

207

```kotlin { .api }

208

fun main() {

209

console.log("Starting WASM application...")

210

211

CanvasBasedWindow("ComposeTarget") {

212

console.log("Window content initialized")

213

App()

214

}

215

}

216

```

217

218

## Performance Considerations

219

220

### Rendering Optimization

221

222

- **Canvas sizing**: Use CSS for responsive sizing, avoid frequent resize operations

223

- **Event handling**: Minimize event listener overhead

224

- **Animation**: Use Compose animation APIs for optimal performance

225

226

### Memory Management

227

228

- **Canvas cleanup**: Browser automatically manages canvas memory

229

- **Event listeners**: Automatically cleaned up when window closes

230

- **Resource cleanup**: Use `DisposableEffect` for manual cleanup

231

232

```kotlin { .api }

233

@Composable

234

fun App() {

235

DisposableEffect(Unit) {

236

val cleanup = { /* cleanup code */ }

237

onDispose { cleanup() }

238

}

239

240

// App content

241

}

242

```

243

244

## Integration with Web Platform

245

246

### Browser Events

247

248

Canvas automatically receives and translates:

249

- **Mouse events**: Click, move, wheel

250

- **Keyboard events**: Key press, release, modifiers

251

- **Touch events**: Touch start, move, end

252

- **Focus events**: Focus in, focus out

253

254

### Accessibility

255

256

- **Screen reader support**: Canvas content is accessible

257

- **Keyboard navigation**: Full tab navigation support

258

- **High contrast**: Automatic high contrast mode detection

259

- **Zoom support**: Responds to browser zoom settings

260

261

### Browser API Access

262

263

Access browser APIs from window content:

264

265

```kotlin { .api }

266

@Composable

267

fun BrowserIntegration() {

268

LaunchedEffect(Unit) {

269

// Access browser window

270

val title = window.document.title

271

272

// Modify browser state

273

window.history.pushState(null, "", "/new-route")

274

275

// Use browser APIs

276

val userLanguage = window.navigator.language

277

}

278

}

279

```