diff --git a/CHANGELOG.md b/CHANGELOG.md index 38601ee00..46b03738f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix potential deadlock in SSH host key verification prompts (semaphore → async/await) - Fix data race in ConnectionStorage, GroupStorage, and TagStorage (added @MainActor isolation) - Add schema versioning to SQLite databases (query history, favorites) for future migrations +- Use semantic selected-text color instead of hardcoded white in selected rows +- Use proper CommandGroup for full-screen shortcut instead of event monitor ### Added diff --git a/TablePro/AppDelegate.swift b/TablePro/AppDelegate.swift index a23bdc532..db256904d 100644 --- a/TablePro/AppDelegate.swift +++ b/TablePro/AppDelegate.swift @@ -136,24 +136,6 @@ class AppDelegate: NSObject, NSApplicationDelegate { name: .databaseDidConnect, object: nil ) - installFullscreenKeyMonitor() - } - - // MARK: - Fullscreen Shortcut - - /// macOS maps Globe+F (fn+F) to ⌃⌘F, but SwiftUI lifecycle apps don't - /// create a real NSMenuItem for "Enter Full Screen" — the shortcut shown - /// in the View menu is a visual hint only, with no key equivalent binding. - private var fullscreenKeyMonitor: Any? - - private func installFullscreenKeyMonitor() { - fullscreenKeyMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in - let mods = event.modifierFlags.intersection(.deviceIndependentFlagsMask) - guard mods == [.control, .command], - event.keyCode == KeyCode.f.rawValue else { return event } - NSApp.keyWindow?.toggleFullScreen(nil) - return nil - } } func applicationDidBecomeActive(_ notification: Notification) { diff --git a/TablePro/Views/DatabaseSwitcher/DatabaseSwitcherSheet.swift b/TablePro/Views/DatabaseSwitcher/DatabaseSwitcherSheet.swift index f78e10af9..91366f5c8 100644 --- a/TablePro/Views/DatabaseSwitcher/DatabaseSwitcherSheet.swift +++ b/TablePro/Views/DatabaseSwitcher/DatabaseSwitcherSheet.swift @@ -264,12 +264,12 @@ struct DatabaseSwitcherSheet: View { Image(systemName: database.icon) .font(.system(size: 14)) .foregroundStyle( - isSelected ? .white : (database.isSystemDatabase ? Color(nsColor: .systemOrange) : Color(nsColor: .systemBlue))) + isSelected ? Color(nsColor: .alternateSelectedControlTextColor) : (database.isSystemDatabase ? Color(nsColor: .systemOrange) : Color(nsColor: .systemBlue))) // Name Text(database.name) .font(.system(size: 13)) - .foregroundStyle(isSelected ? .white : .primary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor) : .primary) Spacer() @@ -277,14 +277,14 @@ struct DatabaseSwitcherSheet: View { if isCurrent { Text("current") .font(.system(size: 10, weight: .medium)) - .foregroundStyle(isSelected ? .white.opacity(0.7) : .secondary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.7) : .secondary) .padding(.horizontal, 6) .padding(.vertical, 2) .background( RoundedRectangle(cornerRadius: 4) .fill( isSelected - ? Color.white.opacity(0.15) + ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.15) : Color(nsColor: .quaternaryLabelColor)) ) } diff --git a/TablePro/Views/QuickSwitcher/QuickSwitcherView.swift b/TablePro/Views/QuickSwitcher/QuickSwitcherView.swift index 8ed23b6f4..8b7a52429 100644 --- a/TablePro/Views/QuickSwitcher/QuickSwitcherView.swift +++ b/TablePro/Views/QuickSwitcher/QuickSwitcherView.swift @@ -163,18 +163,18 @@ internal struct QuickSwitcherSheet: View { return HStack(spacing: 10) { Image(systemName: item.iconName) .font(.system(size: ThemeEngine.shared.activeTheme.iconSizes.default)) - .foregroundStyle(isSelected ? .white : .secondary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor) : .secondary) Text(item.name) .font(.system(size: ThemeEngine.shared.activeTheme.typography.body)) - .foregroundStyle(isSelected ? .white : .primary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor) : .primary) .lineLimit(1) .truncationMode(.tail) if !item.subtitle.isEmpty { Text(item.subtitle) .font(.system(size: ThemeEngine.shared.activeTheme.typography.small)) - .foregroundStyle(isSelected ? Color.white.opacity(0.7) : Color.secondary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.7) : Color.secondary) .lineLimit(1) } @@ -182,12 +182,12 @@ internal struct QuickSwitcherSheet: View { Text(item.kindLabel) .font(.system(size: ThemeEngine.shared.activeTheme.typography.caption, weight: .medium)) - .foregroundStyle(isSelected ? .white.opacity(0.7) : .secondary) + .foregroundStyle(isSelected ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.7) : .secondary) .padding(.horizontal, 6) .padding(.vertical, 2) .background( RoundedRectangle(cornerRadius: 4) - .fill(isSelected ? Color.white.opacity(0.15) : Color(nsColor: .quaternaryLabelColor)) + .fill(isSelected ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.15) : Color(nsColor: .quaternaryLabelColor)) ) } .padding(.vertical, 4) diff --git a/TablePro/Views/Toolbar/ConnectionSwitcherPopover.swift b/TablePro/Views/Toolbar/ConnectionSwitcherPopover.swift index e7f2438d8..27e634c41 100644 --- a/TablePro/Views/Toolbar/ConnectionSwitcherPopover.swift +++ b/TablePro/Views/Toolbar/ConnectionSwitcherPopover.swift @@ -234,19 +234,19 @@ struct ConnectionSwitcherPopover: View { HStack(spacing: 8) { // Color indicator Circle() - .fill(isHighlighted ? Color.white : connection.displayColor) + .fill(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor) : connection.displayColor) .frame(width: 8, height: 8) // Connection info VStack(alignment: .leading, spacing: 1) { Text(connection.name) .font(.system(size: 13, weight: isActive ? .semibold : .regular)) - .foregroundStyle(isHighlighted ? .white : .primary) + .foregroundStyle(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor) : .primary) .lineLimit(1) Text(connectionSubtitle(connection)) .font(.system(size: 11)) - .foregroundStyle(isHighlighted ? .white.opacity(0.7) : .secondary) + .foregroundStyle(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.7) : .secondary) .lineLimit(1) } @@ -258,23 +258,23 @@ struct ConnectionSwitcherPopover: View { .controlSize(.small) } else if isActive { Image(systemName: "checkmark.circle.fill") - .foregroundStyle(isHighlighted ? .white : Color(nsColor: .systemGreen)) + .foregroundStyle(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor) : Color(nsColor: .systemGreen)) .font(.system(size: 14)) } else if isConnected { Circle() - .fill(isHighlighted ? Color.white : Color(nsColor: .systemGreen)) + .fill(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor) : Color(nsColor: .systemGreen)) .frame(width: 6, height: 6) } // Database type badge Text(connection.type.rawValue.uppercased()) .font(.system(size: 9, weight: .medium, design: .monospaced)) - .foregroundStyle(isHighlighted ? .white : .secondary) + .foregroundStyle(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor) : .secondary) .padding(.horizontal, 4) .padding(.vertical, 2) .background( RoundedRectangle(cornerRadius: 3) - .fill(isHighlighted ? Color.white.opacity(0.2) : Color(nsColor: .separatorColor)) + .fill(isHighlighted ? Color(nsColor: .alternateSelectedControlTextColor).opacity(0.2) : Color(nsColor: .separatorColor)) ) } .padding(.vertical, 2)