├── .github └── FUNDING.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Dynamic Dark Mode.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── Dynamic Dark Mode.xcscheme │ └── DynamicLauncher.xcscheme ├── Dynamic Dark Mode.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── swiftpm │ └── Package.resolved ├── Dynamic ├── Auxiliary │ ├── Auxiliary.swift │ ├── Connectivity.swift │ ├── Error.swift │ ├── Localizations.swift │ └── Notification.swift ├── Components │ ├── Appearance │ │ ├── AppleInterfaceStyle+NSAppearance.swift │ │ ├── AppleInterfaceStyle.swift │ │ └── AppleScriptHelper.swift │ ├── AppleInterfaceStyle+Coordinator.swift │ ├── Brightness │ │ ├── NSScreen + Brightness.swift │ │ └── ScreenBrightnessObserver.swift │ ├── Preferences.swift │ └── Scheduler │ │ ├── Location.swift │ │ ├── Scheduler.swift │ │ └── Solar.swift ├── Supporting Files │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 128.png │ │ │ ├── 16.png │ │ │ ├── 256.png │ │ │ ├── 32.png │ │ │ ├── 512.png │ │ │ ├── 64.png │ │ │ ├── Contents.json │ │ │ └── Icon.png │ │ ├── Contents.json │ │ ├── Icon.imageset │ │ │ ├── Contents.json │ │ │ ├── Icon-160.png │ │ │ ├── Icon-160@2x.png │ │ │ └── Icon-160@3x.png │ │ ├── dark.imageset │ │ │ ├── Contents.json │ │ │ ├── baseline_brightness_2_black_18pt_1x.png │ │ │ ├── baseline_brightness_2_black_18pt_2x.png │ │ │ └── baseline_brightness_2_black_18pt_3x.png │ │ ├── light.imageset │ │ │ ├── Contents.json │ │ │ ├── outline_wb_sunny_black_18pt_1x.png │ │ │ ├── outline_wb_sunny_black_18pt_2x.png │ │ │ └── outline_wb_sunny_black_18pt_3x.png │ │ └── status_bar_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── baseline_brightness_2_black_18pt_1x.png │ │ │ ├── baseline_brightness_2_black_18pt_2x.png │ │ │ ├── baseline_brightness_2_black_18pt_3x.png │ │ │ ├── outline_wb_sunny_black_18pt_1x.png │ │ │ ├── outline_wb_sunny_black_18pt_2x.png │ │ │ └── outline_wb_sunny_black_18pt_3x.png │ ├── Credits.html │ ├── Dynamic-Bridging-Header.h │ ├── Dynamic.entitlements │ ├── Info.plist │ ├── NTSolar.swift │ ├── TouchBarPrivateAPI.h │ ├── de.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── eo.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── es.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── fr.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── id.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── ja.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── ko.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── nl.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ ├── ru.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings │ └── zh-Hans.lproj │ │ ├── InfoPlist.strings │ │ └── Localizable.strings └── View Controller │ ├── Access Points │ ├── Shortcut.swift │ ├── StatusBarItem.swift │ └── TouchBar.swift │ ├── AppDelegate.swift │ ├── Base.lproj │ └── Main.storyboard │ ├── Settings │ ├── DynamicDesktopSettingsViewController.swift │ ├── SettingsViewController + TouchBar.swift │ └── SettingsViewController.swift │ ├── Welcome │ ├── AllowLocationViewController.swift │ ├── AllowSystemEventsViewController.swift │ ├── InitialSetupViewController.swift │ ├── SetupStep.swift │ ├── SlideSegue.swift │ └── Welcome.swift │ ├── de.lproj │ └── Main.strings │ ├── eo.lproj │ └── Main.strings │ ├── es.lproj │ └── Main.strings │ ├── fr.lproj │ └── Main.strings │ ├── id.lproj │ └── Main.strings │ ├── ja.lproj │ └── Main.strings │ ├── ko.lproj │ └── Main.strings │ ├── nl.lproj │ └── Main.strings │ ├── ru.lproj │ └── Main.strings │ └── zh-Hans.lproj │ └── Main.strings ├── DynamicLauncher ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── 128.png │ │ ├── 16.png │ │ ├── 256.png │ │ ├── 32.png │ │ ├── 512.png │ │ ├── 64.png │ │ ├── Contents.json │ │ └── Icon.png │ └── Contents.json ├── Base.lproj │ └── MainMenu.xib ├── DynamicLauncher.entitlements ├── Info.plist ├── de.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings ├── eo.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings ├── es.lproj │ └── InfoPlist.strings ├── fr.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings ├── id.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings ├── ja.lproj │ └── InfoPlist.strings ├── ko.lproj │ └── InfoPlist.strings ├── nl.lproj │ └── InfoPlist.strings ├── ru.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings └── zh-Hans.lproj │ ├── InfoPlist.strings │ └── MainMenu.strings ├── Icon.png ├── Icon.sketch ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── Tools └── main.swift ├── _config.yml ├── appcast.xml └── privacy.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ApolloZhu, CaptainYukinoshitaHachiman, pankova] 4 | patreon: apollozhu 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: afdian.net/@ApolloZhu 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | 70 | .DS_Store 71 | *.xcarchive 72 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 5 | 6 | ## [1.5.2] - 2019-09-23 7 | ### Changed 8 | - Switches dark mode with SkyLight when missing AppleScript permission 9 | - Behavior of buttons to adapt to system schedule 10 | - Updated French translation 11 | 12 | ### Fixed 13 | - Wrong sunset/sunrise date when UTC time is in next day 14 | - Version number now works with Sparkle 15 | 16 | ## [1.5.1] - 2019-09-18 17 | ### Added 18 | - Import Spanish translations from Crowdin 19 | - Option to skip setup and AppleScript permission check (#75) 20 | 21 | ### Changed 22 | - Only reschedules when connection is not expensive and not in low data mode 23 | 24 | ### Fixed 25 | - Update for screen brightness should be more reliable 26 | - Now detects system auto appearance on launch to set appropriate schedule type 27 | - Reopening app will open the appropriate screen 28 | 29 | ## [1.5.0] - 2019-09-14 30 | ### Added 31 | - Supports macOS Catalina Apperance Auto (#74) 32 | 33 | ### Changed 34 | - Update for brightness and connectivity changes are delayed (#73, #57) 35 | - Settings panel will adjust to its smallest size possible. 36 | 37 | ### Fixed 38 | - Dynamic wallpaper not updating when the "scheduled" option is not enabled 39 | 40 | ## [1.4.2] - 2019-09-10 41 | ### Changed 42 | - Updated Chinese, Japanese, and Russian translations 43 | 44 | ## [1.4.1] - 2019-09-10 45 | ### Added 46 | - Complete Sparkle integration (#6) 47 | 48 | ## [1.4.0] - 2019-09-08 49 | ### Added 50 | - Dynamic wallpaper based on current appearance (#72) 51 | 52 | ### Fixed 53 | - Automatic appearance switch based on screen brightness works on macOS Mojave 10.14.4 and above (#65, #71) 54 | - Switching apperance won't steal focus from some application and not return it (#70, #62, #18) 55 | 56 | ## [1.3.0] - 2019-05-17 57 | ### Added 58 | - Let's move to `/Applications` 59 | 60 | ### Fixed 61 | - Crash on launch when not installed to `/Applications` folder by asking them to move (#16, #49) 62 | - Switching theme no longer steal focus from focused application (#62) 63 | 64 | ### Removed 65 | - The app is no longer restricted within an application sandbox (#63) 66 | 67 | ## [1.2.0] - 2019-05-07 68 | ### Added 69 | - Disable adjust for brightness when scheduled dark mode on 70 | - Quick dark mode toggle in touch bar through `DFRFoundation` 71 | - Update schedule when network status changes 72 | 73 | ## [1.1.5] - 2019-05-02 74 | ### Added 75 | - Partial translations to Japanese and Korean 76 | - Click on notification to create a new issue, or navigates the existing one for known bugs 77 | 78 | ### Changed 79 | - Updated the program and its dependencies to Swift 5 80 | - Updated Chinese, Esperanto, and Russian translations 81 | - Using `fatalError` or `debugPrint` instead of `os.log` 82 | 83 | ### Fixed 84 | - "nil: estimatedNextExecution" should no longer appear (#59) 85 | 86 | ### Removed 87 | - No more legacy code for supporting macOS 10.13 (never released) 88 | 89 | ## [1.1.4] - 2019-02-28 90 | ### Added 91 | - Nightly builds available at https://rebrand.ly/ddm-nightly 92 | - On Product Hunt at https://www.producthunt.com/posts/dynamic-dark-mode 93 | 94 | ### Changed 95 | - Now using consistent version number style for artifact and release tag 96 | 97 | ### Fixed 98 | - Unnecessary scheduling when Mac awakes from sleep 99 | 100 | ## [1.1.3] - 2019-02-17 101 | ### Added 102 | - Prompt for moving to /Applications folder 103 | 104 | ### Fixed 105 | - Use schedule based dark mode when option turned off 106 | - Ineffective location caching and retrieving 107 | - Control of menu bar icon settings after re-setup 108 | 109 | ## [1.1.2] - 2018-12-20 110 | ### Changed 111 | - Prompt when not authorized to access location 112 | 113 | ### Fixed 114 | - Memory leaks from re-setup 115 | 116 | ### Removed 117 | - Unnecessary setup step 118 | - `exit` that was used to pick up automation privacy settings 119 | 120 | ## [1.1.1] - 2018-12-11 121 | ### Fixed 122 | - Inability to get current location (#41) 123 | - Not observing screen brightness changes (#46) 124 | 125 | ## [1.1.0] - 2018-11-05 126 | ### Changed 127 | - Chinese translation of toggle dark mode 128 | - Rename Dynamic to Dynamic Dark Mode 129 | 130 | ### Fixed 131 | - No scheduled change during sleep 132 | 133 | ## [1.0.6] - 2018-10-22 134 | ### Added 135 | - French translation 136 | - Indonesian translation 137 | - Russian translation 138 | - German translation 139 | 140 | ### Fixed 141 | - Some parts of the interface elements been cut off 142 | 143 | ### Removed 144 | - Hope to be included in the Mac App Store 145 | 146 | ## [1.0.5] - 2018-09-30 147 | ### Fixed 148 | - False alarm about `-1751` AppleScript error 149 | - Wrongly turning on dark mode when custom schedule spans within a single day 150 | 151 | ## [1.0.4] - 2018-09-29 152 | ### Added 153 | - Simplfied Chinese Translation 154 | 155 | ## [1.0.3] - 2018-09-29 156 | ### Added 157 | - Installer pkg for download 158 | - Request for location access during setup process 159 | - Button in app's preferences pane to rerun setup process 160 | 161 | ### Fixed 162 | - Crash on launch (if the app is installed in the `/Applications` folder) 163 | 164 | ## [1.0.2] - 2018-09-28 165 | ### Changed 166 | - Start using non-sandbox-escaping method to control System Events 167 | 168 | ### Removed 169 | - Request to access `~/Library/Application Scripts/${bundleIdentifier}` 170 | 171 | ## [1.0.1] - 2018-09-26 172 | ### Added 173 | - Ability to switch dark mode when global shortcut key combination is performed 174 | - Ability to toggle dark mode when screen brightness is below/above a set threshold 175 | - Ability to turn on/off dark mode based on a scheduled time 176 | - Ability to automatically set scheduled time as sunset/sunrise based on location 177 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at public-apollonian@outlook.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcodeproj/xcshareddata/xcschemes/Dynamic Dark Mode.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 45 | 47 | 53 | 54 | 55 | 56 | 59 | 60 | 61 | 62 | 68 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcodeproj/xcshareddata/xcschemes/DynamicLauncher.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Dynamic Dark Mode.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "masshortcut", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/shpakovski/MASShortcut", 7 | "state" : { 8 | "branch" : "master", 9 | "revision" : "57ccb018863b328a22298a275593a1d87ab4db24" 10 | } 11 | }, 12 | { 13 | "identity" : "schedule", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/luoxiu/Schedule", 16 | "state" : { 17 | "revision" : "e388fcab1d870f32c0359a414fda81b8e81b98c9", 18 | "version" : "2.1.1" 19 | } 20 | }, 21 | { 22 | "identity" : "sparkle", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/sparkle-project/Sparkle", 25 | "state" : { 26 | "revision" : "286edd1fa22505a9e54d170e9fd07d775ea233f2", 27 | "version" : "2.1.0" 28 | } 29 | }, 30 | { 31 | "identity" : "xmlcoder", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/MaxDesiatov/XMLCoder.git", 34 | "state" : { 35 | "revision" : "f30119af03996939cc4f54e0bf0dda9f88a84da5", 36 | "version" : "0.13.1" 37 | } 38 | } 39 | ], 40 | "version" : 2 41 | } 42 | -------------------------------------------------------------------------------- /Dynamic/Auxiliary/Auxiliary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Auxiliary.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/28/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | public typealias Handler = (T) -> Void 12 | public typealias CompletionHandler = () -> Void 13 | 14 | func openURL(_ string: String) { 15 | NSWorkspace.shared.open(URL(string: string)!) 16 | } 17 | -------------------------------------------------------------------------------- /Dynamic/Auxiliary/Connectivity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Connectivity.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 5/4/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Network 10 | import Schedule 11 | 12 | public final class Connectivity { 13 | private var monitor: NWPathMonitor! 14 | private let queue: DispatchQueue 15 | public init(label: String) { 16 | self.queue = DispatchQueue(label: label) 17 | } 18 | public static let `default` = Connectivity(label: "Connectivity") 19 | 20 | private var isObserving = false 21 | private var isInitialUpdate = true 22 | public func startObserving(onSuccess: @escaping () -> Void) { 23 | stopObserving() 24 | monitor = NWPathMonitor() 25 | monitor.pathUpdateHandler = { [weak self] path in 26 | guard let self = self else { return } 27 | guard !self.isInitialUpdate else { 28 | self.isInitialUpdate = false 29 | return 30 | } 31 | switch path.status { 32 | case .satisfied: 33 | if path.isExpensive { return } 34 | if #available(macOS 10.15, *), path.isConstrained { return } 35 | onSuccess() 36 | case .requiresConnection, .unsatisfied: 37 | break 38 | @unknown default: 39 | remindReportingBug("\(path.status)") 40 | } 41 | } 42 | monitor.start(queue: queue) 43 | isObserving = true 44 | } 45 | 46 | public func stopObserving() { 47 | guard isObserving else { return } 48 | isInitialUpdate = true 49 | monitor.cancel() 50 | isObserving = false 51 | task = nil 52 | } 53 | 54 | private var task: Task? 55 | public func scheduleWhenReconnected() { 56 | startObserving { [weak self] in 57 | self?.task = Plan.after(5.seconds).do(queue: .main) { 58 | Scheduler.shared.schedule() 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Dynamic/Auxiliary/Error.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Error.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 2/17/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | struct AnError: LocalizedError { 12 | let errorDescription: String? 13 | } 14 | 15 | public func remindReportingBug(_ text: String, title: String? = nil, issueID: Int? = nil) { 16 | let heading: String 17 | let notification: UserNotification.Identifier 18 | if let id = issueID { 19 | notification = .issue(id: id) 20 | heading = title ?? NSLocalizedString( 21 | "Bug.known.title", 22 | value: "Encountered a Known Issue", 23 | comment: "Request users to provide more context." 24 | ) 25 | } else { 26 | notification = .reportBug 27 | heading = title ?? NSLocalizedString( 28 | "Bug.general.title", 29 | value: "Report Bug To Developer", 30 | comment: "Scare the user so they report bugs." 31 | ) 32 | } 33 | debugPrint(heading + (issueID.map { " #\($0)" } ?? "")) 34 | debugPrint(text) 35 | UserNotification.send(notification, title: heading, subtitle: text) { error in 36 | guard error != nil else { return } 37 | showAlert(withConfiguration: { alert in 38 | alert.alertStyle = .critical 39 | alert.messageText = heading 40 | alert.informativeText = text 41 | }) 42 | } 43 | } 44 | 45 | public func showAlert( 46 | withConfiguration configure: @escaping Handler, 47 | then process: @escaping Handler = { _ in } 48 | ) { 49 | DispatchQueue.main.async { 50 | let alert = NSAlert() 51 | configure(alert) 52 | process(alert.runModal()) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Dynamic/Auxiliary/Localizations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Localizations.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Captain雪ノ下八幡 on 2018/6/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum LocalizedString { 12 | enum SettingsViewController { 13 | static let autoAdjustThreshold = NSLocalizedString( 14 | "SettingsViewController.autoAdjustThreshold", 15 | value: "Auto Adjust Threshold", 16 | comment: "For touch bar button title" 17 | ) 18 | static let scheduleMode = NSLocalizedString( 19 | "SettingsViewController.scheduleMode", 20 | value: "Schedule Mode", 21 | comment: "For touch bar button title" 22 | ) 23 | } 24 | enum SunsetSunrise { 25 | static let official = NSLocalizedString( 26 | "SunsetSunrise.official", 27 | value: "Official", 28 | comment: "Official" 29 | ) 30 | static let civil = NSLocalizedString( 31 | "SunsetSunrise.civil", 32 | value: "Civil", 33 | comment: "Civil" 34 | ) 35 | static let nautical = NSLocalizedString( 36 | "SunsetSunrise.nautical", 37 | value: "Nautical", 38 | comment: "Nautical" 39 | ) 40 | static let astronomical = NSLocalizedString( 41 | "SunsetSunrise.astronomical", 42 | value: "Astronomical", 43 | comment: "Astronomical" 44 | ) 45 | static let customRange = NSLocalizedString( 46 | "SunsetSunrise.customRange", 47 | value: "Custom", 48 | comment: "CustomRange" 49 | ) 50 | static let system = NSLocalizedString( 51 | "SunsetSunrise.system", 52 | value: "System", 53 | comment: "Translate the same as System on preferences screen" 54 | ) 55 | } 56 | enum Location { 57 | static let notAuthorized = NSLocalizedString( 58 | "Location.notAuthorized", 59 | value: "You did NOT authorize Dynamic Dark Mode to get your location.", 60 | comment: "User did not authorize this app to use location." 61 | ) 62 | static let notAvailable = NSLocalizedString( 63 | "Location.notAvailable", 64 | value: "Can't Fetch Current Location", 65 | comment: "Failed to attain user location for sunset/sunrise calculation." 66 | ) 67 | static let timeout = NSLocalizedString( 68 | "Location.timeout", 69 | value: "Timedout. Check your network connection.", 70 | comment: "Took too long to use up retries, most likely off Wi-Fi." 71 | ) 72 | static let useCache = NSLocalizedString( 73 | "Location.useCache", 74 | value: "Scheduled Using Previous Location", 75 | comment: "Can't fetch user's current location. Using cache instead." 76 | ) 77 | } 78 | enum Notification { 79 | static let notAuthorized = NSLocalizedString( 80 | "Notification.notAuthorized", 81 | value: "You did NOT authorize Dynamic Dark Mode to send notifications.", 82 | comment: "User did not authorize this app to send notifications." 83 | ) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Dynamic/Auxiliary/Notification.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Notification.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 2/17/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import UserNotifications 12 | 13 | enum UserNotification { 14 | enum Identifier: RawRepresentable { 15 | case useCache 16 | case reportBug 17 | case issue(id: Int) 18 | 19 | init?(rawValue: String) { 20 | switch rawValue { 21 | case "Scheduler.location.useCache": self = .useCache 22 | case "issues.new": self = .reportBug 23 | default: 24 | guard let last = rawValue.split(separator: ".").last 25 | , let id = Int(last) 26 | else { return nil } 27 | self = .issue(id: id) 28 | } 29 | } 30 | 31 | var rawValue: String { 32 | switch self { 33 | case .useCache: return "Scheduler.location.useCache" 34 | case .reportBug: return "issues.new" 35 | case .issue(let id): return "issues.\(id)" 36 | } 37 | } 38 | } 39 | 40 | static func send(_ identifier: UserNotification.Identifier, 41 | title: String, subtitle: String, 42 | then handle: Handler? = nil) { 43 | var identifier = identifier 44 | let center = UNUserNotificationCenter.current() 45 | center.requestAuthorization(options: [.alert]) { _,_ in 46 | center.getNotificationSettings { settings in 47 | guard settings.authorizationStatus == .authorized else { 48 | handle?(AnError.notificationNotAuthorized);return 49 | } 50 | let content = UNMutableNotificationContent() 51 | content.title = title 52 | content.subtitle = subtitle 53 | if title.contains("-1751") || subtitle.contains("-1751") { 54 | identifier = .issue(id: 18) // annoying and hard to reproduce 55 | } // I don't know where that -1751 is from, but I'll catch u 56 | let request = UNNotificationRequest( 57 | identifier: identifier.rawValue, 58 | content: content, 59 | trigger: nil 60 | ) 61 | center.add(request, withCompletionHandler: handle) 62 | } 63 | } 64 | } 65 | 66 | static func removeAll() { 67 | let center = UNUserNotificationCenter.current() 68 | center.removeAllPendingNotificationRequests() 69 | center.removeAllDeliveredNotifications() 70 | } 71 | } 72 | 73 | extension AppDelegate: UNUserNotificationCenterDelegate { 74 | func userNotificationCenter( 75 | _ center: UNUserNotificationCenter, 76 | willPresent notification: UNNotification, 77 | withCompletionHandler completionHandler: 78 | @escaping (UNNotificationPresentationOptions) -> Void) { 79 | completionHandler(.alert) 80 | } 81 | 82 | func userNotificationCenter( 83 | _ center: UNUserNotificationCenter, 84 | didReceive response: UNNotificationResponse, 85 | withCompletionHandler completionHandler: @escaping () -> Void) { 86 | defer { completionHandler() } 87 | let id = response.notification.request.identifier 88 | switch UserNotification.Identifier(rawValue: id)! { 89 | case .useCache: 90 | break 91 | case .reportBug: 92 | openURL("https://github.com/ApolloZhu/Dynamic-Dark-Mode/issues/new") 93 | case .issue(let id): 94 | openURL("https://github.com/ApolloZhu/Dynamic-Dark-Mode/issues/\(id)") 95 | } 96 | } 97 | } 98 | 99 | extension AnError { 100 | static let notificationNotAuthorized = AnError(errorDescription: 101 | LocalizedString.Notification.notAuthorized 102 | ) 103 | } 104 | -------------------------------------------------------------------------------- /Dynamic/Components/Appearance/AppleInterfaceStyle+NSAppearance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppleInterfaceStyle+NSAppearance.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/6/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Cocoa 11 | 12 | // MARK: - Detect Dark Mode 13 | 14 | extension NSAppearance { 15 | var isDark: Bool { 16 | switch name { 17 | case .aqua, .accessibilityHighContrastAqua, 18 | .vibrantLight, .accessibilityHighContrastVibrantLight: 19 | return false 20 | case .darkAqua, .accessibilityHighContrastDarkAqua, 21 | .vibrantDark, .accessibilityHighContrastVibrantDark: 22 | return true 23 | default: 24 | #if DEBUG 25 | fatalError(name.rawValue) 26 | #else 27 | debugPrint("Dynamic Dark Mode - Unrecognized appearance: \(name.rawValue)") 28 | return false 29 | #endif 30 | } 31 | } 32 | } 33 | 34 | extension AppleInterfaceStyle { 35 | static var current: AppleInterfaceStyle { 36 | return isDark ? .darkAqua : .aqua 37 | } 38 | 39 | static var isDark: Bool { 40 | return NSApp.effectiveAppearance.isDark 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Dynamic/Components/Appearance/AppleInterfaceStyle.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppleInterfaceStyle.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 5/3/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum AppleInterfaceStyle: String { 12 | case aqua 13 | case darkAqua 14 | } 15 | 16 | // MARK: - Toggle Dark Mode 17 | 18 | extension AppleInterfaceStyle { 19 | 20 | static func toggle() { 21 | AppleScript.toggleDarkMode.execute() 22 | } 23 | 24 | func enable() { 25 | guard AppleInterfaceStyle.current != self else { return } 26 | switch self { 27 | case .aqua: 28 | AppleScript.disableDarkMode.execute() 29 | case .darkAqua: 30 | AppleScript.enableDarkMode.execute() 31 | } 32 | } 33 | 34 | static func updateWallpaper() { 35 | guard let url = isDark 36 | ? preferences.darkDesktopURL 37 | : preferences.lightDesktopURL 38 | else { return } 39 | let workspace = NSWorkspace.shared 40 | for screen in NSScreen.screens { 41 | try? workspace.setDesktopImageURL(url, for: screen) 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Dynamic/Components/Appearance/AppleScriptHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppleScriptHelper.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/7/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | // MARK: - All Apple Scripts 12 | 13 | public enum AppleScript: String, CaseIterable { 14 | case toggleDarkMode = "not dark mode" 15 | case enableDarkMode = "true" 16 | case disableDarkMode = "false" 17 | } 18 | 19 | // MARK: - Execution 20 | 21 | extension AppleScript { 22 | public func execute() { 23 | let frontmostApplication = NSWorkspace.shared.frontmostApplication 24 | AppleScript.requestPermission { authorized in 25 | defer { frontmostApplication?.activate(options: [.activateIgnoringOtherApps]) } 26 | 27 | if authorized { 28 | self.useAppleScriptImplementation() 29 | } else { 30 | self.useNonAppStoreCompliantImplementation() 31 | } 32 | } 33 | } 34 | 35 | // MARK: Deprecated API 36 | 37 | /// Turns dark mode on/off/to the opposite. 38 | private var source: String { 39 | return """ 40 | tell application "System Events" 41 | tell appearance preferences to set dark mode to \(rawValue) 42 | end tell 43 | """ 44 | } 45 | 46 | private func useAppleScriptImplementation() { 47 | var errorInfo: NSDictionary? = nil 48 | NSAppleScript(source: self.source)! 49 | .executeAndReturnError(&errorInfo) 50 | // Handle errors 51 | if errorInfo != nil { 52 | useNonAppStoreCompliantImplementation() 53 | } 54 | } 55 | 56 | // MARK: Private API 57 | 58 | private func useNonAppStoreCompliantImplementation() { 59 | switch self { 60 | case .toggleDarkMode: 61 | SLSSetAppearanceThemeLegacy(!SLSGetAppearanceThemeLegacy()) 62 | case .enableDarkMode: 63 | SLSSetAppearanceThemeLegacy(true) 64 | case .disableDarkMode: 65 | SLSSetAppearanceThemeLegacy(false) 66 | } 67 | } 68 | } 69 | 70 | // MARK: - Permission 71 | 72 | extension AppleScript { 73 | public static let notAuthorized = NSLocalizedString( 74 | "AppleScript.authorization.error", 75 | value: "You didn't allow Dynamic Dark Mode to manage dark mode", 76 | comment: "" 77 | ) 78 | 79 | public static func redirectToSystemPreferences() { 80 | openURL("x-apple.systempreferences:com.apple.preference.security?Privacy_Automation") 81 | } 82 | 83 | public static func requestPermission( 84 | retryOnInternalError: Bool = true, 85 | then process: @escaping Handler 86 | ) { 87 | DispatchQueue.global().async { 88 | let systemEvents = "com.apple.systemevents" 89 | // We need to get it running to send it messages 90 | NSWorkspace.shared.launchApplication( 91 | withBundleIdentifier: systemEvents, 92 | additionalEventParamDescriptor: nil, 93 | launchIdentifier: nil 94 | ) 95 | let target = NSAppleEventDescriptor(bundleIdentifier: systemEvents) 96 | let status = AEDeterminePermissionToAutomateTarget( 97 | target.aeDesc, typeWildCard, typeWildCard, true 98 | ) 99 | switch Int(status) { 100 | case Int(noErr): 101 | return process(true) 102 | case errAEEventNotPermitted: 103 | break 104 | case errOSAInvalidID, -1751, 105 | errAEEventWouldRequireUserConsent, 106 | procNotFound: 107 | if retryOnInternalError { 108 | requestPermission(retryOnInternalError: false, then: process) 109 | } // else ignore 110 | default: 111 | remindReportingBug("OSStatus \(status)") 112 | } 113 | process(false) 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Dynamic/Components/AppleInterfaceStyle+Coordinator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppleInterfaceStyle+Coordinator.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 5/3/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension AppleInterfaceStyle { 12 | public static let Coordinator = AppleInterfaceStyleCoordinator() 13 | } 14 | 15 | /// This class coordinates between scheduler and screen brightness observer. 16 | public class AppleInterfaceStyleCoordinator: NSObject { 17 | fileprivate override init() { super.init() } 18 | 19 | private var appearanceObservation: NSKeyValueObservation? { 20 | didSet { 21 | oldValue?.invalidate() 22 | } 23 | } 24 | 25 | @objc public func toggleOrShowInterface() { 26 | if #available(macOS 10.15, *), preferences.AppleInterfaceStyleSwitchesAutomatically { 27 | reopen() 28 | } else { 29 | AppleInterfaceStyle.toggle() 30 | } 31 | } 32 | 33 | public func setup() { 34 | tearDown() 35 | appearanceObservation = NSApp.observe(\.effectiveAppearance) { _, _ in 36 | AppleInterfaceStyle.updateWallpaper() 37 | } 38 | guard preferences.scheduled else { 39 | guard preferences.adjustForBrightness else { return } 40 | // No need for scheduler, only enable brightness observer 41 | return ScreenBrightnessObserver.shared.startObserving() 42 | } 43 | Connectivity.default.scheduleWhenReconnected() 44 | Scheduler.shared.schedule(startBrightnessObserverOnFailure: true) 45 | } 46 | 47 | public func tearDown(stopAppearanceObservation: Bool = true) { 48 | Scheduler.shared.cancel() 49 | Connectivity.default.stopObserving() 50 | ScreenBrightnessObserver.shared.stopObserving() 51 | if stopAppearanceObservation { 52 | appearanceObservation = nil 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Dynamic/Components/Brightness/NSScreen + Brightness.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSScreen + Brightness.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/7/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | extension NSScreen { 12 | /** 13 | Reads and returns the brightness of the "main" display. 14 | 15 | - Todo: 16 | Haven't figured out how to identify main display through IOKit yet, 17 | but Core Graphics can get serial and vendor number through CGDisplay. 18 | 19 | - Note: 20 | https://stackoverflow.com/questions/3239749/programmatically-change-mac-display-brightness 21 | */ 22 | static var brightness: Float { 23 | var iterator: io_iterator_t = IO_OBJECT_NULL 24 | let gotService = IOServiceGetMatchingServices( 25 | kIOMasterPortDefault, 26 | IOServiceMatching("IODisplayConnect"), 27 | &iterator 28 | ) 29 | guard gotService == kIOReturnSuccess else { 30 | debugPrint("Dynamic Dark Mode - Display Connection Failed") 31 | return -1 32 | } 33 | while true { 34 | let display: io_object_t = IOIteratorNext(iterator) 35 | guard display != IO_OBJECT_NULL else { 36 | debugPrint("Dynamic Dark Mode - No Display Found") 37 | return -1 38 | } 39 | var brightness: Float = 0 40 | IODisplayGetFloatParameter( 41 | display, 0, kIODisplayBrightnessKey as CFString, &brightness 42 | ) 43 | IOObjectRelease(display) 44 | return brightness 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Dynamic/Components/Brightness/ScreenBrightnessObserver.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScreenBrightnessObserver.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/8/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Schedule 11 | 12 | final class ScreenBrightnessObserver: NSObject { 13 | 14 | private var notificationPort: IONotificationPortRef? 15 | private let queue = DispatchQueue(label: "ddm.queue.brightness") 16 | private lazy var lastBrightness = NSScreen.brightness 17 | private var callback: IOServiceInterestCallback = { (ctx, service, messageType, messageArgument) in 18 | guard let ctx = ctx else { return } 19 | let observer = Unmanaged.fromOpaque(ctx).takeUnretainedValue() 20 | let newBrightness = NSScreen.brightness 21 | guard observer.lastBrightness != newBrightness else { return } 22 | observer.lastBrightness = newBrightness 23 | observer.setNeedsUpdate() 24 | } 25 | 26 | static let shared = ScreenBrightnessObserver() 27 | private override init() { super.init() } 28 | deinit { stopObserving() } 29 | 30 | public func startObserving(withInitialUpdate: Bool = true) { 31 | stopObserving() 32 | defer { if withInitialUpdate { setNeedsUpdate() } } 33 | let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleBacklightDisplay")) 34 | guard service != IO_OBJECT_NULL else { 35 | #if DEBUG 36 | fatalError("AppleBacklightDisplay is IO_OBJECT_NULL") 37 | #else 38 | return remindReportingBug(NSLocalizedString( 39 | "ScreenBrightnessObserver.startObserving.failed", 40 | value: "Cannot observe screen brightness change.", 41 | comment: "Notification text for bug report" 42 | )) 43 | #endif 44 | } 45 | defer { IOObjectRelease(service) } 46 | notificationPort = IONotificationPortCreate(kIOMasterPortDefault) 47 | IONotificationPortSetDispatchQueue(notificationPort, queue) 48 | var n = io_object_t() 49 | let ctx = UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque()) 50 | IOServiceAddInterestNotification(notificationPort, service, kIOGeneralInterest, callback, ctx, &n) 51 | lastBrightness = NSScreen.brightness 52 | } 53 | 54 | public var suggestedMode: AppleInterfaceStyle { 55 | let brightness = NSScreen.brightness 56 | let threshold = preferences.brightnessThreshold 57 | return brightness < threshold ? .darkAqua : .aqua 58 | } 59 | 60 | private var task: Task? 61 | private func setNeedsUpdate() { 62 | task = Plan.after(0.5.seconds).do(queue: .main, action: _updateForBrightnessChange) 63 | } 64 | 65 | private func _updateForBrightnessChange() { 66 | let newValue = suggestedMode 67 | guard AppleInterfaceStyle.current != newValue else { return } 68 | newValue.enable() 69 | } 70 | 71 | public func stopObserving() { 72 | guard notificationPort != nil else { return } 73 | IONotificationPortDestroy(notificationPort) 74 | notificationPort = nil 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Dynamic/Components/Scheduler/Location.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Location.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 11/17/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import CoreLocation 10 | import Schedule 11 | 12 | public enum Location { 13 | case current(CLLocation) 14 | case cached(CLLocation) 15 | case failed(Error) 16 | } 17 | 18 | final class LocationManager: NSObject, CLLocationManagerDelegate { 19 | public static let serial = LocationManager() 20 | 21 | private var retryCount = 5 22 | private let timeout = 10.seconds 23 | typealias Callback = (process: Handler, onTimeout: Task) 24 | 25 | private var lock = NSLock() 26 | private var callbacks: [Callback] = [] { 27 | didSet { if callbacks.isEmpty { manager.stopUpdatingLocation() } } 28 | } 29 | private func callback(_ location: Location) { 30 | lock.lock() 31 | defer { lock.unlock() } 32 | guard !callbacks.isEmpty else { return } 33 | for callback in callbacks { 34 | callback.onTimeout.cancel() 35 | callback.process(location) 36 | } 37 | callbacks = [] 38 | retryCount = 5 39 | } 40 | 41 | public func fetch(then processor: @escaping Handler) { 42 | lock.lock() 43 | let task = Plan.after(timeout).do(action: onTimeout) 44 | callbacks.append((processor, task)) 45 | lock.unlock() 46 | startUpdatingLocation() 47 | } 48 | 49 | private func onTimeout(_ task: Task) { 50 | lock.lock() 51 | let idx = callbacks.firstIndex { $0.onTimeout == task } 52 | let callback = callbacks.remove(at: idx!) // should not be nil 53 | callback.onTimeout.cancel() 54 | lock.unlock() 55 | onError(AnError(errorDescription: 56 | LocalizedString.Location.timeout 57 | ), run: callback.process) 58 | } 59 | 60 | public weak var delegate: CLLocationManagerDelegate? 61 | private lazy var manager: CLLocationManager = { 62 | var manager = CLLocationManager() 63 | manager.delegate = self 64 | return manager 65 | }() 66 | 67 | func locationManager(_ manager: CLLocationManager, 68 | didChangeAuthorization status: CLAuthorizationStatus) { 69 | delegate?.locationManager?(manager, didChangeAuthorization: status) 70 | startUpdatingLocation() 71 | } 72 | 73 | func locationManager(_ manager: CLLocationManager, 74 | didUpdateLocations locations: [CLLocation]) { 75 | guard let location = locations.last else { return } 76 | manager.stopUpdatingLocation() 77 | preferences.location = location 78 | CLGeocoder().reverseGeocodeLocation(location) { placemarks, _ in 79 | if let name = placemarks?.first?.name { 80 | preferences.placemark = name 81 | } 82 | } 83 | callback(.current(location)) 84 | } 85 | 86 | func locationManager(_ manager: CLLocationManager, 87 | didFailWithError error: Error) { 88 | retryCount -= 1 89 | guard retryCount <= 0 else { return } 90 | manager.stopUpdatingLocation() 91 | onError(error) 92 | } 93 | 94 | private func startUpdatingLocation() { 95 | if Location.deniedAccess { 96 | onError(CLError.denied) 97 | } else { 98 | manager.startUpdatingLocation() 99 | } 100 | } 101 | 102 | private func onError(_ error: Error, run callback: Handler! = nil) { 103 | let callback = callback ?? self.callback 104 | if let location = preferences.location { 105 | callback(.cached(location)) 106 | } else { 107 | callback(.failed(error)) 108 | } 109 | } 110 | } 111 | 112 | extension Location { 113 | static func alertNotAvailable(dueTo error: Error? = nil) { 114 | showAlert(withConfiguration: { alert in 115 | alert.alertStyle = .warning 116 | alert.messageText = error == CLError.denied 117 | ? LocalizedString.Location.notAuthorized 118 | : LocalizedString.Location.notAvailable 119 | guard let error = error else { return } 120 | alert.informativeText = error.localizedDescription 121 | }) 122 | } 123 | } 124 | 125 | // MARK: - Core Location 126 | 127 | extension Location { 128 | static var deniedAccess: Bool { 129 | let status = CLLocationManager.authorizationStatus() 130 | switch status { 131 | case .authorizedAlways, .notDetermined: 132 | return false 133 | case .denied, .restricted: 134 | return true 135 | @unknown default: 136 | remindReportingBug(status.description) 137 | return false 138 | } 139 | } 140 | 141 | static var allowsAccess: Bool { 142 | let status = CLLocationManager.authorizationStatus() 143 | switch status { 144 | case .authorizedAlways: 145 | return true 146 | case .denied, .notDetermined, .restricted: 147 | return false 148 | @unknown default: 149 | remindReportingBug(status.description) 150 | return false 151 | } 152 | } 153 | } 154 | 155 | extension CLError { 156 | static let nsDenied = NSError( 157 | domain: CLError.errorDomain, 158 | code: CLError.Code.denied.rawValue, 159 | userInfo: nil 160 | ) 161 | static let denied = CLError(_nsError: nsDenied) 162 | } 163 | 164 | func == (lhs: Error?, rhs: CLError) -> Bool { 165 | return CLError.nsDenied.isEqual(to: lhs) 166 | } 167 | 168 | extension CLAuthorizationStatus: CustomStringConvertible { 169 | public var description: String { 170 | switch self { 171 | case .notDetermined: 172 | return "CLAuthorizationStatus.notDetermined" 173 | case .restricted: 174 | return "CLAuthorizationStatus.restricted" 175 | case .denied: 176 | return "CLAuthorizationStatus.denied" 177 | case .authorizedAlways: 178 | return "CLAuthorizationStatus.authorizedAlways" 179 | @unknown default: 180 | return "CLAuthorizationStatus.\(self.rawValue)" 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Dynamic/Components/Scheduler/Solar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Solar.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 11/17/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import CoreLocation 10 | 11 | public enum Zenith: Int { 12 | case official 13 | case civil 14 | case nautical 15 | case astronomical 16 | case custom 17 | @available(macOS 10.15, *) 18 | case system 19 | } 20 | 21 | extension Zenith { 22 | static let hasZenithTypeSystem: Bool = { 23 | if #available(macOS 10.15, *) { 24 | return true 25 | } 26 | return false 27 | }() 28 | 29 | var hasSunriseSunsetTime: Bool { 30 | switch self { 31 | case .official, .civil, .nautical, .astronomical: 32 | return true 33 | case .custom, .system: 34 | return false 35 | } 36 | } 37 | } 38 | 39 | struct Solar { 40 | let date: Date 41 | let coordinate: CLLocationCoordinate2D 42 | 43 | init?(for date: Date, coordinate: CLLocationCoordinate2D) { 44 | guard CLLocationCoordinate2DIsValid(coordinate) else { 45 | return nil 46 | } 47 | self.date = date 48 | self.coordinate = coordinate 49 | } 50 | 51 | var sunriseSunsetTime: (sunrise: Date, sunset: Date) { 52 | switch preferences.scheduleZenithType { 53 | case .custom, .system: 54 | fatalError("No custom zenith type in solar") 55 | case .official: 56 | return NTSolar.sunRiseAndSet(forDate: date, 57 | ofKind: .official, 58 | atLocation: coordinate, 59 | inTimeZone: .current)! 60 | case .civil: 61 | return NTSolar.sunRiseAndSet(forDate: date, 62 | ofKind: .civil, 63 | atLocation: coordinate, 64 | inTimeZone: .current)! 65 | case .nautical: 66 | return NTSolar.sunRiseAndSet(forDate: date, 67 | ofKind: .nautical, 68 | atLocation: coordinate, 69 | inTimeZone: .current)! 70 | case .astronomical: 71 | return NTSolar.sunRiseAndSet(forDate: date, 72 | ofKind: .astronomical, 73 | atLocation: coordinate, 74 | inTimeZone: .current)! 75 | } 76 | } 77 | } 78 | 79 | extension DateComponents: Comparable { 80 | public static func < (lhs: DateComponents, rhs: DateComponents) -> Bool { 81 | return lhs.hour! < rhs.hour! 82 | || lhs.hour! == rhs.hour! && lhs.minute! < rhs.minute! 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Icon-160.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Icon-160@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Icon-160@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160@2x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/Icon.imageset/Icon-160@3x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/dark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "baseline_brightness_2_black_18pt_1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "baseline_brightness_2_black_18pt_2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "baseline_brightness_2_black_18pt_3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_1x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_2x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/dark.imageset/baseline_brightness_2_black_18pt_3x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/light.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "outline_wb_sunny_black_18pt_1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "outline_wb_sunny_black_18pt_2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "outline_wb_sunny_black_18pt_3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_1x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_2x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/light.imageset/outline_wb_sunny_black_18pt_3x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "outline_wb_sunny_black_18pt_1x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "baseline_brightness_2_black_18pt_1x.png", 11 | "appearances" : [ 12 | { 13 | "appearance" : "luminosity", 14 | "value" : "dark" 15 | } 16 | ], 17 | "scale" : "1x" 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "filename" : "outline_wb_sunny_black_18pt_2x.png", 22 | "scale" : "2x" 23 | }, 24 | { 25 | "idiom" : "universal", 26 | "filename" : "baseline_brightness_2_black_18pt_2x.png", 27 | "appearances" : [ 28 | { 29 | "appearance" : "luminosity", 30 | "value" : "dark" 31 | } 32 | ], 33 | "scale" : "2x" 34 | }, 35 | { 36 | "idiom" : "universal", 37 | "filename" : "outline_wb_sunny_black_18pt_3x.png", 38 | "scale" : "3x" 39 | }, 40 | { 41 | "idiom" : "universal", 42 | "filename" : "baseline_brightness_2_black_18pt_3x.png", 43 | "appearances" : [ 44 | { 45 | "appearance" : "luminosity", 46 | "value" : "dark" 47 | } 48 | ], 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | }, 56 | "properties" : { 57 | "template-rendering-intent" : "template" 58 | } 59 | } -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_1x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_2x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/baseline_brightness_2_black_18pt_3x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_1x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_2x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Dynamic/Supporting Files/Assets.xcassets/status_bar_icon.imageset/outline_wb_sunny_black_18pt_3x.png -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Credits.html: -------------------------------------------------------------------------------- 1 |

