Feature/fsg gamma team ui fix #3
@@ -416,6 +416,21 @@ class MainWindow(QMainWindow):
|
||||
self._update_dock_guard()
|
||||
self.help_agent.reposition()
|
||||
self.help_agent.raise_()
|
||||
# Build GraphRAG's browser view and first graph once the window is up
|
||||
# and idle, so clicking GraphRAG does not sit on an empty view while
|
||||
# both happen. 3s is after the first paint and any startup refresh.
|
||||
if not getattr(self, "_graph_prewarmed", False):
|
||||
self._graph_prewarmed = True
|
||||
QTimer.singleShot(3000, self._prewarm_graph)
|
||||
|
||||
def _prewarm_graph(self) -> None:
|
||||
view = getattr(self, "structure", None)
|
||||
if view is None or not hasattr(view, "prewarm"):
|
||||
return
|
||||
try:
|
||||
view.prewarm()
|
||||
except Exception: # noqa: BLE001 — a warm-up must never break the app
|
||||
pass
|
||||
|
||||
# ---- i18n ----------------------------------------------------------
|
||||
def _retranslate(self) -> None:
|
||||
|
||||
@@ -50,24 +50,39 @@ def main() -> int:
|
||||
win.show()
|
||||
app.processEvents()
|
||||
st, w = win.structure, win.workspace
|
||||
fails = []
|
||||
fails: list[str] = []
|
||||
|
||||
# first visit builds the view and scans once
|
||||
win._goto(win._ROW_WORKSPACE, w._graphrag_tab_idx)
|
||||
# startup itself must not build any of it
|
||||
if st.web is not None or st._graph is not None:
|
||||
fails.append("dung san do thi ngay luc khoi dong — startup phai nhe")
|
||||
|
||||
# the idle warm-up builds the browser view and the first graph off the
|
||||
# click path (MainWindow fires this on a 3s timer; call it directly here)
|
||||
win._prewarm_graph()
|
||||
deadline = time.monotonic() + 30
|
||||
while st._graph is None and time.monotonic() < deadline:
|
||||
app.processEvents()
|
||||
time.sleep(0.02)
|
||||
if st._graph is None:
|
||||
print("FAIL lan dau khong dung duoc do thi")
|
||||
print("FAIL lam nong khong dung duoc do thi")
|
||||
sys.stdout.flush()
|
||||
os._exit(1)
|
||||
print(f"sau khi lam nong: web={'co' if st.web else 'chua'} do thi={'co' if st._graph else 'chua'}")
|
||||
|
||||
calls = {"scan": 0, "html": 0}
|
||||
real_scan, real_html = st._scan, st._render_d3
|
||||
st._scan = lambda: (calls.__setitem__("scan", calls["scan"] + 1), real_scan())[1]
|
||||
st._render_d3 = lambda: (calls.__setitem__("html", calls["html"] + 1), real_html())[1]
|
||||
|
||||
# ...so the click itself does nothing but show it — this is the flash
|
||||
t0 = time.monotonic()
|
||||
win._goto(win._ROW_WORKSPACE, w._graphrag_tab_idx)
|
||||
app.processEvents()
|
||||
print(f"bam vao GraphRAG: {(time.monotonic() - t0) * 1000:.0f}ms "
|
||||
f"_scan={calls['scan']} setHtml={calls['html']}")
|
||||
if calls["scan"] or calls["html"]:
|
||||
fails.append("bam vao GraphRAG van phai quet/nap lai trang — con chop trang")
|
||||
|
||||
# re-entering an unchanged graph must not rebuild anything
|
||||
for _ in range(3):
|
||||
win._goto(win._ROW_WORKSPACE, w._project_tab_idx)
|
||||
|
||||
@@ -495,10 +495,31 @@ class StructureGraphView(QWidget):
|
||||
f'<pre style="white-space:pre-wrap; font-family:Consolas,monospace; '
|
||||
f'font-size:12px;">{html.escape(text)}</pre>')
|
||||
|
||||
def prewarm(self) -> None:
|
||||
"""Pay for the graph view before it is clicked on, not during.
|
||||
|
||||
Opening GraphRAG built a QWebEngineView (~140ms) and scanned the project
|
||||
(~485ms) while an empty browser sat on screen — long enough, and white
|
||||
enough, to read as the app restarting itself. Called from an idle timer
|
||||
after the window is up, so startup itself is unaffected; the memory the
|
||||
lazy construction was saving is spent a few seconds later instead.
|
||||
"""
|
||||
if not _HAS_WEB or self.web is not None:
|
||||
return
|
||||
self._ensure_web()
|
||||
if self._graph is None and self.path_edit.text().strip():
|
||||
self._needs_scan = False
|
||||
self._scan() # runs on a worker thread
|
||||
|
||||
def _ensure_web(self) -> None:
|
||||
if self.web is not None or not _HAS_WEB:
|
||||
return
|
||||
self.web = QWebEngineView()
|
||||
# Blank the page in the app's own background first. A fresh
|
||||
# QWebEngineView paints white, and on a dark theme that white rectangle
|
||||
# WAS the flash — it showed for as long as the first scan took.
|
||||
self.web.setHtml(
|
||||
f"<body style='margin:0;background:{current_palette().bg}'></body>")
|
||||
self._bridge = _Bridge()
|
||||
self._channel = QWebChannel()
|
||||
self._channel.registerObject("py", self._bridge)
|
||||
|
||||
Reference in New Issue
Block a user