BugFix: MouseOver and Add Feature: Clipboard settings

This commit is contained in:
Hariharan Mudaliar 2025-07-17 22:47:04 +05:30
commit 7137fcd255
7 changed files with 76 additions and 4 deletions

View file

@ -268,6 +268,41 @@ class AppDelegate: NSObject, NSApplicationDelegate {
TimerManager.shared.startDemoTimer(duration: 300) TimerManager.shared.startDemoTimer(duration: 300)
} }
KeyboardShortcuts.onKeyDown(for: .clipboardHistoryPanel) { [weak self] in
guard let self = self else { return }
// Only open clipboard if the feature is enabled
guard Defaults[.enableClipboardManager] else { return }
// Find the appropriate view model based on mouse location
let mouseLocation = NSEvent.mouseLocation
var viewModel = self.vm
if Defaults[.showOnAllDisplays] {
for screen in NSScreen.screens {
if screen.frame.contains(mouseLocation) {
if let screenViewModel = self.viewModels[screen] {
viewModel = screenViewModel
break
}
}
}
}
// Open the notch if it's closed
if viewModel.notchState == .closed {
viewModel.open()
}
// Start clipboard monitoring if not already running
if !ClipboardManager.shared.isMonitoring {
ClipboardManager.shared.startMonitoring()
}
// Post notification to trigger clipboard popover
NotificationCenter.default.post(name: NSNotification.Name("ToggleClipboardPopover"), object: nil)
}
if !Defaults[.showOnAllDisplays] { if !Defaults[.showOnAllDisplays] {
let viewModel = self.vm let viewModel = self.vm
let window = createDynamicIslandWindow( let window = createDynamicIslandWindow(

View file

@ -52,6 +52,9 @@
}, },
"5 items" : { "5 items" : {
},
"7 items" : {
}, },
"10 items" : { "10 items" : {
@ -653,7 +656,7 @@
"Mirror shape" : { "Mirror shape" : {
}, },
"Monitor clipboard changes and keep a history of recent copies. The clipboard button will appear in the header next to the settings gear." : { "Monitor clipboard changes and keep a history of recent copies. Use Cmd+Shift+V to quickly access clipboard history." : {
}, },
"Monitoring Status" : { "Monitoring Status" : {
@ -999,6 +1002,9 @@
}, },
"System Performance" : { "System Performance" : {
},
"The clipboard icon appears in the header next to the settings gear when enabled. Use the global shortcut Cmd+Shift+V or click the icon to access history." : {
}, },
"TheDynamicIsland" : { "TheDynamicIsland" : {

View file

@ -10,6 +10,7 @@ import SwiftUI
struct ClipboardHistoryPopover: View { struct ClipboardHistoryPopover: View {
@ObservedObject var clipboardManager = ClipboardManager.shared @ObservedObject var clipboardManager = ClipboardManager.shared
@Binding var isPresented: Bool @Binding var isPresented: Bool
@EnvironmentObject var vm: DynamicIslandViewModel
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
@ -56,6 +57,18 @@ struct ClipboardHistoryPopover: View {
.stroke(Color.gray.opacity(0.2), lineWidth: 1) .stroke(Color.gray.opacity(0.2), lineWidth: 1)
) )
.shadow(color: .black.opacity(0.3), radius: 10, x: 0, y: 5) .shadow(color: .black.opacity(0.3), radius: 10, x: 0, y: 5)
.onHover { hovering in
// Close popover and notch when mouse exits
if !hovering {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
isPresented = false
// Also close the notch if no other popovers are active
if vm.notchState == .open && !vm.isBatteryPopoverActive {
vm.close()
}
}
}
}
} }
@ViewBuilder @ViewBuilder

View file

@ -65,7 +65,7 @@ struct DynamicIslandHeader: View {
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
} }
if Defaults[.enableClipboardManager] { if Defaults[.enableClipboardManager] && Defaults[.showClipboardIcon] {
Button(action: { Button(action: {
showClipboardPopover.toggle() showClipboardPopover.toggle()
}) { }) {
@ -138,6 +138,12 @@ struct DynamicIslandHeader: View {
} }
.foregroundColor(.gray) .foregroundColor(.gray)
.environmentObject(vm) .environmentObject(vm)
.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("ToggleClipboardPopover"))) { _ in
// Only toggle if clipboard is enabled
if Defaults[.enableClipboardManager] {
showClipboardPopover.toggle()
}
}
} }
} }

