2
0

ChromeWindow.kt 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package org.mjdev.desktop.windows
  2. import androidx.compose.runtime.Composable
  3. import androidx.compose.ui.input.key.KeyEvent
  4. import androidx.compose.ui.unit.Dp
  5. import androidx.compose.ui.unit.DpOffset
  6. import androidx.compose.ui.unit.DpSize
  7. import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
  8. import org.mjdev.desktop.extensions.Compose.isDesign
  9. import org.mjdev.desktop.helpers.keyevents.GlobalKeyListener.Companion.globalKeyEventHandler
  10. import org.mjdev.desktop.helpers.keyevents.KeyEventHandler
  11. import org.mjdev.desktop.helpers.mouseevents.GlobalMouseListener.Companion.globalMouseEventHandler
  12. import org.mjdev.desktop.helpers.mouseevents.MouseEventHandler
  13. import org.mjdev.desktop.windows.ChromeWindowState.Companion.rememberChromeWindowState
  14. import org.mjdev.desktop.windows.ChromeWindowState.Companion.rememberWnState
  15. import org.mjdev.desktop.windows.ChromeWindowState.Companion.updateWindowState
  16. @Suppress("FunctionName")
  17. @Composable
  18. fun ChromeWindow(
  19. name: String? = null,
  20. visible: Boolean = true,
  21. transparent: Boolean = true,
  22. // Ask the compositor to blur whatever is rendered below this window (needs a compositor
  23. // built with scenefx and a window with transparent pixels, see WindowTitle).
  24. blur: Boolean = false,
  25. resizable: Boolean = false,
  26. enabled: Boolean = true,
  27. focusable: Boolean = true,
  28. alwaysOnTop: Boolean = false,
  29. alwaysOnBottom: Boolean = false,
  30. position: DpOffset = DpOffset.Zero,
  31. size: DpSize = DpSize(Dp.Unspecified, Dp.Unspecified),
  32. onCloseRequest: () -> Unit = {},
  33. onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },
  34. onKeyEvent: (KeyEvent) -> Boolean = { false },
  35. onCreated: ChromeWindowState.() -> Unit = {},
  36. onOpened: ChromeWindowState.() -> Unit = {},
  37. onClosed: ChromeWindowState.() -> Unit = {},
  38. onFocusChange: ChromeWindowState.(Boolean) -> Unit = {},
  39. windowState: ChromeWindowState =
  40. rememberChromeWindowState(
  41. visible = visible,
  42. size = size,
  43. position = position,
  44. ),
  45. isGlobalKeyHandlerEnabled: () -> Boolean = { false },
  46. onGlobalKey: KeyEventHandler.() -> Unit = {},
  47. isGlobalMouseHandlerEnabled: () -> Boolean = { false },
  48. onGlobalMouse: MouseEventHandler.() -> Unit = {},
  49. content: @Composable () -> Unit = {},
  50. ) = withDesktopContext {
  51. globalKeyEventHandler(
  52. isEnabled = isGlobalKeyHandlerEnabled,
  53. block = onGlobalKey,
  54. )
  55. globalMouseEventHandler(
  56. enabled = isGlobalMouseHandlerEnabled,
  57. block = onGlobalMouse,
  58. )
  59. if (isDesign) {
  60. content()
  61. } else {
  62. val wnState = rememberWnState()
  63. windowState.onOpened {
  64. onOpened(windowState)
  65. }
  66. windowState.onClosed(onClosed)
  67. windowState.onFocusChange(onFocusChange)
  68. Window(
  69. name = name,
  70. onCreated = { onCreated(windowState) },
  71. onOpened = { onOpened(windowState) },
  72. onClosed = { onClosed(windowState) },
  73. onCloseRequest = onCloseRequest,
  74. state = windowState,
  75. visible = visible,
  76. // Encode the window role into the title as "mjdev::<name>" so the mjdev compositor
  77. // can layer shell windows correctly (background / panel / top). The window is
  78. // undecorated, so the title is never visible; on a non-mjdev WM it is just ignored.
  79. title = WindowTitle.encode(name, blur),
  80. icon = null,
  81. undecorated = true,
  82. transparent = transparent,
  83. resizable = resizable,
  84. enabled = enabled,
  85. focusable = focusable,
  86. alwaysOnTop = alwaysOnTop,
  87. alwaysOnBottom = alwaysOnBottom,
  88. onPreviewKeyEvent = onPreviewKeyEvent,
  89. onKeyEvent = onKeyEvent,
  90. stateHelper = windowState.stateHelper,
  91. focusHelper = windowState.focusHelper,
  92. content = {
  93. // exposes the live screen bounds so glass backdrops can line up with the wallpaper
  94. ProvideWindowBounds(window) {
  95. content()
  96. }
  97. },
  98. )
  99. updateWindowState(visible, wnState, windowState)
  100. }
  101. }