Global hotkeys, in TeamSpeak's own shape
Bindings are captured system-wide rather than only while the window has focus: X11's RECORD extension where the X server sees every key, and a /dev/input reader as the Wayland fallback. Any key can act as a modifier, mouse buttons included, as TS3 allows. The action catalogue, its three categories and the "advanced actions" split are reverse-engineered from the original client; actions this client cannot perform are listed but greyed out. Push-to-talk becomes one of these hotkeys, so the old focus-bound pushToTalkKey setting is gone and the Voice Activation button edits that binding instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,8 @@ import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.awt.Component;
|
||||
|
||||
/**
|
||||
@@ -319,6 +321,33 @@ final class ServerTab implements ConnectionListener, ServerTreePanel.Actions {
|
||||
return c != null ? c.nickname : "Client " + clientId;
|
||||
}
|
||||
|
||||
/** Joins the channel at a "/"-separated path, as the hotkey action names it. */
|
||||
void joinChannelPath(String path) {
|
||||
if (!conn.isConnected() || path == null || path.isBlank()) return;
|
||||
ChannelNode target = conn.getModel().findChannelByPath(path);
|
||||
if (target != null) conn.joinChannel(target.id, null);
|
||||
}
|
||||
|
||||
/** Every channel of this server as a "/"-separated path, in the tree's own order. */
|
||||
List<String> channelPaths() {
|
||||
List<String> out = new ArrayList<>();
|
||||
if (!conn.isConnected()) return out;
|
||||
for (ChannelNode root : conn.getModel().buildTree()) collectPaths(root, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
private void collectPaths(ChannelNode channel, List<String> out) {
|
||||
out.add(conn.getModel().channelPath(channel.id));
|
||||
for (ChannelNode child : channel.children) collectPaths(child, out);
|
||||
}
|
||||
|
||||
/** The channel we are in, or null when not connected. */
|
||||
ChannelNode currentChannel() {
|
||||
if (!conn.isConnected()) return null;
|
||||
ClientEntry self = conn.getModel().getClient(conn.getSelfClientId());
|
||||
return self == null ? null : conn.getModel().getChannel(self.channelId);
|
||||
}
|
||||
|
||||
// ---- ServerTreePanel.Actions ----
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user