diff --git a/examples/README.md b/examples/README.md
index 9897c6a551d..72e5ae0f1d4 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -8,5 +8,4 @@
| [Todoapp Lite](todoapp-lite) | A simple todo app fully based on Compose | Android, iOS, Desktop |
| [Nav Cupcake](nav_cupcake) | Multiscreen app to demonstrate the use of Compose Navigation | Android, iOS, Desktop |
| [Issues tracker](issues) | GitHub issue tracker with an adaptive UI and ktor-client | Android, Desktop |
-| [Notepad](notepad) | Notepad, using the Composable Window API | Desktop |
| [HTML based samples](html/README.md) | Examples written with Compose HTML Library |
diff --git a/examples/notepad/.gitignore b/examples/notepad/.gitignore
deleted file mode 100644
index ba8435b9c5c..00000000000
--- a/examples/notepad/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-*.iml
-.gradle
-/local.properties
-/.idea
-/.idea/caches
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
-/.idea/navEditor.xml
-/.idea/assetWizardSettings.xml
-.DS_Store
-build/
-/captures
-.externalNativeBuild
-.cxx
\ No newline at end of file
diff --git a/examples/notepad/.run/desktop.run.xml b/examples/notepad/.run/desktop.run.xml
deleted file mode 100644
index 4f432247113..00000000000
--- a/examples/notepad/.run/desktop.run.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/examples/notepad/README.md b/examples/notepad/README.md
deleted file mode 100644
index 15b106a9f58..00000000000
--- a/examples/notepad/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Notepad example for desktop written in Compose for Desktop library, using Composable Window API
-
-### Running desktop application
-* To run, launch command: `./gradlew run`
-* Or choose **desktop** configuration in IDE and run it.
- 
-
-### Building native desktop distribution
-```
-./gradlew packageDistributionForCurrentOS
-# outputs are written to build/compose/binaries
-```
-
\ No newline at end of file
diff --git a/examples/notepad/build.gradle.kts b/examples/notepad/build.gradle.kts
deleted file mode 100644
index 258ba6c619e..00000000000
--- a/examples/notepad/build.gradle.kts
+++ /dev/null
@@ -1,37 +0,0 @@
-import org.jetbrains.compose.desktop.application.dsl.TargetFormat
-
-plugins {
- kotlin("jvm")
- kotlin("plugin.compose")
- id("org.jetbrains.compose")
-}
-
-repositories {
- google()
- mavenCentral()
- maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
-}
-
-dependencies {
- implementation(compose.desktop.currentOs)
- implementation(compose.materialIconsExtended)
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.0")
-}
-
-compose.desktop {
- application {
- mainClass = "MainKt"
-
- nativeDistributions {
- targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
- packageName = "Notepad"
- packageVersion = "1.0.0"
-
- windows {
- menu = true
- // see https://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html
- upgradeUuid = "61DAB35E-17CB-43B0-81D5-B30E1C0830FA"
- }
- }
- }
-}
diff --git a/examples/notepad/gradle.properties b/examples/notepad/gradle.properties
deleted file mode 100644
index fd34d88378e..00000000000
--- a/examples/notepad/gradle.properties
+++ /dev/null
@@ -1,6 +0,0 @@
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
-kotlin.code.style=official
-kotlin.version=2.1.20
-compose.version=1.8.2
-org.gradle.configuration-cache=true
-org.gradle.caching=true
diff --git a/examples/notepad/gradle/wrapper/gradle-wrapper.jar b/examples/notepad/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 249e5832f09..00000000000
Binary files a/examples/notepad/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/examples/notepad/gradle/wrapper/gradle-wrapper.properties b/examples/notepad/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 17655d0ef2b..00000000000
--- a/examples/notepad/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
diff --git a/examples/notepad/gradlew b/examples/notepad/gradlew
deleted file mode 100755
index a69d9cb6c20..00000000000
--- a/examples/notepad/gradlew
+++ /dev/null
@@ -1,240 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright © 2015-2021 the original authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-##############################################################################
-#
-# Gradle start up script for POSIX generated by Gradle.
-#
-# Important for running:
-#
-# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
-# noncompliant, but you have some other compliant shell such as ksh or
-# bash, then to run this script, type that shell name before the whole
-# command line, like:
-#
-# ksh Gradle
-#
-# Busybox and similar reduced shells will NOT work, because this script
-# requires all of these POSIX shell features:
-# * functions;
-# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
-# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
-# * compound commands having a testable exit status, especially «case»;
-# * various built-in commands including «command», «set», and «ulimit».
-#
-# Important for patching:
-#
-# (2) This script targets any POSIX shell, so it avoids extensions provided
-# by Bash, Ksh, etc; in particular arrays are avoided.
-#
-# The "traditional" practice of packing multiple parameters into a
-# space-separated string is a well documented source of bugs and security
-# problems, so this is (mostly) avoided, by progressively accumulating
-# options in "$@", and eventually passing that to Java.
-#
-# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
-# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
-# see the in-line comments for details.
-#
-# There are tweaks for specific operating systems such as AIX, CygWin,
-# Darwin, MinGW, and NonStop.
-#
-# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
-# within the Gradle project.
-#
-# You can find Gradle at https://github.com/gradle/gradle/.
-#
-##############################################################################
-
-# Attempt to set APP_HOME
-
-# Resolve links: $0 may be a link
-app_path=$0
-
-# Need this for daisy-chained symlinks.
-while
- APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
- [ -h "$app_path" ]
-do
- ls=$( ls -ld "$app_path" )
- link=${ls#*' -> '}
- case $link in #(
- /*) app_path=$link ;; #(
- *) app_path=$APP_HOME$link ;;
- esac
-done
-
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-APP_NAME="Gradle"
-APP_BASE_NAME=${0##*/}
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD=maximum
-
-warn () {
- echo "$*"
-} >&2
-
-die () {
- echo
- echo "$*"
- echo
- exit 1
-} >&2
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "$( uname )" in #(
- CYGWIN* ) cygwin=true ;; #(
- Darwin* ) darwin=true ;; #(
- MSYS* | MINGW* ) msys=true ;; #(
- NONSTOP* ) nonstop=true ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD=$JAVA_HOME/jre/sh/java
- else
- JAVACMD=$JAVA_HOME/bin/java
- fi
- if [ ! -x "$JAVACMD" ] ; then
- die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
- fi
-else
- JAVACMD=java
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
- case $MAX_FD in #(
- max*)
- MAX_FD=$( ulimit -H -n ) ||
- warn "Could not query maximum file descriptor limit"
- esac
- case $MAX_FD in #(
- '' | soft) :;; #(
- *)
- ulimit -n "$MAX_FD" ||
- warn "Could not set maximum file descriptor limit to $MAX_FD"
- esac
-fi
-
-# Collect all arguments for the java command, stacking in reverse order:
-# * args from the command line
-# * the main class name
-# * -classpath
-# * -D...appname settings
-# * --module-path (only if needed)
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if "$cygwin" || "$msys" ; then
- APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
-
- JAVACMD=$( cygpath --unix "$JAVACMD" )
-
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- for arg do
- if
- case $arg in #(
- -*) false ;; # don't mess with options #(
- /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
- [ -e "$t" ] ;; #(
- *) false ;;
- esac
- then
- arg=$( cygpath --path --ignore --mixed "$arg" )
- fi
- # Roll the args list around exactly as many times as the number of
- # args, so each arg winds up back in the position where it started, but
- # possibly modified.
- #
- # NB: a `for` loop captures its iteration list before it begins, so
- # changing the positional parameters here affects neither the number of
- # iterations, nor the values presented in `arg`.
- shift # remove old arg
- set -- "$@" "$arg" # push replacement arg
- done
-fi
-
-# Collect all arguments for the java command;
-# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-# shell script including quotes and variable substitutions, so put them in
-# double quotes to make sure that they get re-expanded; and
-# * put everything else in single quotes, so that it's not re-expanded.
-
-set -- \
- "-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
- org.gradle.wrapper.GradleWrapperMain \
- "$@"
-
-# Stop when "xargs" is not available.
-if ! command -v xargs >/dev/null 2>&1
-then
- die "xargs is not available"
-fi
-
-# Use "xargs" to parse quoted args.
-#
-# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
-#
-# In Bash we could simply go:
-#
-# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
-# set -- "${ARGS[@]}" "$@"
-#
-# but POSIX shell has neither arrays nor command substitution, so instead we
-# post-process each arg (as a line of input to sed) to backslash-escape any
-# character that might be a shell metacharacter, then use eval to reverse
-# that process (while maintaining the separation between arguments), and wrap
-# the whole thing up as a single "set" statement.
-#
-# This will of course break if any of these variables contains a newline or
-# an unmatched quote.
-#
-
-eval "set -- $(
- printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
- xargs -n1 |
- sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
- tr '\n' ' '
- )" '"$@"'
-
-exec "$JAVACMD" "$@"
diff --git a/examples/notepad/gradlew.bat b/examples/notepad/gradlew.bat
deleted file mode 100644
index f127cfd49d4..00000000000
--- a/examples/notepad/gradlew.bat
+++ /dev/null
@@ -1,91 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%"=="" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%"=="" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if %ERRORLEVEL% equ 0 goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if %ERRORLEVEL% equ 0 goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-set EXIT_CODE=%ERRORLEVEL%
-if %EXIT_CODE% equ 0 set EXIT_CODE=1
-if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
-exit /b %EXIT_CODE%
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/examples/notepad/screenshots/desktop-run-configuration.png b/examples/notepad/screenshots/desktop-run-configuration.png
deleted file mode 100644
index 3688407c6f7..00000000000
Binary files a/examples/notepad/screenshots/desktop-run-configuration.png and /dev/null differ
diff --git a/examples/notepad/screenshots/notepad.gif b/examples/notepad/screenshots/notepad.gif
deleted file mode 100644
index f289318857a..00000000000
Binary files a/examples/notepad/screenshots/notepad.gif and /dev/null differ
diff --git a/examples/notepad/settings.gradle.kts b/examples/notepad/settings.gradle.kts
deleted file mode 100644
index 377c453a535..00000000000
--- a/examples/notepad/settings.gradle.kts
+++ /dev/null
@@ -1,12 +0,0 @@
-pluginManagement {
- repositories {
- gradlePluginPortal()
- maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
- }
-
- plugins {
- kotlin("jvm").version(extra["kotlin.version"] as String)
- kotlin("plugin.compose").version(extra["kotlin.version"] as String)
- id("org.jetbrains.compose").version(extra["compose.version"] as String)
- }
-}
diff --git a/examples/notepad/src/main/kotlin/NotepadApplication.kt b/examples/notepad/src/main/kotlin/NotepadApplication.kt
deleted file mode 100644
index 1d29567ff38..00000000000
--- a/examples/notepad/src/main/kotlin/NotepadApplication.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.key
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.window.ApplicationScope
-import androidx.compose.ui.window.MenuScope
-import androidx.compose.ui.window.Tray
-import common.LocalAppResources
-import kotlinx.coroutines.launch
-import window.NotepadWindow
-
-@Composable
-fun ApplicationScope.NotepadApplication(state: NotepadApplicationState) {
- if (state.settings.isTrayEnabled && state.windows.isNotEmpty()) {
- ApplicationTray(state)
- }
-
- for (window in state.windows) {
- key(window) {
- NotepadWindow(window)
- }
- }
-}
-
-@Composable
-private fun ApplicationScope.ApplicationTray(state: NotepadApplicationState) {
- Tray(
- LocalAppResources.current.icon,
- state = state.tray,
- tooltip = "Notepad",
- menu = { ApplicationMenu(state) }
- )
-}
-
-@Composable
-private fun MenuScope.ApplicationMenu(state: NotepadApplicationState) {
- val scope = rememberCoroutineScope()
- fun exit() = scope.launch { state.exit() }
-
- Item("New", onClick = state::newWindow)
- Separator()
- Item("Exit", onClick = { exit() })
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/NotepadApplicationState.kt b/examples/notepad/src/main/kotlin/NotepadApplicationState.kt
deleted file mode 100644
index b8a1c29d345..00000000000
--- a/examples/notepad/src/main/kotlin/NotepadApplicationState.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateListOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.window.Notification
-import androidx.compose.ui.window.TrayState
-import common.Settings
-import window.NotepadWindowState
-
-@Composable
-fun rememberApplicationState() = remember {
- NotepadApplicationState().apply {
- newWindow()
- }
-}
-
-class NotepadApplicationState {
- val settings = Settings()
- val tray = TrayState()
-
- private val _windows = mutableStateListOf()
- val windows: List get() = _windows
-
- fun newWindow() {
- _windows.add(
- NotepadWindowState(
- application = this,
- path = null,
- exit = _windows::remove
- )
- )
- }
-
- fun sendNotification(notification: Notification) {
- tray.sendNotification(notification)
- }
-
- suspend fun exit() {
- val windowsCopy = windows.reversed()
- for (window in windowsCopy) {
- if (!window.exit()) {
- break
- }
- }
- }
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/common/AppResources.kt b/examples/notepad/src/main/kotlin/common/AppResources.kt
deleted file mode 100644
index 865e53e0403..00000000000
--- a/examples/notepad/src/main/kotlin/common/AppResources.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package common
-
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Description
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.staticCompositionLocalOf
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.graphics.vector.RenderVectorGroup
-import androidx.compose.ui.graphics.vector.VectorPainter
-import androidx.compose.ui.graphics.vector.rememberVectorPainter
-
-val LocalAppResources = staticCompositionLocalOf {
- error("LocalNotepadResources isn't provided")
-}
-
-@Composable
-fun rememberAppResources(): AppResources {
- val icon = rememberVectorPainter(Icons.Default.Description, tintColor = Color(0xFF2CA4E1))
- return remember { AppResources(icon) }
-}
-
-class AppResources(val icon: VectorPainter)
-
-@Composable
-fun rememberVectorPainter(image: ImageVector, tintColor: Color) =
- rememberVectorPainter(
- defaultWidth = image.defaultWidth,
- defaultHeight = image.defaultHeight,
- viewportWidth = image.viewportWidth,
- viewportHeight = image.viewportHeight,
- name = image.name,
- tintColor = tintColor,
- tintBlendMode = image.tintBlendMode,
- autoMirror = false,
- content = { _, _ -> RenderVectorGroup(group = image.root) }
- )
diff --git a/examples/notepad/src/main/kotlin/common/Settings.kt b/examples/notepad/src/main/kotlin/common/Settings.kt
deleted file mode 100644
index 4576f060d11..00000000000
--- a/examples/notepad/src/main/kotlin/common/Settings.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package common
-
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-
-class Settings {
- var isTrayEnabled by mutableStateOf(true)
- private set
-
- fun toggleTray() {
- isTrayEnabled = !isTrayEnabled
- }
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/main.kt b/examples/notepad/src/main/kotlin/main.kt
deleted file mode 100644
index c39a9258b0d..00000000000
--- a/examples/notepad/src/main/kotlin/main.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.ui.window.application
-import common.LocalAppResources
-import common.rememberAppResources
-
-fun main() = application {
- CompositionLocalProvider(LocalAppResources provides rememberAppResources()) {
- NotepadApplication(rememberApplicationState())
- }
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/util/Compose.kt b/examples/notepad/src/main/kotlin/util/Compose.kt
deleted file mode 100644
index 61eda384546..00000000000
--- a/examples/notepad/src/main/kotlin/util/Compose.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package util
-
-import androidx.compose.runtime.Applier
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Composition
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.MonotonicFrameClock
-import androidx.compose.runtime.withRunningRecomposer
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.LayoutDirection
-import kotlinx.coroutines.withContext
-import kotlinx.coroutines.yield
-
-/**
- * Helper function that allows to use Composable functions that return value in non-composable scope
- */
-@Suppress("UNCHECKED_CAST")
-suspend fun compose(content: @Composable () -> T): T {
- var result: Any? = Unit
- withContext(YieldFrameClock) {
- withRunningRecomposer { recomposer ->
- val composition = Composition(UnitApplier(), recomposer)
- composition.setContent {
- val density = Density(1f)
- val layoutDirection = LayoutDirection.Ltr
- CompositionLocalProvider(
- LocalDensity provides density,
- LocalLayoutDirection provides layoutDirection,
- ) {
- result = content()
- }
- }
- }
- }
- return result as T
-}
-
-private object YieldFrameClock : MonotonicFrameClock {
- override suspend fun withFrameNanos(
- onFrame: (frameTimeNanos: Long) -> R
- ): R {
- yield()
- return onFrame(System.nanoTime())
- }
-}
-
-private class UnitApplier : Applier {
- override val current: Unit = Unit
- override fun down(node: Unit) = Unit
- override fun up() = Unit
- override fun insertTopDown(index: Int, instance: Unit) = Unit
- override fun insertBottomUp(index: Int, instance: Unit) = Unit
- override fun remove(index: Int, count: Int) = Unit
- override fun move(from: Int, to: Int, count: Int) = Unit
- override fun clear() = Unit
- override fun onEndChanges() = Unit
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/util/Dialogs.kt b/examples/notepad/src/main/kotlin/util/Dialogs.kt
deleted file mode 100644
index 884556c54fe..00000000000
--- a/examples/notepad/src/main/kotlin/util/Dialogs.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package util
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.window.AwtWindow
-import androidx.compose.ui.window.FrameWindowScope
-import androidx.compose.ui.window.WindowScope
-import kotlinx.coroutines.DelicateCoroutinesApi
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.swing.Swing
-import java.awt.FileDialog
-import java.io.File
-import java.nio.file.Path
-import javax.swing.JOptionPane
-
-@Composable
-fun FrameWindowScope.FileDialog(
- title: String,
- isLoad: Boolean,
- onResult: (result: Path?) -> Unit
-) = AwtWindow(
- create = {
- object : FileDialog(window, "Choose a file", if (isLoad) LOAD else SAVE) {
- override fun setVisible(value: Boolean) {
- super.setVisible(value)
- if (value) {
- if (file != null) {
- onResult(File(directory).resolve(file).toPath())
- } else {
- onResult(null)
- }
- }
- }
- }.apply {
- this.title = title
- }
- },
- dispose = FileDialog::dispose
-)
-
-@OptIn(DelicateCoroutinesApi::class)
-@Composable
-fun WindowScope.YesNoCancelDialog(
- title: String,
- message: String,
- onResult: (result: AlertDialogResult) -> Unit
-) {
- DisposableEffect(Unit) {
- val job = GlobalScope.launch(Dispatchers.Swing) {
- val resultInt = JOptionPane.showConfirmDialog(
- window, message, title, JOptionPane.YES_NO_CANCEL_OPTION
- )
- val result = when (resultInt) {
- JOptionPane.YES_OPTION -> AlertDialogResult.Yes
- JOptionPane.NO_OPTION -> AlertDialogResult.No
- else -> AlertDialogResult.Cancel
- }
- onResult(result)
- }
-
- onDispose {
- job.cancel()
- }
- }
-}
-
-enum class AlertDialogResult {
- Yes, No, Cancel
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/window/NotepadWindow.kt b/examples/notepad/src/main/kotlin/window/NotepadWindow.kt
deleted file mode 100644
index e600ec24b6b..00000000000
--- a/examples/notepad/src/main/kotlin/window/NotepadWindow.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-package window
-
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.text.BasicTextField
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.window.*
-import common.LocalAppResources
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-import util.FileDialog
-import util.YesNoCancelDialog
-
-@Composable
-fun NotepadWindow(state: NotepadWindowState) {
- val scope = rememberCoroutineScope()
-
- fun exit() = scope.launch { state.exit() }
-
- Window(
- state = state.window,
- title = titleOf(state),
- icon = LocalAppResources.current.icon,
- onCloseRequest = { exit() }
- ) {
- LaunchedEffect(Unit) { state.run() }
-
- WindowNotifications(state)
- WindowMenuBar(state)
-
- // TextField isn't efficient for big text files, we use it for simplicity
- BasicTextField(
- state.text,
- state::text::set,
- enabled = state.isInit,
- modifier = Modifier.fillMaxSize()
- )
-
- if (state.openDialog.isAwaiting) {
- FileDialog(
- title = "Notepad",
- isLoad = true,
- onResult = {
- state.openDialog.onResult(it)
- }
- )
- }
-
- if (state.saveDialog.isAwaiting) {
- FileDialog(
- title = "Notepad",
- isLoad = false,
- onResult = { state.saveDialog.onResult(it) }
- )
- }
-
- if (state.exitDialog.isAwaiting) {
- YesNoCancelDialog(
- title = "Notepad",
- message = "Save changes?",
- onResult = { state.exitDialog.onResult(it) }
- )
- }
- }
-}
-
-private fun titleOf(state: NotepadWindowState): String {
- val changeMark = if (state.isChanged) "*" else ""
- val filePath = state.path ?: "Untitled"
- return "$changeMark$filePath - Notepad"
-}
-
-@Composable
-private fun WindowNotifications(state: NotepadWindowState) {
- // Usually we take into account something like LocalLocale.current here
- fun NotepadWindowNotification.format() = when (this) {
- is NotepadWindowNotification.SaveSuccess -> Notification(
- "File is saved", path.toString(), Notification.Type.Info
- )
- is NotepadWindowNotification.SaveError -> Notification(
- "File isn't saved", path.toString(), Notification.Type.Error
- )
- }
-
- LaunchedEffect(Unit) {
- state.notifications.collect {
- state.sendNotification(it.format())
- }
- }
-}
-
-@Composable
-private fun FrameWindowScope.WindowMenuBar(state: NotepadWindowState) = MenuBar {
- val scope = rememberCoroutineScope()
-
- fun save() = scope.launch { state.save() }
- fun open() = scope.launch { state.open() }
- fun exit() = scope.launch { state.exit() }
-
- Menu("File") {
- Item("New window", onClick = state::newWindow)
- Item("Open...", onClick = { open() })
- Item("Save", onClick = { save() }, enabled = state.isChanged || state.path == null)
- Separator()
- Item("Exit", onClick = { exit() })
- }
-
- Menu("Settings") {
- Item(
- if (state.settings.isTrayEnabled) "Hide tray" else "Show tray",
- onClick = state.settings::toggleTray
- )
- Item(
- if (state.window.placement == WindowPlacement.Fullscreen) "Exit fullscreen" else "Enter fullscreen",
- onClick = state::toggleFullscreen
- )
- }
-}
\ No newline at end of file
diff --git a/examples/notepad/src/main/kotlin/window/NotepadWindowState.kt b/examples/notepad/src/main/kotlin/window/NotepadWindowState.kt
deleted file mode 100644
index 74f7f725e81..00000000000
--- a/examples/notepad/src/main/kotlin/window/NotepadWindowState.kt
+++ /dev/null
@@ -1,200 +0,0 @@
-package window
-
-import NotepadApplicationState
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.window.Notification
-import androidx.compose.ui.window.WindowPlacement
-import androidx.compose.ui.window.WindowState
-import common.Settings
-import kotlinx.coroutines.*
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.receiveAsFlow
-import util.AlertDialogResult
-import java.nio.file.Path
-
-class NotepadWindowState(
- private val application: NotepadApplicationState,
- path: Path?,
- private val exit: (NotepadWindowState) -> Unit
-) {
- val settings: Settings get() = application.settings
-
- val window = WindowState()
-
- var path by mutableStateOf(path)
- private set
-
- var isChanged by mutableStateOf(false)
- private set
-
- val openDialog = DialogState()
- val saveDialog = DialogState()
- val exitDialog = DialogState()
-
- private var _notifications = Channel(0)
- val notifications: Flow get() = _notifications.receiveAsFlow()
-
- private var _text by mutableStateOf("")
-
- var text: String
- get() = _text
- set(value) {
- check(isInit)
- _text = value
- isChanged = true
- }
-
- var isInit by mutableStateOf(false)
- private set
-
- fun toggleFullscreen() {
- window.placement = if (window.placement == WindowPlacement.Fullscreen) {
- WindowPlacement.Floating
- } else {
- WindowPlacement.Fullscreen
- }
- }
-
- suspend fun run() {
- if (path != null) {
- open(path!!)
- } else {
- initNew()
- }
- }
-
- private suspend fun open(path: Path) {
- isInit = false
- isChanged = false
- this.path = path
- try {
- _text = path.readTextAsync()
- isInit = true
- } catch (e: Exception) {
- e.printStackTrace()
- text = "Cannot read $path"
- }
- }
-
- private fun initNew() {
- _text = ""
- isInit = true
- isChanged = false
- }
-
- fun newWindow() {
- application.newWindow()
- }
-
- suspend fun open() {
- if (askToSave()) {
- val path = openDialog.awaitResult()
- if (path != null) {
- open(path)
- }
- }
- }
-
- suspend fun save(): Boolean {
- check(isInit)
- if (path == null) {
- val path = saveDialog.awaitResult()
- if (path != null) {
- save(path)
- return true
- }
- } else {
- save(path!!)
- return true
- }
- return false
- }
-
- private var saveJob: Job? = null
-
- private suspend fun save(path: Path) {
- isChanged = false
- this.path = path
-
- saveJob?.cancel()
- saveJob = path.launchSaving(text)
-
- try {
- saveJob?.join()
- _notifications.trySend(NotepadWindowNotification.SaveSuccess(path))
- } catch (e: Exception) {
- isChanged = true
- e.printStackTrace()
- _notifications.trySend(NotepadWindowNotification.SaveError(path))
- }
- }
-
- suspend fun exit(): Boolean {
- return if (askToSave()) {
- exit(this)
- true
- } else {
- false
- }
- }
-
- private suspend fun askToSave(): Boolean {
- if (isChanged) {
- when (exitDialog.awaitResult()) {
- AlertDialogResult.Yes -> {
- if (save()) {
- return true
- }
- }
- AlertDialogResult.No -> {
- return true
- }
- AlertDialogResult.Cancel -> return false
- }
- } else {
- return true
- }
-
- return false
- }
-
- fun sendNotification(notification: Notification) {
- application.sendNotification(notification)
- }
-}
-
-@OptIn(DelicateCoroutinesApi::class)
-private fun Path.launchSaving(text: String) = GlobalScope.launch {
- writeTextAsync(text)
-}
-
-private suspend fun Path.writeTextAsync(text: String) = withContext(Dispatchers.IO) {
- toFile().writeText(text)
-}
-
-private suspend fun Path.readTextAsync() = withContext(Dispatchers.IO) {
- toFile().readText()
-}
-
-sealed class NotepadWindowNotification {
- class SaveSuccess(val path: Path) : NotepadWindowNotification()
- class SaveError(val path: Path) : NotepadWindowNotification()
-}
-
-class DialogState {
- private var onResult: CompletableDeferred? by mutableStateOf(null)
-
- val isAwaiting get() = onResult != null
-
- suspend fun awaitResult(): T {
- onResult = CompletableDeferred()
- val result = onResult!!.await()
- onResult = null
- return result
- }
-
- fun onResult(result: T) = onResult!!.complete(result)
-}
\ No newline at end of file
diff --git a/examples/validateExamples.sh b/examples/validateExamples.sh
index 6571905176f..7a044d6dc62 100755
--- a/examples/validateExamples.sh
+++ b/examples/validateExamples.sh
@@ -23,7 +23,6 @@ runGradle chat packageDistributionForCurrentOS
runGradle codeviewer packageDistributionForCurrentOS
runGradle imageviewer packageDistributionForCurrentOS
runGradle issues packageDistributionForCurrentOS
-runGradle notepad packageDistributionForCurrentOS
runGradle todoapp-lite packageDistributionForCurrentOS
runGradle graphics-2d packageDistributionForCurrentOS
runGradle jetsnack packageDistributionForCurrentOS