Dock the tray icon once the window is on screen

Docking waits for the panel to adopt the icon, which held up the main
window; wait at most half a second for it before falling back to AWT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 12:25:44 +00:00
parent 75df46a03a
commit 002b1ac7ce
2 changed files with 15 additions and 4 deletions

View File

@@ -79,8 +79,8 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
private MainMenuBar menuBar;
private javax.swing.Timer statusTimer;
/** Mirrors the active server's own client state next to the clock. */
private TrayController tray;
/** Mirrors the active server's own client state next to the clock; set once the window is up. */
private volatile TrayController tray;
private MainToolbar toolbar;
private StatusBar statusBar;
@@ -112,12 +112,17 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
public void windowClosing(WindowEvent e) {
quit();
}
@Override
public void windowOpened(WindowEvent e) {
// Docking waits for the panel to adopt the icon, so it must not hold up the window.
SwingUtilities.invokeLater(MainFrame.this::installTray);
}
});
// Catches Ctrl+C / SIGTERM so we still leave the servers cleanly.
Runtime.getRuntime().addShutdownHook(shutdownHook);
setMinimumSize(UIScale.scale(new Dimension(720, 480)));
tray = new TrayController(this, this::quit);
menuBar = buildMenuBar();
setJMenuBar(menuBar);
@@ -853,6 +858,12 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
return selected != null && selected.session().isConnected() ? selected : null;
}
private void installTray() {
if (shuttingDown.get()) return;
tray = new TrayController(this, this::quit);
updateTray();
}
private void updateTray() {
if (tray == null) return;
ServerTab tab = trayTab();

View File

@@ -33,7 +33,7 @@ public final class X11Tray implements TrayBackend {
private static final int DEFAULT_SIZE = 24;
private static final int POLL_MS = 40;
/** How long to give the panel to adopt the icon before falling back to AWT. */
private static final int DOCK_TIMEOUT_MS = 1500;
private static final int DOCK_TIMEOUT_MS = 500;
/** Anything narrower than this is a sliver, not an icon the panel meant to give us. */
private static final int MIN_SENSIBLE_SIZE = 8;
/** A tall panel should still not get a huge icon. */