Tabbed servers: multiple simultaneous connections

Each connection now lives in its own ServerTab with its own tree, info
and chat views plus its own mic-mute, deafen, away and commander state.
MainFrame keeps only the shell (menus, toolbar, status bar) and shows
one tab at a time; the tab bar below the toolbar appears once a second
server is open.

Incoming voice from every connection mixes into the same output — each
connection already renders one line per speaker. Capture is exclusive:
a connection only opens the microphone while it holds it, and a toolbar
button moves it to the visible tab. The mic follows a disconnect to
another connected tab, and push-to-talk drives whoever holds it.

Startup bookmarks are no longer mutually exclusive: every flagged
bookmark opens its own tab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 15:18:47 +00:00
parent 5db3f4d8c4
commit 03c6ea9a3b
7 changed files with 843 additions and 373 deletions

View File

@@ -108,7 +108,8 @@ public final class BookmarksDialog extends JDialog {
channel.setToolTipText("Channel path, e.g. \"Lobby/Games\", or a channel id. "
+ "Leave empty for the server's default channel.");
connectOnStartup.setToolTipText("Connect to this server automatically when the client starts.");
connectOnStartup.setToolTipText("Connect to this server automatically when the client starts. "
+ "Several bookmarks may be flagged; each opens its own tab.");
int row = 0;
addRow(panel, row++, "Label:", label);
@@ -199,12 +200,6 @@ public final class BookmarksDialog extends JDialog {
editing.channelPassword = new String(channelPassword.getPassword());
editing.identityId = identity.getSelectedIdentityId();
editing.connectOnStartup = connectOnStartup.isSelected();
// Only one bookmark can be connected to at startup.
if (editing.connectOnStartup) {
for (Bookmark other : bookmarks.all()) {
if (other != editing) other.connectOnStartup = false;
}
}
list.repaint();
}