keyboard shortcut to cycle servers

This commit is contained in:
Ian Gulliver
2026-10-18 21:40:27 -07:00
parent 7b65ff1bb9
commit a367e4bb73
4 changed files with 37 additions and 3 deletions
+12
View File
@@ -110,11 +110,23 @@ struct ByreCommands: Commands {
goButton("Project", "p")
goButton("Lead", "l")
goButton("Merge", "s")
serverButton("Previous Server", "[", -1)
serverButton("Next Server", "]", 1)
Divider()
goButton("Keyboard Shortcuts", "/")
}
}
private func serverButton(_ label: String, _ key: Character, _ step: Int) -> some View {
Button(label) {
if let origin = Servers.shared.step(from: focus?.origin, by: step) {
openWindow(id: "main", value: origin)
}
}
.keyboardShortcut(KeyEquivalent(key))
.disabled(Servers.shared.origins.isEmpty)
}
private func goButton(_ label: String, _ key: String) -> some View {
Button(label) {
if let store = focus?.store, let overlays = focus?.overlays {
+22 -1
View File
@@ -88,6 +88,13 @@ final class Servers {
saveRecords()
}
func step(from origin: String?, by step: Int) -> String? {
guard let i = origin.flatMap({ origins.firstIndex(of: $0) }) else {
return origins.first
}
return origins[(i + step + origins.count) % origins.count]
}
func openAll() {
if origins.isEmpty {
openWindow?(nil)
@@ -315,6 +322,7 @@ struct FatalView: View {
}
struct ServerFocus {
let origin: String?
let store: Store?
let overlays: Overlays
let forget: (() -> Void)?
@@ -340,7 +348,7 @@ struct ServerWindow: View {
if connection != nil {
forgetting = forget
}
return ServerFocus(store: connection?.store, overlays: overlays, forget: forgetting)
return ServerFocus(origin: connection?.origin.absoluteString, store: connection?.store, overlays: overlays, forget: forgetting)
}
private var frameColor: Color {
@@ -387,6 +395,9 @@ struct ServerWindow: View {
var body: some View {
framed
.navigationTitle(connection?.origin.host() ?? "byre")
.background {
WindowReader(found: joinTabs)
}
.focusedSceneValue(\.serverWindow, focus)
.onChange(of: origin, initial: true) { old, new in
moved(old, new)
@@ -431,6 +442,16 @@ struct ServerWindow: View {
Notifier.shared.deliver()
}
private func joinTabs(_ window: NSWindow) {
window.tabbingMode = .preferred
DispatchQueue.main.async {
let host = NSApp.windows.first { $0 !== window && $0.isVisible && $0.tabbingIdentifier == window.tabbingIdentifier }
if let host, !(host.tabbedWindows ?? []).contains(window) {
host.addTabbedWindow(window, ordered: .above)
}
}
}
private func adopt(_ candidates: [String]) {
guard origin == nil, form.serverText.isEmpty, !form.connecting, let next = candidates.first(where: { !Servers.shared.shown.contains($0) }) else {
return
+1
View File
@@ -46,6 +46,7 @@ private let shortcuts: [(String, [(String, String)])] = [
("⌘P", "Open the Project tab"),
("⌘L", "Open the Lead tab and its composer"),
("⌘S", "Merge the right pane's task"),
("⌘[ ⌘]", "Bring the previous or next server's window forward"),
("⌘/", "Show these shortcuts"),
("Esc", "Close the switcher or a dialog"),
]),