Просмотр исходного кода

bar and control center raise on reveal instead of always on top

Milan Jurkulak 3 месяцев назад
Родитель
Сommit
f0bf5541d8

+ 3 - 3
shared/src/desktopMain/kotlin/org/mjdev/desktop/components/appsmenu/AppsMenuWindow.kt

@@ -81,9 +81,9 @@ fun AppsMenuWindow(
     ChromeWindow(
         name = "AppsMenu",
         visible = menuState.isVisible,
-        // Always on top like the bar/control center — a shell surface that must never end up
-        // behind the desktop window.
-        alwaysOnTop = true,
+        // Not alwaysOnTop: DesktopState's focusOnShow (see MainWindow's register call) already
+        // raises + focuses this window on open — a normal toFront(), not a permanent OS-level
+        // pin that would keep it above external apps too.
         size = size,
         position = position,
         windowState = menuState,

+ 3 - 3
shared/src/desktopMain/kotlin/org/mjdev/desktop/components/controlcenter/ControlCenterWindow.kt

@@ -60,9 +60,9 @@ fun ControlCenterWindow(
     ChromeWindow(
         name = "ControlCenter",
         visible = true,
-        // Always on top: the control center (and its right-edge reveal handle) must stay above the
-        // desktop window so the handle is always reachable.
-        alwaysOnTop = true,
+        // Not alwaysOnTop: DesktopState's focusOnShow (see MainWindow's register call) already
+        // raises + focuses this window whenever the reveal hotspot is entered — a normal
+        // toFront(), not a permanent OS-level pin that would keep it above external apps too.
         windowState = controlCenterState,
         onFocusChange = onFocusChange,
         position = position,

+ 5 - 4
shared/src/desktopMain/kotlin/org/mjdev/desktop/components/dockbar/DockBarWindow.kt

@@ -105,10 +105,11 @@ fun DockBarWindow(
     ChromeWindow(
         name = "DockBar",
         visible = true,
-        // Always on top: the bar (and its thin reveal handle when collapsed) must sit above the
-        // desktop window, or a click that raises the desktop would bury the handle and it stops
-        // working.
-        alwaysOnTop = true,
+        // Not alwaysOnTop: that pins it above every other app window permanently, so an
+        // external app (e.g. a calculator) can never cover it even when it should. Staying
+        // above the desktop is instead handled by focus-on-reveal (see DesktopState's
+        // focusOnShow -> ChromeWindowState.focus() -> toFront()), a normal raise, not a
+        // persistent OS-level pin.
         position = position,
         size = size,
         onFocusChange = onFocusChange,

+ 4 - 0
shared/src/desktopMain/kotlin/org/mjdev/desktop/components/main/MainWindow.kt

@@ -104,6 +104,10 @@ fun MainWindow() = withDesktopContext {
             kind = SurfaceKind.Bar,
             window = panelState,
             bounds = { rectOf(panelState) },
+            // raise (toFront, no keyboard focus steal) on reveal so it visibly comes back above
+            // whatever app window was overlapping it, without a permanent alwaysOnTop pin that
+            // would keep it above external apps even when it shouldn't be.
+            raiseOnShow = true,
             // reveal strip along whichever edge the dock lives on (only used when overlapped).
             // Derived from PanelLocation so drag-to-edge later needs no change here.
             revealHotspot = {

+ 6 - 2
shared/src/desktopMain/kotlin/org/mjdev/desktop/state/DesktopState.kt

@@ -39,6 +39,7 @@ class DesktopState(
         val bounds: () -> ScreenRect,
         val revealHotspot: () -> ScreenRect?,
         val focusOnShow: Boolean,
+        val raiseOnShow: Boolean,
         val onApply: (visible: Boolean) -> Unit,
     )
 
@@ -60,9 +61,10 @@ class DesktopState(
         bounds: () -> ScreenRect,
         revealHotspot: () -> ScreenRect? = { null },
         focusOnShow: Boolean = false,
+        raiseOnShow: Boolean = false,
         onApply: (visible: Boolean) -> Unit = {},
     ) {
-        surfaces[kind] = Surface(window, bounds, revealHotspot, focusOnShow, onApply)
+        surfaces[kind] = Surface(window, bounds, revealHotspot, focusOnShow, raiseOnShow, onApply)
         reconcile()
     }
 
@@ -185,8 +187,10 @@ class DesktopState(
             if (visible) {
                 surface.window.show()
                 // grab keyboard focus on open so Escape reaches it right away (control center /
-                // menu). The bar never steals focus.
+                // menu). The bar never steals focus, only raises (see raiseOnShow) so an
+                // always-on-top pin isn't needed to stay above whatever app was on top before.
                 if (surface.focusOnShow) surface.window.focus()
+                if (surface.raiseOnShow) surface.window.raise()
             } else {
                 surface.window.hide(force = true)
             }

+ 8 - 0
shared/src/desktopMain/kotlin/org/mjdev/desktop/windows/ChromeWindowState.kt

@@ -208,6 +208,14 @@ open class ChromeWindowState(
         }.onFailure { e -> Log.e(e) }
     }
 
+    /** Raises the window above others without stealing keyboard focus (unlike [focus]). */
+    suspend fun raise() {
+        runCatching {
+            Log.d("ChromeWindow raise: ${geom()}")
+            window?.toFront()
+        }.onFailure { e -> Log.e(e) }
+    }
+
     suspend fun showOrFocus() {
         if (isNotVisible) {
             show()