diff --git a/clakr/clakr.xcodeproj/project.pbxproj b/clakr/clakr.xcodeproj/project.pbxproj index 142abc7..a09ef31 100644 --- a/clakr/clakr.xcodeproj/project.pbxproj +++ b/clakr/clakr.xcodeproj/project.pbxproj @@ -345,7 +345,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 400; + CURRENT_PROJECT_VERSION = 431; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_ASSET_PATHS = "\"clakr/Preview Content\""; DEVELOPMENT_TEAM = DC484S2P7A; @@ -376,7 +376,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 400; + CURRENT_PROJECT_VERSION = 431; DEVELOPMENT_ASSET_PATHS = "\"clakr/Preview Content\""; DEVELOPMENT_TEAM = DC484S2P7A; ENABLE_HARDENED_RUNTIME = YES; diff --git a/clakr/clakr/AppDelegate.swift b/clakr/clakr/AppDelegate.swift index cf6bfb2..3e4fe27 100644 --- a/clakr/clakr/AppDelegate.swift +++ b/clakr/clakr/AppDelegate.swift @@ -68,13 +68,24 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { return Constants.fixedWindowSize } + func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool + { + if !flag { + // If there are no visible windows, bring back the main window + if let window = window { + NSApp.activate(ignoringOtherApps: true) + window.makeKeyAndOrderFront(nil) + } + } + return true + } + // Checks and requests accessibility permissions necessary for the app private func checkAccessibilityPermissions() { let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true] as CFDictionary - guard !AXIsProcessTrustedWithOptions(options) else { return } + if AXIsProcessTrustedWithOptions(options) { return } - // Show an alert if permissions are not granted let alert = NSAlert() alert.messageText = "Accessibility Permission Required" alert.informativeText = @@ -96,11 +107,41 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { // Sets up a listener for keyboard shortcuts private func setupKeyboardShortcutListener() { + let notificationCenter = NotificationCenter.default + + notificationCenter.addObserver( + self, + selector: #selector(updateShortcutStatus), + name: NSApplication.didBecomeActiveNotification, + object: nil + ) + + notificationCenter.addObserver( + self, + selector: #selector(updateShortcutStatus), + name: NSApplication.willResignActiveNotification, + object: nil + ) + KeyboardShortcuts.onKeyUp(for: .openSettingsShortcut) { [weak self] in self?.toggleSettings() } } + // Don't forget to remove observers when they are no longer needed + deinit { + NotificationCenter.default.removeObserver(self) + } + + // Helper method to enable/disable the shortcut based on application's active status + @objc private func updateShortcutStatus(notification: Notification) { + if notification.name == NSApplication.didBecomeActiveNotification { + KeyboardShortcuts.enable(.openSettingsShortcut) + } else if notification.name == NSApplication.willResignActiveNotification { + KeyboardShortcuts.disable(.openSettingsShortcut) + } + } + // Toggles between the menu bar mode and windowed mode @objc private func toggleMenuBarMode() { guard let window = window else { diff --git a/clakr/clakr/Settings/Settings.swift b/clakr/clakr/Settings/Settings.swift index 4929713..cb10662 100644 --- a/clakr/clakr/Settings/Settings.swift +++ b/clakr/clakr/Settings/Settings.swift @@ -233,80 +233,113 @@ struct AboutView: View { @Environment(\.presentationMode) var presentationMode var body: some View { - VStack { + VStack(alignment: .leading, spacing: 10) { SectionHeaderView(title: "About Clakr") Divider() - VStack(alignment: .leading, spacing: 5) { - Text("Thank you to the following:") - .font(.headline) - .padding(.bottom, 5) + aboutClakrSection - HStack(alignment: .top) { - Text("• Sindre Sorhus:") - .fontWeight(.semibold) - VStack(alignment: .leading) { - Link( - "KeyboardShortcuts", - destination: URL(string: "https://github.com/sindresorhus/KeyboardShortcuts")!) - } - } + Divider() - HStack(alignment: .top) { - Text("• KawaiiFumiko002:") - .fontWeight(.semibold) - Text("App icon creator") - } - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding() + acknowledgementsSection Divider() - VStack(alignment: .leading, spacing: 5) { - Text("More about clakr:") - .font(.headline) - .padding(.bottom, 5) - - Text( - "Clakr is a simple, lightweight auto-clicker designed for macOS. It can be used as a menu bar app, or a stand alone app, play a sound when the clicker starts? It's up to you!" - ) - Text( - "Clakr is entirely open-sourced, this allows for user and developer transparency and an up-to-date, free and fast auto-clicker." - ) - Text( - "Please be aware that by using Clakr, you accept full responsibility for any consequences, such as bans or penalties from software or services that prohibit the use of auto-clickers." - ) - Link( - "I do not charge anuthing for Clakr, however, if you'd like to support me you can do so here", - destination: URL(string: "https://github.com/SenpaiHunters/Clakr/blob/main/LICENSE.md")! - ) - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding() - - Spacer() + copyrightAndVersionSection + } + .padding() + } - Divider() + private var acknowledgementsSection: some View { + VStack(alignment: .leading, spacing: 5) { + Text("Acknowledgements") + .font(.title2) + .padding(.bottom, 5) HStack { - Text("© \(currentYear) Kami. All rights reserved.") - .font(.footnote) + Text("Sindre Sorhus") + .bold() Spacer() Link( - "MIT License", - destination: URL(string: "https://github.com/SenpaiHunters/Clakr/blob/main/LICENSE.md")! - ) + "KeyboardShortcuts library", + destination: URL(string: "https://github.com/sindresorhus/KeyboardShortcuts")!) + } + .padding(.bottom, 3) + + HStack { + Text("KawaiiFumiko002") + .bold() + Spacer() + Text("App icon creator") + } + } + .padding(.vertical) + } + + private var aboutClakrSection: some View { + VStack(alignment: .leading, spacing: 5) { + Text("More about Clakr") + .font(.title2) + .padding(.bottom, 2) + + Text("Clakr is a simple, lightweight auto-clicker designed for macOS. It can be used as a menu bar app, or a standalone app, with optional sound effects when the clicker starts.") + .padding(.bottom, 1) + + Text("Clakr is entirely open-sourced, ensuring user and developer transparency for an up-to-date, free, and fast auto-clicker.") + .padding(.bottom, 1) + + Text("Please be aware that by using Clakr, you accept full responsibility for any consequences, such as bans or penalties from software or services that prohibit the use of auto-clickers.") + .padding(.bottom, 1) + + Link("Support Clakr's development", destination: URL(string: "https://www.buymeacoffee.com/kamiamvs")!) + .padding(.bottom, 1) + } + .padding(.vertical) + } + + private var copyrightAndVersionSection: some View { + HStack { + Text("© \(currentYear) Kami. All rights reserved.") .font(.footnote) + Link( + "MIT License", + destination: URL(string: "https://github.com/SenpaiHunters/Clakr/blob/main/LICENSE.md")! + ) + .font(.footnote) + Spacer() + Text("\(appVersionAndBuild)") + .font(.footnote) + Button(action: copyVersionToClipboard) { + Image(systemName: "doc.on.doc") + .foregroundColor(.accentColor) } - .padding() + .buttonStyle(BorderlessButtonStyle()) + .help("Copy version to clipboard") } + .padding(.vertical) } - var currentYear: String { + private func copyVersionToClipboard() { + let pasteboard = NSPasteboard.general + pasteboard.clearContents() + pasteboard.setString(appVersionAndBuild, forType: .string) + } + + private var currentYear: String { let formatter = DateFormatter() formatter.dateFormat = "yyyy" return formatter.string(from: Date()) } + + private var appVersionAndBuild: String { + guard + let versionNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") + as? String, + let buildNumber = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String + else { + return "Unknown" + } + return "Version: \(versionNumber) (\(buildNumber))" + } } diff --git a/releases/clakr.app.zip b/releases/clakr.app.zip index 5087edf..c3e5c75 100644 Binary files a/releases/clakr.app.zip and b/releases/clakr.app.zip differ