diff --git a/ts3-client/core/src/main/java/com/ts3client/hotkey/HotkeyEngine.java b/ts3-client/core/src/main/java/com/ts3client/hotkey/HotkeyEngine.java index 8bcb2d3..bac87cb 100644 --- a/ts3-client/core/src/main/java/com/ts3client/hotkey/HotkeyEngine.java +++ b/ts3-client/core/src/main/java/com/ts3client/hotkey/HotkeyEngine.java @@ -88,22 +88,20 @@ public final class HotkeyEngine implements GlobalInputHook.Listener { return; } - synchronized (hotkeys.all()) { - for (Hotkey h : hotkeys.all()) { - if (!h.enabled || !h.isValid() || !h.action.supported()) continue; - if (!h.combo.contains(key)) continue; + for (Hotkey h : hotkeys.all()) { + if (!h.enabled || !h.isValid() || !h.action.supported()) continue; + if (!h.combo.contains(key)) continue; - boolean satisfied = h.combo.isSatisfiedBy(pressed); - if (satisfied && active.add(h)) { - if (h.action.momentary() || h.trigger == Hotkey.Trigger.KEY_DOWN) { - fired.add(() -> handler.onHotkey(h, true)); - } - } else if (!satisfied && active.remove(h)) { - if (h.action.momentary()) { - fired.add(() -> handler.onHotkey(h, false)); - } else if (h.trigger == Hotkey.Trigger.KEY_UP) { - fired.add(() -> handler.onHotkey(h, true)); - } + boolean satisfied = h.combo.isSatisfiedBy(pressed); + if (satisfied && active.add(h)) { + if (h.action.momentary() || h.trigger == Hotkey.Trigger.KEY_DOWN) { + fired.add(() -> handler.onHotkey(h, true)); + } + } else if (!satisfied && active.remove(h)) { + if (h.action.momentary()) { + fired.add(() -> handler.onHotkey(h, false)); + } else if (h.trigger == Hotkey.Trigger.KEY_UP) { + fired.add(() -> handler.onHotkey(h, true)); } } } diff --git a/ts3-client/core/src/main/java/com/ts3client/hotkey/Hotkeys.java b/ts3-client/core/src/main/java/com/ts3client/hotkey/Hotkeys.java index cfbcaa4..1948ace 100644 --- a/ts3-client/core/src/main/java/com/ts3client/hotkey/Hotkeys.java +++ b/ts3-client/core/src/main/java/com/ts3client/hotkey/Hotkeys.java @@ -22,9 +22,11 @@ public final class Hotkeys { private final List entries = Collections.synchronizedList(new ArrayList<>()); - /** Live view; iterate under {@code synchronized (all())} when the engine may be running. */ + /** The bindings as they are now; later changes do not show up in the returned list. */ public List all() { - return entries; + synchronized (entries) { + return List.copyOf(entries); + } } public void add(Hotkey hotkey) { diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeyService.java b/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeyService.java index c2d9680..40dfb99 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeyService.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeyService.java @@ -70,10 +70,8 @@ final class HotkeyService { /** The binding for an action with no argument, or {@code null} when unbound. */ Hotkey find(HotkeyAction action) { - synchronized (hotkeys.all()) { - for (Hotkey h : hotkeys.all()) { - if (h.action == action) return h; - } + for (Hotkey h : hotkeys.all()) { + if (h.action == action) return h; } return null; } diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeysPanel.java b/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeysPanel.java index c406ea8..9f38cf8 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeysPanel.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/HotkeysPanel.java @@ -39,9 +39,7 @@ final class HotkeysPanel extends JPanel { this.service = service; setBorder(new ScaledEmptyBorder(8, 8, 8, 8)); - synchronized (service.all()) { - for (Hotkey h : service.all()) working.add(h.copy()); - } + for (Hotkey h : service.all()) working.add(h.copy()); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setRowHeight(table.getRowHeight() + UIScale.scale(4)); @@ -113,9 +111,7 @@ final class HotkeysPanel extends JPanel { /** Picks the stored bindings up again after something else changed them. */ void reload() { working.clear(); - synchronized (service.all()) { - for (Hotkey h : service.all()) working.add(h.copy()); - } + for (Hotkey h : service.all()) working.add(h.copy()); model.fireTableDataChanged(); } diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/VoiceActivationPanel.java b/ts3-client/swing/src/main/java/com/ts3client/ui/VoiceActivationPanel.java index 29fcd3e..d37d641 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/VoiceActivationPanel.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/VoiceActivationPanel.java @@ -325,10 +325,8 @@ final class VoiceActivationPanel extends FormPanel { dlg.setVisible(true); if (!dlg.isConfirmed()) return; List updated = new java.util.ArrayList<>(); - synchronized (hotkeys.all()) { - for (Hotkey h : hotkeys.all()) { - if (h != existing) updated.add(h.copy()); - } + for (Hotkey h : hotkeys.all()) { + if (h != existing) updated.add(h.copy()); } updated.add(dlg.result()); hotkeys.replaceAll(updated);