Browse Source

atomic absolute geometry, kill the reveal line bug

Milan Jurkulak 3 months ago
parent
commit
e0b4f86230

+ 7 - 28
ai-todo.txt

@@ -19,32 +19,11 @@
       preview {
   -------------------------------------------
 
-- 2 - build cache hapruje, neustale se pri buildu stahuju uz stahnute knihovny, to je antipattern gradle.
-    mozna opraveno skontroluj.
+- tooltip ma u control center spatne souradnice vypada tp debilne, tos neotestoval.
+- v runDesktop nefunguje rotace pozadi, z jakyho duvodu kurnajs kdyz v runDesktopNested to jde?
+  pujde to na android vubec kdyz je to takhle doslova rozmrdane?
+- v runDesktop nefunguje bottom bar, dock se NIKDY nezobrazi. muzes se kurva jebat dolu mysi kolik kurva chces.
+- uplne nova skurvena novinka je ze taby v controlbare jsou jaksi neklikatelne do pici tu!!! resp. na ikonku je nutne kliknut 658765678x aby se tab pojebany prepol. do pici.
+- vnc - zatim netestuju nemam nervy resit ze to istotne nejde, nebo jde mozna tak na 1/10, to otestuju pozdejc.
+- ostatni jsem kuli dojebanemu vsemu cos dojebat mohl otestovat nemohl
 
-- 3 - buildAll konci : Build Fail, skontrolovat
-
-- 4 -  chyba asi gradle tasku nejspis: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 186117 (apt-get),
-  skontrolovat generovani iso a vse kde se pozuivaji commandy linuxu
-
-- 5 - tooltip v desktopu vyhodit stavajici logiku a tooltip bude samostatne auto hide (fadeout and delay) chromewindow.
-
-- 6 -  when control center is shown and then user is going to a dock bottom bar, dock bottom bar
-  is below control center, focus jvm issue. fix it.
-
-- 7 - bottom bar is show in center of desktop, this should never happen.
-  your fixes little bit improve stability but this shows thats not enough.
-
-- 8 - memory widget have time to time unstable color, diferrent on another in some cases.
-
-- 9 - stabilize mouse focuses and events, this is probably done. check it by runDesktopNested
-   and by simulating mouse moves and clicks and key buttons, there is already built interface in composer i think
-
-- 10 - handles that are on sliding windows change to 12dp please, there is 9dp i think yet.
-
-- 11 - in log, when building, there is a lot of warnings and errors, i want to have
-  clean log  if possible.
-
-- 12 - control center, when shown should hide menu and bottom bar if it is visible.
-
-- 13 - remote desktop or a connection aka VNC (any standardized protocol) to desktop by ip address, aka X11

BIN
fix-it/Snímek obrazovky z 2026-06-15 20-54-18.png


BIN
fix-it/Snímek obrazovky z 2026-06-15 21-05-48.png


BIN
fix-it/Snímek obrazovky z 2026-06-16 09-44-51.png


BIN
fix-it/Snímek obrazovky z 2026-06-16 09-58-11.png


+ 9 - 17
shared/src/desktopMain/kotlin/org/mjdev/desktop/components/dockbar/DockBarWindow.kt

@@ -95,12 +95,11 @@ fun DockBarWindow(
         )
     }
     val position by rememberComputed(size) {
-        // Bottom anchor that survives the bottom-right moveBy in ChromeWindowState.size:
-        // start at (containerW, containerH); the first 0 -> size grow's moveBy lands it at
-        // (containerW - width, containerH - height) = (0, containerH - height).
+        // True absolute bottom-anchored top-left: (0, containerH - height). Applied atomically
+        // via panelState.applyBounds so it never races the size change (no relative moveBy).
         DpOffset(
-            containerSize.width,
-            containerSize.height,
+            0.dp,
+            containerSize.height - size.height,
         )
     }
     val mouseRange by rememberCalculated(
@@ -144,8 +143,7 @@ fun DockBarWindow(
         onFocusChange = onFocusChange,
         windowState = panelState,
         onCreated = {
-            panelState.position = position
-            panelState.size = size
+            runAsync { panelState.applyBounds(position, size) }
         },
         isGlobalKeyHandlerEnabled = {
             panelState.isVisible && panelState.enabled
@@ -226,17 +224,11 @@ fun DockBarWindow(
             },
         )
     }
+    // Single atomic driver for the dock's geometry: position + size applied absolutely together
+    // on every change, so the "grew to full height but stayed at the collapsed anchor -> only a
+    // 12px line visible" race can't happen.
     LaunchedEffect(size, position) {
-        panelState.size = size
-        // Deterministic bottom anchor: the size setter's relative moveBy dance can drift
-        // when show/hide flips interleave (the bar then lands mid-screen). Re-pinning the
-        // absolute position after every size change makes the final geometry always
-        // (0, containerH - height), whatever the intermediate moves did.
-        panelState.position =
-            DpOffset(
-                0.dp,
-                containerSize.height - size.height,
-            )
+        panelState.applyBounds(position, size)
     }
 }
 

+ 28 - 2
shared/src/desktopMain/kotlin/org/mjdev/desktop/windows/ChromeWindowState.kt

@@ -82,11 +82,15 @@ open class ChromeWindowState(
     val isFocused
         get() = window?.isFocused ?: false
 
+    // Guard: when true the position/size setters only update the backing field and skip their
+    // async apply coroutines — [applyBounds] is driving the window directly and atomically.
+    private var applyingBounds = false
+
     override var position: DpOffset = position
         set(value) {
             Log.d("ChromeWindow position: $field -> $value")
             field = value
-            if (isCreated) {
+            if (isCreated && !applyingBounds) {
                 scope.launch {
                     setPosition(value)
                 }
@@ -98,7 +102,7 @@ open class ChromeWindowState(
             Log.d("ChromeWindow size: $field -> $value")
             val oldSize = field
             field = value
-            if (isCreated) {
+            if (isCreated && !applyingBounds) {
                 scope.launch {
                     moveBy(
                         value.width - oldSize.width,
@@ -109,6 +113,28 @@ open class ChromeWindowState(
             }
         }
 
+    /**
+     * Sets position AND size to absolute values in ONE ordered coroutine, with no relative
+     * moveBy. The default reactive setters each launch their own coroutine and the size setter
+     * uses a relative moveBy — for a bottom-anchored window (the dock) those race and land the
+     * window at the wrong position/size (grown to full height but still at the collapsed anchor,
+     * so only a thin sliver is on-screen). Driving both absolutely here is order-independent, so
+     * the final geometry is always exactly `(position, size)`.
+     */
+    suspend fun applyBounds(
+        position: DpOffset,
+        size: DpSize,
+    ) {
+        applyingBounds = true
+        this.size = size // backing field only — no async apply (guard is set)
+        this.position = position
+        applyingBounds = false
+        // size first (AWT keeps the top-left fixed and extends downward), then the absolute
+        // position pulls the top up to the anchor — the reverse would flash off-screen.
+        setSize(size)
+        setPosition(position)
+    }
+
     override var isMinimized: Boolean = false
 
     val x: Dp