From 55ca2df62ac680e338563fc38af1e0f207e61ea1 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 18 May 2026 06:10:40 +0100 Subject: [PATCH] fix: polish Mac settings layout --- CHANGELOG.md | 3 ++ .../Sources/OpenClaw/GeneralSettings.swift | 35 +++++++++++-------- .../OpenClaw/PermissionsSettings.swift | 5 ++- .../Sources/OpenClaw/SettingsComponents.swift | 4 ++- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94324f971ec7..05a060ce65c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,9 @@ Docs: https://docs.openclaw.ai - Gateway/sessions: keep ACP/acpx and runtime child sessions visible in configured-only session lists when their owner or parent session belongs to a configured agent. - Mac app: keep app-level menu commands and Dashboard failure states reachable when the remote Gateway is disconnected, and keep the Settings sidebar toggle in the leading titlebar area. - Mac app: allow longer Gateway and Context errors to wrap in the menu instead of truncating the useful failure detail. +- Mac app: tighten remote Gateway fields in Settings so the Connection pane keeps readable labels and full action button text. +- Mac app: keep custom Settings card rows left-aligned and full-width so Discovery and status sections no longer appear centered or detached. +- Mac app: align Location permission controls to the same trailing column as the rest of Settings. - Gateway/webchat: hide internal runtime-context and other `display: false` transcript messages from Chat history and live message events. Fixes #83216. Thanks @EmpireCreator. - CLI/help: keep `gateway`, `doctor`, `status`, and `health` help registration out of action/runtime imports so subcommand `--help` stays lightweight in constrained terminals. Fixes #83228. Thanks @dfguerrerom. - Cron/Discord: keep explicit announce runs in message-tool-only source-reply mode so scheduled agent turns post once instead of also echoing through automatic visible replies. Fixes #83261. Thanks @Theralley. diff --git a/apps/macos/Sources/OpenClaw/GeneralSettings.swift b/apps/macos/Sources/OpenClaw/GeneralSettings.swift index e86e58892024..2f0fa72b4506 100644 --- a/apps/macos/Sources/OpenClaw/GeneralSettings.swift +++ b/apps/macos/Sources/OpenClaw/GeneralSettings.swift @@ -11,6 +11,9 @@ struct GeneralSettings: View { case connection } + private static let remoteFieldWidth: CGFloat = 320 + private static let remoteSecretFieldWidth: CGFloat = 300 + @Bindable var state: AppState @AppStorage(cameraEnabledKey) private var cameraEnabled: Bool = false let page: Page @@ -384,6 +387,7 @@ struct GeneralSettings: View { self.applyDiscoveredGateway(gateway) } } + .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 14) .padding(.vertical, 11) .overlay(alignment: .bottom) { @@ -500,7 +504,7 @@ struct GeneralSettings: View { SettingsCardRow(title: "SSH target", subtitle: "User and host for the remote Gateway machine.") { TextField("user@host[:22]", text: self.$state.remoteTarget) .textFieldStyle(.roundedBorder) - .frame(width: 420) + .frame(width: Self.remoteFieldWidth) self.remoteTestButton(disabled: !canTest) } if let validationMessage { @@ -514,20 +518,20 @@ struct GeneralSettings: View { } private var remoteDirectRow: some View { - VStack(alignment: .leading, spacing: 0) { - SettingsCardRow(title: "Gateway URL", subtitle: "The WebSocket URL exposed by the remote Gateway.") { - TextField("wss://gateway.example.ts.net", text: self.$state.remoteUrl) - .textFieldStyle(.roundedBorder) - .frame(width: 420) - self.remoteTestButton( - disabled: self.state.remoteUrl.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty) + SettingsCardRow(title: "Gateway URL", subtitle: "The WebSocket URL exposed by the remote Gateway.") { + VStack(alignment: .leading, spacing: 6) { + HStack(spacing: 8) { + TextField("wss://gateway.example.ts.net", text: self.$state.remoteUrl) + .textFieldStyle(.roundedBorder) + .frame(width: Self.remoteFieldWidth) + self.remoteTestButton( + disabled: self.state.remoteUrl.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty) + } + Text("Use wss:// for public hosts. ws:// is allowed for localhost, LAN, .local, and Tailnet hosts.") + .font(.caption) + .foregroundStyle(.secondary) + .fixedSize(horizontal: false, vertical: true) } - Text( - "Use wss:// for public hosts. ws:// is allowed for localhost, LAN, .local, and Tailnet hosts.") - .font(.caption) - .foregroundStyle(.secondary) - .padding(.horizontal, 14) - .padding(.bottom, 10) } } @@ -540,7 +544,7 @@ struct GeneralSettings: View { { SecureField("remote gateway auth token (gateway.remote.token)", text: self.$state.remoteToken) .textFieldStyle(.roundedBorder) - .frame(width: 360) + .frame(width: Self.remoteSecretFieldWidth) } if self.state.remoteTokenUnsupported { Text( @@ -566,6 +570,7 @@ struct GeneralSettings: View { } } .buttonStyle(.borderedProminent) + .frame(minWidth: 116) .disabled(self.remoteStatus == .checking || disabled) } diff --git a/apps/macos/Sources/OpenClaw/PermissionsSettings.swift b/apps/macos/Sources/OpenClaw/PermissionsSettings.swift index e71f27ce4494..b99b9746f499 100644 --- a/apps/macos/Sources/OpenClaw/PermissionsSettings.swift +++ b/apps/macos/Sources/OpenClaw/PermissionsSettings.swift @@ -80,6 +80,8 @@ struct PermissionsSettings: View { } private struct LocationAccessSettings: View { + private static let controlWidth: CGFloat = 180 + @AppStorage(locationModeKey) private var locationModeRaw: String = OpenClawLocationMode.off.rawValue @AppStorage(locationPreciseKey) private var locationPreciseEnabled: Bool = true @State private var lastLocationModeRaw: String = OpenClawLocationMode.off.rawValue @@ -97,7 +99,7 @@ private struct LocationAccessSettings: View { } .labelsHidden() .pickerStyle(.menu) - .frame(width: 190) + .frame(width: Self.controlWidth, alignment: .trailing) } SettingsCardRow( @@ -108,6 +110,7 @@ private struct LocationAccessSettings: View { Toggle("Precise Location", isOn: self.$locationPreciseEnabled) .labelsHidden() .toggleStyle(.switch) + .frame(width: Self.controlWidth, alignment: .trailing) .disabled(self.locationMode == .off) } } diff --git a/apps/macos/Sources/OpenClaw/SettingsComponents.swift b/apps/macos/Sources/OpenClaw/SettingsComponents.swift index cf39d02dfd51..9d8b60d29692 100644 --- a/apps/macos/Sources/OpenClaw/SettingsComponents.swift +++ b/apps/macos/Sources/OpenClaw/SettingsComponents.swift @@ -63,9 +63,10 @@ struct SettingsCardGroup: View { .font(.subheadline.weight(.semibold)) .foregroundStyle(.secondary) - VStack(spacing: 0) { + VStack(alignment: .leading, spacing: 0) { self.content } + .frame(maxWidth: .infinity, alignment: .leading) .background(.quaternary.opacity(0.38), in: RoundedRectangle(cornerRadius: 12, style: .continuous)) .overlay { RoundedRectangle(cornerRadius: 12, style: .continuous) @@ -110,6 +111,7 @@ struct SettingsCardRow: View { self.content } + .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 14) .padding(.vertical, 11) .overlay(alignment: .bottom) {