Hand out hotkey bindings as a snapshot
Hotkeys.all() returned its synchronised list, and every reader had to lock it while iterating: a lock owned by one class and taken by four others. It now returns a copy, and the lock stays inside Hotkeys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ public final class Hotkeys {
|
||||
|
||||
private final List<Hotkey> 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<Hotkey> all() {
|
||||
return entries;
|
||||
synchronized (entries) {
|
||||
return List.copyOf(entries);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(Hotkey hotkey) {
|
||||
|
||||
Reference in New Issue
Block a user