Acknowledgements

2 | 3 | This application makes use of the following third party libraries: 4 | 5 |

LetsMove

6 | 7 | Public domain 8 | 9 |

MASShortcut

10 | 11 |

 12 | Copyright (c) 2012-2013, Vadim Shpakovski
 13 | All rights reserved.
 14 | 
 15 | Redistribution and use in source and binary forms, with or without
 16 | modification, are permitted provided that the following conditions are met:
 17 | 
 18 | 1. Redistributions of source code must retain the above copyright notice, this
 19 |    list of conditions and the following disclaimer.
 20 | 2. Redistributions in binary form must reproduce the above copyright notice,
 21 |    this list of conditions and the following disclaimer in the documentation
 22 |    and/or other materials provided with the distribution.
 23 | 
 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 25 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 26 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 27 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 28 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 29 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 30 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 31 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 33 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 34 | 
35 | 36 |

NTSolar.swift

37 | 38 |

 39 | Created by Neil Tiffin on 5/8/19.
 40 | Copyright (c) 2019 Performance Champions, Inc.
 41 | Copyright (c) 2019 Neil Tiffin.
 42 | 
 43 | Released to the public domain by Neil Tiffin, May 2019
 44 | Released to the public domain by Performance Champions, Inc., May 2019
 45 | 
46 | 47 |

sunriset.c

48 | 49 |

 50 | SUNRISET.C - computes Sun rise/set times, start/end of twilight, and
 51 |              the length of the day at any date and latitude
 52 | 
 53 | Written as DAYLEN.C, 1989-08-16
 54 | 
 55 | Modified to SUNRISET.C, 1992-12-01
 56 | 
 57 | (c) Paul Schlyter, 1989, 1992
 58 | 
 59 | Released to the public domain by Paul Schlyter, December 1992
 60 | 
61 | 62 |

Schedule

63 | 64 |

 65 | MIT License
 66 | 
 67 | Copyright (c) 2018 Quentin Jin
 68 | 
 69 | Permission is hereby granted, free of charge, to any person obtaining a copy
 70 | of this software and associated documentation files (the "Software"), to deal
 71 | in the Software without restriction, including without limitation the rights
 72 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 73 | copies of the Software, and to permit persons to whom the Software is
 74 | furnished to do so, subject to the following conditions:
 75 | 
 76 | The above copyright notice and this permission notice shall be included in all
 77 | copies or substantial portions of the Software.
 78 | 
 79 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 80 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 81 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 82 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 83 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 84 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 85 | SOFTWARE.
 86 | 
87 | 88 |

Sparkle

89 | 90 |

 91 | Copyright (c) 2006-2013 Andy Matuschak.
 92 | Copyright (c) 2009-2013 Elgato Systems GmbH.
 93 | Copyright (c) 2011-2014 Kornel Lesiński.
 94 | Copyright (c) 2015-2017 Mayur Pawashe.
 95 | Copyright (c) 2014 C.W. Betts.
 96 | Copyright (c) 2014 Petroules Corporation.
 97 | Copyright (c) 2014 Big Nerd Ranch.
 98 | All rights reserved.
 99 | 
