diff --git a/Cargo.lock b/Cargo.lock index a4bc1cd..31d65df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -452,7 +452,7 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "ranma-cli" -version = "0.1.9" +version = "0.1.10" dependencies = [ "argh", "libc", @@ -462,7 +462,7 @@ dependencies = [ [[package]] name = "ranma-core" -version = "0.1.9" +version = "0.1.10" dependencies = [ "parking_lot", "serde", @@ -737,7 +737,7 @@ dependencies = [ [[package]] name = "uniffi-bindgen" -version = "0.1.9" +version = "0.1.10" dependencies = [ "uniffi", ] diff --git a/app/Sources/BarViewModel.swift b/app/Sources/BarViewModel.swift index 62da9bc..0932b4f 100644 --- a/app/Sources/BarViewModel.swift +++ b/app/Sources/BarViewModel.swift @@ -19,33 +19,44 @@ final class BarViewModel: StateChangeHandler, @unchecked Sendable { private var fullscreenDisplays: Set = [] func onStateChange(event: StateChangeEvent) throws { - DispatchQueue.main.async { [self] in - switch event { - case let .nodeAdded(display, node): - nodes[display, default: []].append(node) - scheduleRefresh(display) - - case let .nodeRemoved(display, _): - let updated = getNodesForDisplay(display: display) - nodes[display] = updated - scheduleRefresh(display) - - case let .nodeUpdated(display, node): - if let idx = nodes[display]?.firstIndex(where: { $0.name == node.name }) { - nodes[display]?[idx] = node - } - scheduleRefresh(display) - - case let .nodeMoved(oldDisplay, newDisplay, node): - nodes[oldDisplay]?.removeAll { $0.name == node.name } - scheduleRefresh(oldDisplay) - nodes[newDisplay, default: []].append(node) - scheduleRefresh(newDisplay) + if Thread.isMainThread { + MainActor.assumeIsolated { + handleEvent(event) + } + } else { + DispatchQueue.main.async { [self] in + handleEvent(event) + } + } + } - case let .fullRefresh(display, newNodes): - nodes[display] = newNodes - scheduleRefresh(display) + @MainActor + private func handleEvent(_ event: StateChangeEvent) { + switch event { + case let .nodeAdded(display, node): + nodes[display, default: []].append(node) + scheduleRefresh(display) + + case let .nodeRemoved(display, _): + let updated = getNodesForDisplay(display: display) + nodes[display] = updated + scheduleRefresh(display) + + case let .nodeUpdated(display, node): + if let idx = nodes[display]?.firstIndex(where: { $0.name == node.name }) { + nodes[display]?[idx] = node } + scheduleRefresh(display) + + case let .nodeMoved(oldDisplay, newDisplay, node): + nodes[oldDisplay]?.removeAll { $0.name == node.name } + scheduleRefresh(oldDisplay) + nodes[newDisplay, default: []].append(node) + scheduleRefresh(newDisplay) + + case let .fullRefresh(display, newNodes): + nodes[display] = newNodes + scheduleRefresh(display) } }