diff --git a/rhino/oberleiste.py b/rhino/oberleiste.py index b1a2d99..ee3f4ec 100644 --- a/rhino/oberleiste.py +++ b/rhino/oberleiste.py @@ -760,21 +760,69 @@ def _layout_name_to_guid(name): return None +_LAYOUT_MARKER_PATH = os.path.expanduser( + "~/Library/Application Support/ch.gabrielevarano.Dossier/layout_marker.json") + + +def _is_layout_recently_applied(name, max_age_sec=600): + """True wenn das gegebene Layout vor < max_age_sec Sekunden via DOSSIER + appliziert wurde (Marker-File). Wird benutzt um den teuren + `_-WindowLayout`-RunScript bei Quick-Restarts zu skippen — Rhino haelt + die Panel-Positionen dann meistens noch in seinem internen State.""" + try: + if not os.path.isfile(_LAYOUT_MARKER_PATH): return False + import time as _t, json as _j + with open(_LAYOUT_MARKER_PATH, "rb") as f: + data = _j.loads(f.read().decode("utf-8")) + if not isinstance(data, dict): return False + if (data.get("layoutName") or "") != (name or ""): return False + try: age = _t.time() - float(data.get("appliedAt", 0)) + except Exception: return False + return 0 <= age <= max_age_sec + except Exception as ex: + print("[OBERLEISTE] layout-marker read:", ex) + return False + + +def _mark_layout_applied(name): + """Schreibt den Marker nach erfolgreichem Apply.""" + try: + import time as _t, json as _j + d = os.path.dirname(_LAYOUT_MARKER_PATH) + if not os.path.isdir(d): + try: os.makedirs(d) + except Exception: pass + with open(_LAYOUT_MARKER_PATH, "wb") as f: + f.write(_j.dumps({ + "layoutName": name, + "appliedAt": _t.time(), + }, ensure_ascii=False).encode("utf-8")) + except Exception as ex: + print("[OBERLEISTE] layout-marker write:", 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 Scripted-Commands je nach Rhino-Version variieren. STOP on success — - pruefen via RunScript-Return-Value oder via fehlerfreiem API-Call.""" + pruefen via RunScript-Return-Value oder via fehlerfreiem API-Call. + Schreibt nach erfolgreichem Apply einen Marker fuer Quick-Restart-Skip + (siehe _is_layout_recently_applied). + """ if not name: print("[OBERLEISTE] apply_window_layout: leerer Name") return False import time as _t_wl _t_wl_start = _t_wl.time() + _ret = False try: _ret = _apply_window_layout_impl(name) finally: try: panel_base._t_mark("window_layout", name, _t_wl_start) except Exception: pass + if _ret: + try: _mark_layout_applied(name) + except Exception: pass return _ret @@ -1305,14 +1353,26 @@ class OberleisteBridge(panel_base.BaseBridge): # Default-Window-Layout anwenden, wenn aktiviert und noch nicht in # DIESER Rhino-Session geschehen (sticky-flag = process-lifetime). # Mac Rhino persistiert die Window-Anordnung zwischen Sessions - # NICHT zuverlaessig — der Cold-Start-Apply muss jedes Mal laufen. + # NICHT zuverlaessig — der Cold-Start-Apply lief bisher jedes Mal + # (= ~3s _-WindowLayout RunScript-Blocker). + # Optimierung: Marker-File mit Timestamp + Name. Wenn der letzte + # erfolgreiche Apply < 10 min her ist UND derselbe Layout-Name → skip + # (Rhino "remembers" wahrscheinlich noch). Bei langem Abstand + # (Pause, neuer Tag, Reboot) → apply normal. 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) + if _is_layout_recently_applied(layout_name, max_age_sec=600): + print("[OBERLEISTE] Layout '{}' wurde vor < 10min " + "appliziert — skip (~3s gespart). Manuell neu " + "anwenden via Oberleiste-Einstellungen wenn noetig.".format( + layout_name)) + else: + _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")):