100 | Permission is hereby granted, free of charge, to any person obtaining a copy of
101 | this software and associated documentation files (the "Software"), to deal in
102 | the Software without restriction, including without limitation the rights to
103 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
104 | the Software, and to permit persons to whom the Software is furnished to do so,
105 | subject to the following conditions:
106 | 
107 | The above copyright notice and this permission notice shall be included in all
108 | copies or substantial portions of the Software.
109 | 
110 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
111 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
112 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
113 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
114 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
115 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
116 | 
117 | =================
118 | EXTERNAL LICENSES
119 | =================
120 | 
121 | bspatch.c and bsdiff.c, from bsdiff 4.3:
122 |     Copyright (c) 2003-2005 Colin Percival.
123 | 
124 | sais.c and sais.c, from sais-lite (2010/08/07):
125 |     Copyright (c) 2008-2010 Yuta Mori.
126 | 
127 | SUSignatureVerifier.m:
128 |     Copyright (c) 2011 Mark Hamlin.
129 | 
130 | All rights reserved.
131 | 
132 | Redistribution and use in source and binary forms, with or without
133 | modification, are permitted providing that the following conditions
134 | are met:
135 | 1. Redistributions of source code must retain the above copyright
136 |    notice, this list of conditions and the following disclaimer.
137 | 2. Redistributions in binary form must reproduce the above copyright
138 |    notice, this list of conditions and the following disclaimer in the
139 |    documentation and/or other materials provided with the distribution.
140 | 
141 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
142 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
144 | ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
145 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
146 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
147 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
148 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
149 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
150 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
151 | POSSIBILITY OF SUCH DAMAGE.
152 | 
153 | 154 |

XMLCoder

155 | 156 |