View file

@ -1309,6 +1309,7 @@ struct ClipboardSettings: View {
@ObservedObject var clipboardManager = ClipboardManager.shared @ObservedObject var clipboardManager = ClipboardManager.shared
@Default(.enableClipboardManager) var enableClipboardManager @Default(.enableClipboardManager) var enableClipboardManager
@Default(.clipboardHistorySize) var clipboardHistorySize @Default(.clipboardHistorySize) var clipboardHistorySize
@Default(.showClipboardIcon) var showClipboardIcon
var body: some View { var body: some View {
Form { Form {
@ -1324,17 +1325,20 @@ struct ClipboardSettings: View {
} header: { } header: {
Text("Clipboard Manager") Text("Clipboard Manager")
} footer: { } footer: {
Text("Monitor clipboard changes and keep a history of recent copies. The clipboard button will appear in the header next to the settings gear.") Text("Monitor clipboard changes and keep a history of recent copies. Use Cmd+Shift+V to quickly access clipboard history.")
} }
if enableClipboardManager { if enableClipboardManager {
Section { Section {
Defaults.Toggle("Show Clipboard Icon", key: .showClipboardIcon)
HStack { HStack {
Text("History Size") Text("History Size")
Spacer() Spacer()
Picker("History Size", selection: $clipboardHistorySize) { Picker("History Size", selection: $clipboardHistorySize) {
Text("3 items").tag(3) Text("3 items").tag(3)
Text("5 items").tag(5) Text("5 items").tag(5)
Text("7 items").tag(7)
Text("10 items").tag(10) Text("10 items").tag(10)
} }
.pickerStyle(.menu) .pickerStyle(.menu)
@ -1356,6 +1360,8 @@ struct ClipboardSettings: View {
} }
} header: { } header: {
Text("Settings") Text("Settings")
} footer: {
Text("The clipboard icon appears in the header next to the settings gear when enabled. Use the global shortcut Cmd+Shift+V or click the icon to access history.")
} }
Section { Section {

View file

@ -10,6 +10,7 @@ import SwiftUI
import Combine import Combine
import Foundation import Foundation
import UniformTypeIdentifiers import UniformTypeIdentifiers
import Defaults
// Clipboard item data structure // Clipboard item data structure
struct ClipboardItem: Identifiable, Codable { struct ClipboardItem: Identifiable, Codable {
@ -152,7 +153,11 @@ class ClipboardManager: ObservableObject {
private var timer: Timer? private var timer: Timer?
private var lastChangeCount: Int = 0 private var lastChangeCount: Int = 0
private let maxHistoryItems = 3
// Use configurable history size from settings
private var maxHistoryItems: Int {
return Defaults[.clipboardHistorySize]
}
// Directory for storing clipboard data files // Directory for storing clipboard data files
static let clipboardDataDirectory: URL = { static let clipboardDataDirectory: URL = {

View file

@ -160,6 +160,7 @@ extension Defaults.Keys {
// MARK: Clipboard Feature // MARK: Clipboard Feature
static let enableClipboardManager = Key<Bool>("enableClipboardManager", default: true) static let enableClipboardManager = Key<Bool>("enableClipboardManager", default: true)
static let clipboardHistorySize = Key<Int>("clipboardHistorySize", default: 3) static let clipboardHistorySize = Key<Int>("clipboardHistorySize", default: 3)
static let showClipboardIcon = Key<Bool>("showClipboardIcon", default: true)
// Helper to determine the default media controller based on macOS version // Helper to determine the default media controller based on macOS version
static var defaultMediaController: MediaControllerType { static var defaultMediaController: MediaControllerType {