From ce81d429164a1095237c1c3764a790cce6794837 Mon Sep 17 00:00:00 2001 From: karim Date: Tue, 19 May 2026 04:40:05 +0200 Subject: [PATCH] Window-Layout Auto-Apply: skip wenn bereits persistent angewendet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cold-Start-Perf: das Auto-Apply von DOSSIERUIV0.2 lief bei jedem Rhino- Start einmal — Rhino's Window-Layout-Restore mountet dabei mehrere Panels neu (zweite Mount-Welle, ~70 ms gemessen + Rhino-internes Re- Layout). Rhino merkt sich die Window-Anordnung aber selbst persistent nach dem ersten erfolgreichen Apply. Loesung: zweite Persistenz-Ebene neben sticky. - sticky["_dossier_layout_applied"] bleibt fuer process-lifetime (verhindert Endlos-Loops bei Re-Mounts) - cfg["windowLayoutLastApplied"] in dossier_settings.json — bei naechstem Cold-Start wird verglichen: wenn name unveraendert → skip Apply-Cmd - _mark_layout_applied() helper schreibt nach erfolgreichem Apply - Alle 4 Apply-Pfade umgestellt: _on_ready (cold-start), open_settings_dialog (Eto-Button), APPLY_LAYOUT-Message (React), pendingApplyLayout (Launcher) Edge cases: - User aendert Layout-Name → last_applied != name → Re-Apply trotzdem - User klickt "Jetzt anwenden" → marker wird aktualisiert - Mac Rhino verliert Window-Anordnung → User muss manuell triggern (settings-button "Jetzt anwenden"); flag verhindert nicht das, nur das automatische Re-Apply Co-Authored-By: Claude Opus 4.7 --- rhino/oberleiste.py | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/rhino/oberleiste.py b/rhino/oberleiste.py index 3d72ed8..d058748 100644 --- a/rhino/oberleiste.py +++ b/rhino/oberleiste.py @@ -360,6 +360,22 @@ def _layout_name_to_guid(name): return None +def _mark_layout_applied(name): + """Schreibt den zuletzt erfolgreich angewendeten Layout-Namen in die + Launcher-settings.json. Spaetere Cold-Starts vergleichen und skippen + den Apply-Cmd wenn der Layout-Name unveraendert ist (Rhino merkt sich + die Window-Anordnung dann selbst persistent).""" + if not name: return + try: + cfg = _settings_load() + if cfg.get("windowLayoutLastApplied") == name: + return + cfg["windowLayoutLastApplied"] = name + _settings_save(cfg) + except Exception as ex: + print("[OBERLEISTE] _mark_layout_applied:", ex) + + def _apply_window_layout(name): """Wendet ein benanntes Window-Layout an. Probiert mehrere Wege weil Mac Rhino 8 keine offizielle Python-API dafuer exponiert und die @@ -516,7 +532,8 @@ def open_settings_dialog(): btn_apply.Text = "Jetzt anwenden" def _on_apply(s, e): if state["defaultLayout"]: - _apply_window_layout(state["defaultLayout"]) + if _apply_window_layout(state["defaultLayout"]): + _mark_layout_applied(state["defaultLayout"]) btn_apply.Click += _on_apply btn_save = _ef.Button() @@ -814,17 +831,27 @@ class OberleisteBridge(panel_base.BaseBridge): self._dm_sent = False self._commands_sent = False # Default-Window-Layout anwenden, wenn aktiviert und noch nicht in - # dieser Session geschehen (sticky-flag verhindert Endlos-Schleifen - # falls die Layout-Restoration unsere Panels neu mountet). Layout-Name - # wird vom Launcher unter `windowLayout` geschrieben; Legacy-Key - # `defaultLayout` wird in _settings_load() bereits normalisiert. + # dieser Session geschehen. Doppelte Persistenz: + # 1) `sticky["_dossier_layout_applied"]` — process-lifetime, schuetzt + # vor Endlos-Loops wenn die Layout-Restoration Panels re-mountet. + # 2) `cfg["windowLayoutLastApplied"]` — file-persistent, schuetzt vor + # re-apply bei jedem Cold-Start. Rhino merkt sich die Window- + # Anordnung selbststaendig nach dem ersten erfolgreichen Apply; + # spaetere Starts brauchen den Layout-Cmd nicht mehr. try: cfg = _settings_load() if not sc.sticky.get("_dossier_layout_applied"): layout_name = cfg.get("windowLayout") or cfg.get("defaultLayout") if cfg.get("autoApplyLayout") and layout_name: sc.sticky["_dossier_layout_applied"] = True - _apply_window_layout(layout_name) + last_applied = cfg.get("windowLayoutLastApplied") or "" + if last_applied == layout_name: + print("[OBERLEISTE] Window-Layout '{}' bereits " + "persistent angewendet — skip Cold-Start-Apply " + "(spart Panel-Re-Mount-Welle)".format(layout_name)) + else: + if _apply_window_layout(layout_name): + _mark_layout_applied(layout_name) # Viewport-Colors einmalig pro Session auto-applien (wenn aktiviert) if (cfg.get("autoApplyViewColors") and not sc.sticky.get("_dossier_view_colors_applied")): @@ -1033,7 +1060,8 @@ class OberleisteBridge(panel_base.BaseBridge): self._send_settings_state() elif t == "APPLY_LAYOUT": name = (p.get("name") or "").strip() - if name: _apply_window_layout(name) + if name and _apply_window_layout(name): + _mark_layout_applied(name) elif t == "SAVE_LAYOUT_PREF": cfg = _settings_load() if "windowLayout" in p: @@ -1148,7 +1176,8 @@ class OberleisteBridge(panel_base.BaseBridge): pend_layout = cfg.get("pendingApplyLayout") if isinstance(pend_layout, str) and pend_layout: print("[OBERLEISTE] pendingApplyLayout:", pend_layout) - _apply_window_layout(pend_layout) + if _apply_window_layout(pend_layout): + cfg["windowLayoutLastApplied"] = pend_layout cfg.pop("pendingApplyLayout", None) mutated = True