157 | MIT License
158 | 
159 | Copyright (c) 2018-2019 Shawn Moore and XMLCoder contributors
160 | 
161 | Permission is hereby granted, free of charge, to any person obtaining a copy
162 | of this software and associated documentation files (the "Software"), to deal
163 | in the Software without restriction, including without limitation the rights
164 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
165 | copies of the Software, and to permit persons to whom the Software is
166 | furnished to do so, subject to the following conditions:
167 | 
168 | The above copyright notice and this permission notice shall be included in all
169 | copies or substantial portions of the Software.
170 | 
171 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
172 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
173 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
174 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
175 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
176 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
177 | SOFTWARE.
178 | 
179 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Dynamic-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "TouchBarPrivateAPI.h" 6 | 7 | // MARK: - Skylight 8 | 9 | BOOL SLSGetAppearanceThemeLegacy(); 10 | void SLSSetAppearanceThemeLegacy(BOOL); 11 | BOOL SLSGetAppearanceThemeSwitchesAutomatically() API_AVAILABLE(macosx(10.15)); 12 | void SLSSetAppearanceThemeSwitchesAutomatically(BOOL) API_AVAILABLE(macosx(10.15)); 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Dynamic.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.automation.apple-events 6 | 7 | com.apple.security.personal-information.location 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(VERSION) 21 | CFBundleVersion 22 | $(VERSION) 23 | ITSAppUsesNonExemptEncryption 24 | 25 | LSApplicationCategoryType 26 | public.app-category.lifestyle 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | LSUIElement 30 | 31 | NSAppleEventsUsageDescription 32 | This is how Dynamic Dark Mode manage the dark mode for you. 33 | NSHumanReadableCopyright 34 | Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 35 | NSLocationUsageDescription 36 | This is how Dynamic Dark Mode calculates sunset/sunrise time. 37 | NSMainStoryboardFile 38 | Main 39 | NSPrincipalClass 40 | NSApplication 41 | SUEnableAutomaticChecks 42 | 43 | SUFeedURL 44 | https://apollozhu.github.io/Dynamic-Dark-Mode/appcast.xml 45 | SUPublicEDKey 46 | zM1yWGw3lamVzX/q4ByZu05CrxU8YDil3Cslo/uN7J8= 47 | 48 | 49 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/TouchBarPrivateAPI.h: -------------------------------------------------------------------------------- 1 | // 2 | // TouchBarPrivateAPI.h 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Captain雪ノ下八幡 on 2018/6/27. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | #import 10 | extern void DFRElementSetControlStripPresenceForIdentifier(NSTouchBarItemIdentifier, BOOL); 11 | extern void DFRSystemModalShowsCloseBoxWhenFrontMost(BOOL); 12 | 13 | @interface NSTouchBarItem (PrivateMethods) 14 | + (void)addSystemTrayItem:(NSTouchBarItem *)item; 15 | + (void)removeSystemTrayItem:(NSTouchBarItem *)item; 16 | @end 17 | 18 | 19 | @interface NSTouchBar (PrivateMethods) 20 | + (void)presentSystemModalTouchBar:(NSTouchBar *)touchBar placement:(long long)placement systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier; 21 | + (void)presentSystemModalTouchBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSTouchBarItemIdentifier)identifier; 22 | + (void)dismissSystemModalTouchBar:(NSTouchBar *)touchBar; 23 | + (void)minimizeSystemModalTouchBar:(NSTouchBar *)touchBar; 24 | @end 25 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Automatischer Dark Mode"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Automatischer Dark Mode. All Rechte vorbehalten."; 6 | 7 | /* Privacy - AppleEvents Sending Usage Description */ 8 | "NSAppleEventsUsageDescription" = "Wie Automatischer Dark Mode den Dark Mode verwaltet."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Wie Automatischer Dark Mode den Sonnenauf- und untergang berechnet."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/de.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Umschalten des Dark Modes fehlgeschlagen"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "Etwas lief falsch"; 6 | 7 | /* No comment provided by engineer. */ 8 | "AppleScript.authorization.instruction" = "Wir öffnen die Systemeinstellungen für Sie."; 9 | 10 | /* something went wrong. But it's okay */ 11 | "AppleScript.execute.error" = "Umschalten des Dark Modes fehlgeschlagen"; 12 | 13 | /* Scare the user so they report bugs. */ 14 | "Bug.general.title" = "Kritischen Bug an den Developer melden"; 15 | 16 | /* Failed to attain user location for sunset/sunrise calculation. */ 17 | "Location.notAvailable" = "Zugriff auf Position fehlgeschlagen"; 18 | 19 | /* Can't fetch user's current location. Using cache instead. */ 20 | "Location.useCache" = "Verwendet vorherige Position"; 21 | 22 | /* Drop down menu item to show preferences */ 23 | "Menu.preferences" = "Einstellungen…"; 24 | 25 | /* Use system translation for quit */ 26 | "Menu.quit" = "Beenden"; 27 | 28 | /* Action item to toggle in from menu bar */ 29 | "Menu.toggle" = "Dark Mode umschalten"; 30 | 31 | /* AutoAdjustThreshold */ 32 | "SettingsViewController.autoAdjustThreshold" = "Schwelle automatisch einstellen"; 33 | 34 | /* ScheduleMode */ 35 | "SettingsViewController.scheduleMode" = "Geplanter Modus"; 36 | 37 | /* Astronomical */ 38 | "SunsetSunrise.astronomical" = "Astronomisch"; 39 | 40 | /* Civil */ 41 | "SunsetSunrise.civil" = "Zivil"; 42 | 43 | /* CustomRange */ 44 | "SunsetSunrise.customRange" = "Eigene"; 45 | 46 | /* Nautical */ 47 | "SunsetSunrise.nautical" = "Nautische"; 48 | 49 | /* Official */ 50 | "SunsetSunrise.official" = "Offizielle"; 51 | 52 | /* No comment provided by engineer. */ 53 | "SystemPreferences.open" = "Öffne Systemeinstellungen"; 54 | 55 | /* No comment provided by engineer. */ 56 | "SystemPreferences.skip" = "Überspringen"; 57 | 58 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/eo.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Aŭtomatika Malluma Modo"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "Aŭtomatika Malluma Modo bezonas ĉi tion por administri la malluman modon."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "Kopirajto © 2018-2022 Aŭtomatika Malluma Modo. Ĉiuj rajtoj rezervitaj."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Aŭtomatika Malluma Modo bezonas ĉi tion por kalkuli la tempon de sunleviĝo/sunsubiro."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/eo.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Vi ne permisis Aŭtomatikan Malluman Modon administri la malluman modon."; 3 | 4 | /* Scare the user so they report bugs. */ 5 | "Bug.general.title" = "Raportu Gravan Eraron al la Ellaboranto"; 6 | 7 | /* Request users to provide more context. */ 8 | "Bug.known.title" = "Encountered a Known Issue"; 9 | 10 | /* User did not authorize this app to use location. */ 11 | "Location.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to get your location."; 12 | 13 | /* Failed to attain user location for sunset/sunrise calculation. */ 14 | "Location.notAvailable" = "Ne Eblas Ricevi la Nuna Lokon"; 15 | 16 | /* Took too long to use up retries, most likely off Wi-Fi. */ 17 | "Location.timeout" = "Timedout. Check your network connection."; 18 | 19 | /* Can't fetch user's current location. Using cache instead. */ 20 | "Location.useCache" = "Tempoplanis Uzi Antaŭan Lokon"; 21 | 22 | /* Drop down menu item to show preferences */ 23 | "Menu.preferences" = "Preferoj…"; 24 | 25 | /* Use system translation for quit */ 26 | "Menu.quit" = "Forlasu"; 27 | 28 | /* Action item to toggle in from menu bar */ 29 | "Menu.toggle" = "Baskuligu la Malluman Modon"; 30 | 31 | /* User did not authorize this app to send notifications. */ 32 | "Notification.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to send notifications."; 33 | 34 | /* Indicates either enable or disable opens at login failed. */ 35 | "Preferences.opensAtLogin.failed" = "Failed to update \"opens at login\" settings"; 36 | 37 | /* Notification text for bug report */ 38 | "ScreenBrightnessObserver.startObserving.failed" = "Cannot observe screen brightness change."; 39 | 40 | /* For touch bar button title */ 41 | "SettingsViewController.autoAdjustThreshold" = "Ĝustigi la Sojlon Aŭtomatike"; 42 | 43 | /* For touch bar button title */ 44 | "SettingsViewController.scheduleMode" = "Tempoplana Modo"; 45 | 46 | /* Astronomical */ 47 | "SunsetSunrise.astronomical" = "Astronomia"; 48 | 49 | /* Civil */ 50 | "SunsetSunrise.civil" = "Civila"; 51 | 52 | /* CustomRange */ 53 | "SunsetSunrise.customRange" = "Agordi"; 54 | 55 | /* Nautical */ 56 | "SunsetSunrise.nautical" = "Naŭtika"; 57 | 58 | /* Official */ 59 | "SunsetSunrise.official" = "Ofica"; 60 | 61 | /* Translate the same as System on preferences screen */ 62 | "SunsetSunrise.system" = "Sistemo"; 63 | 64 | /* No comment provided by engineer. */ 65 | "SystemPreferences.open" = "Iru al Sistemaj Preferoj"; 66 | 67 | /* Translate the same as in all other setup process */ 68 | "SystemPreferences.skip" = "Preterpasu"; 69 | 70 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Modo Oscuro Dinámico"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "Esto es como el Modo Oscuro Dinámico te administra el modo oscuro."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Modo Oscuro Dinámico. Todos los derechos reservados."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Esto es como el Modo Oscuro Dinámico calcula el tiempo del amanecer/atardecer."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/es.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "No has permitido el Modo Oscuro Dinámico administrar el modo oscuro"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "Algo salió mal"; 6 | 7 | /* Go to System Preferences */ 8 | "AppleScript.authorization.goToSystemPreferences" = "OK"; 9 | 10 | /* No comment provided by engineer. */ 11 | "AppleScript.authorization.instruction" = "Te llevaremos a Preferencias del Sistema."; 12 | 13 | /* User thinks they have given us permission to control System Events */ 14 | "AppleScript.authorization.nope" = "Not true"; 15 | 16 | /* Something went wrong. But it's okay */ 17 | "AppleScript.execute.error" = "Error al alternar el modo oscuro"; 18 | 19 | /* Scare the user so they report bugs. */ 20 | "Bug.general.title" = "Reportar error al desarrollador"; 21 | 22 | /* Request users to provide more context. */ 23 | "Bug.known.title" = "Encontrado un problema conocido"; 24 | 25 | /* User did not authorize this app to use location. */ 26 | "Location.notAuthorized" = "No has autorizado el Modo Oscuro Dinámico ubicarte."; 27 | 28 | /* Failed to attain user location for sunset/sunrise calculation. */ 29 | "Location.notAvailable" = "No se puede obtener la ubicación actual"; 30 | 31 | /* Took too long to use up retries, most likely off Wi-Fi. */ 32 | "Location.timeout" = "La conexión de red ha expirado. Por favor, compruebala."; 33 | 34 | /* Can't fetch user's current location. Using cache instead. */ 35 | "Location.useCache" = "Programado usando la ubicación anterior"; 36 | 37 | /* Drop down menu item to show preferences */ 38 | "Menu.preferences" = "Preferencias…"; 39 | 40 | /* Use system translation for quit */ 41 | "Menu.quit" = "Salir"; 42 | 43 | /* Action item to toggle in from menu bar */ 44 | "Menu.toggle" = "Conmutar el modo oscuro"; 45 | 46 | /* User did not authorize this app to send notifications. */ 47 | "Notification.notAuthorized" = "No has autorizado el Modo Oscuro Dinámico mandar notificaciones."; 48 | 49 | /* Indicates either enable or disable opens at login failed. */ 50 | "Preferences.opensAtLogin.failed" = "Error al actualizar la configuración de \"abrir al iniciar sesión\""; 51 | 52 | /* Notification text for bug report */ 53 | "ScreenBrightnessObserver.startObserving.failed" = "No se puede observar el cambio de brillo de la pantalla."; 54 | 55 | /* For touch bar button title */ 56 | "SettingsViewController.autoAdjustThreshold" = "Ajustar umbral automáticamente"; 57 | 58 | /* For touch bar button title */ 59 | "SettingsViewController.scheduleMode" = "Modo de programación"; 60 | 61 | /* Astronomical */ 62 | "SunsetSunrise.astronomical" = "Astronómica"; 63 | 64 | /* Civil */ 65 | "SunsetSunrise.civil" = "Civil"; 66 | 67 | /* CustomRange */ 68 | "SunsetSunrise.customRange" = "Personalizado"; 69 | 70 | /* Nautical */ 71 | "SunsetSunrise.nautical" = "Náutica"; 72 | 73 | /* Official */ 74 | "SunsetSunrise.official" = "Oficial"; 75 | 76 | /* No comment provided by engineer. */ 77 | "SystemPreferences.open" = "Abrir Preferencias del Sistema"; 78 | 79 | /* No comment provided by engineer. */ 80 | "SystemPreferences.skip" = "Saltar"; 81 | 82 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamic Dark Mode"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "Voici comment Dynamic Dark Mode gère pour vous le mode sombre."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. Tous droits réservés."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Dynamic Dark Mode nécessite cette autorisation pour calculer le cycle solaire."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/fr.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Vous n'avez pas autorisé Dynamic Dark Dynamic Dark Mode à gérer le Mode sombre"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "Quelque chose c'est mal passé"; 6 | 7 | /* Something went wrong. But it's okay */ 8 | "AppleScript.execute.error" = "Echec du passage en Mode sombre"; 9 | 10 | /* Scare the user so they report bugs. */ 11 | "Bug.general.title" = "Envoyer un rapport de bug critique au développeur"; 12 | 13 | /* Request users to provide more context. */ 14 | "Bug.known.title" = "A rencontré un problème connu"; 15 | 16 | /* User did not authorize this app to use location. */ 17 | "Location.notAuthorized" = "Vous n'avez PAS autorisé Dynamic Dark Mode à obtenir votre localisation."; 18 | 19 | /* Failed to attain user location for sunset/sunrise calculation. */ 20 | "Location.notAvailable" = "Impossible de récupérer la position géographique actuelle"; 21 | 22 | /* Took too long to use up retries, most likely off Wi-Fi. */ 23 | "Location.timeout" = "Erreur. Vérifiez votre connexion internet."; 24 | 25 | /* Can't fetch user's current location. Using cache instead. */ 26 | "Location.useCache" = "Planifié en utilisant la position géographique précédente"; 27 | 28 | /* Drop down menu item to show preferences */ 29 | "Menu.preferences" = "Préférences…"; 30 | 31 | /* Use system translation for quit */ 32 | "Menu.quit" = "Quitter"; 33 | 34 | /* Action item to toggle in from menu bar */ 35 | "Menu.toggle" = "Basculer en Mode sombre"; 36 | 37 | /* User did not authorize this app to send notifications. */ 38 | "Notification.notAuthorized" = "Vous n'avez PAS autorisé Dynamic Dark Mode à envoyer des notifications."; 39 | 40 | /* Indicates either enable or disable opens at login failed. */ 41 | "Preferences.opensAtLogin.failed" = "Impossible de mettre à jour les paramètres \"Ouvrir au démarrage\""; 42 | 43 | /* Notification text for bug report */ 44 | "ScreenBrightnessObserver.startObserving.failed" = "Impossible d'observer le changement de luminosité de l'écran."; 45 | 46 | /* For touch bar button title */ 47 | "SettingsViewController.autoAdjustThreshold" = "Ajustement automatique du seuil"; 48 | 49 | /* For touch bar button title */ 50 | "SettingsViewController.scheduleMode" = "Mode planifié"; 51 | 52 | /* Astronomical */ 53 | "SunsetSunrise.astronomical" = "Astronomique"; 54 | 55 | /* Civil */ 56 | "SunsetSunrise.civil" = "Civil"; 57 | 58 | /* CustomRange */ 59 | "SunsetSunrise.customRange" = "Personnalisé"; 60 | 61 | /* Nautical */ 62 | "SunsetSunrise.nautical" = "Nautique"; 63 | 64 | /* Official */ 65 | "SunsetSunrise.official" = "Officiel"; 66 | 67 | /* Translate the same as System on preferences screen */ 68 | "SunsetSunrise.system" = "Système"; 69 | 70 | /* No comment provided by engineer. */ 71 | "SystemPreferences.open" = "Ouvrir les Préférences système"; 72 | 73 | /* Translate the same as in all other setup process */ 74 | "SystemPreferences.skip" = "Passer"; 75 | 76 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/id.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamic Dark Mode"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Hak cipta © 2018-2022 Dynamic Dark Mode. Seluruh Hak Cipta."; 6 | 7 | /* Privacy - AppleEvents Sending Usage Description */ 8 | "NSAppleEventsUsageDescription" = "Ini merupakan prosedur bagaimana Dynamic Dark Mode mengatur mode gelap untuk Anda."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Ini merupakan prosedur bagaimana Dynamic Dark Mode mengkalkulasi waktu matahari terbenam dan terbit."; 12 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/id.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Anda tidak mengijinkan Dynamic Dark Mode untuk mengatur mode gelap"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "Terdapat sebuah kesalahan"; 6 | 7 | /* No comment provided by engineer. */ 8 | "AppleScript.authorization.instruction" = "Kami akan membawa Anda ke pengaturan sistem."; 9 | 10 | /* something went wrong. But it's okay */ 11 | "AppleScript.execute.error" = "Gagal untuk beralih ke mode gelap"; 12 | 13 | /* Scare the user so they report bugs. */ 14 | "Bug.general.title" = "Laporkan bug penting ke pengembang"; 15 | 16 | /* Failed to attain user location for sunset/sunrise calculation. */ 17 | "Location.notAvailable" = "Tidak dapat mendapatkan lokasi saat ini"; 18 | 19 | /* Can't fetch user's current location. Using cache instead. */ 20 | "Location.useCache" = "Dijadwalkan menggunakan lokasi sebelumnya"; 21 | 22 | /* Drop down menu item to show preferences */ 23 | "Menu.preferences" = "Pengaturan"; 24 | 25 | /* Use system translation for quit */ 26 | "Menu.quit" = "Keluar"; 27 | 28 | /* Action item to toggle in from menu bar */ 29 | "Menu.toggle" = "Beralih ke Mode Gelap"; 30 | 31 | /* AutoAdjustThreshold */ 32 | "SettingsViewController.autoAdjustThreshold" = "Pengaturan Batas Otomatis"; 33 | 34 | /* ScheduleMode */ 35 | "SettingsViewController.scheduleMode" = "Modus Jadwal"; 36 | 37 | /* Astronomical */ 38 | "SunsetSunrise.astronomical" = "Astronomis"; 39 | 40 | /* Civil */ 41 | "SunsetSunrise.civil" = "Sipil"; 42 | 43 | /* CustomRange */ 44 | "SunsetSunrise.customRange" = "Pribadi"; 45 | 46 | /* Nautical */ 47 | "SunsetSunrise.nautical" = "Nautika"; 48 | 49 | /* Official */ 50 | "SunsetSunrise.official" = "Resmi"; 51 | 52 | /* No comment provided by engineer. */ 53 | "SystemPreferences.open" = "Buka Pengaturan Sistem"; 54 | 55 | /* No comment provided by engineer. */ 56 | "SystemPreferences.skip" = "Lewati"; 57 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamic Dark Mode"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "This is how Dynamic Dark Mode manage the dark mode for you."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "© 2018-2022 Dynamic Dark Mode. All rights reserved.(不許複製・禁無断転載)"; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "This is how Dynamic Dark Mode calculates sunset/sunrise time."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ja.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "You didn't allow Dynamic Dark Mode to manage dark mode"; 3 | 4 | /* Scare the user so they report bugs. */ 5 | "Bug.general.title" = "バグを報告する"; 6 | 7 | /* Request users to provide more context. */ 8 | "Bug.known.title" = "Encountered a Known Issue"; 9 | 10 | /* User did not authorize this app to use location. */ 11 | "Location.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to get your location."; 12 | 13 | /* Failed to attain user location for sunset/sunrise calculation. */ 14 | "Location.notAvailable" = "現在地を取得できませんでした"; 15 | 16 | /* Took too long to use up retries, most likely off Wi-Fi. */ 17 | "Location.timeout" = "タイムアウトしました。ネットワークの接続を確認してください"; 18 | 19 | /* Can't fetch user's current location. Using cache instead. */ 20 | "Location.useCache" = "Scheduled Using Previous Location"; 21 | 22 | /* Drop down menu item to show preferences */ 23 | "Menu.preferences" = "設定…"; 24 | 25 | /* Use system translation for quit */ 26 | "Menu.quit" = "終了"; 27 | 28 | /* Action item to toggle in from menu bar */ 29 | "Menu.toggle" = "ダークモードを切り替える"; 30 | 31 | /* User did not authorize this app to send notifications. */ 32 | "Notification.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to send notifications."; 33 | 34 | /* Indicates either enable or disable opens at login failed. */ 35 | "Preferences.opensAtLogin.failed" = "Failed to update \"opens at login\" settings"; 36 | 37 | /* Notification text for bug report */ 38 | "ScreenBrightnessObserver.startObserving.failed" = "Cannot observe screen brightness change."; 39 | 40 | /* For touch bar button title */ 41 | "SettingsViewController.autoAdjustThreshold" = "Auto Adjust Threshold"; 42 | 43 | /* For touch bar button title */ 44 | "SettingsViewController.scheduleMode" = "Schedule Mode"; 45 | 46 | /* Astronomical */ 47 | "SunsetSunrise.astronomical" = "Astronomical"; 48 | 49 | /* Civil */ 50 | "SunsetSunrise.civil" = "Civil"; 51 | 52 | /* CustomRange */ 53 | "SunsetSunrise.customRange" = "カスタム"; 54 | 55 | /* Nautical */ 56 | "SunsetSunrise.nautical" = "Nautical"; 57 | 58 | /* Official */ 59 | "SunsetSunrise.official" = "公式"; 60 | 61 | /* Translate the same as System on preferences screen */ 62 | "SunsetSunrise.system" = "システム"; 63 | 64 | /* No comment provided by engineer. */ 65 | "SystemPreferences.open" = "設定を開く"; 66 | 67 | /* Translate the same as in all other setup process */ 68 | "SystemPreferences.skip" = "スキップ"; 69 | 70 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ko.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamic Dark Mode"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "This is how Dynamic Dark Mode manage the dark mode for you."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. 모든 권리 보유."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Dynamic Dark Mode가 일출과 일몰 시간을 자동으로 계산하기 위해 사용자의 위치 정보 권한을 필요로 합니다."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ko.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Dynamic Dark Mode가 Dark Mode를 관리할 권한이 없습니다."; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "오류가 발생했습니다."; 6 | 7 | /* No comment provided by engineer. */ 8 | "AppleScript.authorization.instruction" = "시스템 환경 설정으로 이동합니다. 새로운 설정이 적용되려면 Dynamic Dark Mode를 재시작해야할 수 있습니다."; 9 | 10 | /* Something went wrong. But it's okay */ 11 | "AppleScript.execute.error" = "Dark Mode를 활성화하는데 실패했습니다."; 12 | 13 | /* Scare the user so they report bugs. */ 14 | "Bug.general.title" = "개발자에게 치명적 오류를 리포트하세요."; 15 | 16 | /* Request users to provide more context. */ 17 | "Bug.known.title" = "Encountered a Known Issue"; 18 | 19 | /* User did not authorize this app to use location. */ 20 | "Location.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to get your location."; 21 | 22 | /* Failed to attain user location for sunset/sunrise calculation. */ 23 | "Location.notAvailable" = "위치 정보를 읽어올 수 없었습니다."; 24 | 25 | /* Took too long to use up retries, most likely off Wi-Fi. */ 26 | "Location.timeout" = "Timedout. Check your network connection."; 27 | 28 | /* Can't fetch user's current location. Using cache instead. */ 29 | "Location.useCache" = "기존에 임시 저장된 위치 정보를 사용합니다."; 30 | 31 | /* Drop down menu item to show preferences */ 32 | "Menu.preferences" = "설정…"; 33 | 34 | /* Use system translation for quit */ 35 | "Menu.quit" = "종료"; 36 | 37 | /* Action item to toggle in from menu bar */ 38 | "Menu.toggle" = "Dark Mode 활성화"; 39 | 40 | /* User did not authorize this app to send notifications. */ 41 | "Notification.notAuthorized" = "You did NOT authorize Dynamic Dark Mode to send notifications."; 42 | 43 | /* Indicates either enable or disable opens at login failed. */ 44 | "Preferences.opensAtLogin.failed" = "Failed to update \"opens at login\" settings"; 45 | 46 | /* Notification text for bug report */ 47 | "ScreenBrightnessObserver.startObserving.failed" = "Cannot observe screen brightness change."; 48 | 49 | /* For touch bar button title */ 50 | "SettingsViewController.autoAdjustThreshold" = "Auto Adjust Threshold"; 51 | 52 | /* For touch bar button title */ 53 | "SettingsViewController.scheduleMode" = "Schedule Mode"; 54 | 55 | /* Astronomical */ 56 | "SunsetSunrise.astronomical" = "Astronomical"; 57 | 58 | /* Civil */ 59 | "SunsetSunrise.civil" = "Civil"; 60 | 61 | /* CustomRange */ 62 | "SunsetSunrise.customRange" = "Custom"; 63 | 64 | /* Nautical */ 65 | "SunsetSunrise.nautical" = "Nautical"; 66 | 67 | /* Official */ 68 | "SunsetSunrise.official" = "Official"; 69 | 70 | /* No comment provided by engineer. */ 71 | "SystemPreferences.open" = "시스템 환경설정 열기"; 72 | 73 | /* No comment provided by engineer. */ 74 | "SystemPreferences.skip" = "건너뛰기"; 75 | 76 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamische Donkere Modus"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "Zó beheert dynamische Donkere Modus de donkere modus voor je."; 6 | 7 | /* Privacy - Location Usage Description */ 8 | "NSLocationUsageDescription" = "Zó berekent Dynamische Donkere Modus de zonsopgang en -ondergang."; 9 | 10 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/nl.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "Je hebt geen toestemming gegeven om Dynamische Donkere Modus de donkere modus te laten beheren"; 3 | 4 | /* Scare the user so they report bugs. */ 5 | "Bug.general.title" = "Meld deze bug aan de ontwikkelaar"; 6 | 7 | /* Request users to provide more context. */ 8 | "Bug.known.title" = "Je bent tegen een bekend probleem aangelopen"; 9 | 10 | /* User did not authorize this app to use location. */ 11 | "Location.notAuthorized" = "Je hebt GEEN toestemming gegeven om Dynamische Donkere Modus je locatie te laten opvragen"; 12 | 13 | /* Failed to attain user location for sunset/sunrise calculation. */ 14 | "Location.notAvailable" = "Kan huidige locatie niet opvragen"; 15 | 16 | /* Took too long to use up retries, most likely off Wi-Fi. */ 17 | "Location.timeout" = "Verzoek verlopen. Controleer je internetverbinding."; 18 | 19 | /* Can't fetch user's current location. Using cache instead. */ 20 | "Location.useCache" = "Ingepland op basis van vorige locatie"; 21 | 22 | /* Drop down menu item to show preferences */ 23 | "Menu.preferences" = "Voorkeuren…"; 24 | 25 | /* Use system translation for quit */ 26 | "Menu.quit" = "Sluit af"; 27 | 28 | /* Action item to toggle in from menu bar */ 29 | "Menu.toggle" = "Schakel donkere modus in/uit"; 30 | 31 | /* User did not authorize this app to send notifications. */ 32 | "Notification.notAuthorized" = "Je hebt GEEN toestemming gegeven om Dynamische Donkere Modus meldingen te laten sturen"; 33 | 34 | /* Indicates either enable or disable opens at login failed. */ 35 | "Preferences.opensAtLogin.failed" = "Kan de automatisch opstarten-instellingen niet aanpassen"; 36 | 37 | /* Notification text for bug report */ 38 | "ScreenBrightnessObserver.startObserving.failed" = "Kan de schermhelderheidsaanpassing niet opvragen"; 39 | 40 | /* For touch bar button title */ 41 | "SettingsViewController.autoAdjustThreshold" = "Drempelw. automatisch aanpassen"; 42 | 43 | /* For touch bar button title */ 44 | "SettingsViewController.scheduleMode" = "Planning"; 45 | 46 | /* Astronomical */ 47 | "SunsetSunrise.astronomical" = "Astronomisch"; 48 | 49 | /* Civil */ 50 | "SunsetSunrise.civil" = "Normaal"; 51 | 52 | /* CustomRange */ 53 | "SunsetSunrise.customRange" = "Aangepast"; 54 | 55 | /* Nautical */ 56 | "SunsetSunrise.nautical" = "Nautisch"; 57 | 58 | /* Official */ 59 | "SunsetSunrise.official" = "Officieel"; 60 | 61 | /* Translate the same as System on preferences screen */ 62 | "SunsetSunrise.system" = "Systeem"; 63 | 64 | /* No comment provided by engineer. */ 65 | "SystemPreferences.open" = "Open systeemvoorkeuren"; 66 | 67 | /* Translate the same as in all other setup process */ 68 | "SystemPreferences.skip" = "Sla over"; 69 | 70 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Dynamic Dark Mode"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "This is how Dynamic Dark Mode manage the dark mode for you."; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. Все права защищены."; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "Так Dynamic Dark Mode рассчитывает время рассвета/заката."; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/ru.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "У Dynamic Dark Mode нет разрешения управлять темным оформлением"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "Что-то пошло не так"; 6 | 7 | /* No comment provided by engineer. */ 8 | "AppleScript.authorization.instruction" = "Переход в Системные настройки."; 9 | 10 | /* Something went wrong. But it's okay */ 11 | "AppleScript.execute.error" = "Не удалось сменить оформление"; 12 | 13 | /* Scare the user so they report bugs. */ 14 | "Bug.general.title" = "Сообщить об ошибке разработчикам"; 15 | 16 | /* Request users to provide more context. */ 17 | "Bug.known.title" = "Это известная проблема"; 18 | 19 | /* User did not authorize this app to use location. */ 20 | "Location.notAuthorized" = "Предоставьте Dynamic Dark Mode доступ к вашему местоположению."; 21 | 22 | /* Failed to attain user location for sunset/sunrise calculation. */ 23 | "Location.notAvailable" = "Не удалось определить местоположение"; 24 | 25 | /* Took too long to use up retries, most likely off Wi-Fi. */ 26 | "Location.timeout" = "Проверьте подключение к интернету."; 27 | 28 | /* Can't fetch user's current location. Using cache instead. */ 29 | "Location.useCache" = "Расписание составлено на основе последней геолокации"; 30 | 31 | /* Drop down menu item to show preferences */ 32 | "Menu.preferences" = "Настройки…"; 33 | 34 | /* Use system translation for quit */ 35 | "Menu.quit" = "Выход"; 36 | 37 | /* Action item to toggle in from menu bar */ 38 | "Menu.toggle" = "Сменить режим"; 39 | 40 | /* User did not authorize this app to send notifications. */ 41 | "Notification.notAuthorized" = "Разрешите Dynamic Dark Mode слать уведомления."; 42 | 43 | /* Indicates either enable or disable opens at login failed. */ 44 | "Preferences.opensAtLogin.failed" = "Не удалось обновить настройку \"Запустить при входе в систему\""; 45 | 46 | /* Notification text for bug report */ 47 | "ScreenBrightnessObserver.startObserving.failed" = "Cannot observe screen brightness change."; 48 | 49 | /* For touch bar button title */ 50 | "SettingsViewController.autoAdjustThreshold" = "Автонастройка порога"; 51 | 52 | /* For touch bar button title */ 53 | "SettingsViewController.scheduleMode" = "Расписание"; 54 | 55 | /* Astronomical */ 56 | "SunsetSunrise.astronomical" = "Астрономическое"; 57 | 58 | /* Civil */ 59 | "SunsetSunrise.civil" = "Гражданское"; 60 | 61 | /* CustomRange */ 62 | "SunsetSunrise.customRange" = "Пользовательское"; 63 | 64 | /* Nautical */ 65 | "SunsetSunrise.nautical" = "Навигационное"; 66 | 67 | /* Official */ 68 | "SunsetSunrise.official" = "Официальное"; 69 | 70 | /* No comment provided by engineer. */ 71 | "SystemPreferences.open" = "Открыть Системные настройки"; 72 | 73 | /* No comment provided by engineer. */ 74 | "SystemPreferences.skip" = "Пропустить"; 75 | 76 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "自动深色模式"; 3 | 4 | /* Privacy - AppleEvents Sending Usage Description */ 5 | "NSAppleEventsUsageDescription" = "“自动深色模式”必须要您的允许才能管理深色模式。"; 6 | 7 | /* Copyright (human-readable) */ 8 | "NSHumanReadableCopyright" = "版权所有 © 2018-2022 自动深色模式。保留所有权利。"; 9 | 10 | /* Privacy - Location Usage Description */ 11 | "NSLocationUsageDescription" = "“自动深色模式”需要您允许读取当前位置才能计算日出日落时间。"; 12 | 13 | -------------------------------------------------------------------------------- /Dynamic/Supporting Files/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* No comment provided by engineer. */ 2 | "AppleScript.authorization.error" = "你并未允许“自动深色模式”管理外观模式。"; 3 | 4 | /* Generic error happened */ 5 | "AppleScript.authorization.failed" = "出错了 QAQ"; 6 | 7 | /* Go to System Preferences */ 8 | "AppleScript.authorization.goToSystemPreferences" = "好"; 9 | 10 | /* No comment provided by engineer. */ 11 | "AppleScript.authorization.instruction" = "我们将带您到“系统偏好设置”。"; 12 | 13 | /* User thinks they have given us permission to control System Events */ 14 | "AppleScript.authorization.nope" = "已经授权"; 15 | 16 | /* Something went wrong. But it's okay */ 17 | "AppleScript.execute.error" = "未能切换外观模式"; 18 | 19 | /* Scare the user so they report bugs. */ 20 | "Bug.general.title" = "告诉开发者 TA 们又写严重的 Bug 了"; 21 | 22 | /* Request users to provide more context. */ 23 | "Bug.known.title" = "能告诉我们发生了什么吗?"; 24 | 25 | /* User did not authorize this app to use location. */ 26 | "Location.notAuthorized" = "您并未授权“自动深色模式”获取您的位置来定时启用深色模式。"; 27 | 28 | /* Failed to attain user location for sunset/sunrise calculation. */ 29 | "Location.notAvailable" = "无法获取当前位置"; 30 | 31 | /* Took too long to use up retries, most likely off Wi-Fi. */ 32 | "Location.timeout" = "未能获取您的当前位置。请检查您的网络连接。"; 33 | 34 | /* Can't fetch user's current location. Using cache instead. */ 35 | "Location.useCache" = "使用之前的位置定时"; 36 | 37 | /* Drop down menu item to show preferences */ 38 | "Menu.preferences" = "偏好设置..."; 39 | 40 | /* Use system translation for quit */ 41 | "Menu.quit" = "退出"; 42 | 43 | /* Action item to toggle in from menu bar */ 44 | "Menu.toggle" = "切换外观模式"; 45 | 46 | /* User did not authorize this app to send notifications. */ 47 | "Notification.notAuthorized" = "您并未允许“自动深色模式”发送通知。\n\n我们不会发送无用的通知,建议您到“系统偏好设置”里开启。"; 48 | 49 | /* Indicates either enable or disable opens at login failed. */ 50 | "Preferences.opensAtLogin.failed" = "未能更新“开机自启动”设置"; 51 | 52 | /* Notification text for bug report */ 53 | "ScreenBrightnessObserver.startObserving.failed" = "无法根据屏幕亮度自动切换深色模式。"; 54 | 55 | /* For touch bar button title */ 56 | "SettingsViewController.autoAdjustThreshold" = "自动切换阀值"; 57 | 58 | /* For touch bar button title */ 59 | "SettingsViewController.scheduleMode" = "定时选项"; 60 | 61 | /* Astronomical */ 62 | "SunsetSunrise.astronomical" = "天文"; 63 | 64 | /* Civil */ 65 | "SunsetSunrise.civil" = "法定"; 66 | 67 | /* CustomRange */ 68 | "SunsetSunrise.customRange" = "自定"; 69 | 70 | /* Nautical */ 71 | "SunsetSunrise.nautical" = "航海"; 72 | 73 | /* Official */ 74 | "SunsetSunrise.official" = "标准"; 75 | 76 | /* No comment provided by engineer. */ 77 | "SystemPreferences.open" = "打开“系统偏好设置”"; 78 | 79 | /* No comment provided by engineer. */ 80 | "SystemPreferences.skip" = "跳过"; 81 | 82 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Access Points/Shortcut.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Shortcut.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 5/3/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import MASShortcut 11 | 12 | enum Shortcut { 13 | public static func startObserving() { 14 | setDefaultToggleShortcut() 15 | MASShortcutBinder.shared()?.bindShortcut( 16 | withDefaultsKey: Preferences.toggleShortcutKey, 17 | toAction: AppleInterfaceStyle.Coordinator.toggleOrShowInterface 18 | ) // will, it will never show interface since it's disabled for that 19 | } 20 | 21 | public static func stopObserving() { 22 | MASShortcutBinder.shared()?.breakBinding(withDefaultsKey: Preferences.toggleShortcutKey) 23 | } 24 | 25 | /// Command-Shift-T 26 | private static func setDefaultToggleShortcut() { 27 | guard !preferences.exists(Preferences.toggleShortcutKey) else { return } 28 | let event = NSEvent.keyEvent(with: .keyDown, location: .zero, modifierFlags: [.command, .shift], 29 | timestamp: 0, windowNumber: 0, context: nil, 30 | characters: "T", charactersIgnoringModifiers: "t", 31 | isARepeat: false, keyCode: UInt16(kVK_ANSI_T))! 32 | let shortcut = MASShortcut(event: event) 33 | let shortcuts = [Preferences.toggleShortcutKey: shortcut] 34 | MASShortcutBinder.shared()?.registerDefaultShortcuts(shortcuts) 35 | let data = try! NSKeyedArchiver.archivedData(withRootObject: shortcut, requiringSecureCoding: true) 36 | preferences.setPreferred(to: data, forKey: Preferences.toggleShortcutKey) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Access Points/StatusBarItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarItem.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 12/11/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | public final class StatusBarItem { 12 | public static let only = StatusBarItem() 13 | private init() { } 14 | 15 | enum Style: Int { 16 | case menu 17 | case rightClick 18 | case hidden 19 | } 20 | 21 | private var statusBarItem: NSStatusItem? 22 | 23 | private var statusBarItemImage: NSImage { 24 | AppleInterfaceStyle.isDark ? #imageLiteral(resourceName: "dark") : #imageLiteral(resourceName: "light") 25 | } 26 | 27 | private func createStatusBarItemIfNecessary() { 28 | guard statusBarItem == nil else { return } 29 | statusBarItem = NSStatusBar.system.statusItem( 30 | withLength: NSStatusItem.squareLength 31 | ) 32 | statusBarItem?.button?.image = statusBarItemImage 33 | statusBarItem?.button?.sendAction(on: [.leftMouseUp, .rightMouseUp]) 34 | statusBarItem?.button?.action = #selector(handleEvent) 35 | statusBarItem?.button?.target = self 36 | } 37 | 38 | @objc private func handleEvent() { 39 | if NSApp.currentEvent?.type == .rightMouseUp { 40 | SettingsViewController.show() 41 | } else { 42 | AppleInterfaceStyle.Coordinator.toggleOrShowInterface() 43 | } 44 | } 45 | 46 | private func buildMenu() -> NSMenu { 47 | let menu = NSMenu() 48 | let toggleItem = NSMenuItem( 49 | title: NSLocalizedString( 50 | "Menu.toggle", 51 | value: "Toggle Dark Mode", 52 | comment: "Action item to toggle in from menu bar"), 53 | action: #selector(handleEvent), 54 | keyEquivalent: "" 55 | ) 56 | toggleItem.target = self 57 | if #available(macOS 10.15, *) { 58 | toggleItem.bindEnabledToNotAppleInterfaceStyleSwitchesAutomatically() 59 | } 60 | menu.addItem(toggleItem) 61 | menu.addItem(.separator()) 62 | let preferencesItem = NSMenuItem( 63 | title: NSLocalizedString( 64 | "Menu.preferences", 65 | value: "Preferences…", 66 | comment: "Drop down menu item to show preferences"), 67 | action: #selector(SettingsViewController.show), 68 | keyEquivalent: "," 69 | ) 70 | preferencesItem.keyEquivalentModifierMask = .command 71 | preferencesItem.target = SettingsViewController.self 72 | menu.addItem(preferencesItem) 73 | let quitItem = NSMenuItem( 74 | title: NSLocalizedString( 75 | "Menu.quit", 76 | value: "Quit", 77 | comment: "Use system translation for quit"), 78 | action: #selector(NSApplication.terminate(_:)), 79 | keyEquivalent: "Q" 80 | ) 81 | quitItem.keyEquivalentModifierMask = .command 82 | menu.addItem(quitItem) 83 | return menu 84 | } 85 | 86 | private var appearanceObservation: NSKeyValueObservation? 87 | private var settingsStyleObservation: NSKeyValueObservation? 88 | 89 | public func startObserving() { 90 | appearanceObservation = NSApp.observe(\.effectiveAppearance) { 91 | [weak self] _, _ in 92 | guard let self = self else { return } 93 | self.statusBarItem?.button?.image = self.statusBarItemImage 94 | } 95 | settingsStyleObservation = preferences.observe( 96 | \.rawSettingsStyle, options: [.initial, .new] 97 | ) { [weak self] _, change in 98 | guard let self = self else { return } 99 | switch preferences.settingsStyle { 100 | case .menu: 101 | self.createStatusBarItemIfNecessary() 102 | self.statusBarItem?.menu = self.buildMenu() 103 | case .rightClick: 104 | self.createStatusBarItemIfNecessary() 105 | self.statusBarItem?.menu = nil 106 | case .hidden: 107 | guard let statusBarItem = self.statusBarItem else { return } 108 | NSStatusBar.system.removeStatusItem(statusBarItem) 109 | self.statusBarItem = nil 110 | } 111 | } 112 | } 113 | 114 | public func stopObserving() { 115 | appearanceObservation?.invalidate() 116 | settingsStyleObservation?.invalidate() 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Access Points/TouchBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TouchBar.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 5/3/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | enum TouchBar { 12 | private static let itemID = NSTouchBarItem.Identifier(rawValue: "io.github.apollozhu.Dynamic.switch") 13 | 14 | private static let item: NSTouchBarItem = { 15 | let item = NSCustomTouchBarItem(identifier: itemID) 16 | let button = NSButton(image: #imageLiteral(resourceName: "Icon"), 17 | target: AppleInterfaceStyle.Coordinator, 18 | action: #selector(AppleInterfaceStyleCoordinator.toggleOrShowInterface)) 19 | item.view = button 20 | return item 21 | }() 22 | 23 | public static func setup() { 24 | // DFRSystemModalShowsCloseBoxWhenFrontMost(false) 25 | NSTouchBarItem.addSystemTrayItem(item) 26 | } 27 | 28 | public static func tearDown() { 29 | NSTouchBarItem.removeSystemTrayItem(item) 30 | } 31 | 32 | public static func show() { 33 | DFRElementSetControlStripPresenceForIdentifier(itemID, true) 34 | } 35 | 36 | public static func hide() { 37 | DFRElementSetControlStripPresenceForIdentifier(itemID, false) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Dynamic/View Controller/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/6/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import UserNotifications 11 | #if canImport(LetsMove) 12 | import LetsMove 13 | #endif 14 | 15 | @NSApplicationMain 16 | class AppDelegate: NSObject, NSApplicationDelegate { 17 | func applicationDidFinishLaunching(_ aNotification: Notification) { 18 | #if !DEBUG 19 | PFMoveToApplicationsFolderIfNecessary() 20 | #endif 21 | 22 | UNUserNotificationCenter.current().delegate = self 23 | TouchBar.setup() 24 | Shortcut.startObserving() 25 | if #available(macOS 10.15, *), preferences.AppleInterfaceStyleSwitchesAutomatically { 26 | Shortcut.stopObserving() 27 | preferences.scheduleZenithType = .system 28 | } 29 | if preferences.hasLaunchedBefore { 30 | Preferences.setupDefaultsForNewFeatures() 31 | Preferences.startObserving() 32 | AppleInterfaceStyle.Coordinator.setup() 33 | } else { 34 | Welcome.show() 35 | } 36 | } 37 | 38 | public func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { 39 | reopen() 40 | return false 41 | } 42 | 43 | func applicationWillTerminate(_ notification: Notification) { 44 | Welcome.close() 45 | TouchBar.tearDown() 46 | Preferences.stopObserving() 47 | AppleInterfaceStyle.Coordinator.tearDown() 48 | } 49 | } 50 | 51 | func reopen() { 52 | if preferences.hasLaunchedBefore { 53 | SettingsViewController.show() 54 | } else { 55 | Welcome.show() 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Settings/DynamicDesktopSettingsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicDesktopSettingsViewController.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by CaptainYukinoshitaHachiman on 8/7/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class DynamicDesktopSettingsViewController: NSViewController { 12 | 13 | @IBOutlet weak var lightDesktopButton: NSButton! 14 | @IBOutlet weak var darkDesktopButton: NSButton! 15 | @IBOutlet weak var clearButton: NSButton! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | updateContents() 20 | } 21 | 22 | private func updateContents() { 23 | // Since clear will directly dismiss, 24 | // we only need to handle the cases where there're images set 25 | if let lightDesktopURL = preferences.lightDesktopURL { 26 | lightDesktopButton.image = NSImage(byReferencing: lightDesktopURL) 27 | } else { 28 | lightDesktopButton.image = NSImage(named: NSImage.folderName) 29 | } 30 | if let darkDesktopURL = preferences.darkDesktopURL { 31 | darkDesktopButton.image = NSImage(byReferencing: darkDesktopURL) 32 | } else { 33 | darkDesktopButton.image = NSImage(named: NSImage.folderName) 34 | } 35 | clearButton.isEnabled = preferences.exists(\.lightDesktopURL) 36 | || preferences.exists(\.darkDesktopURL) 37 | AppleInterfaceStyle.updateWallpaper() 38 | } 39 | 40 | @IBAction func clearDesktop(_ sender: Any) { 41 | preferences.lightDesktopURL = nil 42 | preferences.darkDesktopURL = nil 43 | updateContents() 44 | } 45 | 46 | @IBAction func setLightDesktop(_ sender: Any) { 47 | selectImage { [unowned self] url in 48 | preferences.lightDesktopURL = url 49 | self.updateContents() 50 | } 51 | } 52 | 53 | @IBAction func setDarkDesktop(_ sender: Any) { 54 | selectImage { [unowned self] url in 55 | preferences.darkDesktopURL = url 56 | self.updateContents() 57 | } 58 | } 59 | 60 | private func selectImage(then process: @escaping (URL?) -> Void) { 61 | let openPanel = NSOpenPanel() 62 | openPanel.allowsMultipleSelection = false 63 | openPanel.canChooseDirectories = false 64 | openPanel.canCreateDirectories = false 65 | openPanel.canChooseFiles = true 66 | openPanel.allowedFileTypes = ["jpg", "jpeg", "png", "tiff"] 67 | openPanel.begin { response in 68 | guard response == .OK else { return } 69 | process(openPanel.url) 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Settings/SettingsViewController + TouchBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsViewController + TouchBar.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Captain雪ノ下八幡 on 2018/6/27. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | extension SettingsViewController: NSTouchBarDelegate { 12 | override func makeTouchBar() -> NSTouchBar? { 13 | let touchBar = NSTouchBar() 14 | touchBar.delegate = self 15 | touchBar.defaultItemIdentifiers = [.thresholdPopoverItem, .scheduleTypePopoverItem] 16 | return touchBar 17 | } 18 | 19 | func touchBar(_ touchBar: NSTouchBar, makeItemForIdentifier identifier: NSTouchBarItem.Identifier) -> NSTouchBarItem? { 20 | let defaultsController = NSUserDefaultsController.shared 21 | switch identifier { 22 | case .thresholdPopoverItem: 23 | let popoverItem = NSPopoverTouchBarItem(identifier: identifier) 24 | let sliderTouchBar = NSTouchBar() 25 | sliderTouchBar.defaultItemIdentifiers = [.thresholdSubSliderItem] 26 | sliderTouchBar.delegate = self 27 | popoverItem.popoverTouchBar = sliderTouchBar 28 | popoverItem.pressAndHoldTouchBar = sliderTouchBar 29 | popoverItem.collapsedRepresentationLabel = LocalizedString.SettingsViewController.autoAdjustThreshold 30 | popoverItem.view?.bind(.enabled, to: defaultsController, 31 | withKeyPath: preferences.bindingKeyPath(\.adjustForBrightness), options: nil) 32 | if #available(macOS 10.15, *) { 33 | popoverItem.view?.bindEnabledToNotAppleInterfaceStyleSwitchesAutomatically(withName: .enabled2) 34 | } 35 | return popoverItem 36 | case .thresholdSubSliderItem: 37 | let sliderItem = NSSliderTouchBarItem(identifier: identifier) 38 | sliderItem.label = LocalizedString.SettingsViewController.autoAdjustThreshold 39 | sliderItem.slider.minValue = 0 40 | sliderItem.slider.maxValue = 100 41 | sliderItem.slider.bind(.value, to: defaultsController, 42 | withKeyPath: preferences.bindingKeyPath(\.brightnessThreshold), options: nil) 43 | sliderItem.slider.bind(.enabled, to: defaultsController, 44 | withKeyPath: preferences.bindingKeyPath(\.adjustForBrightness), options: nil) 45 | if #available(macOS 10.15, *) { 46 | sliderItem.slider.bindEnabledToNotAppleInterfaceStyleSwitchesAutomatically(withName: .enabled2) 47 | } 48 | return sliderItem 49 | case .scheduleTypePopoverItem: 50 | let popoverItem = NSPopoverTouchBarItem(identifier: identifier) 51 | let scrubberTouchBar = NSTouchBar() 52 | scrubberTouchBar.defaultItemIdentifiers = [.scheduleTypeSubScrubberItem] 53 | scrubberTouchBar.delegate = self 54 | popoverItem.collapsedRepresentationLabel = LocalizedString.SettingsViewController.scheduleMode 55 | popoverItem.popoverTouchBar = scrubberTouchBar 56 | popoverItem.view?.bind(.enabled, to: defaultsController, 57 | withKeyPath: preferences.bindingKeyPath(\.scheduled), options: nil) 58 | return popoverItem 59 | case .scheduleTypeSubScrubberItem: 60 | let scrubber = NSScrubber() 61 | scrubber.dataSource = self 62 | scrubber.delegate = self 63 | scrubber.floatsSelectionViews = true 64 | scrubber.isContinuous = true 65 | scrubber.mode = .fixed 66 | scrubber.floatsSelectionViews = true 67 | scrubber.selectionOverlayStyle = .outlineOverlay 68 | scrubber.scrubberLayout = NSScrubberProportionalLayout( 69 | numberOfVisibleItems: numberOfItems(for: scrubber) 70 | ) 71 | scrubber.backgroundColor = .scrubberTexturedBackground 72 | scrubber.bind(.selectedIndex, to: defaultsController, 73 | withKeyPath: preferences.bindingKeyPath(\.scheduleType), options: nil) 74 | let scrubberItem = NSCustomTouchBarItem(identifier: identifier) 75 | scrubberItem.view = scrubber 76 | return scrubberItem 77 | default: 78 | fatalError("Unexpected identifier") 79 | } 80 | } 81 | } 82 | 83 | extension SettingsViewController: NSScrubberDataSource, NSScrubberDelegate { 84 | func numberOfItems(for scrubber: NSScrubber) -> Int { 85 | return Zenith.hasZenithTypeSystem ? 6 : 5 86 | } 87 | 88 | func scrubber(_ scrubber: NSScrubber, viewForItemAt index: Int) -> NSScrubberItemView { 89 | let view = NSScrubberTextItemView() 90 | switch index { 91 | case 0: 92 | view.title = LocalizedString.SunsetSunrise.official 93 | case 1: 94 | view.title = LocalizedString.SunsetSunrise.civil 95 | case 2: 96 | view.title = LocalizedString.SunsetSunrise.nautical 97 | case 3: 98 | view.title = LocalizedString.SunsetSunrise.astronomical 99 | case 4: 100 | view.title = LocalizedString.SunsetSunrise.customRange 101 | case 5: 102 | guard Zenith.hasZenithTypeSystem else { fallthrough } 103 | view.title = LocalizedString.SunsetSunrise.system 104 | default: 105 | fatalError("Unexpected index number") 106 | } 107 | return view 108 | } 109 | 110 | func scrubber(_ scrubber: NSScrubber, didSelectItemAt selectedIndex: Int) { 111 | preferences.scheduleZenithType = Zenith(rawValue: selectedIndex) ?? .official 112 | } 113 | } 114 | 115 | extension NSTouchBarItem.Identifier: ExpressibleByStringLiteral { 116 | public init(stringLiteral value: StringLiteralType) { 117 | self.init(rawValue: value) 118 | } 119 | } 120 | 121 | extension NSTouchBarItem.Identifier { 122 | static let thresholdPopoverItem = "thresholdPopoverItem" as NSTouchBarItem.Identifier 123 | static let scheduleTypePopoverItem = "scheduleTypePopoverItem" as NSTouchBarItem.Identifier 124 | static let thresholdSubSliderItem = "thresholdSubSliderItem" as NSTouchBarItem.Identifier 125 | static let scheduleTypeSubScrubberItem = "scheduleTypeSubSliderItem" as NSTouchBarItem.Identifier 126 | } 127 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Settings/SettingsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsViewController.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 6/9/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | extension NSStoryboard { 12 | static let main = NSStoryboard(name: "Main", bundle: nil) 13 | } 14 | 15 | class SettingsViewController: NSViewController { 16 | @objc dynamic private let hasZenithTypeSystem = Zenith.hasZenithTypeSystem 17 | 18 | private static weak var window: NSWindow? = nil 19 | @objc public static func show() { 20 | if window == nil { 21 | ValueTransformer.setValueTransformer( 22 | UsesCustomRange(), forName: .usesCustomRangeTransformerName 23 | ) 24 | let windowController = NSStoryboard.main 25 | .instantiateController(withIdentifier: "window") 26 | as! NSWindowController 27 | windowController.showWindow(nil) 28 | window = windowController.window 29 | } 30 | window?.windowController?.showWindow(nil) 31 | NSApp.activate(ignoringOtherApps: true) 32 | window?.makeKeyAndOrderFront(nil) 33 | } 34 | 35 | @IBAction func close(_ sender: Any) { 36 | SettingsViewController.window?.close() 37 | } 38 | 39 | override func viewDidAppear() { 40 | super.viewDidAppear() 41 | // The following is required to attach touchbar to a view controller. 42 | // https://stackoverflow.com/questions/42342231/how-to-show-touch-bar-in-a-viewcontroller 43 | view.window?.unbind(NSBindingName(rawValue: #keyPath(touchBar))) 44 | view.window?.bind(NSBindingName(rawValue: #keyPath(touchBar)), to: self, withKeyPath: #keyPath(touchBar), options: nil) 45 | NSUserDefaultsController.shared.appliesImmediately = true 46 | } 47 | 48 | override func viewDidDisappear() { 49 | super.viewDidDisappear() 50 | UserNotification.removeAll() 51 | } 52 | 53 | @IBAction func reSetup(_ sender: Any) { 54 | let name = Bundle.main.bundleIdentifier! 55 | preferences.removePersistentDomain(forName: name) 56 | Preferences.stopObserving() 57 | StatusBarItem.only.stopObserving() 58 | Scheduler.shared.cancel() 59 | ScreenBrightnessObserver.shared.stopObserving() 60 | close(self) 61 | Welcome.show() 62 | } 63 | } 64 | 65 | class UsesCustomRange: ValueTransformer { 66 | override class func transformedValueClass() -> AnyClass { 67 | return NSNumber.self 68 | } 69 | 70 | override class func allowsReverseTransformation() -> Bool { 71 | return false 72 | } 73 | 74 | override func transformedValue(_ value: Any?) -> Any? { 75 | return (value as? NSNumber)?.intValue == Zenith.custom.rawValue 76 | } 77 | } 78 | 79 | extension NSValueTransformerName { 80 | static let usesCustomRangeTransformerName 81 | = NSValueTransformerName(rawValue: "UsesCustomRange") 82 | } 83 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/AllowLocationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AllowLocationViewController.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/28/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import CoreLocation 11 | 12 | class AllowLocationViewController: NSViewController, LastSetupStep { 13 | 14 | @IBOutlet weak var showPreferences: NSButton! 15 | 16 | var whenNotAuthorized: Bool { 17 | if Location.allowsAccess { 18 | showNextOnce() 19 | return false 20 | } else { 21 | return true 22 | } 23 | } 24 | 25 | override func viewDidAppear() { 26 | super.viewDidAppear() 27 | guard whenNotAuthorized else { return } 28 | showPreferences.isHidden = false 29 | LocationManager.serial.delegate = self 30 | LocationManager.serial.fetch { [weak self] in 31 | switch $0 { 32 | case .failed(let error): 33 | self?.onError(error) 34 | case .cached: 35 | self?.onError() 36 | case .current: 37 | self?.showNextOnce() 38 | } 39 | } 40 | } 41 | 42 | // MARK: - Navigation 43 | 44 | @IBAction func skip(_ sender: Any) { 45 | showNextOnce() 46 | } 47 | 48 | @IBAction func openPreferences(_ sender: NSButton) { 49 | guard whenNotAuthorized else { return } 50 | redirectToSystemPreferences() 51 | } 52 | 53 | private var firstTime = true 54 | 55 | func showNextOnce() { 56 | if firstTime { 57 | firstTime = false 58 | showNext() 59 | } 60 | } 61 | } 62 | 63 | private func redirectToSystemPreferences() { 64 | openURL("x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices") 65 | } 66 | 67 | // MARK: - Delegate Implementation 68 | 69 | extension AllowLocationViewController: CLLocationManagerDelegate { 70 | private func onError(_ error: Error? = nil) { 71 | needsPermission(error == CLError.denied 72 | ? LocalizedString.Location.notAuthorized 73 | : LocalizedString.Location.notAvailable, 74 | openPreferences: redirectToSystemPreferences, 75 | skip: showNextOnce) 76 | } 77 | 78 | func locationManager(_ manager: CLLocationManager, 79 | didChangeAuthorization status: CLAuthorizationStatus) { 80 | _ = whenNotAuthorized 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/AllowSystemEventsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AllowSystemEventsViewController.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/25/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class AllowSystemEventsViewController: NSViewController, SetupStep { 12 | override func viewDidAppear() { 13 | super.viewDidAppear() 14 | AppleScript.requestPermission { [weak self] authorized in 15 | if authorized { 16 | self?.showNext() 17 | } else { 18 | DispatchQueue.main.async { [weak self] in 19 | self?.showPreferences.isHidden = false 20 | } 21 | } 22 | } 23 | } 24 | 25 | @IBAction func skip(_ sender: Any) { 26 | showNext() 27 | } 28 | 29 | @IBOutlet weak var showPreferences: NSButton! 30 | @IBAction func openPreferences(_ sender: NSButton) { 31 | AppleScript.requestPermission { [weak self] authorized in 32 | guard let self = self else { return } 33 | if authorized { 34 | self.showNext() 35 | } else { 36 | self.needsPermission(AppleScript.notAuthorized, 37 | openPreferences: AppleScript.redirectToSystemPreferences, 38 | skip: self.showNext) 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/InitialSetupViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InitialSetupViewController.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/16/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class InitialSetupViewController: NSViewController { 12 | @IBAction func skip(_ sender: Any) { 13 | Welcome.skip() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/SetupStep.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SetupStep.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 12/11/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | protocol SetupStep: AnyObject { 12 | func showNext() 13 | } 14 | 15 | var setupSteps = [NSViewController]() 16 | 17 | func rewindSetupSteps() { 18 | while case let viewController? = setupSteps.popLast() { 19 | viewController.presentedViewControllers?.forEach { 20 | viewController.dismiss($0) 21 | } 22 | } 23 | } 24 | 25 | extension SetupStep where Self: NSViewController { 26 | func showNext() { 27 | setupSteps.append(self) 28 | DispatchQueue.main.async { [weak self] in 29 | self?.performSegue(withIdentifier: "next", sender: nil) 30 | } 31 | } 32 | 33 | func needsPermission(_ message: String, 34 | openPreferences: @escaping () -> Void, 35 | skip: @escaping () -> Void) { 36 | showAlert(withConfiguration: { alert in 37 | alert.messageText = message 38 | alert.addButton(withTitle: NSLocalizedString( 39 | "SystemPreferences.open", 40 | value: "Open System Preferences", 41 | comment: "" 42 | )) 43 | alert.addButton(withTitle: NSLocalizedString( 44 | "SystemPreferences.skip", 45 | value: "Skip", 46 | comment: "Translate the same as in all other setup process" 47 | )) 48 | alert.alertStyle = .warning 49 | }, then: { response in 50 | switch response { 51 | case .alertFirstButtonReturn: 52 | openPreferences() 53 | case .alertSecondButtonReturn: 54 | skip() 55 | default: 56 | fatalError("Unhandled authorization response") 57 | } 58 | }) 59 | } 60 | } 61 | 62 | protocol LastSetupStep: SetupStep { } 63 | 64 | extension LastSetupStep { 65 | func showNext() { 66 | Welcome.skip() 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/SlideSegue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SlideSegue.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/25/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class SlideSegue: NSStoryboardSegue, NSViewControllerPresentationAnimator { 12 | override func perform() { 13 | let source = sourceController as! NSViewController 14 | let destination = destinationController as! NSViewController 15 | source.present(destination, animator: self) 16 | } 17 | 18 | private let animationDuration: TimeInterval = 0.75 19 | private let frameWidth: CGFloat = 480 20 | private lazy var origin = CGPoint(x: frameWidth, y: 0) 21 | 22 | func animatePresentation(of viewController: NSViewController, from fromViewController: NSViewController) { 23 | let presented = viewController.view 24 | presented.wantsLayer = true 25 | let presentor = fromViewController.view 26 | presentor.addSubview(presented) 27 | presented.frame.origin = origin 28 | NSAnimationContext.runAnimationGroup { context in 29 | context.duration = animationDuration 30 | presentor.subviews.forEach { 31 | if $0 == presented { return } 32 | $0.animator().alphaValue = 0 33 | } 34 | presented.animator().frame.origin = .zero 35 | presented.animator().frame.size.width = frameWidth 36 | } 37 | } 38 | 39 | func animateDismissal(of viewController: NSViewController, from fromViewController: NSViewController) { 40 | let presented = viewController.view 41 | let presentor = fromViewController.view 42 | NSAnimationContext.runAnimationGroup({ context in 43 | context.duration = animationDuration 44 | presented.animator().frame.origin = origin 45 | presentor.subviews.forEach { 46 | if $0 == presented { return } 47 | $0.animator().alphaValue = 1 48 | } 49 | }, completionHandler: { 50 | presented.removeFromSuperview() 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Dynamic/View Controller/Welcome/Welcome.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Welcome.swift 3 | // Dynamic Dark Mode 4 | // 5 | // Created by Apollo Zhu on 9/26/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class Welcome: NSWindowController { 12 | private static var welcome: Welcome? = nil 13 | 14 | public static func show() { 15 | if welcome == nil { 16 | welcome = NSStoryboard.main 17 | .instantiateController(withIdentifier: "setup") 18 | as? Welcome 19 | rewindSetupSteps() 20 | setupSteps.append(welcome!.contentViewController!) 21 | } 22 | welcome?.window?.level = .floating 23 | welcome?.showWindow(nil) 24 | NSApp.activate(ignoringOtherApps: true) 25 | welcome?.window?.makeKeyAndOrderFront(nil) 26 | } 27 | 28 | public static func skip() { 29 | Welcome.close() 30 | preferences.hasLaunchedBefore = true 31 | Preferences.setupAsSuggested() 32 | Preferences.startObserving() 33 | AppleInterfaceStyle.Coordinator.setup() 34 | SettingsViewController.show() 35 | } 36 | 37 | public static func close() { 38 | welcome?.close() 39 | rewindSetupSteps() 40 | welcome = nil 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Dynamic/View Controller/de.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode"; ObjectID = "1Xt-HY-uBw"; */ 2 | "1Xt-HY-uBw.title" = "Automatischer Dark Mode"; 3 | 4 | /* Class = "NSTextFieldCell"; title = "From:"; ObjectID = "4da-BG-PBG"; */ 5 | "4da-BG-PBG.title" = "Von:"; 6 | 7 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 8 | "4J7-dP-txa.title" = "Vollbildmodus"; 9 | 10 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "4NB-3a-2UR"; */ 11 | "4NB-3a-2UR.title" = "Speichern"; 12 | 13 | /* Class = "NSTextFieldCell"; title = "Auto Adjust"; ObjectID = "4Oz-wH-7ZV"; */ 14 | "4Oz-wH-7ZV.title" = "Automatisch anpassen"; 15 | 16 | /* Class = "NSMenuItem"; title = "Quit Dynamic Dark Mode"; ObjectID = "4sb-4s-VLi"; */ 17 | "4sb-4s-VLi.title" = "Automatischer Dark Mode beenden"; 18 | 19 | /* Class = "NSMenuItem"; title = "About Dynamic Dark Mode"; ObjectID = "5kV-Vb-QxS"; */ 20 | "5kV-Vb-QxS.title" = "Über Automatischer Dark Mode"; 21 | 22 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode Preferences"; ObjectID = "32v-z6-q8Z"; */ 23 | "32v-z6-q8Z.title" = "Automatischer Dark Mode Einstellungen"; 24 | 25 | /* Class = "NSTextFieldCell"; title = "To Open Preferences..."; ObjectID = "87M-Sa-k9k"; */ 26 | "87M-Sa-k9k.title" = "Um die Einstellungen zu öffnen..."; 27 | 28 | /* Class = "NSTextFieldCell"; title = "Allow Controlling System Events"; ObjectID = "92J-gp-8D9"; */ 29 | "92J-gp-8D9.title" = "Erlaube die Kontrolle von “System Events”"; 30 | 31 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 32 | "aTl-1u-JFS.title" = "Drucken…"; 33 | 34 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 35 | "aUF-d1-5bR.title" = "Fenster"; 36 | 37 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 38 | "AYu-sK-qS6.title" = "Hauptmenü"; 39 | 40 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 41 | "bib-Uj-vzu.title" = "Dati"; 42 | 43 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 44 | "BOF-NM-1cW.title" = "Einstellungen…"; 45 | 46 | /* Class = "NSTextFieldCell"; title = "Welcome to Dynamic Dark Mode"; ObjectID = "Buz-5v-iiv"; */ 47 | "Buz-5v-iiv.title" = "Willkommen zu Automatischer Dark Mode"; 48 | 49 | /* Class = "NSButtonCell"; title = "Dark Mode On Between"; ObjectID = "Dcd-f7-wbP"; */ 50 | "Dcd-f7-wbP.title" = "Dark Mode an zwischen"; 51 | 52 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 53 | "dMs-cI-mzQ.title" = "Datei"; 54 | 55 | /* Class = "NSTextFieldCell"; title = "Threshold:"; ObjectID = "do3-JG-x5l"; */ 56 | "do3-JG-x5l.title" = "Schwelle:"; 57 | 58 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 59 | "DVo-aG-piG.title" = "Schließen"; 60 | 61 | /* Class = "NSButtonCell"; title = "Left click on the menu bar icon to show menu, then choose Preferences..."; ObjectID = "EJk-BY-RUI"; */ 62 | "EJk-BY-RUI.title" = "Linksklick auf das Icon im Menü, dann Einstellungen auswählen...”"; 63 | 64 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 65 | "F2S-fz-NVQ.title" = "Hilfe"; 66 | 67 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode Help"; ObjectID = "FKE-Sm-Kum"; */ 68 | "FKE-Sm-Kum.title" = "Automatischer Dark Mode Hilfe"; 69 | 70 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 71 | "H8h-7b-M4v.title" = "Anzeige"; 72 | 73 | /* Class = "NSTextFieldCell"; title = "To:"; ObjectID = "hBx-FP-5Wr"; */ 74 | "hBx-FP-5Wr.title" = "Bis:"; 75 | 76 | /* Class = "NSTextFieldCell"; title = "This is where you can later decide if you want to turn on and off dark mode based on your screen brightness, set a custom schedule of when to turn it on and off, or according to the calculated sunset-sunrise time based your location."; ObjectID = "heB-g6-Sln"; */ 77 | "heB-g6-Sln.title" = "Hier können Sie später entscheiden ob sie den Dark Mode anhand der Bildschirmhelligkeit an- oder ausschalten möchten, eine festgelegte Zeit für den Dark Mode, oder anhand des Sonnenauf- oder untergangs"; 78 | 79 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 80 | "HyV-fh-RgO.title" = "Anzeige"; 81 | 82 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 83 | "hz9-B4-Xy5.title" = "Services"; 84 | 85 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "i9M-2z-rxR"; */ 86 | "i9M-2z-rxR.title" = "Überspringen"; 87 | 88 | /* Class = "NSButtonCell"; title = "Opens At Login"; ObjectID = "IB3-f2-BQf"; */ 89 | "IB3-f2-BQf.title" = "Beim Login öffnen"; 90 | 91 | /* Class = "NSMenuItem"; title = "Custom Range"; ObjectID = "Ibh-ok-jMp"; */ 92 | "Ibh-ok-jMp.title" = "Benutzerdefinierter Zeitraum"; 93 | 94 | /* Class = "NSTextFieldCell"; title = "Allow Access Current Location"; ObjectID = "jwe-Zh-ib0"; */ 95 | "jwe-Zh-ib0.title" = "Zugriff auf die aktuelle Position erlauben"; 96 | 97 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 98 | "Kd2-mp-pUS.title" = "Alle anzeigen"; 99 | 100 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 101 | "LE2-aR-0XJ.title" = "Alle in den Vordergrund"; 102 | 103 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; ObjectID = "mGd-Ks-iSW"; */ 104 | "mGd-Ks-iSW.title" = "Automatischer Dark Mode muss commands an “System Events” schicken, um den Dark Mode an oder aus zu schalten."; 105 | 106 | /* Class = "NSTextFieldCell"; title = "Shortcut"; ObjectID = "MI9-bf-6dt"; */ 107 | "MI9-bf-6dt.title" = "Shortcut"; 108 | 109 | /* Class = "NSMenuItem"; title = "Astronomical Sunset Sunrise"; ObjectID = "N5L-wl-yWc"; */ 110 | "N5L-wl-yWc.title" = "Astronomischer Sonnenauf- und untergang"; 111 | 112 | /* Class = "NSButtonCell"; title = "Re-setup"; ObjectID = "nFa-hm-K6y"; */ 113 | "nFa-hm-K6y.title" = "Rekonfigurieren"; 114 | 115 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 116 | "NMo-om-nkz.title" = "Services"; 117 | 118 | /* Class = "NSTextFieldCell"; title = "Scheduled"; ObjectID = "O5v-cY-mFV"; */ 119 | "O5v-cY-mFV.title" = "Geplant"; 120 | 121 | /* Class = "NSMenuItem"; title = "Hide Dynamic Dark Mode"; ObjectID = "Olw-nP-bQN"; */ 122 | "Olw-nP-bQN.title" = "Automatischer Dark Mode verstecken"; 123 | 124 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 125 | "OY7-WF-poV.title" = "Minimieren"; 126 | 127 | /* Class = "NSButtonCell"; title = "Open Preferences >>"; ObjectID = "pDT-Ae-cZU"; */ 128 | "pDT-Ae-cZU.title" = "Öffne die Einstellungen >>"; 129 | 130 | /* Class = "NSMenuItem"; title = "Official Sunset Sunrise"; ObjectID = "QiA-MM-zn7"; */ 131 | "QiA-MM-zn7.title" = "Genereller Sonnenauf- und untergang"; 132 | 133 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 134 | "qIS-W8-SiK.title" = "Seiteneinrichtung…"; 135 | 136 | /* Class = "NSButtonCell"; title = "Right click on the menu bar icon"; ObjectID = "qmW-4e-u5z"; */ 137 | "qmW-4e-u5z.title" = "Rechtsklick auf das Icon in der Menu Bar"; 138 | 139 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 140 | "R4o-n2-Eq4.title" = "Zoom"; 141 | 142 | /* Class = "NSMenuItem"; title = "Nautical Sunset Sunrise"; ObjectID = "RtR-kN-8f8"; */ 143 | "RtR-kN-8f8.title" = "Nautischer Sonnenauf- und untergang"; 144 | 145 | /* Class = "NSWindow"; title = "Setup"; ObjectID = "T1i-3L-V9g"; */ 146 | "T1i-3L-V9g.title" = "Setup"; 147 | 148 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 149 | "Td7-aD-5lo.title" = "Fenster"; 150 | 151 | /* Class = "NSTextFieldCell"; title = "Other"; ObjectID = "tF8-qA-5Bo"; */ 152 | "tF8-qA-5Bo.title" = "Andere"; 153 | 154 | /* Class = "NSButtonCell"; title = "Single Click to Toggle, Right Click for Preferences"; ObjectID = "UGa-lO-tpW"; */ 155 | "UGa-lO-tpW.title" = "Linksklick zum Umschalten, Rechtsklick für Einstellungen"; 156 | 157 | /* Class = "NSMenu"; title = "Dynamic Dark Mode"; ObjectID = "uQy-DD-JDr"; */ 158 | "uQy-DD-JDr.title" = "Automatischer Dark Mode"; 159 | 160 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 161 | "Vdr-fp-XzO.title" = "Andere verstecken"; 162 | 163 | /* Class = "NSMenuItem"; title = "Civil Sunset Sunrise"; ObjectID = "VHN-z1-e7t"; */ 164 | "VHN-z1-e7t.title" = "Ziviler Sonnenauf- und untergang"; 165 | 166 | /* Class = "NSButtonCell"; title = "Quit (⌘Q)"; ObjectID = "vzJ-gO-E1h"; */ 167 | "vzJ-gO-E1h.title" = "Beenden (⌘Q)"; 168 | 169 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 170 | "wpr-3q-Mcd.title" = "Hilfe"; 171 | 172 | /* Class = "NSButtonCell"; title = "Exit & Configure >>"; ObjectID = "X4y-Vz-jYE"; */ 173 | "X4y-Vz-jYE.title" = "Beenden & Configurieren >>"; 174 | 175 | /* Class = "NSButtonCell"; title = "Setup >>"; ObjectID = "y0s-hF-kCC"; */ 176 | "y0s-hF-kCC.title" = "Setup >>"; 177 | 178 | /* Class = "NSButtonCell"; title = "Start >>"; ObjectID = "YvB-h5-jjV"; */ 179 | "YvB-h5-jjV.title" = "Start >>"; 180 | 181 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; ObjectID = "ZMe-eD-uJT"; */ 182 | "ZMe-eD-uJT.title" = "Automatischer Dark Mode braucht zugriff auf Ihre momentane Position um die Zeit des Sonnenauf- und untergangs zu berechnen, um den Dark Mode in der Nacht einzuschalten."; 183 | 184 | /* Class = "NSButtonCell"; title = "Turn On Dark Mode Based On Brightness"; ObjectID = "znm-gt-cHP"; */ 185 | "znm-gt-cHP.title" = "Schalte den Dark Mode anhand der Helligkeit ein"; 186 | 187 | /* Class = "NSWindow"; title = "Dynamic Dark Mode"; ObjectID = "ZWC-1W-uDl"; */ 188 | "ZWC-1W-uDl.title" = "Automatischer Dark Mode"; 189 | 190 | -------------------------------------------------------------------------------- /Dynamic/View Controller/id.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode"; ObjectID = "1Xt-HY-uBw"; */ 3 | "1Xt-HY-uBw.title" = "Dynamic Dark Mode"; 4 | 5 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode Preferences"; ObjectID = "32v-z6-q8Z"; */ 6 | "32v-z6-q8Z.title" = "Pengaturan Dynamic Dark Mode"; 7 | 8 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 9 | "4J7-dP-txa.title" = "Masuk Layar Penuh"; 10 | 11 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "4NB-3a-2UR"; */ 12 | "4NB-3a-2UR.title" = "Simpan"; 13 | 14 | /* Class = "NSTextFieldCell"; title = "Auto Adjust"; ObjectID = "4Oz-wH-7ZV"; */ 15 | "4Oz-wH-7ZV.title" = "Penyesuaian Otomatis"; 16 | 17 | /* Class = "NSTextFieldCell"; title = "From:"; ObjectID = "4da-BG-PBG"; */ 18 | "4da-BG-PBG.title" = "Dari:"; 19 | 20 | /* Class = "NSMenuItem"; title = "Quit Dynamic Dark Mode"; ObjectID = "4sb-4s-VLi"; */ 21 | "4sb-4s-VLi.title" = "Keluar dari Dynamic Dark Mode"; 22 | 23 | /* Class = "NSMenuItem"; title = "About Dynamic Dark Mode"; ObjectID = "5kV-Vb-QxS"; */ 24 | "5kV-Vb-QxS.title" = "Tentang Dynamic Dark Mode"; 25 | 26 | /* Class = "NSTextFieldCell"; title = "To Open Preferences..."; ObjectID = "87M-Sa-k9k"; */ 27 | "87M-Sa-k9k.title" = "Untuk membuka pengaturan..."; 28 | 29 | /* Class = "NSTextFieldCell"; title = "Allow Controlling System Events"; ObjectID = "92J-gp-8D9"; */ 30 | "92J-gp-8D9.title" = "Ijinkan kontrol terhadap kejadian dari sistem"; 31 | 32 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 33 | "AYu-sK-qS6.title" = "Menu Utama"; 34 | 35 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 36 | "BOF-NM-1cW.title" = "Pengaturan…"; 37 | 38 | /* Class = "NSTextFieldCell"; title = "Welcome to Dynamic Dark Mode"; ObjectID = "Buz-5v-iiv"; */ 39 | "Buz-5v-iiv.title" = "Salamat Datang di Dynamic Dark Mode"; 40 | 41 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 42 | "DVo-aG-piG.title" = "Tutup"; 43 | 44 | /* Class = "NSButtonCell"; title = "Dark Mode On Between"; ObjectID = "Dcd-f7-wbP"; */ 45 | "Dcd-f7-wbP.title" = "Mode Gelap Diantara"; 46 | 47 | /* Class = "NSButtonCell"; title = "Left click on the menu bar icon to show menu, then choose Preferences..."; ObjectID = "EJk-BY-RUI"; */ 48 | "EJk-BY-RUI.title" = "Klik kiri pada ikon bar menu untuk menampilkan menu, kemudian pilih 49 | Pengaturan..."; 50 | 51 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 52 | "F2S-fz-NVQ.title" = "Bantuan"; 53 | 54 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode Help"; ObjectID = "FKE-Sm-Kum"; */ 55 | "FKE-Sm-Kum.title" = "Bantuan Dynamic Dark Mode"; 56 | 57 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 58 | "H8h-7b-M4v.title" = "Lihat"; 59 | 60 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 61 | "HyV-fh-RgO.title" = "Lihat"; 62 | 63 | /* Class = "NSButtonCell"; title = "Opens At Login"; ObjectID = "IB3-f2-BQf"; */ 64 | "IB3-f2-BQf.title" = "Buka saat Login"; 65 | 66 | /* Class = "NSMenuItem"; title = "Custom Range"; ObjectID = "Ibh-ok-jMp"; */ 67 | "Ibh-ok-jMp.title" = "Rentang Pribadi"; 68 | 69 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 70 | "Kd2-mp-pUS.title" = "Tampilkan Semua"; 71 | 72 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 73 | "LE2-aR-0XJ.title" = "Tampilkan Semua Kedepan"; 74 | 75 | /* Class = "NSTextFieldCell"; title = "Shortcut"; ObjectID = "MI9-bf-6dt"; */ 76 | "MI9-bf-6dt.title" = "Jalan Pintas"; 77 | 78 | /* Class = "NSMenuItem"; title = "Astronomical Sunset Sunrise"; ObjectID = "N5L-wl-yWc"; */ 79 | "N5L-wl-yWc.title" = "Matahari Tenggelam Terbit Berdasarkan Astronomis"; 80 | 81 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 82 | "NMo-om-nkz.title" = "Layanan"; 83 | 84 | /* Class = "NSTextFieldCell"; title = "Scheduled"; ObjectID = "O5v-cY-mFV"; */ 85 | "O5v-cY-mFV.title" = "Dijadwalkan"; 86 | 87 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 88 | "OY7-WF-poV.title" = "Memperkecil"; 89 | 90 | /* Class = "NSMenuItem"; title = "Hide Dynamic Dark Mode"; ObjectID = "Olw-nP-bQN"; */ 91 | "Olw-nP-bQN.title" = "Sembunyikan Dynamic Dark Mode"; 92 | 93 | /* Class = "NSMenuItem"; title = "Official Sunset Sunrise"; ObjectID = "QiA-MM-zn7"; */ 94 | "QiA-MM-zn7.title" = "Matahari Tenggelam Terbit Resmi"; 95 | 96 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 97 | "R4o-n2-Eq4.title" = "Perbesar"; 98 | 99 | /* Class = "NSMenuItem"; title = "Nautical Sunset Sunrise"; ObjectID = "RtR-kN-8f8"; */ 100 | "RtR-kN-8f8.title" = "Matahari Tenggelam Terbit Berdasarkan Nautika"; 101 | 102 | /* Class = "NSWindow"; title = "Setup"; ObjectID = "T1i-3L-V9g"; */ 103 | "T1i-3L-V9g.title" = "Mempersiapkan"; 104 | 105 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 106 | "Td7-aD-5lo.title" = "Jendela"; 107 | 108 | /* Class = "NSButtonCell"; title = "Single Click to Toggle, Right Click for Preferences"; ObjectID = "UGa-lO-tpW"; */ 109 | "UGa-lO-tpW.title" = "Klik satu kali untuk beralih, klik kanan untuk Pengaturan"; 110 | 111 | /* Class = "NSMenuItem"; title = "Civil Sunset Sunrise"; ObjectID = "VHN-z1-e7t"; */ 112 | "VHN-z1-e7t.title" = "Matahari Tenggelam Terbit Berdasarkan Sipil"; 113 | 114 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 115 | "Vdr-fp-XzO.title" = "Sembunyikan yang Lain"; 116 | 117 | /* Class = "NSButtonCell"; title = "Exit & Configure >>"; ObjectID = "X4y-Vz-jYE"; */ 118 | "X4y-Vz-jYE.title" = "Keluar & Konfigurasi >>"; 119 | 120 | /* Class = "NSButtonCell"; title = "Start >>"; ObjectID = "YvB-h5-jjV"; */ 121 | "YvB-h5-jjV.title" = "Mulai >>"; 122 | 123 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; ObjectID = "ZMe-eD-uJT"; */ 124 | "ZMe-eD-uJT.title" = "Dynamic Dark Mode perlu mengetahu lokasi Anda sekarang untuk melakukan perhitungan waktu matahari tenggelam/terbit, dengan demikian mode gelap dapat dinyalakan pada saat malam hari."; 125 | 126 | /* Class = "NSWindow"; title = "Dynamic Dark Mode"; ObjectID = "ZWC-1W-uDl"; */ 127 | "ZWC-1W-uDl.title" = "Dynamic Dark Mode"; 128 | 129 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 130 | "aTl-1u-JFS.title" = "Cetak…"; 131 | 132 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 133 | "aUF-d1-5bR.title" = "Jendela"; 134 | 135 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 136 | "bib-Uj-vzu.title" = "Berkas"; 137 | 138 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 139 | "dMs-cI-mzQ.title" = "Berkas"; 140 | 141 | /* Class = "NSTextFieldCell"; title = "Threshold:"; ObjectID = "do3-JG-x5l"; */ 142 | "do3-JG-x5l.title" = "Ambang Batas:"; 143 | 144 | /* Class = "NSTextFieldCell"; title = "To:"; ObjectID = "hBx-FP-5Wr"; */ 145 | "hBx-FP-5Wr.title" = "Ke:"; 146 | 147 | /* Class = "NSTextFieldCell"; title = "This is where you can later decide if you want to turn on and off dark mode based on your screen brightness, set a custom schedule of when to turn it on and off, or according to the calculated sunset-sunrise time based your location."; ObjectID = "heB-g6-Sln"; */ 148 | "heB-g6-Sln.title" = "Ini merupakan bagian yang dapat Anda atur nanti jika Anda ingin menyalakan dan mematikan mode gelap berdasarkan tingkat cerahan layar Anda, pengaturan penjadwalan pribadi untuk mematikan dan menyalakan, atau berdasarkan perhitungan waktu matahari tenggelam-terbit berdasarkan lokasi Anda."; 149 | 150 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 151 | "hz9-B4-Xy5.title" = "Layanan"; 152 | 153 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "i9M-2z-rxR"; */ 154 | "i9M-2z-rxR.title" = "Lewati"; 155 | 156 | /* Class = "NSTextFieldCell"; title = "Allow Access Current Location"; ObjectID = "jwe-Zh-ib0"; */ 157 | "jwe-Zh-ib0.title" = "Ijinkan mengakses lokasi saat ini"; 158 | 159 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; ObjectID = "mGd-Ks-iSW"; */ 160 | "mGd-Ks-iSW.title" = "Dynamic Dark Mode butuh mengirimkan perintah ke \"Kejadian dari Sistem\" guna mengalihkan ke mode gelap untuk Anda."; 161 | 162 | /* Class = "NSButtonCell"; title = "Re-setup"; ObjectID = "nFa-hm-K6y"; */ 163 | "nFa-hm-K6y.title" = "Mempersiapkan Ulang"; 164 | 165 | /* Class = "NSButtonCell"; title = "Open Preferences >>"; ObjectID = "pDT-Ae-cZU"; */ 166 | "pDT-Ae-cZU.title" = "Buka Pengaturan >>"; 167 | 168 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 169 | "qIS-W8-SiK.title" = "Halaman Persiapan…"; 170 | 171 | /* Class = "NSButtonCell"; title = "Right click on the menu bar icon"; ObjectID = "qmW-4e-u5z"; */ 172 | "qmW-4e-u5z.title" = "Klik kanan pada ikon di menu bar"; 173 | 174 | /* Class = "NSTextFieldCell"; title = "Other"; ObjectID = "tF8-qA-5Bo"; */ 175 | "tF8-qA-5Bo.title" = "Lainnya"; 176 | 177 | /* Class = "NSMenu"; title = "Dynamic Dark Mode"; ObjectID = "uQy-DD-JDr"; */ 178 | "uQy-DD-JDr.title" = "Dynamic Dark Mode"; 179 | 180 | /* Class = "NSButtonCell"; title = "Quit (⌘Q)"; ObjectID = "vzJ-gO-E1h"; */ 181 | "vzJ-gO-E1h.title" = "Keluar (⌘Q)"; 182 | 183 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 184 | "wpr-3q-Mcd.title" = "Bantuan"; 185 | 186 | /* Class = "NSButtonCell"; title = "Setup >>"; ObjectID = "y0s-hF-kCC"; */ 187 | "y0s-hF-kCC.title" = "Mempersiapkan >>"; 188 | 189 | /* Class = "NSButtonCell"; title = "Turn On Dark Mode Based On Brightness"; ObjectID = "znm-gt-cHP"; */ 190 | "znm-gt-cHP.title" = "Nyalakan Mode Gelap Berdasarkan Tingkat Kecerahan"; 191 | -------------------------------------------------------------------------------- /Dynamic/View Controller/ja.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode"; ObjectID = "1Xt-HY-uBw"; */ 2 | "1Xt-HY-uBw.title" = "Dynamic Dark Mode"; 3 | 4 | /* Class = "NSTextFieldCell"; title = "From:"; ObjectID = "4da-BG-PBG"; */ 5 | "4da-BG-PBG.title" = "開始:"; 6 | 7 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 8 | "4J7-dP-txa.title" = "Enter Full Screen"; 9 | 10 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "4NB-3a-2UR"; */ 11 | "4NB-3a-2UR.title" = "保存"; 12 | 13 | /* Class = "NSTextFieldCell"; title = "Auto Adjust"; ObjectID = "4Oz-wH-7ZV"; */ 14 | "4Oz-wH-7ZV.title" = "自動調整"; 15 | 16 | /* Class = "NSMenuItem"; title = "Quit Dynamic Dark Mode"; ObjectID = "4sb-4s-VLi"; */ 17 | "4sb-4s-VLi.title" = "Quit Dynamic Dark Mode"; 18 | 19 | /* Class = "NSMenuItem"; title = "About Dynamic Dark Mode"; ObjectID = "5kV-Vb-QxS"; */ 20 | "5kV-Vb-QxS.title" = "Dynamic Dark Modeについて"; 21 | 22 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "7Bk-9y-xQc"; */ 23 | "7Bk-9y-xQc.title" = "スキップ"; 24 | 25 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode Preferences"; ObjectID = "32v-z6-q8Z"; */ 26 | "32v-z6-q8Z.title" = "Dynamic Dark Mode 設定"; 27 | 28 | /* Class = "NSTextFieldCell"; title = "Allow Controlling System Events"; ObjectID = "92J-gp-8D9"; */ 29 | "92J-gp-8D9.title" = "Allow Controlling System Events"; 30 | 31 | /* Class = "NSMenuItem"; title = "Show Dropdown Menu"; ObjectID = "apZ-rU-OFQ"; */ 32 | "apZ-rU-OFQ.title" = "ドロップメニューを表示"; 33 | 34 | /* Class = "NSButtonCell"; title = "Clear"; ObjectID = "ArU-ey-Yv0"; */ 35 | "ArU-ey-Yv0.title" = "Clear"; 36 | 37 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 38 | "aTl-1u-JFS.title" = "プリント…"; 39 | 40 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 41 | "aUF-d1-5bR.title" = "ウィンドウ"; 42 | 43 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 44 | "AYu-sK-qS6.title" = "メインメニュー"; 45 | 46 | /* Class = "NSTextFieldCell"; title = "Touch Bar"; ObjectID = "B2S-Yj-Ih0"; */ 47 | "B2S-Yj-Ih0.title" = "Touch Bar"; 48 | 49 | /* Class = "NSMenuItem"; title = "System"; ObjectID = "bE4-JC-bEZ"; */ 50 | "bE4-JC-bEZ.title" = "システム"; 51 | 52 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 53 | "bib-Uj-vzu.title" = "ファイル"; 54 | 55 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 56 | "BOF-NM-1cW.title" = "設定…"; 57 | 58 | /* Class = "NSTextFieldCell"; title = "Welcome to Dynamic Dark Mode"; ObjectID = "Buz-5v-iiv"; */ 59 | "Buz-5v-iiv.title" = "Welcome to Dynamic Dark Mode"; 60 | 61 | /* Class = "NSButtonCell"; title = "Show Dark Mode Toggle In System Tray"; ObjectID = "Cgb-Kl-NJf"; */ 62 | "Cgb-Kl-NJf.title" = "Show Dark Mode Toggle In System Tray"; 63 | 64 | /* Class = "NSButtonCell"; title = "Check for Updates"; ObjectID = "D6A-w5-8EN"; */ 65 | "D6A-w5-8EN.title" = "Check for Updates"; 66 | 67 | /* Class = "NSButtonCell"; title = "Dark Mode On Between"; ObjectID = "Dcd-f7-wbP"; */ 68 | "Dcd-f7-wbP.title" = "Dark Mode On Between"; 69 | 70 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 71 | "dMs-cI-mzQ.title" = "ファイル"; 72 | 73 | /* Class = "NSTextFieldCell"; title = "Threshold:"; ObjectID = "do3-JG-x5l"; */ 74 | "do3-JG-x5l.title" = "Threshold:"; 75 | 76 | /* Class = "NSButtonCell"; title = "Dark"; ObjectID = "du9-VW-tDe"; */ 77 | "du9-VW-tDe.title" = "ダーク"; 78 | 79 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 80 | "DVo-aG-piG.title" = "閉じる"; 81 | 82 | /* Class = "NSMenuItem"; title = "Hidden"; ObjectID = "eib-A2-uKg"; */ 83 | "eib-A2-uKg.title" = "非表示"; 84 | 85 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 86 | "F2S-fz-NVQ.title" = "ヘルプ"; 87 | 88 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode Help"; ObjectID = "FKE-Sm-Kum"; */ 89 | "FKE-Sm-Kum.title" = "Dynamic Dark Mode ヘルプ"; 90 | 91 | /* Class = "NSTextFieldCell"; title = "Desktop"; ObjectID = "FZe-x2-1Zh"; */ 92 | "FZe-x2-1Zh.title" = "デスクトップ"; 93 | 94 | /* Class = "NSButtonCell"; title = "Configure Dynamic Wallpapers"; ObjectID = "G30-nf-HWb"; */ 95 | "G30-nf-HWb.title" = "Configure Dynamic Wallpapers"; 96 | 97 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 98 | "H8h-7b-M4v.title" = "View"; 99 | 100 | /* Class = "NSTextFieldCell"; title = "To:"; ObjectID = "hBx-FP-5Wr"; */ 101 | "hBx-FP-5Wr.title" = "終了:"; 102 | 103 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 104 | "HyV-fh-RgO.title" = "View"; 105 | 106 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 107 | "hz9-B4-Xy5.title" = "サービス"; 108 | 109 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "i9M-2z-rxR"; */ 110 | "i9M-2z-rxR.title" = "スキップ"; 111 | 112 | /* Class = "NSButtonCell"; title = "Opens At Login"; ObjectID = "IB3-f2-BQf"; */ 113 | "IB3-f2-BQf.title" = "ログイン時に起動"; 114 | 115 | /* Class = "NSMenuItem"; title = "Custom Range"; ObjectID = "Ibh-ok-jMp"; */ 116 | "Ibh-ok-jMp.title" = "Custom Range"; 117 | 118 | /* Class = "NSButtonCell"; title = "Done"; ObjectID = "jnk-LX-UU9"; */ 119 | "jnk-LX-UU9.title" = "完了"; 120 | 121 | /* Class = "NSTextFieldCell"; title = "Allow Access Current Location"; ObjectID = "jwe-Zh-ib0"; */ 122 | "jwe-Zh-ib0.title" = "位置情報のへのアクセスを許可"; 123 | 124 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 125 | "Kd2-mp-pUS.title" = "Show All"; 126 | 127 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 128 | "LE2-aR-0XJ.title" = "Bring All to Front"; 129 | 130 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; ObjectID = "mGd-Ks-iSW"; */ 131 | "mGd-Ks-iSW.title" = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; 132 | 133 | /* Class = "NSTextFieldCell"; title = "Shortcut"; ObjectID = "MI9-bf-6dt"; */ 134 | "MI9-bf-6dt.title" = "切り替えショートカットキー"; 135 | 136 | /* Class = "NSMenuItem"; title = "Astronomical Sunset Sunrise"; ObjectID = "N5L-wl-yWc"; */ 137 | "N5L-wl-yWc.title" = "天文薄明時"; 138 | 139 | /* Class = "NSButtonCell"; title = "Re-setup"; ObjectID = "nFa-hm-K6y"; */ 140 | "nFa-hm-K6y.title" = "リセット"; 141 | 142 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 143 | "NMo-om-nkz.title" = "Services"; 144 | 145 | /* Class = "NSTextFieldCell"; title = "Scheduled"; ObjectID = "O5v-cY-mFV"; */ 146 | "O5v-cY-mFV.title" = "Scheduled"; 147 | 148 | /* Class = "NSMenuItem"; title = "Hide Dynamic Dark Mode"; ObjectID = "Olw-nP-bQN"; */ 149 | "Olw-nP-bQN.title" = "Hide Dynamic Dark Mode"; 150 | 151 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 152 | "OY7-WF-poV.title" = "最小化"; 153 | 154 | /* Class = "NSButtonCell"; title = "Open Preferences >>"; ObjectID = "pDT-Ae-cZU"; */ 155 | "pDT-Ae-cZU.title" = "設定を開く >>"; 156 | 157 | /* Class = "NSMenuItem"; title = "Official Sunset Sunrise"; ObjectID = "QiA-MM-zn7"; */ 158 | "QiA-MM-zn7.title" = "日の出・日の入り時"; 159 | 160 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 161 | "qIS-W8-SiK.title" = "書類設定"; 162 | 163 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 164 | "R4o-n2-Eq4.title" = "Zoom"; 165 | 166 | /* Class = "NSMenuItem"; title = "Toggle Dark Mode"; ObjectID = "RMC-yX-fzH"; */ 167 | "RMC-yX-fzH.title" = "ダークモードを切り替える"; 168 | 169 | /* Class = "NSMenuItem"; title = "Nautical Sunset Sunrise"; ObjectID = "RtR-kN-8f8"; */ 170 | "RtR-kN-8f8.title" = "航海薄明時"; 171 | 172 | /* Class = "NSTextFieldCell"; title = "Menu Bar Item"; ObjectID = "scf-Wn-qXQ"; */ 173 | "scf-Wn-qXQ.title" = "Menu Bar Item"; 174 | 175 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "Sng-PU-cQQ"; */ 176 | "Sng-PU-cQQ.title" = "スキップ"; 177 | 178 | /* Class = "NSWindow"; title = "Setup"; ObjectID = "T1i-3L-V9g"; */ 179 | "T1i-3L-V9g.title" = "設定"; 180 | 181 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 182 | "Td7-aD-5lo.title" = "ウィンドウ"; 183 | 184 | /* Class = "NSTextFieldCell"; title = "Other"; ObjectID = "tF8-qA-5Bo"; */ 185 | "tF8-qA-5Bo.title" = "その他"; 186 | 187 | /* Class = "NSMenu"; title = "Dynamic Dark Mode"; ObjectID = "uQy-DD-JDr"; */ 188 | "uQy-DD-JDr.title" = "Dynamic Dark Mode"; 189 | 190 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 191 | "Vdr-fp-XzO.title" = "Hide Others"; 192 | 193 | /* Class = "NSMenuItem"; title = "Civil Sunset Sunrise"; ObjectID = "VHN-z1-e7t"; */ 194 | "VHN-z1-e7t.title" = "市民薄明時"; 195 | 196 | /* Class = "NSButtonCell"; title = "Quit (⌘Q)"; ObjectID = "vzJ-gO-E1h"; */ 197 | "vzJ-gO-E1h.title" = "終了(⌘Q)"; 198 | 199 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 200 | "wpr-3q-Mcd.title" = "ヘルプ"; 201 | 202 | /* Class = "NSButtonCell"; title = "Check Permission >>"; ObjectID = "X4y-Vz-jYE"; */ 203 | "X4y-Vz-jYE.title" = "Check Permission >>"; 204 | 205 | /* Class = "NSButtonCell"; title = "Setup >>"; ObjectID = "y0s-hF-kCC"; */ 206 | "y0s-hF-kCC.title" = "設定 >>"; 207 | 208 | /* Class = "NSButtonCell"; title = "Disable During Scheduled Dark Mode"; ObjectID = "yl0-uh-cim"; */ 209 | "yl0-uh-cim.title" = "Disable During Scheduled Dark Mode"; 210 | 211 | /* Class = "NSButtonCell"; title = "Light"; ObjectID = "yM1-aa-gcH"; */ 212 | "yM1-aa-gcH.title" = "ライト"; 213 | 214 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; ObjectID = "ZMe-eD-uJT"; */ 215 | "ZMe-eD-uJT.title" = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; 216 | 217 | /* Class = "NSButtonCell"; title = "Turn On Dark Mode Based On Brightness"; ObjectID = "znm-gt-cHP"; */ 218 | "znm-gt-cHP.title" = "Turn On Dark Mode Based On Brightness"; 219 | 220 | /* Class = "NSWindow"; title = "Dynamic Dark Mode"; ObjectID = "ZWC-1W-uDl"; */ 221 | "ZWC-1W-uDl.title" = "Dynamic Dark Mode"; 222 | 223 | -------------------------------------------------------------------------------- /Dynamic/View Controller/ko.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode"; ObjectID = "1Xt-HY-uBw"; */ 2 | "1Xt-HY-uBw.title" = "Dynamic Dark Mode"; 3 | 4 | /* Class = "NSTextFieldCell"; title = "From:"; ObjectID = "4da-BG-PBG"; */ 5 | "4da-BG-PBG.title" = "From:"; 6 | 7 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 8 | "4J7-dP-txa.title" = "전체 화면 진입"; 9 | 10 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "4NB-3a-2UR"; */ 11 | "4NB-3a-2UR.title" = "저장"; 12 | 13 | /* Class = "NSTextFieldCell"; title = "Auto Adjust"; ObjectID = "4Oz-wH-7ZV"; */ 14 | "4Oz-wH-7ZV.title" = "자동 조정"; 15 | 16 | /* Class = "NSMenuItem"; title = "Quit Dynamic Dark Mode"; ObjectID = "4sb-4s-VLi"; */ 17 | "4sb-4s-VLi.title" = "Dynamic Dark Mode 종료"; 18 | 19 | /* Class = "NSMenuItem"; title = "About Dynamic Dark Mode"; ObjectID = "5kV-Vb-QxS"; */ 20 | "5kV-Vb-QxS.title" = "Dynamic Dark Mode에 대하여"; 21 | 22 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode Preferences"; ObjectID = "32v-z6-q8Z"; */ 23 | "32v-z6-q8Z.title" = "설정"; 24 | 25 | /* Class = "NSTextFieldCell"; title = "Allow Controlling System Events"; ObjectID = "92J-gp-8D9"; */ 26 | "92J-gp-8D9.title" = "시스템 이벤트 관리 권한 부여"; 27 | 28 | /* Class = "NSMenuItem"; title = "Show Dropdown Menu"; ObjectID = "apZ-rU-OFQ"; */ 29 | "apZ-rU-OFQ.title" = "Show Dropdown Menu"; 30 | 31 | /* Class = "NSButtonCell"; title = "Clear"; ObjectID = "ArU-ey-Yv0"; */ 32 | "ArU-ey-Yv0.title" = "Clear"; 33 | 34 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 35 | "aTl-1u-JFS.title" = "인쇄…"; 36 | 37 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 38 | "aUF-d1-5bR.title" = "창"; 39 | 40 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 41 | "AYu-sK-qS6.title" = "메인 메뉴"; 42 | 43 | /* Class = "NSTextFieldCell"; title = "Touch Bar"; ObjectID = "B2S-Yj-Ih0"; */ 44 | "B2S-Yj-Ih0.title" = "Touch Bar"; 45 | 46 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 47 | "bib-Uj-vzu.title" = "파일"; 48 | 49 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 50 | "BOF-NM-1cW.title" = "환경 설정…"; 51 | 52 | /* Class = "NSTextFieldCell"; title = "Welcome to Dynamic Dark Mode"; ObjectID = "Buz-5v-iiv"; */ 53 | "Buz-5v-iiv.title" = "Dynamic Dark Mode에 오신 것을 환영합니다."; 54 | 55 | /* Class = "NSButtonCell"; title = "Show Dark Mode Toggle In System Tray"; ObjectID = "Cgb-Kl-NJf"; */ 56 | "Cgb-Kl-NJf.title" = "Show Dark Mode Toggle In System Tray"; 57 | 58 | /* Class = "NSButtonCell"; title = "Check for Updates"; ObjectID = "D6A-w5-8EN"; */ 59 | "D6A-w5-8EN.title" = "Check for Updates"; 60 | 61 | /* Class = "NSButtonCell"; title = "Automatically Check for Updates"; ObjectID = "DbR-nY-gKC"; */ 62 | "DbR-nY-gKC.title" = "Automatically Check for Updates"; 63 | 64 | /* Class = "NSButtonCell"; title = "Dark Mode On Between"; ObjectID = "Dcd-f7-wbP"; */ 65 | "Dcd-f7-wbP.title" = "사이의 Dark Mode"; 66 | 67 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 68 | "dMs-cI-mzQ.title" = "파일"; 69 | 70 | /* Class = "NSTextFieldCell"; title = "Threshold:"; ObjectID = "do3-JG-x5l"; */ 71 | "do3-JG-x5l.title" = "기준:"; 72 | 73 | /* Class = "NSButtonCell"; title = "Dark"; ObjectID = "du9-VW-tDe"; */ 74 | "du9-VW-tDe.title" = "Dark"; 75 | 76 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 77 | "DVo-aG-piG.title" = "닫기"; 78 | 79 | /* Class = "NSMenuItem"; title = "Hidden"; ObjectID = "eib-A2-uKg"; */ 80 | "eib-A2-uKg.title" = "Hidden"; 81 | 82 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 83 | "F2S-fz-NVQ.title" = "지원"; 84 | 85 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode Help"; ObjectID = "FKE-Sm-Kum"; */ 86 | "FKE-Sm-Kum.title" = "Dynamic Dark Mode 지원"; 87 | 88 | /* Class = "NSTextFieldCell"; title = "Desktop"; ObjectID = "FZe-x2-1Zh"; */ 89 | "FZe-x2-1Zh.title" = "Desktop"; 90 | 91 | /* Class = "NSButtonCell"; title = "Configure Dynamic Wallpapers"; ObjectID = "G30-nf-HWb"; */ 92 | "G30-nf-HWb.title" = "Configure Dynamic Wallpapers"; 93 | 94 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 95 | "H8h-7b-M4v.title" = "보기"; 96 | 97 | /* Class = "NSTextFieldCell"; title = "To:"; ObjectID = "hBx-FP-5Wr"; */ 98 | "hBx-FP-5Wr.title" = "To:"; 99 | 100 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 101 | "HyV-fh-RgO.title" = "보기"; 102 | 103 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 104 | "hz9-B4-Xy5.title" = "서비스"; 105 | 106 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "i9M-2z-rxR"; */ 107 | "i9M-2z-rxR.title" = "건너뛰기"; 108 | 109 | /* Class = "NSButtonCell"; title = "Opens At Login"; ObjectID = "IB3-f2-BQf"; */ 110 | "IB3-f2-BQf.title" = "시스템 로그인과 함께 열기"; 111 | 112 | /* Class = "NSMenuItem"; title = "Custom Range"; ObjectID = "Ibh-ok-jMp"; */ 113 | "Ibh-ok-jMp.title" = "커스텀 범위"; 114 | 115 | /* Class = "NSButtonCell"; title = "Done"; ObjectID = "jnk-LX-UU9"; */ 116 | "jnk-LX-UU9.title" = "Done"; 117 | 118 | /* Class = "NSTextFieldCell"; title = "Allow Access Current Location"; ObjectID = "jwe-Zh-ib0"; */ 119 | "jwe-Zh-ib0.title" = "현재 위치 정보 접근 허용"; 120 | 121 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 122 | "Kd2-mp-pUS.title" = "모두 보이기"; 123 | 124 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 125 | "LE2-aR-0XJ.title" = "모두 맨 앞으로 가져오기"; 126 | 127 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; ObjectID = "mGd-Ks-iSW"; */ 128 | "mGd-Ks-iSW.title" = "Dynamic Dark Mode는 내장된 \"System Events\"에 Dark Mode 전환 요청을 보내야합니다."; 129 | 130 | /* Class = "NSTextFieldCell"; title = "Shortcut"; ObjectID = "MI9-bf-6dt"; */ 131 | "MI9-bf-6dt.title" = "단축키"; 132 | 133 | /* Class = "NSMenuItem"; title = "Astronomical Sunset Sunrise"; ObjectID = "N5L-wl-yWc"; */ 134 | "N5L-wl-yWc.title" = "천문학적 일출 일몰"; 135 | 136 | /* Class = "NSButtonCell"; title = "Re-setup"; ObjectID = "nFa-hm-K6y"; */ 137 | "nFa-hm-K6y.title" = "다시 설정"; 138 | 139 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 140 | "NMo-om-nkz.title" = "서비스"; 141 | 142 | /* Class = "NSTextFieldCell"; title = "Scheduled"; ObjectID = "O5v-cY-mFV"; */ 143 | "O5v-cY-mFV.title" = "예약됨"; 144 | 145 | /* Class = "NSMenuItem"; title = "Hide Dynamic Dark Mode"; ObjectID = "Olw-nP-bQN"; */ 146 | "Olw-nP-bQN.title" = "Dynamic Dark Mode 감추기"; 147 | 148 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 149 | "OY7-WF-poV.title" = "최소화"; 150 | 151 | /* Class = "NSButtonCell"; title = "Open Preferences >>"; ObjectID = "pDT-Ae-cZU"; */ 152 | "pDT-Ae-cZU.title" = "환경설정 열기 →"; 153 | 154 | /* Class = "NSMenuItem"; title = "Official Sunset Sunrise"; ObjectID = "QiA-MM-zn7"; */ 155 | "QiA-MM-zn7.title" = "공식 일출 일몰"; 156 | 157 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 158 | "qIS-W8-SiK.title" = "창 설정"; 159 | 160 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 161 | "R4o-n2-Eq4.title" = "확대"; 162 | 163 | /* Class = "NSMenuItem"; title = "Toggle Dark Mode"; ObjectID = "RMC-yX-fzH"; */ 164 | "RMC-yX-fzH.title" = "Dark Mode 활성화"; 165 | 166 | /* Class = "NSMenuItem"; title = "Nautical Sunset Sunrise"; ObjectID = "RtR-kN-8f8"; */ 167 | "RtR-kN-8f8.title" = "해상 일출 일몰"; 168 | 169 | /* Class = "NSTextFieldCell"; title = "Menu Bar Item"; ObjectID = "scf-Wn-qXQ"; */ 170 | "scf-Wn-qXQ.title" = "Menu Bar Item"; 171 | 172 | /* Class = "NSWindow"; title = "Setup"; ObjectID = "T1i-3L-V9g"; */ 173 | "T1i-3L-V9g.title" = "설정하기"; 174 | 175 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 176 | "Td7-aD-5lo.title" = "윈도우"; 177 | 178 | /* Class = "NSTextFieldCell"; title = "Other"; ObjectID = "tF8-qA-5Bo"; */ 179 | "tF8-qA-5Bo.title" = "그 외"; 180 | 181 | /* Class = "NSMenu"; title = "Dynamic Dark Mode"; ObjectID = "uQy-DD-JDr"; */ 182 | "uQy-DD-JDr.title" = "Dynamic Dark Mode"; 183 | 184 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 185 | "Vdr-fp-XzO.title" = "다른 것들 감추기"; 186 | 187 | /* Class = "NSMenuItem"; title = "Civil Sunset Sunrise"; ObjectID = "VHN-z1-e7t"; */ 188 | "VHN-z1-e7t.title" = "시민 일출 일몰"; 189 | 190 | /* Class = "NSButtonCell"; title = "Quit (⌘Q)"; ObjectID = "vzJ-gO-E1h"; */ 191 | "vzJ-gO-E1h.title" = "종료 (⌘Q)"; 192 | 193 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 194 | "wpr-3q-Mcd.title" = "지원"; 195 | 196 | /* Class = "NSButtonCell"; title = "Check Permission >>"; ObjectID = "X4y-Vz-jYE"; */ 197 | "X4y-Vz-jYE.title" = "종료 & 조정 →"; 198 | 199 | /* Class = "NSButtonCell"; title = "Setup >>"; ObjectID = "y0s-hF-kCC"; */ 200 | "y0s-hF-kCC.title" = "설정하기 →"; 201 | 202 | /* Class = "NSButtonCell"; title = "Disable During Scheduled Dark Mode"; ObjectID = "yl0-uh-cim"; */ 203 | "yl0-uh-cim.title" = "Disable During Scheduled Dark Mode"; 204 | 205 | /* Class = "NSButtonCell"; title = "Light"; ObjectID = "yM1-aa-gcH"; */ 206 | "yM1-aa-gcH.title" = "Light"; 207 | 208 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; ObjectID = "ZMe-eD-uJT"; */ 209 | "ZMe-eD-uJT.title" = "Dynamic Dark Mode는 자동적으로 일출과 일몰 정보를 계산하여 자동으로 Dark Mode를 활성화하고 비활성화합니다. 이때 일출과 일몰 시각을 계산하기 위해 사용자의 현재 위치 정보가 필요합니다."; 210 | 211 | /* Class = "NSButtonCell"; title = "Turn On Dark Mode Based On Brightness"; ObjectID = "znm-gt-cHP"; */ 212 | "znm-gt-cHP.title" = "화면 밝기에 따라 Dark Mode 자동으로 켜기"; 213 | 214 | /* Class = "NSWindow"; title = "Dynamic Dark Mode"; ObjectID = "ZWC-1W-uDl"; */ 215 | "ZWC-1W-uDl.title" = "Dynamic Dark Mode"; 216 | 217 | -------------------------------------------------------------------------------- /Dynamic/View Controller/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode"; ObjectID = "1Xt-HY-uBw"; */ 2 | "1Xt-HY-uBw.title" = "自动深色模式"; 3 | 4 | /* Class = "NSTextFieldCell"; title = "From:"; ObjectID = "4da-BG-PBG"; */ 5 | "4da-BG-PBG.title" = "从:"; 6 | 7 | /* Class = "NSMenuItem"; title = "Enter Full Screen"; ObjectID = "4J7-dP-txa"; */ 8 | "4J7-dP-txa.title" = "进入全屏幕"; 9 | 10 | /* Class = "NSButtonCell"; title = "Save"; ObjectID = "4NB-3a-2UR"; */ 11 | "4NB-3a-2UR.title" = "保存"; 12 | 13 | /* Class = "NSTextFieldCell"; title = "Auto Adjust"; ObjectID = "4Oz-wH-7ZV"; */ 14 | "4Oz-wH-7ZV.title" = "自动切换"; 15 | 16 | /* Class = "NSMenuItem"; title = "Quit Dynamic Dark Mode"; ObjectID = "4sb-4s-VLi"; */ 17 | "4sb-4s-VLi.title" = "退出“自动深色模式”"; 18 | 19 | /* Class = "NSMenuItem"; title = "About Dynamic Dark Mode"; ObjectID = "5kV-Vb-QxS"; */ 20 | "5kV-Vb-QxS.title" = "关于“自动深色模式”"; 21 | 22 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "7Bk-9y-xQc"; */ 23 | "7Bk-9y-xQc.title" = "跳过"; 24 | 25 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode Preferences"; ObjectID = "32v-z6-q8Z"; */ 26 | "32v-z6-q8Z.title" = "自动深色模式设置"; 27 | 28 | /* Class = "NSTextFieldCell"; title = "Allow Controlling System Events"; ObjectID = "92J-gp-8D9"; */ 29 | "92J-gp-8D9.title" = "允许控制“System Events”"; 30 | 31 | /* Class = "NSMenuItem"; title = "Show Dropdown Menu"; ObjectID = "apZ-rU-OFQ"; */ 32 | "apZ-rU-OFQ.title" = "显示下拉菜单"; 33 | 34 | /* Class = "NSButtonCell"; title = "Clear"; ObjectID = "ArU-ey-Yv0"; */ 35 | "ArU-ey-Yv0.title" = "重置"; 36 | 37 | /* Class = "NSMenuItem"; title = "Print…"; ObjectID = "aTl-1u-JFS"; */ 38 | "aTl-1u-JFS.title" = "打印…"; 39 | 40 | /* Class = "NSMenuItem"; title = "Window"; ObjectID = "aUF-d1-5bR"; */ 41 | "aUF-d1-5bR.title" = "窗口"; 42 | 43 | /* Class = "NSMenu"; title = "Main Menu"; ObjectID = "AYu-sK-qS6"; */ 44 | "AYu-sK-qS6.title" = "主菜单"; 45 | 46 | /* Class = "NSTextFieldCell"; title = "Touch Bar"; ObjectID = "B2S-Yj-Ih0"; */ 47 | "B2S-Yj-Ih0.title" = "触控栏"; 48 | 49 | /* Class = "NSMenuItem"; title = "System"; ObjectID = "bE4-JC-bEZ"; */ 50 | "bE4-JC-bEZ.title" = "系统自带"; 51 | 52 | /* Class = "NSMenu"; title = "File"; ObjectID = "bib-Uj-vzu"; */ 53 | "bib-Uj-vzu.title" = "文件"; 54 | 55 | /* Class = "NSMenuItem"; title = "Preferences…"; ObjectID = "BOF-NM-1cW"; */ 56 | "BOF-NM-1cW.title" = "偏好设置…"; 57 | 58 | /* Class = "NSTextFieldCell"; title = "Welcome to Dynamic Dark Mode"; ObjectID = "Buz-5v-iiv"; */ 59 | "Buz-5v-iiv.title" = "欢迎使用自动深色模式"; 60 | 61 | /* Class = "NSButtonCell"; title = "Show Dark Mode Toggle In System Tray"; ObjectID = "Cgb-Kl-NJf"; */ 62 | "Cgb-Kl-NJf.title" = "在功能栏显示外观模式切换按钮"; 63 | 64 | /* Class = "NSButtonCell"; title = "Check for Updates"; ObjectID = "D6A-w5-8EN"; */ 65 | "D6A-w5-8EN.title" = "检查更新"; 66 | 67 | /* Class = "NSButtonCell"; title = "Dark Mode On Between"; ObjectID = "Dcd-f7-wbP"; */ 68 | "Dcd-f7-wbP.title" = "在此期间启用深色模式"; 69 | 70 | /* Class = "NSMenuItem"; title = "File"; ObjectID = "dMs-cI-mzQ"; */ 71 | "dMs-cI-mzQ.title" = "文件"; 72 | 73 | /* Class = "NSTextFieldCell"; title = "Threshold:"; ObjectID = "do3-JG-x5l"; */ 74 | "do3-JG-x5l.title" = "阈值:"; 75 | 76 | /* Class = "NSButtonCell"; title = "Dark"; ObjectID = "du9-VW-tDe"; */ 77 | "du9-VW-tDe.title" = "深色"; 78 | 79 | /* Class = "NSMenuItem"; title = "Close"; ObjectID = "DVo-aG-piG"; */ 80 | "DVo-aG-piG.title" = "关闭"; 81 | 82 | /* Class = "NSMenuItem"; title = "Hidden"; ObjectID = "eib-A2-uKg"; */ 83 | "eib-A2-uKg.title" = "隐藏"; 84 | 85 | /* Class = "NSMenu"; title = "Help"; ObjectID = "F2S-fz-NVQ"; */ 86 | "F2S-fz-NVQ.title" = "帮助"; 87 | 88 | /* Class = "NSMenuItem"; title = "Dynamic Dark Mode Help"; ObjectID = "FKE-Sm-Kum"; */ 89 | "FKE-Sm-Kum.title" = "“自动深色模式”帮助"; 90 | 91 | /* Class = "NSTextFieldCell"; title = "Desktop"; ObjectID = "FZe-x2-1Zh"; */ 92 | "FZe-x2-1Zh.title" = "桌面"; 93 | 94 | /* Class = "NSButtonCell"; title = "Configure Dynamic Wallpapers"; ObjectID = "G30-nf-HWb"; */ 95 | "G30-nf-HWb.title" = "配置动态桌面图片"; 96 | 97 | /* Class = "NSMenuItem"; title = "View"; ObjectID = "H8h-7b-M4v"; */ 98 | "H8h-7b-M4v.title" = "显示"; 99 | 100 | /* Class = "NSTextFieldCell"; title = "To:"; ObjectID = "hBx-FP-5Wr"; */ 101 | "hBx-FP-5Wr.title" = "至:"; 102 | 103 | /* Class = "NSMenu"; title = "View"; ObjectID = "HyV-fh-RgO"; */ 104 | "HyV-fh-RgO.title" = "显示"; 105 | 106 | /* Class = "NSMenu"; title = "Services"; ObjectID = "hz9-B4-Xy5"; */ 107 | "hz9-B4-Xy5.title" = "服务"; 108 | 109 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "i9M-2z-rxR"; */ 110 | "i9M-2z-rxR.title" = "跳过"; 111 | 112 | /* Class = "NSButtonCell"; title = "Opens At Login"; ObjectID = "IB3-f2-BQf"; */ 113 | "IB3-f2-BQf.title" = "加入登录项"; 114 | 115 | /* Class = "NSMenuItem"; title = "Custom Range"; ObjectID = "Ibh-ok-jMp"; */ 116 | "Ibh-ok-jMp.title" = "自定义时间段"; 117 | 118 | /* Class = "NSButtonCell"; title = "Done"; ObjectID = "jnk-LX-UU9"; */ 119 | "jnk-LX-UU9.title" = "完成"; 120 | 121 | /* Class = "NSTextFieldCell"; title = "Allow Access Current Location"; ObjectID = "jwe-Zh-ib0"; */ 122 | "jwe-Zh-ib0.title" = "允许访问当前位置"; 123 | 124 | /* Class = "NSMenuItem"; title = "Show All"; ObjectID = "Kd2-mp-pUS"; */ 125 | "Kd2-mp-pUS.title" = "全部显示"; 126 | 127 | /* Class = "NSMenuItem"; title = "Bring All to Front"; ObjectID = "LE2-aR-0XJ"; */ 128 | "LE2-aR-0XJ.title" = "前置所有窗口"; 129 | 130 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to send commands to the built-in \"System Events\" in order to toggle dark mode for you."; ObjectID = "mGd-Ks-iSW"; */ 131 | "mGd-Ks-iSW.title" = "“自动深色模式”需要能够向系统自带的“System Events”(系统事件)发送请求才能为您切换深色模式。"; 132 | 133 | /* Class = "NSTextFieldCell"; title = "Shortcut"; ObjectID = "MI9-bf-6dt"; */ 134 | "MI9-bf-6dt.title" = "切换快捷键"; 135 | 136 | /* Class = "NSMenuItem"; title = "Astronomical Sunset Sunrise"; ObjectID = "N5L-wl-yWc"; */ 137 | "N5L-wl-yWc.title" = "天文日出日落"; 138 | 139 | /* Class = "NSButtonCell"; title = "Re-setup"; ObjectID = "nFa-hm-K6y"; */ 140 | "nFa-hm-K6y.title" = "重新配置"; 141 | 142 | /* Class = "NSMenuItem"; title = "Services"; ObjectID = "NMo-om-nkz"; */ 143 | "NMo-om-nkz.title" = "服务"; 144 | 145 | /* Class = "NSTextFieldCell"; title = "Scheduled"; ObjectID = "O5v-cY-mFV"; */ 146 | "O5v-cY-mFV.title" = "定时"; 147 | 148 | /* Class = "NSMenuItem"; title = "Hide Dynamic Dark Mode"; ObjectID = "Olw-nP-bQN"; */ 149 | "Olw-nP-bQN.title" = "隐藏自动深色模式"; 150 | 151 | /* Class = "NSMenuItem"; title = "Minimize"; ObjectID = "OY7-WF-poV"; */ 152 | "OY7-WF-poV.title" = "最小化"; 153 | 154 | /* Class = "NSButtonCell"; title = "Open Preferences >>"; ObjectID = "pDT-Ae-cZU"; */ 155 | "pDT-Ae-cZU.title" = "打开“系统偏好设置” >>"; 156 | 157 | /* Class = "NSMenuItem"; title = "Official Sunset Sunrise"; ObjectID = "QiA-MM-zn7"; */ 158 | "QiA-MM-zn7.title" = "标准日出日落"; 159 | 160 | /* Class = "NSMenuItem"; title = "Page Setup…"; ObjectID = "qIS-W8-SiK"; */ 161 | "qIS-W8-SiK.title" = "页面设置…"; 162 | 163 | /* Class = "NSMenuItem"; title = "Zoom"; ObjectID = "R4o-n2-Eq4"; */ 164 | "R4o-n2-Eq4.title" = "缩放"; 165 | 166 | /* Class = "NSMenuItem"; title = "Toggle Dark Mode"; ObjectID = "RMC-yX-fzH"; */ 167 | "RMC-yX-fzH.title" = "切换外观模式"; 168 | 169 | /* Class = "NSMenuItem"; title = "Nautical Sunset Sunrise"; ObjectID = "RtR-kN-8f8"; */ 170 | "RtR-kN-8f8.title" = "航海日出日落"; 171 | 172 | /* Class = "NSTextFieldCell"; title = "Menu Bar Item"; ObjectID = "scf-Wn-qXQ"; */ 173 | "scf-Wn-qXQ.title" = "菜单栏图标"; 174 | 175 | /* Class = "NSButtonCell"; title = "Skip"; ObjectID = "Sng-PU-cQQ"; */ 176 | "Sng-PU-cQQ.title" = "跳过"; 177 | 178 | /* Class = "NSWindow"; title = "Setup"; ObjectID = "T1i-3L-V9g"; */ 179 | "T1i-3L-V9g.title" = "配置"; 180 | 181 | /* Class = "NSMenu"; title = "Window"; ObjectID = "Td7-aD-5lo"; */ 182 | "Td7-aD-5lo.title" = "窗口"; 183 | 184 | /* Class = "NSTextFieldCell"; title = "Other"; ObjectID = "tF8-qA-5Bo"; */ 185 | "tF8-qA-5Bo.title" = "其他"; 186 | 187 | /* Class = "NSMenu"; title = "Dynamic Dark Mode"; ObjectID = "uQy-DD-JDr"; */ 188 | "uQy-DD-JDr.title" = "自动深色模式"; 189 | 190 | /* Class = "NSMenuItem"; title = "Hide Others"; ObjectID = "Vdr-fp-XzO"; */ 191 | "Vdr-fp-XzO.title" = "隐藏其他"; 192 | 193 | /* Class = "NSMenuItem"; title = "Civil Sunset Sunrise"; ObjectID = "VHN-z1-e7t"; */ 194 | "VHN-z1-e7t.title" = "法定日出日落"; 195 | 196 | /* Class = "NSButtonCell"; title = "Quit (⌘Q)"; ObjectID = "vzJ-gO-E1h"; */ 197 | "vzJ-gO-E1h.title" = "退出 (⌘Q)"; 198 | 199 | /* Class = "NSMenuItem"; title = "Help"; ObjectID = "wpr-3q-Mcd"; */ 200 | "wpr-3q-Mcd.title" = "帮助"; 201 | 202 | /* Class = "NSButtonCell"; title = "Check Permission >>"; ObjectID = "X4y-Vz-jYE"; */ 203 | "X4y-Vz-jYE.title" = "确认权限 >>"; 204 | 205 | /* Class = "NSButtonCell"; title = "Setup >>"; ObjectID = "y0s-hF-kCC"; */ 206 | "y0s-hF-kCC.title" = "开始配置 >>"; 207 | 208 | /* Class = "NSButtonCell"; title = "Disable During Scheduled Dark Mode"; ObjectID = "yl0-uh-cim"; */ 209 | "yl0-uh-cim.title" = "在定时深色模式期间停用自动切换"; 210 | 211 | /* Class = "NSButtonCell"; title = "Light"; ObjectID = "yM1-aa-gcH"; */ 212 | "yM1-aa-gcH.title" = "淡色"; 213 | 214 | /* Class = "NSTextFieldCell"; title = "Dynamic Dark Mode needs to know your current location in order to calculate sunset/sunrise time, thereby turning on dark mode at night."; ObjectID = "ZMe-eD-uJT"; */ 215 | "ZMe-eD-uJT.title" = "“自动深色模式”需要访问您的当前位置来计算日出日落时间,以便在合适的时候为您自动切换深色模式。"; 216 | 217 | /* Class = "NSButtonCell"; title = "Turn On Dark Mode Based On Brightness"; ObjectID = "znm-gt-cHP"; */ 218 | "znm-gt-cHP.title" = "根据屏幕亮度启用深色模式"; 219 | 220 | /* Class = "NSWindow"; title = "Dynamic Dark Mode"; ObjectID = "ZWC-1W-uDl"; */ 221 | "ZWC-1W-uDl.title" = "自动深色模式"; 222 | 223 | -------------------------------------------------------------------------------- /DynamicLauncher/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DynamicLauncher 4 | // 5 | // Created by Apollo Zhu on 6/9/18. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | let id = "io.github.apollozhu.Dynamic" 12 | 13 | var noInstanceRunning: Bool { 14 | return NSRunningApplication 15 | .runningApplications(withBundleIdentifier: id) 16 | .filter { $0.isActive } 17 | .isEmpty 18 | } 19 | 20 | @NSApplicationMain 21 | class AppDelegate: NSObject, NSApplicationDelegate { 22 | @IBOutlet weak var window: NSWindow! 23 | 24 | func applicationDidFinishLaunching(_ aNotification: Notification) { 25 | defer { NSApp.terminate(nil) } 26 | guard noInstanceRunning else { return } 27 | NSWorkspace.shared.launchApplication( 28 | withBundleIdentifier: id, 29 | options: .default, 30 | additionalEventParamDescriptor: nil, 31 | launchIdentifier: nil 32 | ) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/DynamicLauncher/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /DynamicLauncher/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DynamicLauncher/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /DynamicLauncher/DynamicLauncher.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DynamicLauncher/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(VERSION) 21 | CFBundleVersion 22 | $(VERSION) 23 | ITSAppUsesNonExemptEncryption 24 | 25 | LSApplicationCategoryType 26 | public.app-category.utilities 27 | LSMinimumSystemVersion 28 | $(MACOSX_DEPLOYMENT_TARGET) 29 | LSUIElement 30 | 31 | NSHumanReadableCopyright 32 | Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /DynamicLauncher/de.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Automatischer Dark Mode. Alle Rechte vorbehalten."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/de.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DynamicLauncher/eo.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Kopirajto © 2018-2022 Aŭtomatika Malluma Modo. Ĉiuj rajtoj rezervitaj."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/eo.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DynamicLauncher/es.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "Lanzador dinámico"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Modo Oscuro Dinámico. Todos los derechos reservados."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/fr.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. Tous droits réservés."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/fr.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DynamicLauncher/id.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Hak cipta © 2018-2022 Dynamic Dark Mode. Seluruh Hak Cipta."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/id.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DynamicLauncher/ja.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "DynamicLauncher"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "© 2018-2022 Dynamic Dark Mode. All rights reserved.(不許複製・禁無断転載)"; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/ko.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. 모든 권리 보유."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/nl.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "DynamicLauncher"; 3 | 4 | -------------------------------------------------------------------------------- /DynamicLauncher/ru.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "Copyright © 2018-2022 Dynamic Dark Mode. Все права защищены."; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/ru.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /DynamicLauncher/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Bundle name */ 2 | "CFBundleName" = "$(PRODUCT_NAME)"; 3 | 4 | /* Copyright (human-readable) */ 5 | "NSHumanReadableCopyright" = "版权所有 © 2018-2022 自动深色模式。保留所有权利。"; 6 | 7 | -------------------------------------------------------------------------------- /DynamicLauncher/zh-Hans.lproj/MainMenu.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Icon.png -------------------------------------------------------------------------------- /Icon.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApolloZhu/Dynamic-Dark-Mode/fd152ad8a77ad2a0daa5012ea98a07de71dfeef9/Icon.sketch -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14' 2 | install! 'cocoapods', 3 | :generate_multiple_pod_projects => true, 4 | :incremental_installation => true 5 | 6 | target 'Dynamic Dark Mode' do 7 | use_modular_headers! 8 | inhibit_all_warnings! 9 | # Pods for Dynamic Dark Mode 10 | pod 'LetsMove' 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - LetsMove (1.25) 3 | 4 | DEPENDENCIES: 5 | - LetsMove 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - LetsMove 10 | 11 | SPEC CHECKSUMS: 12 | LetsMove: 7b9fe44737707d984fbd3f47af46609a9a07b461 13 | 14 | PODFILE CHECKSUM: abcffd5de7a4807e38f06fa9c8565646e5806f40 15 | 16 | COCOAPODS: 1.11.3 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dynamic Dark Mode 2 | 3 | Dynamic Dark Mode - The smart, automatic Dark Mode toggle for macOS Mojave | Product Hunt Embed 4 | 5 | *Dynamic Dark Mode* is the app you are looking for to power up Dark Mode on macOS Mojave and beyond. 6 | 7 | Instead of looking for the switch for dark mode in System Preferences, just click the icon in the menu bar. Ever felt your eyes getting hurt because the screen is so bright in the night? Have to worry no more, we Dynamically enable dark mode in dim lights, after sunset, or just anytime. When you wake up in the morning, it'll a be another bright day. 8 | 9 | ![Settings for Dynamic Dark Mode](https://user-images.githubusercontent.com/10842684/54065701-b240e800-41f2-11e9-8f7a-5d502ab27c4e.png) 10 | 11 | ## Install 12 | 13 | ### Via [Homebrew](https://brew.sh/) [Cask](https://formulae.brew.sh/cask/dynamic-dark-mode) (Recommended) 14 | 15 | ``` 16 | brew install --cask dynamic-dark-mode 17 | ``` 18 | 19 |
Didn't work? Try this if you have an earlier version of Homebrew 20 | 21 |
brew cask install dynamic-dark-mode
22 |
23 | 24 | ### Direct Download 25 | 26 |
27 | Latest Release 28 | 29 | Additionally, you may also download: 30 | 31 | 36 | 37 |
38 | 39 | ## License 40 | 41 | ``` 42 | Dynamic Dark Mode - the smart, automatic Dark Mode toggle for macOS 43 | Copyright (C) 2018-2021 Zhiyu Zhu (@ApolloZhu) 44 | 45 | This program is free software: you can redistribute it and/or modify 46 | it under the terms of the GNU General Public License as published by 47 | the Free Software Foundation, either version 3 of the License, or 48 | (at your option) any later version. 49 | 50 | This program is distributed in the hope that it will be useful, 51 | but WITHOUT ANY WARRANTY; without even the implied warranty of 52 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 53 | GNU General Public License for more details. 54 | 55 | You should have received a copy of the GNU General Public License 56 | along with this program. If not, see . 57 | ``` 58 | 59 | ## Alternatives 60 | 61 | This is not quite what you are looking for? Here's a non-comprehensive list of options you could try: 62 | 63 | | | Daylight Schedule | Custom Schedule | Ambient Light | Touch Bar | Shortcut Key | Menu Bar | CLI | Per App | Localized | 64 | | ------------------------------------------------------------ | ----------------------- | --------------- | ------------- | ------------------------------------------------------------ | ------------ | -------- | ---- | ------- | --------- | 65 | | [macOS Dark Mode, Auto](https://support.apple.com/en-us/HT208976) | ✅ | | | | | | | | ✅ | 66 | | Dynamic Dark Mode | ✅ | ✅ | ✅* | ✅ | ✅ | ✅ | | | ✅ | 67 | | [NightOwl](https://nightowl.kramser.xyz/) | ✅ | ✅ | | | ✅ | ✅ | | ✅ | | 68 | | [DarkModeBuddy](https://gumroad.com/l/darkmodebuddy) | | | ✅ | | | | | | | 69 | | [DarkLight](https://github.com/L1cardo/DarkLight) | | | | ✅ | ✅ | | | | | 70 | | [Nocturnal](https://github.com/HarshilShah/Nocturnal) | | | | | | ✅ | | | | 71 | | [darkmode](https://github.com/katernet/darkmode) by katernet | ✅ | ✅ | | | | | ✅ | | | 72 | | [dark-mode](https://github.com/sindresorhus/dark-mode) by sindresorhus | | | | | | | ✅ | | | 73 | | [Gray](https://github.com/zenangst/Gray) | | | | | | | | ✅ | ✅ | 74 | | [f.lux](https://justgetflux.com/) (night shift) | ✅ | ✅ | | | | | | | | 75 | | [Shifty](https://shifty.natethompson.io) (Night Shift) | ✅ | ✅ | | | | | | | ✅ | 76 | | [Irvu‪e‬](https://apps.apple.com/app/id1039633667) (wallpaper) | | | | | ✅ | ✅ | | | | 77 | | [One Switch](https://fireball.studio/oneswitch/) (multi-tool) | | | | | | ✅ | | | ✅ | 78 | 79 | > \* Dynamic Dark Mode uses screen brightness, and requires "Automatically adjust brightness" option enabled in System Preferences for ambient light based changes. 80 | 81 | --- 82 | 83 |
84 | 85 | 86 | 99 | 100 |
101 | -------------------------------------------------------------------------------- /Tools/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // Tools 4 | // 5 | // Created by Apollo Zhu on 9/10/19. 6 | // Copyright © 2018-2022 Dynamic Dark Mode. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import XMLCoder 12 | 13 | let releasesURL = "https://github.com/ApolloZhu/Dynamic-Dark-Mode/releases.atom" 14 | 15 | struct Feed: Codable { 16 | struct Entry: Codable { 17 | let id: String 18 | let updated: Date 19 | let title: String 20 | let content: String 21 | } 22 | let entry: [Entry] 23 | } 24 | 25 | let dateFormatter = DateFormatter() 26 | dateFormatter.locale = Locale(identifier: "en_US_POSIX") 27 | dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) 28 | dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss ZZ" 29 | 30 | extension Feed.Entry { 31 | func appcastItem() -> String { 32 | let version = id[id.index(after: id.lastIndex(of: "/")!)...] 33 | return """ 34 | 35 | \(title) 36 | \(dateFormatter.string(from: updated)) 37 | 10.14 38 | 39 | 40 | 41 | """ 42 | } 43 | } 44 | 45 | URLSession.shared.dataTask(with: URL(string: releasesURL)!) { data, _, _ in 46 | guard let data = data else { return } 47 | let decoder = XMLDecoder() 48 | decoder.dateDecodingStrategy = .iso8601 49 | let feed = try! decoder.decode(Feed.self, from: data) 50 | print(feed.entry.first!.appcastItem()) 51 | /* 52 | // I don't know how to do the checksum, so commented out... 53 | 54 | let items = feed.entry.enumerated().reduce("") { (result, item) -> String in 55 | return result + item.1.appcastItem() + "\n" // sparkleVersion: feed.entry.count - item.0 - 1 56 | } 57 | let string = """ 58 | 59 | 60 | Dynamic Dark Mode 61 | 62 | https://apollozhu.github.io/Dynamic-Dark-Mode/appcast.xml 63 | 64 | en 65 | \(items) 66 | 67 | 68 | """ 69 | try! string.write(toFile: "appcast.xml", atomically: true, encoding: .utf8) 70 | print(FileManager.default.currentDirectoryPath) 71 | */ 72 | exit(EXIT_SUCCESS) 73 | }.resume() 74 | 75 | RunLoop.main.run() 76 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /privacy.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy 2 | 3 | App "Dynamic Dark Mode" and it's original author Zhiyu Zhu (sometimes known as Apollo/Apollonian) 4 | is NOT interested in your personal data AT ALL. We'll ensure [others who contribute to this 5 | app](https://github.com/ApolloZhu/Dynamic-Dark-Mode/graphs/contributors) also 6 | does not add any suspicous stuff to the app. If you can't trust us, the source of this app is hosted at 7 | [https://github.com/ApolloZhu/Dynamic-Dark-Mode](https://github.com/ApolloZhu/Dynamic-Dark-Mode). 8 | For your information, it is licensed under [GNU General Public License v3.0](./LICENSE). 9 | 10 | The owner of this app developer account, Haizhen Fan, is one of Apollo's legal guardians. 11 | She doesn't not have access to your personal data either (since we aren't collecting any). 12 | 13 | However, you should read [Apple's Privacy Policy](https://www.apple.com/legal/privacy/) 14 | to check what they report to us to help fix problems you encountered while using our app. 15 | 16 |
17 | 18 | 19 | 24 | 25 |
26 | --------------------------------------------------------------------------------