cache hidden panes

This commit is contained in:
Gregor Lohaus
2026-05-31 19:56:09 +02:00
parent 528afafcda
commit 51f64e7ca8
2 changed files with 35 additions and 8 deletions

View File

@@ -162,6 +162,14 @@ public final class Compositor {
return tabs.isEmpty() ? List.of() : currentTab().panes(); return tabs.isEmpty() ? List.of() : currentTab().panes();
} }
private List<TerminalPane> allOpenPanes() {
List<TerminalPane> panes = new ArrayList<>();
for (Tab tab : tabs) {
panes.addAll(tab.allPanes());
}
return panes;
}
private boolean isActive(TerminalPane pane) { private boolean isActive(TerminalPane pane) {
return !tabs.isEmpty() && currentTab().isActive(pane); return !tabs.isEmpty() && currentTab().isActive(pane);
} }
@@ -180,8 +188,9 @@ public final class Compositor {
long contentVersion = tabs.isEmpty() ? 0 : currentTab().contentVersion(); long contentVersion = tabs.isEmpty() ? 0 : currentTab().contentVersion();
boolean geometryChanged = width != lastWidth || height != lastHeight; boolean geometryChanged = width != lastWidth || height != lastHeight;
boolean contentChanged = contentVersion != lastContentVersion; boolean contentChanged = contentVersion != lastContentVersion;
boolean syncScene = sceneDirty || geometryChanged;
if (!sceneDirty && !geometryChanged && !contentChanged) { if (!syncScene && !contentChanged) {
return; return;
} }
@@ -189,14 +198,17 @@ public final class Compositor {
lastHeight = height; lastHeight = height;
lastContentVersion = contentVersion; lastContentVersion = contentVersion;
sceneDirty = false; sceneDirty = false;
renderFrame(width, height); if (syncScene) {
syncSceneGraph(width, height);
}
renderVisiblePanes();
} }
private void markSceneDirty() { private void markSceneDirty() {
sceneDirty = true; sceneDirty = true;
} }
private void renderFrame(double width, double height) { private void syncSceneGraph(double width, double height) {
double topInset = tabs.size() > 1 ? TAB_BAR_HEIGHT : 0.0; double topInset = tabs.size() > 1 ? TAB_BAR_HEIGHT : 0.0;
paneLayer.resizeRelocate(0.0, 0.0, width, height); paneLayer.resizeRelocate(0.0, 0.0, width, height);
@@ -207,18 +219,26 @@ public final class Compositor {
} }
List<TerminalPane> panes = currentPanes(); List<TerminalPane> panes = currentPanes();
retainNodes(panes); retainNodes(allOpenPanes());
List<TerminalPaneNode> orderedNodes = new ArrayList<>(panes.size()); List<TerminalPaneNode> orderedNodes = new ArrayList<>(panes.size());
for (TerminalPane pane : panes) { for (TerminalPane pane : panes) {
pane.fitToBounds(); pane.fitToBounds();
TerminalPaneNode node = nodeFor(pane); TerminalPaneNode node = nodeFor(pane);
node.resizeRelocate(Math.round(pane.x()), Math.round(pane.y()), pane.width(), pane.height()); node.resizeRelocate(Math.round(pane.x()), Math.round(pane.y()), pane.width(), pane.height());
node.renderIncremental(isActive(pane));
orderedNodes.add(node); orderedNodes.add(node);
} }
paneLayer.getChildren().setAll(orderedNodes); paneLayer.getChildren().setAll(orderedNodes);
} }
private void renderVisiblePanes() {
for (TerminalPane pane : currentPanes()) {
TerminalPaneNode node = nodes.get(pane);
if (node != null) {
node.renderIncremental(isActive(pane));
}
}
}
private TerminalPaneNode nodeFor(TerminalPane pane) { private TerminalPaneNode nodeFor(TerminalPane pane) {
return nodes.computeIfAbsent(pane, this::createNode); return nodes.computeIfAbsent(pane, this::createNode);
} }
@@ -233,9 +253,9 @@ public final class Compositor {
return node; return node;
} }
private void retainNodes(List<TerminalPane> visiblePanes) { private void retainNodes(List<TerminalPane> openPanes) {
Set<TerminalPane> visible = new HashSet<>(visiblePanes); Set<TerminalPane> open = new HashSet<>(openPanes);
nodes.keySet().removeIf(pane -> !visible.contains(pane)); nodes.keySet().removeIf(pane -> !open.contains(pane));
} }
private void updateTabBar(double width, double barHeight) { private void updateTabBar(double width, double barHeight) {

View File

@@ -75,6 +75,13 @@ final class Tab implements AutoCloseable {
return List.copyOf(ordered); return List.copyOf(ordered);
} }
List<TerminalPane> allPanes() {
List<TerminalPane> all = new ArrayList<>(tiled.size() + floating.size());
all.addAll(tiled);
all.addAll(floating);
return List.copyOf(all);
}
boolean isActive(TerminalPane pane) { boolean isActive(TerminalPane pane) {
return pane != null && pane == active; return pane != null && pane == active;
} }