From 6a955e28eabb7a732ec104016cd061f175e443cd Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 30 Oct 2025 22:58:18 +0000 Subject: [PATCH 1/3] Update comment: clarify quick paste supports positions 1-5 --- Jumpcut/Jumpcut.xcodeproj/project.pbxproj | 68 +++++++++++++++-------- Jumpcut/Jumpcut/AppDelegate.swift | 55 ++++++++++++++++++ 2 files changed, 99 insertions(+), 24 deletions(-) diff --git a/Jumpcut/Jumpcut.xcodeproj/project.pbxproj b/Jumpcut/Jumpcut.xcodeproj/project.pbxproj index b03e81b..2f1ef13 100644 --- a/Jumpcut/Jumpcut.xcodeproj/project.pbxproj +++ b/Jumpcut/Jumpcut.xcodeproj/project.pbxproj @@ -302,7 +302,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1320; - LastUpgradeCheck = 1320; + LastUpgradeCheck = 2600; TargetAttributes = { AA311585280A60DB00CBAF91 = { CreatedOnToolsVersion = 13.2.1; @@ -397,6 +397,7 @@ outputFileListPaths = ( ); outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(CONTENTS_FOLDER_PATH)/Library/LoginItems/JumpcutHelper.app", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -504,9 +505,12 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 4987SK7L6Z; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -521,11 +525,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 14.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; + ONLY_ACTIVE_ARCH = NO; SDKROOT = macosx; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; @@ -565,9 +570,12 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 4987SK7L6Z; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -576,10 +584,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 14.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; @@ -594,13 +604,16 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 20231204; - DEVELOPMENT_TEAM = 4987SK7L6Z; + CURRENT_PROJECT_VERSION = 20251014; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; ENABLE_HARDENED_RUNTIME = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Jumpcut/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ""; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Steve Cook"; INFOPLIST_KEY_NSMainNibFile = MainMenu; INFOPLIST_KEY_NSPrincipalClass = NSApplication; @@ -608,8 +621,9 @@ "$(inherited)", "@executable_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 0.84; - PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut; + PRODUCT_BUNDLE_IDENTIFIER = com.beammicrosystems.Jumpcut; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -625,13 +639,16 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 20231204; - DEVELOPMENT_TEAM = 4987SK7L6Z; + CURRENT_PROJECT_VERSION = 20251014; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; ENABLE_HARDENED_RUNTIME = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Jumpcut/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ""; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Steve Cook"; INFOPLIST_KEY_NSMainNibFile = MainMenu; INFOPLIST_KEY_NSPrincipalClass = NSApplication; @@ -639,8 +656,9 @@ "$(inherited)", "@executable_path/../Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 0.84; - PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut; + PRODUCT_BUNDLE_IDENTIFIER = com.beammicrosystems.Jumpcut; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -650,13 +668,13 @@ AA3115AD280A60DD00CBAF91 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 12.2; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -669,13 +687,13 @@ AA3115AE280A60DD00CBAF91 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 12.2; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -688,11 +706,12 @@ AA3115B0280A60DD00CBAF91 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutUITests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -705,11 +724,12 @@ AA3115B1280A60DD00CBAF91 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutUITests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -730,7 +750,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = JumpcutHelper/Info.plist; @@ -740,7 +760,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutHelper; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -762,7 +782,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4987SK7L6Z; + DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = JumpcutHelper/Info.plist; @@ -772,7 +792,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut.JumpcutHelper; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Jumpcut/Jumpcut/AppDelegate.swift b/Jumpcut/Jumpcut/AppDelegate.swift index 86fe5dc..18a0440 100644 --- a/Jumpcut/Jumpcut/AppDelegate.swift +++ b/Jumpcut/Jumpcut/AppDelegate.swift @@ -25,6 +25,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, SPUStandardU private var hotKey: HotKey? public var hotKeyBase: SauceKey? public var mainHotkeyIsRecording = false + // Quick paste hotkeys (positions 1-5) + private var quickPasteHotkeys: [HotKey] = [] // Sparkle public var sparkleUpdater: SPUUpdater! @@ -71,6 +73,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, SPUStandardU // Set up hotkey and bezel handlers setHotkey() + setQuickPasteHotkeys() interactions.setHotkeyHandlers() // If we are coming from an earlier version, let's set the new launch-on-login @@ -148,6 +151,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, SPUStandardU @objc func updateKeyboardCodes(_ notification: Notification) { setHotkey() + setQuickPasteHotkeys() } @objc func updateStateFromSettings(_ notification: Notification) { @@ -156,6 +160,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, SPUStandardU // of what has changed. statusItem.setVisibility() menu.rebuild(stack: stack) + setQuickPasteHotkeys() } func checkMenuBehavior(_ event: NSEvent) -> Bool { @@ -274,6 +279,56 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate, SPUStandardU } } + func setQuickPasteHotkeys() { + // Clear existing quick paste hotkeys + quickPasteHotkeys = [] + + // Check if quick paste is enabled + guard UserDefaults.standard.bool(forKey: SettingsPath.quickPasteEnabled.rawValue) else { + return + } + + // Get the modifiers from the main hotkey + guard let dictionary = UserDefaults.standard.value(forKey: SettingsPath.mainHotkey.rawValue) + as? [AnyHashable: Any] else { + return + } + + // Convert to carbon modifier flags for HotKey library + let shortcut = Shortcut.init(dictionary: dictionary) + guard shortcut != nil else { + return + } + let carbonModifiers = shortcut!.carbonModifierFlags + + // Key codes for number keys 1-5 (QWERTY layout) + let numberKeyCodes: [UInt32] = [ + 18, // 1 + 19, // 2 + 20, // 3 + 21, // 4 + 23 // 5 + ] + + // Register hotkeys for positions 1-5 (array indices 0-4) + for (index, keyCode) in numberKeyCodes.enumerated() { + let position = index // This gives us positions 0, 1, 2, 3, 4 (for clippings 1, 2, 3, 4, 5) + let hotKey = HotKey( + carbonKeyCode: keyCode, + carbonModifiers: carbonModifiers + ) + hotKey.keyDownHandler = { [weak self] in + guard let self = self else { return } + guard !self.mainHotkeyIsRecording else { + // We're recording, so don't trigger paste + return + } + self.interactions.pasteAtPosition(position: position) + } + quickPasteHotkeys.append(hotKey) + } + } + func pasteboardChangeClosure() { guard pasteboard.lastFound != nil else { return From 35c52c350dc0915283ba760855a4cfe9f76acaa5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 5 Nov 2025 14:54:28 +0000 Subject: [PATCH 2/3] Update comment: ensured bundle identifier is correct --- Jumpcut/Jumpcut.xcodeproj/project.pbxproj | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Jumpcut/Jumpcut.xcodeproj/project.pbxproj b/Jumpcut/Jumpcut.xcodeproj/project.pbxproj index 2f1ef13..bf61091 100644 --- a/Jumpcut/Jumpcut.xcodeproj/project.pbxproj +++ b/Jumpcut/Jumpcut.xcodeproj/project.pbxproj @@ -302,7 +302,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1320; - LastUpgradeCheck = 2600; + LastUpgradeCheck = 2610; TargetAttributes = { AA311585280A60DB00CBAF91 = { CreatedOnToolsVersion = 13.2.1; @@ -528,7 +528,7 @@ MACOSX_DEPLOYMENT_TARGET = 14.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = NO; + ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -623,7 +623,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 0.84; - PRODUCT_BUNDLE_IDENTIFIER = com.beammicrosystems.Jumpcut; + PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -658,7 +658,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 0.84; - PRODUCT_BUNDLE_IDENTIFIER = com.beammicrosystems.Jumpcut; + PRODUCT_BUNDLE_IDENTIFIER = net.sf.Jumpcut; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -751,6 +751,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = JumpcutHelper/Info.plist; @@ -783,6 +784,7 @@ COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = D9U7U6P65Q; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = JumpcutHelper/Info.plist; From b741e0a5387f5667f569fa067c9c41825c4b3dc3 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 7 Nov 2025 15:10:55 +0000 Subject: [PATCH 3/3] Restore missing quick paste implementation files from backup branch - Restored pasteAtPosition() function in Interactions.swift - Restored quickPasteEnabled setting in Settings.swift - Restored quick paste checkbox UI in HotkeyPreferenceViewController.swift - Restored deprecation fixes in StatusItem.swift These files were lost during the rebase but are required for the quick paste feature to work. --- Jumpcut/Jumpcut/Interactions.swift | 25 +++++++++++++ .../HotkeyPreferenceViewController.swift | 36 +++++++++++++++++-- Jumpcut/Jumpcut/Settings.swift | 25 ++++++++++--- Jumpcut/Jumpcut/StatusItem.swift | 8 +++-- 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/Jumpcut/Jumpcut/Interactions.swift b/Jumpcut/Jumpcut/Interactions.swift index c483be1..32f5fc7 100644 --- a/Jumpcut/Jumpcut/Interactions.swift +++ b/Jumpcut/Jumpcut/Interactions.swift @@ -74,6 +74,31 @@ public class Interactions: NSObject { } } + func pasteAtPosition(position: Int) { + // Direct paste from a specific position in the stack (used by quick paste hotkeys) + // Unlike paste() which hides the app, this version is for background use + guard let clipping = stack.itemAt(position: position) else { + return + } + + // Place on pasteboard without hiding the app + pasteboard.set(clipping.fullText) + + // Send Command-V to paste + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + self.pasteboard.fakeCommandV() + } + + // Optionally move used clipping to top of stack + let moveToTop = UserDefaults.standard.value( + forKey: SettingsPath.moveClippingsAfterUse.rawValue + ) as? Bool ?? false + if moveToTop { + stack.moveItemToTop(position: position) + menu.rebuild(stack: stack) + } + } + // BEZEL public func bezelSelection() { let clipping = stack.itemAt(position: stack.position) diff --git a/Jumpcut/Jumpcut/Preferences/HotkeyPreferenceViewController.swift b/Jumpcut/Jumpcut/Preferences/HotkeyPreferenceViewController.swift index d7eaa24..58a80e4 100644 --- a/Jumpcut/Jumpcut/Preferences/HotkeyPreferenceViewController.swift +++ b/Jumpcut/Jumpcut/Preferences/HotkeyPreferenceViewController.swift @@ -22,12 +22,44 @@ final class HotkeyPreferenceViewController: NSViewController, PreferencePane { override func viewDidLoad() { let settings = Settings() toolbarItemIcon.isTemplate = true - self.preferredContentSize = CGSize(width: 480, height: 180) + self.preferredContentSize = CGSize(width: 480, height: 240) super.viewDidLoad() + let recorder = settings.shortcutRecorder(title: "Main hotkey", key: .mainHotkey) - let grid = NSStackView(views: [ recorder ]) + + // Quick paste feature + let quickPasteCheckbox = settings.checkbox( + title: "Enable quick paste shortcuts", + key: SettingsPath.quickPasteEnabled + ) + + // Get the main hotkey modifiers to show in the description + var modifierDescription = "⌃⌥" // Default to Control-Option + if let dictionary = UserDefaults.standard.value(forKey: SettingsPath.mainHotkey.rawValue) as? [AnyHashable: Any], + let modifierFlags = dictionary["modifierFlags"] as? Int { + var parts: [String] = [] + if modifierFlags & 256 != 0 { parts.append("⌘") } // Command + if modifierFlags & 2048 != 0 { parts.append("⌥") } // Option + if modifierFlags & 4096 != 0 { parts.append("⌃") } // Control + if modifierFlags & 512 != 0 { parts.append("⇧") } // Shift + if !parts.isEmpty { + modifierDescription = parts.joined() + } + } + + let quickPasteDescription = settings.smallText( + "Pastes clipping 1-5 using \(modifierDescription)1, \(modifierDescription)2, \(modifierDescription)3, \(modifierDescription)4, \(modifierDescription)5" + ) + + let quickPasteStack = NSStackView(views: [quickPasteCheckbox, quickPasteDescription]) + quickPasteStack.orientation = .vertical + quickPasteStack.alignment = .leading + quickPasteStack.spacing = 4 + + let grid = NSStackView(views: [ recorder, quickPasteStack ]) grid.orientation = .vertical grid.alignment = .leading + grid.spacing = 16 self.view.addSubview(grid) self.view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) NSLayoutConstraint.activate([ diff --git a/Jumpcut/Jumpcut/Settings.swift b/Jumpcut/Jumpcut/Settings.swift index aa36493..3839308 100644 --- a/Jumpcut/Jumpcut/Settings.swift +++ b/Jumpcut/Jumpcut/Settings.swift @@ -32,6 +32,7 @@ enum SettingsPath: String { case menuIcon case menuSelectionPastes case moveClippingsAfterUse + case quickPasteEnabled case rememberNum case skipSave case stickyBezel @@ -76,6 +77,7 @@ private let settingsDefaults: [String: Any] = [ SettingsPath.menuSelectionPastes.rawValue: true, SettingsPath.moveClippingsAfterUse.rawValue: false, SettingsPath.menuIcon.rawValue: 0, + SettingsPath.quickPasteEnabled.rawValue: false, SettingsPath.rememberNum.rawValue: 99, SettingsPath.skipSave.rawValue: false, SettingsPath.stickyBezel.rawValue: false, @@ -196,10 +198,25 @@ public class Settings: NSObject { } registerDefaults() let helper = "net.sf.Jumpcut.JumpcutHelper" - if !SMLoginItemSetEnabled(helper as CFString, false) { - #if DEBUG - print("SMLoginItemSetEnabled for \(helper) (false) failed") - #endif + if #available(macOS 13.0, *) { + // Use modern SMAppService API + do { + let service = SMAppService.loginItem(identifier: helper) + if service.status == .enabled { + try service.unregister() + } + } catch { + #if DEBUG + print("SMAppService unregister for \(helper) failed: \(error)") + #endif + } + } else { + // Fallback for older macOS versions + if !SMLoginItemSetEnabled(helper as CFString, false) { + #if DEBUG + print("SMLoginItemSetEnabled for \(helper) (false) failed") + #endif + } } } diff --git a/Jumpcut/Jumpcut/StatusItem.swift b/Jumpcut/Jumpcut/StatusItem.swift index e4c8337..2b6166a 100644 --- a/Jumpcut/Jumpcut/StatusItem.swift +++ b/Jumpcut/Jumpcut/StatusItem.swift @@ -32,10 +32,12 @@ class StatusItem { guard statusItem != nil else { return } - statusItem!.highlightMode = true // Highlight bodge: Stop the highlight flicker (see async call below). - statusItem!.button?.isHighlighted = true + // Highlight bodge: Stop the highlight flicker + if let button = statusItem!.button { + button.isHighlighted = true + } statusItem!.menu = activeMenu - statusItem!.popUpMenu(activeMenu) + statusItem!.button?.performClick(nil) statusItem!.menu = nil // Otherwise clicks won't be processed again }