diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..76d5726 Binary files /dev/null and b/.DS_Store differ diff --git a/Blurred.xcodeproj/project.pbxproj b/Blurred.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5f8ede7 --- /dev/null +++ b/Blurred.xcodeproj/project.pbxproj @@ -0,0 +1,592 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + 08203CD023CD9CBE0006AE7C /* Bundle+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08203CCF23CD9CBE0006AE7C /* Bundle+Extension.swift */; }; + 083501CC23C5DF0400F6E567 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 083501CB23C5DF0400F6E567 /* EventMonitor.swift */; }; + 0851749B23FD099400B3B84F /* SettingObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0851749923FD099400B3B84F /* SettingObservable.swift */; }; + 0851749C23FD099400B3B84F /* PreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0851749A23FD099400B3B84F /* PreferenceView.swift */; }; + 085174A123FD2E9700B3B84F /* HotKey in Frameworks */ = {isa = PBXBuildFile; productRef = 085174A023FD2E9700B3B84F /* HotKey */; }; + 085174A323FD2EF300B3B84F /* GlobalKeyBindPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 085174A223FD2EF300B3B84F /* GlobalKeyBindPreferences.swift */; }; + 085174A523FD34C500B3B84F /* PreferencesWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 085174A423FD34C500B3B84F /* PreferencesWindow.swift */; }; + 0853667723C4C0AC00567AA8 /* WindowInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0853667623C4C0AC00567AA8 /* WindowInfo.swift */; }; + 0853667923C58F1E00567AA8 /* Collection+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0853667823C58F1E00567AA8 /* Collection+Extension.swift */; }; + 0889D10523C4720E00E867FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0889D10423C4720E00E867FF /* AppDelegate.swift */; }; + 0889D10923C4721100E867FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0889D10823C4721100E867FF /* Assets.xcassets */; }; + 0889D10C23C4721100E867FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0889D10A23C4721100E867FF /* Main.storyboard */; }; + 0889D11423C4738900E867FF /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0889D11323C4738900E867FF /* ServiceManagement.framework */; }; + 0889D11623C473A400E867FF /* BlurredLauncher.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0889D10223C4720E00E867FF /* BlurredLauncher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 0889D11823C4758900E867FF /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0889D11723C4758900E867FF /* Util.swift */; }; + 08FF678D23A9156A00EACD58 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08FF678C23A9156A00EACD58 /* AppDelegate.swift */; }; + 08FF679123A9156C00EACD58 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 08FF679023A9156C00EACD58 /* Assets.xcassets */; }; + 08FF679423A9156C00EACD58 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 08FF679223A9156C00EACD58 /* Main.storyboard */; }; + 5515742323C43FC5006BE18F /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5515742223C43FC5006BE18F /* StatusBarController.swift */; }; + 5515742523C46FE8006BE18F /* UserDefaults+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5515742423C46FE8006BE18F /* UserDefaults+Extension.swift */; }; + 553B8D1B23C2E43D0009CA0F /* DimManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 553B8D1A23C2E43D0009CA0F /* DimManager.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 0889D11523C4739600E867FF /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = Contents/Library/LoginItems; + dstSubfolderSpec = 1; + files = ( + 0889D11623C473A400E867FF /* BlurredLauncher.app in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 08203CCF23CD9CBE0006AE7C /* Bundle+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+Extension.swift"; sourceTree = ""; }; + 083501CB23C5DF0400F6E567 /* EventMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMonitor.swift; sourceTree = ""; }; + 0851749923FD099400B3B84F /* SettingObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingObservable.swift; sourceTree = ""; }; + 0851749A23FD099400B3B84F /* PreferenceView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferenceView.swift; sourceTree = ""; }; + 0851749D23FD0A0B00B3B84F /* Blurred.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Blurred.entitlements; sourceTree = ""; }; + 0851749E23FD0A3100B3B84F /* BlurredLauncher.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = BlurredLauncher.entitlements; sourceTree = ""; }; + 085174A223FD2EF300B3B84F /* GlobalKeyBindPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalKeyBindPreferences.swift; sourceTree = ""; }; + 085174A423FD34C500B3B84F /* PreferencesWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindow.swift; sourceTree = ""; }; + 0853667623C4C0AC00567AA8 /* WindowInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowInfo.swift; sourceTree = ""; }; + 0853667823C58F1E00567AA8 /* Collection+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Extension.swift"; sourceTree = ""; }; + 0889D10223C4720E00E867FF /* BlurredLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BlurredLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0889D10423C4720E00E867FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 0889D10823C4721100E867FF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 0889D10B23C4721100E867FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 0889D10D23C4721100E867FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0889D11323C4738900E867FF /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; }; + 0889D11723C4758900E867FF /* Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; }; + 08FF678923A9156A00EACD58 /* Blurred.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Blurred.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 08FF678C23A9156A00EACD58 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 08FF679023A9156C00EACD58 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 08FF679323A9156C00EACD58 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 08FF679523A9156C00EACD58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5515742223C43FC5006BE18F /* StatusBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarController.swift; sourceTree = ""; }; + 5515742423C46FE8006BE18F /* UserDefaults+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+Extension.swift"; sourceTree = ""; }; + 553B8D1A23C2E43D0009CA0F /* DimManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DimManager.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0889D0FF23C4720E00E867FF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08FF678623A9156A00EACD58 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 085174A123FD2E9700B3B84F /* HotKey in Frameworks */, + 0889D11423C4738900E867FF /* ServiceManagement.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0853667523C4C09F00567AA8 /* Models */ = { + isa = PBXGroup; + children = ( + 0853667623C4C0AC00567AA8 /* WindowInfo.swift */, + 085174A223FD2EF300B3B84F /* GlobalKeyBindPreferences.swift */, + ); + path = Models; + sourceTree = ""; + }; + 0889D10323C4720E00E867FF /* BlurredLauncher */ = { + isa = PBXGroup; + children = ( + 0851749E23FD0A3100B3B84F /* BlurredLauncher.entitlements */, + 0889D10423C4720E00E867FF /* AppDelegate.swift */, + 0889D10823C4721100E867FF /* Assets.xcassets */, + 0889D10A23C4721100E867FF /* Main.storyboard */, + 0889D10D23C4721100E867FF /* Info.plist */, + ); + path = BlurredLauncher; + sourceTree = ""; + }; + 0889D11223C4738900E867FF /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0889D11323C4738900E867FF /* ServiceManagement.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 08FF678023A9156A00EACD58 = { + isa = PBXGroup; + children = ( + 08FF678B23A9156A00EACD58 /* Blurred */, + 0889D10323C4720E00E867FF /* BlurredLauncher */, + 0889D11223C4738900E867FF /* Frameworks */, + ); + sourceTree = ""; + }; + 08FF678A23A9156A00EACD58 /* Products */ = { + isa = PBXGroup; + children = ( + 08FF678923A9156A00EACD58 /* Blurred.app */, + 0889D10223C4720E00E867FF /* BlurredLauncher.app */, + ); + name = Products; + path = ..; + sourceTree = ""; + }; + 08FF678B23A9156A00EACD58 /* Blurred */ = { + isa = PBXGroup; + children = ( + 0851749D23FD0A0B00B3B84F /* Blurred.entitlements */, + 0853667523C4C09F00567AA8 /* Models */, + 55AA99F623B07ACC005478F2 /* Utilities */, + 55AA99F523B07AB8005478F2 /* ViewControllers */, + 08FF678C23A9156A00EACD58 /* AppDelegate.swift */, + 08FF679023A9156C00EACD58 /* Assets.xcassets */, + 08FF679223A9156C00EACD58 /* Main.storyboard */, + 08FF679523A9156C00EACD58 /* Info.plist */, + 08FF678A23A9156A00EACD58 /* Products */, + ); + path = Blurred; + sourceTree = ""; + }; + 55AA99F523B07AB8005478F2 /* ViewControllers */ = { + isa = PBXGroup; + children = ( + 0851749A23FD099400B3B84F /* PreferenceView.swift */, + 0851749923FD099400B3B84F /* SettingObservable.swift */, + 5515742223C43FC5006BE18F /* StatusBarController.swift */, + 085174A423FD34C500B3B84F /* PreferencesWindow.swift */, + ); + path = ViewControllers; + sourceTree = ""; + }; + 55AA99F623B07ACC005478F2 /* Utilities */ = { + isa = PBXGroup; + children = ( + 5515742423C46FE8006BE18F /* UserDefaults+Extension.swift */, + 553B8D1A23C2E43D0009CA0F /* DimManager.swift */, + 0889D11723C4758900E867FF /* Util.swift */, + 0853667823C58F1E00567AA8 /* Collection+Extension.swift */, + 083501CB23C5DF0400F6E567 /* EventMonitor.swift */, + 08203CCF23CD9CBE0006AE7C /* Bundle+Extension.swift */, + ); + path = Utilities; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 0889D10123C4720E00E867FF /* BlurredLauncher */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0889D11123C4721100E867FF /* Build configuration list for PBXNativeTarget "BlurredLauncher" */; + buildPhases = ( + 0889D0FE23C4720E00E867FF /* Sources */, + 0889D0FF23C4720E00E867FF /* Frameworks */, + 0889D10023C4720E00E867FF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = BlurredLauncher; + productName = dimmerBarLauncher; + productReference = 0889D10223C4720E00E867FF /* BlurredLauncher.app */; + productType = "com.apple.product-type.application"; + }; + 08FF678823A9156A00EACD58 /* Blurred */ = { + isa = PBXNativeTarget; + buildConfigurationList = 08FF679923A9156C00EACD58 /* Build configuration list for PBXNativeTarget "Blurred" */; + buildPhases = ( + 08FF678523A9156A00EACD58 /* Sources */, + 08FF678623A9156A00EACD58 /* Frameworks */, + 08FF678723A9156A00EACD58 /* Resources */, + 0889D11523C4739600E867FF /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Blurred; + packageProductDependencies = ( + 085174A023FD2E9700B3B84F /* HotKey */, + ); + productName = "Dimmer Bar"; + productReference = 08FF678923A9156A00EACD58 /* Blurred.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FF678123A9156A00EACD58 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1130; + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = "Dwarves Foundation"; + TargetAttributes = { + 0889D10123C4720E00E867FF = { + CreatedOnToolsVersion = 11.3; + }; + 08FF678823A9156A00EACD58 = { + CreatedOnToolsVersion = 11.3; + }; + }; + }; + buildConfigurationList = 08FF678423A9156A00EACD58 /* Build configuration list for PBXProject "Blurred" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 08FF678023A9156A00EACD58; + packageReferences = ( + 0851749F23FD2E9700B3B84F /* XCRemoteSwiftPackageReference "HotKey" */, + ); + productRefGroup = 08FF678A23A9156A00EACD58 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 08FF678823A9156A00EACD58 /* Blurred */, + 0889D10123C4720E00E867FF /* BlurredLauncher */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0889D10023C4720E00E867FF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0889D10923C4721100E867FF /* Assets.xcassets in Resources */, + 0889D10C23C4721100E867FF /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08FF678723A9156A00EACD58 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 08FF679123A9156C00EACD58 /* Assets.xcassets in Resources */, + 08FF679423A9156C00EACD58 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 0889D0FE23C4720E00E867FF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0889D10523C4720E00E867FF /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 08FF678523A9156A00EACD58 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 553B8D1B23C2E43D0009CA0F /* DimManager.swift in Sources */, + 083501CC23C5DF0400F6E567 /* EventMonitor.swift in Sources */, + 5515742323C43FC5006BE18F /* StatusBarController.swift in Sources */, + 0851749B23FD099400B3B84F /* SettingObservable.swift in Sources */, + 08203CD023CD9CBE0006AE7C /* Bundle+Extension.swift in Sources */, + 0889D11823C4758900E867FF /* Util.swift in Sources */, + 5515742523C46FE8006BE18F /* UserDefaults+Extension.swift in Sources */, + 08FF678D23A9156A00EACD58 /* AppDelegate.swift in Sources */, + 0853667923C58F1E00567AA8 /* Collection+Extension.swift in Sources */, + 0853667723C4C0AC00567AA8 /* WindowInfo.swift in Sources */, + 085174A523FD34C500B3B84F /* PreferencesWindow.swift in Sources */, + 085174A323FD2EF300B3B84F /* GlobalKeyBindPreferences.swift in Sources */, + 0851749C23FD099400B3B84F /* PreferenceView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 0889D10A23C4721100E867FF /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 0889D10B23C4721100E867FF /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 08FF679223A9156C00EACD58 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 08FF679323A9156C00EACD58 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 0889D10F23C4721100E867FF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = BlurredLauncher/BlurredLauncher.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = W777S7V8TN; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = BlurredLauncher/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = foundation.dwarves.blurredlauncher; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 0889D11023C4721100E867FF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = BlurredLauncher/BlurredLauncher.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = W777S7V8TN; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = BlurredLauncher/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = foundation.dwarves.blurredlauncher; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 08FF679723A9156C00EACD58 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 08FF679823A9156C00EACD58 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 08FF679A23A9156C00EACD58 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = Blurred/Blurred.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = W777S7V8TN; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = Blurred/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = foundation.dwarves.blurred; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 08FF679B23A9156C00EACD58 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = Blurred/Blurred.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = W777S7V8TN; + ENABLE_HARDENED_RUNTIME = YES; + INFOPLIST_FILE = Blurred/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.15; + MARKETING_VERSION = 1.0.0; + PRODUCT_BUNDLE_IDENTIFIER = foundation.dwarves.blurred; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0889D11123C4721100E867FF /* Build configuration list for PBXNativeTarget "BlurredLauncher" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0889D10F23C4721100E867FF /* Debug */, + 0889D11023C4721100E867FF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 08FF678423A9156A00EACD58 /* Build configuration list for PBXProject "Blurred" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08FF679723A9156C00EACD58 /* Debug */, + 08FF679823A9156C00EACD58 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 08FF679923A9156C00EACD58 /* Build configuration list for PBXNativeTarget "Blurred" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 08FF679A23A9156C00EACD58 /* Debug */, + 08FF679B23A9156C00EACD58 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 0851749F23FD2E9700B3B84F /* XCRemoteSwiftPackageReference "HotKey" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/soffes/HotKey"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.1.3; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 085174A023FD2E9700B3B84F /* HotKey */ = { + isa = XCSwiftPackageProductDependency; + package = 0851749F23FD2E9700B3B84F /* XCRemoteSwiftPackageReference "HotKey" */; + productName = HotKey; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 08FF678123A9156A00EACD58 /* Project object */; +} diff --git a/Blurred.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Blurred.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Blurred.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Blurred.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Blurred.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/Blurred.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..2525f86 --- /dev/null +++ b/Blurred.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "HotKey", + "repositoryURL": "https://github.com/soffes/HotKey", + "state": { + "branch": null, + "revision": "c13662730cb5bc28de4a799854bbb018a90649bf", + "version": "0.1.3" + } + } + ] + }, + "version": 1 +} diff --git a/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred launcher.xcscheme b/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred launcher.xcscheme new file mode 100644 index 0000000..54d7ac0 --- /dev/null +++ b/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred launcher.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred.xcscheme b/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred.xcscheme new file mode 100644 index 0000000..915376d --- /dev/null +++ b/Blurred.xcodeproj/xcshareddata/xcschemes/Blurred.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Blurred/.DS_Store b/Blurred/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/Blurred/.DS_Store differ diff --git a/Blurred/AppDelegate.swift b/Blurred/AppDelegate.swift new file mode 100644 index 0000000..b8d0c12 --- /dev/null +++ b/Blurred/AppDelegate.swift @@ -0,0 +1,53 @@ +// +// AppDelegate.swift +// Dimmer Bar +// +// Created by phucld on 12/17/19. +// Copyright © 2019 Dwarves Foundation. All rights reserved. +// + +import Cocoa +import SwiftUI +import HotKey + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + let statusBarController = StatusBarController() + + var hotKey: HotKey? { + didSet { + guard let hotKey = hotKey else { return } + + hotKey.keyDownHandler = { + DimManager.sharedInstance.setting.isEnabled.toggle() + } + } + } + + func setupHotKey() { + guard let globalKey = UserDefaults.globalKey else {return} + hotKey = HotKey(keyCombo: KeyCombo(carbonKeyCode: globalKey.keyCode, carbonModifiers: globalKey.carbonFlags)) + } + + func applicationDidFinishLaunching(_ aNotification: Notification) { + hideDockIcon() + setupAutoStartAtLogin() + openPrefWindowIfNeeded() + setupHotKey() + } + + func openPrefWindowIfNeeded() { + if UserDefaults.isOpenPrefWhenOpenApp { + statusBarController.openPreferences() + } + } + + func setupAutoStartAtLogin() { + let isAutoStart = UserDefaults.isStartWhenLogin + Util.setUpAutoStart(isAutoStart: isAutoStart) + } + + func hideDockIcon() { + NSApp.setActivationPolicy(.accessory) + } +} diff --git a/Blurred/Assets.xcassets/.DS_Store b/Blurred/Assets.xcassets/.DS_Store new file mode 100644 index 0000000..eb50085 Binary files /dev/null and b/Blurred/Assets.xcassets/.DS_Store differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/1024.png b/Blurred/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 0000000..a3cc7b2 Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/128.png b/Blurred/Assets.xcassets/AppIcon.appiconset/128.png new file mode 100644 index 0000000..7987337 Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/128.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/16.png b/Blurred/Assets.xcassets/AppIcon.appiconset/16.png new file mode 100644 index 0000000..57bdc7a Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/16.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/256.png b/Blurred/Assets.xcassets/AppIcon.appiconset/256.png new file mode 100644 index 0000000..74277db Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/256.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/32.png b/Blurred/Assets.xcassets/AppIcon.appiconset/32.png new file mode 100644 index 0000000..ad9eeea Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/32.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/512.png b/Blurred/Assets.xcassets/AppIcon.appiconset/512.png new file mode 100644 index 0000000..26736e0 Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/512.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/64.png b/Blurred/Assets.xcassets/AppIcon.appiconset/64.png new file mode 100644 index 0000000..b1b0f1d Binary files /dev/null and b/Blurred/Assets.xcassets/AppIcon.appiconset/64.png differ diff --git a/Blurred/Assets.xcassets/AppIcon.appiconset/Contents.json b/Blurred/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13520f7 --- /dev/null +++ b/Blurred/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/Contents.json b/Blurred/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Blurred/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/desktop.imageset/Contents.json b/Blurred/Assets.xcassets/desktop.imageset/Contents.json new file mode 100644 index 0000000..32a7903 --- /dev/null +++ b/Blurred/Assets.xcassets/desktop.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "desktop.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/desktop.imageset/desktop.png b/Blurred/Assets.xcassets/desktop.imageset/desktop.png new file mode 100644 index 0000000..f90253b Binary files /dev/null and b/Blurred/Assets.xcassets/desktop.imageset/desktop.png differ diff --git a/Blurred/Assets.xcassets/ico_app.imageset/Blurred.png b/Blurred/Assets.xcassets/ico_app.imageset/Blurred.png new file mode 100644 index 0000000..81ba4b3 Binary files /dev/null and b/Blurred/Assets.xcassets/ico_app.imageset/Blurred.png differ diff --git a/Blurred/Assets.xcassets/ico_app.imageset/Contents.json b/Blurred/Assets.xcassets/ico_app.imageset/Contents.json new file mode 100644 index 0000000..6896f85 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_app.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Blurred.png" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_compass.imageset/Contents.json b/Blurred/Assets.xcassets/ico_compass.imageset/Contents.json new file mode 100644 index 0000000..5fe8e89 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_compass.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ico_compass.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_compass.imageset/ico_compass.pdf b/Blurred/Assets.xcassets/ico_compass.imageset/ico_compass.pdf new file mode 100644 index 0000000..50c2cc6 Binary files /dev/null and b/Blurred/Assets.xcassets/ico_compass.imageset/ico_compass.pdf differ diff --git a/Blurred/Assets.xcassets/ico_email.imageset/Contents.json b/Blurred/Assets.xcassets/ico_email.imageset/Contents.json new file mode 100644 index 0000000..42aa569 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_email.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ico_email.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_email.imageset/ico_email.pdf b/Blurred/Assets.xcassets/ico_email.imageset/ico_email.pdf new file mode 100644 index 0000000..2c4fef5 Binary files /dev/null and b/Blurred/Assets.xcassets/ico_email.imageset/ico_email.pdf differ diff --git a/Blurred/Assets.xcassets/ico_github.imageset/Contents.json b/Blurred/Assets.xcassets/ico_github.imageset/Contents.json new file mode 100644 index 0000000..c500dce --- /dev/null +++ b/Blurred/Assets.xcassets/ico_github.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ico_github.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_github.imageset/ico_github.pdf b/Blurred/Assets.xcassets/ico_github.imageset/ico_github.pdf new file mode 100644 index 0000000..d19e21c Binary files /dev/null and b/Blurred/Assets.xcassets/ico_github.imageset/ico_github.pdf differ diff --git a/Blurred/Assets.xcassets/ico_line.imageset/Contents.json b/Blurred/Assets.xcassets/ico_line.imageset/Contents.json new file mode 100644 index 0000000..161dfb8 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_line.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_line.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_line.imageset/ic_line.png b/Blurred/Assets.xcassets/ico_line.imageset/ic_line.png new file mode 100644 index 0000000..41ec7c5 Binary files /dev/null and b/Blurred/Assets.xcassets/ico_line.imageset/ic_line.png differ diff --git a/Blurred/Assets.xcassets/ico_menu.imageset/Blurred icon.png b/Blurred/Assets.xcassets/ico_menu.imageset/Blurred icon.png new file mode 100644 index 0000000..88e64e6 Binary files /dev/null and b/Blurred/Assets.xcassets/ico_menu.imageset/Blurred icon.png differ diff --git a/Blurred/Assets.xcassets/ico_menu.imageset/Contents.json b/Blurred/Assets.xcassets/ico_menu.imageset/Contents.json new file mode 100644 index 0000000..223a351 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_menu.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Blurred icon.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_twitter.imageset/Contents.json b/Blurred/Assets.xcassets/ico_twitter.imageset/Contents.json new file mode 100644 index 0000000..cb49dd8 --- /dev/null +++ b/Blurred/Assets.xcassets/ico_twitter.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ico_twitter.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/ico_twitter.imageset/ico_twitter.pdf b/Blurred/Assets.xcassets/ico_twitter.imageset/ico_twitter.pdf new file mode 100644 index 0000000..bc8ce6a Binary files /dev/null and b/Blurred/Assets.xcassets/ico_twitter.imageset/ico_twitter.pdf differ diff --git a/Blurred/Assets.xcassets/window.imageset/Contents.json b/Blurred/Assets.xcassets/window.imageset/Contents.json new file mode 100644 index 0000000..da7ce5a --- /dev/null +++ b/Blurred/Assets.xcassets/window.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Screen Shot 2020-01-07 at 09.49.24.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Blurred/Assets.xcassets/window.imageset/Screen Shot 2020-01-07 at 09.49.24.png b/Blurred/Assets.xcassets/window.imageset/Screen Shot 2020-01-07 at 09.49.24.png new file mode 100644 index 0000000..d279474 Binary files /dev/null and b/Blurred/Assets.xcassets/window.imageset/Screen Shot 2020-01-07 at 09.49.24.png differ diff --git a/Blurred/Base.lproj/Main.storyboard b/Blurred/Base.lproj/Main.storyboard new file mode 100644 index 0000000..e8dcefe --- /dev/null +++ b/Blurred/Base.lproj/Main.storyboard @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Blurred/Blurred.entitlements b/Blurred/Blurred.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/Blurred/Blurred.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/Blurred/Info.plist b/Blurred/Info.plist new file mode 100644 index 0000000..a25c628 --- /dev/null +++ b/Blurred/Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + 1 + LSApplicationCategoryType + public.app-category.utilities + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + LSUIElement + + NSHumanReadableCopyright + Copyright © 2019 Dwarves Foundation. All rights reserved. + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + NSSupportsAutomaticTermination + + NSSupportsSuddenTermination + + + diff --git a/Blurred/Models/GlobalKeyBindPreferences.swift b/Blurred/Models/GlobalKeyBindPreferences.swift new file mode 100644 index 0000000..aa66560 --- /dev/null +++ b/Blurred/Models/GlobalKeyBindPreferences.swift @@ -0,0 +1,54 @@ +// +// GlobalKeyBindPreferences.swift +// Blurred +// +// Created by phucld on 2/19/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation + +struct GlobalKeybindPreferences: Codable, CustomStringConvertible { + let function : Bool + let control : Bool + let command : Bool + let shift : Bool + let option : Bool + let capsLock : Bool + let carbonFlags : UInt32 + let characters : String? + let keyCode : UInt32 + + var description: String { + var stringBuilder = "" + if self.function { + stringBuilder += "Fn" + } + if self.control { + stringBuilder += "⌃" + } + if self.option { + stringBuilder += "⌥" + } + if self.command { + stringBuilder += "⌘" + } + if self.shift { + stringBuilder += "⇧" + } + if self.capsLock { + stringBuilder += "⇪" + } + if let characters = self.characters { + stringBuilder += characters.uppercased() + } + return "\(stringBuilder)" + } +} + +extension GlobalKeybindPreferences { + func save() { + + } +} + diff --git a/Blurred/Models/WindowInfo.swift b/Blurred/Models/WindowInfo.swift new file mode 100644 index 0000000..ecbe877 --- /dev/null +++ b/Blurred/Models/WindowInfo.swift @@ -0,0 +1,47 @@ +// +// WindowInfo.swift +// Dimmer Bar +// +// Created by phucld on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation +import Cocoa + +// The keys that are guaranteed to be available in a window’s information dictionary. +// https://developer.apple.com/documentation/coregraphics/quartz_window_services/required_window_list_keys?language=objc + +struct WindowInfo { + var alpha: Double + var backingLocationVideoMemory: Bool? + var bounds: CGRect? + var isOnScreen: Bool? + var layer: Int + var memoryUsage: Double + var name: String? + var number: Int + var ownerName: String? + var ownerPID: Int + var sharingState: Int + var storeType: Int +} + +extension WindowInfo { + init(dict: [String: Any]) { + alpha = dict["kCGWindowAlpha"] as! Double + backingLocationVideoMemory = dict["CGWindowBackingLocationVideoMemory"] as? Bool + let boundsDict = dict["kCGWindowBounds"] as! CFDictionary + bounds = CGRect(dictionaryRepresentation: boundsDict) + isOnScreen = dict["kCGWindowIsOnscreen"] as? Bool + layer = dict["kCGWindowLayer"] as! Int + memoryUsage = dict["kCGWindowMemoryUsage"] as! Double + name = dict["kCGWindowName"] as? String + number = dict["kCGWindowNumber"] as! Int + ownerName = dict["kCGWindowOwnerName"] as? String + ownerPID = dict["kCGWindowOwnerPID"] as! Int + sharingState = dict["kCGWindowSharingState"] as! Int + storeType = dict["kCGWindowStoreType"] as! Int + } +} + diff --git a/Blurred/Utilities/Bundle+Extension.swift b/Blurred/Utilities/Bundle+Extension.swift new file mode 100644 index 0000000..fe190cf --- /dev/null +++ b/Blurred/Utilities/Bundle+Extension.swift @@ -0,0 +1,18 @@ +// +// Bundle+Extension.swift +// Dimmer Bar +// +// Created by phucld on 1/14/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation + +extension Bundle { + var releaseVersionNumber: String? { + return infoDictionary?["CFBundleShortVersionString"] as? String + } + var buildVersionNumber: String? { + return infoDictionary?["CFBundleVersion"] as? String + } +} diff --git a/Blurred/Utilities/Collection+Extension.swift b/Blurred/Utilities/Collection+Extension.swift new file mode 100644 index 0000000..481a4a4 --- /dev/null +++ b/Blurred/Utilities/Collection+Extension.swift @@ -0,0 +1,17 @@ +// +// Collection+Extension.swift +// Dimmer Bar +// +// Created by phucld on 1/8/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation + +extension Collection { + + /// Returns the element at the specified index if it is within bounds, otherwise nil. + subscript (safe index: Index) -> Element? { + return indices.contains(index) ? self[index] : nil + } +} diff --git a/Blurred/Utilities/DimManager.swift b/Blurred/Utilities/DimManager.swift new file mode 100644 index 0000000..a652998 --- /dev/null +++ b/Blurred/Utilities/DimManager.swift @@ -0,0 +1,132 @@ +// +// DimManager.swift +// Dimmer Bar +// +// Created by Trung Phan on 12/23/19. +// Copyright © 2019 Dwarves Foundation. All rights reserved. +// + +import Foundation +import Cocoa + +enum DimMode: Int { + case single + case parallel +} + +class DimManager { + //MARK: - Init + static let sharedInstance = DimManager() + + private init() {} + + //MARK: - Variable(s) + var didReciptActiveApplicationChanged: ((NSRunningApplication?) -> Void)? + + let setting = SettingObservable() + private var windows:[NSWindow] = [] + +} + +//MARK: - Core function Helper Methods +extension DimManager { + func getFrontMostApplication() -> NSRunningApplication? { + return NSWorkspace.shared.frontmostApplication + } + + func windowForScreen(screen: NSScreen, color: NSColor, windowInfos: [WindowInfo]) -> NSWindow { + + let frame = NSRect(origin: .zero, size: screen.frame.size) + let overlayWindow = NSWindow.init(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false, screen: screen) + overlayWindow.isReleasedWhenClosed = false + overlayWindow.animationBehavior = .none + overlayWindow.backgroundColor = color + overlayWindow.ignoresMouseEvents = true + overlayWindow.collectionBehavior = [.transient, .fullScreenNone] + overlayWindow.level = .normal + + var windowNumber = 0 + switch setting.dimMode { + case .single: + windowNumber = windowInfos[safe: 0]?.number ?? 0 + case .parallel: + // Get frontmost window of each screen + let newScreen = NSRect(x: screen.frame.minX, y: NSScreen.screens[0].frame.maxY - screen.frame.maxY, width: screen.frame.width, height: screen.frame.height) + let windowInfo = windowInfos.first(where: { + return newScreen.minX < $0.bounds!.midX && + newScreen.maxX > $0.bounds!.midX && + newScreen.minY < $0.bounds!.midY && + newScreen.maxY > $0.bounds!.midY + }) + + windowNumber = windowInfo?.number ?? 0 + } + + overlayWindow.order(.below, relativeTo: windowNumber) + return overlayWindow + } +} + +extension DimManager { + func observerActiveWindowChanged() { + let nc = NSWorkspace.shared.notificationCenter + nc.addObserver(self, selector: #selector(workspaceDidReceiptAppllicatinActiveNotification), name: NSWorkspace.didActivateApplicationNotification, object: nil) + } + + private func removeAllNotification() { + NSWorkspace.shared.notificationCenter.removeObserver(self, name: NSWorkspace.didActivateApplicationNotification, object: nil) + } + + @objc private func workspaceDidReceiptAppllicatinActiveNotification(ntf: Notification) { + if let activeAppDict = ntf.userInfo as? [AnyHashable : NSRunningApplication], + let didReciptActiveApplicationChanged = self.didReciptActiveApplicationChanged, + let activeApplication = activeAppDict["NSWorkspaceApplicationKey"] { + didReciptActiveApplicationChanged(activeApplication) + } + } +} + +extension DimManager { + func prepareForDim() { + DimManager.sharedInstance.observerActiveWindowChanged() + DimManager.sharedInstance.didReciptActiveApplicationChanged = {[weak self] runningApplication in + self?.dim(runningApplication: runningApplication) + } + } + + + func dim(runningApplication: NSRunningApplication?) { + self.removeAllOverlay() + + if DimManager.sharedInstance.setting.isEnabled == false {return} + + if let bundle = runningApplication?.bundleIdentifier, bundle == "com.apple.finder" { + return + } + + let windowInfos = getWindowInfos() + let screens = NSScreen.screens + + let color = NSColor.black.withAlphaComponent(CGFloat(DimManager.sharedInstance.setting.alpha/100.0)) + + for screen in screens { + let overlayWindow = DimManager.sharedInstance.windowForScreen(screen: screen, color: color, windowInfos: windowInfos) + self.windows.append(overlayWindow) + } + } + + private func removeAllOverlay() { + for overlayWindow in self.windows { + overlayWindow.close() + } + self.windows.removeAll() + } + + private func getWindowInfos() -> [WindowInfo] { + let options = CGWindowListOption([.optionOnScreenOnly, .excludeDesktopElements]) + let windowsListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0)) + let infoList = windowsListInfo as! [[String:Any]] + let windowInfos = infoList.map { WindowInfo.init(dict: $0) }.filter { $0.layer == 0 } + return windowInfos + } +} diff --git a/Blurred/Utilities/EventMonitor.swift b/Blurred/Utilities/EventMonitor.swift new file mode 100644 index 0000000..1fcf034 --- /dev/null +++ b/Blurred/Utilities/EventMonitor.swift @@ -0,0 +1,36 @@ +// +// EventMonitor.swift +// Dimmer Bar +// +// Created by phucld on 1/8/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Cocoa + +public class EventMonitor { + + private var monitor: Any? + private let mask: NSEvent.EventTypeMask + private let handler: (NSEvent?) -> () + + public init(mask: NSEvent.EventTypeMask, handler: @escaping (NSEvent?) -> ()) { + self.mask = mask + self.handler = handler + } + + deinit { + stop() + } + + public func start() { + monitor = NSEvent.addGlobalMonitorForEvents(matching: mask, handler: handler) + } + + public func stop() { + if monitor != nil { + NSEvent.removeMonitor(monitor!) + monitor = nil + } + } +} diff --git a/Blurred/Utilities/UserDefaults+Extension.swift b/Blurred/Utilities/UserDefaults+Extension.swift new file mode 100644 index 0000000..fab3d8c --- /dev/null +++ b/Blurred/Utilities/UserDefaults+Extension.swift @@ -0,0 +1,119 @@ +// +// UserDefaults+Extension.swift +// Dimmer Bar +// +// Created by Trung Phan on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation +import Cocoa + +let defaultAlpha = 70.0 + + +extension UserDefaults { + private struct Key { + static let isStartWhenLogin = "IS_START_WHEN_LOGIN" + static let alpha = "ALPHA" + static let isEnabled = "IS_ENABLED" + static let isActiveSceenMode = "IS_ACTIVE_SCREEN_MODE" + static let isOpenPrefWhenOpenApp = "IS_OPEN_PREF_WHEN_OPEN_APP" + static let dimMode = "DIM_MODE" + static let globalKey = "GLOBAL_KEY" + } + + static var isStartWhenLogin: Bool { + get { + return UserDefaults.standard.bool(forKey: UserDefaults.Key.isStartWhenLogin) + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.isStartWhenLogin) + Util.setUpAutoStart(isAutoStart: newValue) + } + } + + static var isOpenPrefWhenOpenApp: Bool { + get { + UserDefaults.standard.register(defaults: [Key.isOpenPrefWhenOpenApp : true]) + return UserDefaults.standard.bool(forKey: UserDefaults.Key.isOpenPrefWhenOpenApp) + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.isOpenPrefWhenOpenApp) + } + } + + static var dimMode: Int { + get { + return UserDefaults.standard.integer(forKey: UserDefaults.Key.dimMode) + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.dimMode) + } + } + + static var alpha: Double { + get { + let alpha = UserDefaults.standard.double(forKey: UserDefaults.Key.alpha) + if alpha == 0.0 { + UserDefaults.standard.set(defaultAlpha, forKey: UserDefaults.Key.alpha) + return defaultAlpha + }else { + return alpha + } + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.alpha) + } + } + + static var isEnabled: Bool { + get { + return UserDefaults.standard.bool(forKey: UserDefaults.Key.isEnabled) + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.isEnabled) + } + } + + static var isActiveSceenMode: Bool { + get { + return UserDefaults.standard.bool(forKey: UserDefaults.Key.isActiveSceenMode) + } + set { + UserDefaults.standard.set(newValue, forKey: UserDefaults.Key.isActiveSceenMode) + } + } + + static var globalKey: GlobalKeybindPreferences? { + get { + guard let data = UserDefaults.standard.value(forKey: UserDefaults.Key.globalKey) as? Data else { return nil } + return try? JSONDecoder().decode(GlobalKeybindPreferences.self, from: data) + } + + set { + guard let data = try? JSONEncoder().encode(newValue) else { return } + UserDefaults.standard.set(data, forKey: UserDefaults.Key.globalKey) + } + } +} + + +extension NSWindow.Level { + private static func level(for cgLevelKey: CGWindowLevelKey) -> NSWindow.Level { + NSWindow.Level(rawValue: Int(CGWindowLevelForKey(cgLevelKey))) + } + + public static let desktop = level(for: .desktopWindow) + public static let desktopIcon = level(for: .desktopIconWindow) + public static let backstopMenu = level(for: .backstopMenu) + public static let dragging = level(for: .draggingWindow) + public static let overlay = level(for: .overlayWindow) + public static let help = level(for: .helpWindow) + public static let utility = level(for: .utilityWindow) + public static let assistiveTechHigh = level(for: .assistiveTechHighWindow) + public static let cursor = level(for: .cursorWindow) + + public static let minimum = level(for: .minimumWindow) + public static let maximum = level(for: .maximumWindow) +} diff --git a/Blurred/Utilities/Util.swift b/Blurred/Utilities/Util.swift new file mode 100644 index 0000000..0cd210e --- /dev/null +++ b/Blurred/Utilities/Util.swift @@ -0,0 +1,26 @@ +// +// Util.swift +// Dimmer Bar +// +// Created by phucld on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import SwiftUI +import Foundation +import ServiceManagement + +enum Util { + static func setUpAutoStart(isAutoStart:Bool) { + let launcherAppId = "foundation.dwarves.blurredlauncher" + let runningApps = NSWorkspace.shared.runningApplications + let isRunning = !runningApps.filter { $0.bundleIdentifier == launcherAppId }.isEmpty + + SMLoginItemSetEnabled(launcherAppId as CFString, isAutoStart) + + if isRunning { + DistributedNotificationCenter.default().post(name: Notification.Name("killLauncher"), + object: Bundle.main.bundleIdentifier!) + } + } +} diff --git a/Blurred/ViewControllers/PreferenceView.swift b/Blurred/ViewControllers/PreferenceView.swift new file mode 100644 index 0000000..ad91299 --- /dev/null +++ b/Blurred/ViewControllers/PreferenceView.swift @@ -0,0 +1,215 @@ +// +// PreferenceView.swift +// Dimmer Bar +// +// Created by Trung Phan on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import SwiftUI + +struct PreferenceView: View { + @ObservedObject var setting: SettingObservable + @State private var tag = 1 + + var body: some View { + VStack { + Picker(selection: self.$tag, label: Text("Picker")) { + Text("Settings").tag(1) + Text("About").tag(2) + } + .pickerStyle(SegmentedPickerStyle()) + .labelsHidden() + .frame(width: 200) + .padding() + + HStack { + Text(self.tag == 1 ? "Settings" : "About") + .font(.largeTitle) + .fontWeight(.bold) + Spacer() + }.padding() + + if self.tag == 1 { + SettingView(setting: setting).padding() + } else { + AboutView() + } + } + } +} + +struct PreferenceView_Previews: PreviewProvider { + static var previews: some View { + PreferenceView(setting: DimManager.sharedInstance.setting) + } +} + +struct SettingView: View { + @ObservedObject var setting: SettingObservable + + var body: some View { + VStack { + HStack { + ZStack { + Image("desktop") + .resizable() + .scaledToFit() + .overlay(Color.black.opacity(setting.isEnabled ? setting.alpha/100.0 : 0)) + .frame(maxWidth: .infinity) + + + Image("window") + .resizable() + .scaledToFit() + .frame(width: 400) + } + .frame(width: 600, height: 320) + } + + HStack(alignment: .center) { + VStack(alignment: .leading) { + + Toggle(isOn: $setting.isEnabled) { + Text("Enable Blurred") + }.padding(.top) + + Toggle(isOn: $setting.isStartWhenLogin) { + Text("Start Blurred when log in") + } + + Toggle(isOn: $setting.isOpenPrefWhenOpenApp) { + Text("Open Preferences Window when login") + } + .padding(.bottom, 10) + + Picker(selection: $setting.dimMode, label: Text("Dim mode")) { + Text("Single").tag(DimMode.single) + Text("Parallel").tag(DimMode.parallel) + }.fixedSize() + + Text("Dimmer level:") + HStack { + Text("10%") + Slider(value: $setting.alpha, in: 10...100, step: 10) + .frame(width: 200) + .disabled(!setting.isEnabled) + Text("\(setting.alpha, specifier: "%.f")%") + } + + } + Spacer() + VStack(alignment: .center) { + Text("Global shortcut") + .font(.headline) + HStack(spacing: 0) { + + Button(setting.currentHotkeyLabel) { + self.setting.isListenningForHotkey = true + } + .background(setting.isListenningForHotkey ? + RoundedRectangle(cornerRadius: 2).foregroundColor(Color(NSColor.controlHighlightColor)) : + RoundedRectangle(cornerRadius: 2).foregroundColor(Color(NSColor.controlBackgroundColor)) + ) + + Button("⌫") { + self.setting.isListenningForHotkey = false + self.setting.currentHotkeyLabel = "Set Hotkey" + self.setting.globalHotkey = nil + let appDelegate = NSApplication.shared.delegate as! AppDelegate + appDelegate.hotKey = nil + } + .disabled(setting.isListenningForHotkey || setting.globalHotkey == nil) + } + .padding(5) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(Color.secondary.opacity(0.5)) + ) + + } + } + } + } +} + + +struct LinkView: View { + var imageName: String + var title: String + var link: String + var body: some View { + HStack { + Button(action: { + if let url = URL(string: self.link) { + NSWorkspace.shared.open(url) + } + }) { + HStack { + Image(imageName) + .antialiased(true) + .resizable() + .frame(width: 24, height: 24) + .foregroundColor(.primary) + + Text(title) + .foregroundColor(.primary) + } + }.buttonStyle(LinkButtonStyle()) + } + } +} + + +struct AboutView: View { + private let releaseVersion = Bundle.main.releaseVersionNumber ?? "" + private let buildVersion = Bundle.main.buildVersionNumber ?? "" + + var body: some View { + VStack { + HStack { + Image("ico_app") + .antialiased(true) + .resizable() + .scaledToFit() + .frame(width: 150) + + + VStack(alignment: .leading) { + Text("Blurred") + .font(.largeTitle) + .fontWeight(.bold) + .foregroundColor(.primary) + + Text("Focus to your work") + .font(.headline) + .foregroundColor(.secondary) + + Text("Version \(releaseVersion) (\(buildVersion))") + .font(.footnote) + .foregroundColor(.secondary) + } + } + .frame(maxWidth: .infinity, maxHeight: 300) + .background(Color.white.opacity(0.1)) + + VStack(alignment: .leading, spacing: 16) { + LinkView(imageName: "ico_compass", title: "Know more about us", link: "https://dwarves.foundation/apps") + LinkView(imageName: "ico_twitter", title: "Follow us on Twitter", link:"https://twitter.com/dwarvesf") + LinkView(imageName: "ico_github", title: "This app is fully open source", link: "https://github.com/dwarvesf/Blurred") + LinkView(imageName: "ico_email", title: "Email us", link: "mailto:macos@d.foundation") + } + + Text("MIT © Dwarves Foundation") + .font(.footnote) + .foregroundColor(.secondary) + .padding(.bottom) + } + } +} + +struct AboutView_Previews: PreviewProvider { + static var previews: some View { + AboutView() + } +} diff --git a/Blurred/ViewControllers/PreferencesWindow.swift b/Blurred/ViewControllers/PreferencesWindow.swift new file mode 100644 index 0000000..d8be0da --- /dev/null +++ b/Blurred/ViewControllers/PreferencesWindow.swift @@ -0,0 +1,82 @@ +// +// PreferencesWindow.swift +// Blurred +// +// Created by phucld on 2/19/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Cocoa +import HotKey + +class PreferencesWindow: NSWindow { + override func keyDown(with event: NSEvent) { + super.keyDown(with: event) + guard DimManager.sharedInstance.setting.isListenningForHotkey else {return} + updateGlobalShortcut(event) + } + + override func flagsChanged(with event: NSEvent) { + super.flagsChanged(with: event) + guard DimManager.sharedInstance.setting.isListenningForHotkey else {return} + updateModiferFlags(event) + } + + + private func updateGlobalShortcut(_ event: NSEvent) { + + DimManager.sharedInstance.setting.isListenningForHotkey = false + + guard let characters = event.charactersIgnoringModifiers else {return} + + let newGlobalKeybind = GlobalKeybindPreferences( + function: event.modifierFlags.contains(.function), + control: event.modifierFlags.contains(.control), + command: event.modifierFlags.contains(.command), + shift: event.modifierFlags.contains(.shift), + option: event.modifierFlags.contains(.option), + capsLock: event.modifierFlags.contains(.capsLock), + carbonFlags: event.modifierFlags.carbonFlags, + characters: characters, + keyCode: uint32(event.keyCode)) + + if newGlobalKeybind.description.count != 1 { + DimManager.sharedInstance.setting.globalHotkey = newGlobalKeybind + } + + updateKeybindButton(newGlobalKeybind) + + let appDelegate = NSApplication.shared.delegate as! AppDelegate + appDelegate.hotKey = HotKey(keyCombo: KeyCombo(carbonKeyCode: UInt32(event.keyCode), carbonModifiers: event.modifierFlags.carbonFlags)) + } + + private func updateModiferFlags(_ event: NSEvent) { + let newGlobalKeybind = GlobalKeybindPreferences( + function: event.modifierFlags.contains(.function), + control: event.modifierFlags.contains(.control), + command: event.modifierFlags.contains(.command), + shift: event.modifierFlags.contains(.shift), + option: event.modifierFlags.contains(.option), + capsLock: event.modifierFlags.contains(.capsLock), + carbonFlags: 0, + characters: nil, + keyCode: uint32(event.keyCode)) + + updateKeybindButton(newGlobalKeybind) + } + + // Set the shortcut button to show the keys to press + private func updateKeybindButton(_ globalKeybindPreference : GlobalKeybindPreferences) { + + DimManager.sharedInstance.setting.currentHotkeyLabel = globalKeybindPreference.description + + if globalKeybindPreference.description.isEmpty { + DimManager.sharedInstance.setting.currentHotkeyLabel = "Set Hotkey" + DimManager.sharedInstance.setting.globalHotkey = nil + DimManager.sharedInstance.setting.isListenningForHotkey = false + let appDelegate = NSApplication.shared.delegate as! AppDelegate + appDelegate.hotKey = nil + } + } + +} diff --git a/Blurred/ViewControllers/SettingObservable.swift b/Blurred/ViewControllers/SettingObservable.swift new file mode 100644 index 0000000..1528a92 --- /dev/null +++ b/Blurred/ViewControllers/SettingObservable.swift @@ -0,0 +1,69 @@ +// +// SettingObservable.swift +// Dimmer Bar +// +// Created by Trung Phan on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation +import Combine + +final class SettingObservable: ObservableObject { + let objectWillChange = PassthroughSubject() + + var isStartWhenLogin: Bool = UserDefaults.isStartWhenLogin { + willSet { + UserDefaults.isStartWhenLogin = newValue + objectWillChange.send() + } + } + + var isOpenPrefWhenOpenApp: Bool = UserDefaults.isOpenPrefWhenOpenApp { + willSet { + UserDefaults.isOpenPrefWhenOpenApp = newValue + objectWillChange.send() + } + } + + var dimMode: DimMode = DimMode(rawValue: UserDefaults.dimMode) ?? .single { + willSet { + UserDefaults.dimMode = newValue.rawValue + objectWillChange.send() + } + } + + var alpha: Double = UserDefaults.alpha { + willSet { + UserDefaults.alpha = newValue + objectWillChange.send() + } + } + + var isEnabled: Bool = UserDefaults.isEnabled { + willSet { + UserDefaults.isEnabled = newValue + objectWillChange.send() + } + } + + var globalHotkey: GlobalKeybindPreferences? = UserDefaults.globalKey { + willSet { + UserDefaults.globalKey = newValue + objectWillChange.send() + } + } + + var currentHotkeyLabel: String = UserDefaults.globalKey?.description ?? "Set Hotkey" { + willSet { + objectWillChange.send() + } + } + + var isListenningForHotkey: Bool = false { + willSet { + objectWillChange.send() + } + } + +} diff --git a/Blurred/ViewControllers/StatusBarController.swift b/Blurred/ViewControllers/StatusBarController.swift new file mode 100644 index 0000000..16579bb --- /dev/null +++ b/Blurred/ViewControllers/StatusBarController.swift @@ -0,0 +1,136 @@ +// +// StatusBarController.swift +// Dimmer Bar +// +// Created by Trung Phan on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Foundation +import Cocoa +import Combine +import SwiftUI + +class StatusBarController{ + + private let menuStatusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength) + private let slider = NSSlider() + private var subscriptions = Set() + + lazy private var window: NSWindow = { + let contentView = PreferenceView(setting: DimManager.sharedInstance.setting) + let window = PreferencesWindow( + contentRect: NSRect.zero, + styleMask: [.borderless,.titled,.closable], + backing: .buffered, defer: false) + + window.center() + window.isReleasedWhenClosed = false + window.contentView = NSHostingView(rootView: contentView) + window.level = .floating + return window + }() + + init() { + setupView() + setupSlider() + DimManager.sharedInstance.prepareForDim() + autoReloadWhenSettingChanged() + } + + private func autoReloadWhenSettingChanged() { + DimManager.sharedInstance.setting.objectWillChange + .receive(on: RunLoop.main) + .debounce(for: 0.1, scheduler: RunLoop.main) + .sink { _ in + DimManager.sharedInstance.dim(runningApplication: DimManager.sharedInstance.getFrontMostApplication()) + } + .store(in: &subscriptions) + } + + private func setupView() { + if let button = menuStatusItem.button { + button.image = #imageLiteral(resourceName: "ico_menu") + } + menuStatusItem.menu = getContextMenu() + } + + @objc private func handleGesture(gestureRecognizer: NSMagnificationGestureRecognizer) { + switch gestureRecognizer.state { + case .changed: + print(gestureRecognizer) + default: break + } + } + + private func setupSlider() { + slider.minValue = 10.0 + slider.maxValue = 100.0 + slider.doubleValue = DimManager.sharedInstance.setting.alpha + + DimManager.sharedInstance.setting.objectWillChange + .receive(on: RunLoop.main) + .sink {[weak self] _ in + self?.slider.doubleValue = DimManager.sharedInstance.setting.alpha + self?.slider.isEnabled = DimManager.sharedInstance.setting.isEnabled + } + .store(in: &subscriptions) + + slider.target = self + slider.action = #selector(sliderChanged) + } + + @objc private func sliderChanged() { + DimManager.sharedInstance.setting.alpha = slider.doubleValue + DimManager.sharedInstance.dim(runningApplication: DimManager.sharedInstance.getFrontMostApplication()) + } + + private func getContextMenu() -> NSMenu { + let menu = NSMenu() + let sliderMenuItem = NSMenuItem() + let titleEnable = DimManager.sharedInstance.setting.isEnabled ? "Disable" : "Enable" + + let enableButton = NSMenuItem(title: titleEnable, action: #selector(toggleEnable), keyEquivalent: "E") + enableButton.target = self + DimManager.sharedInstance.setting.objectWillChange + .receive(on: RunLoop.main) + .sink {[weak enableButton] _ in + let title = DimManager.sharedInstance.setting.isEnabled ? "Disable" : "Enable" + enableButton?.title = title + } + .store(in: &subscriptions) + + let view = NSView() + view.setFrameSize(NSSize(width: 100, height: 22)) + view.autoresizingMask = .width + view.addSubview(slider) + slider.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + NSLayoutConstraint(item: slider, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 16), + NSLayoutConstraint(item: slider, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: -16), + NSLayoutConstraint(item: slider, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0), + NSLayoutConstraint(item: slider, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0), + ]) + + sliderMenuItem.view = view + menu.addItem(withTitle: "Slide to set Dim level", action: nil, keyEquivalent: "") + menu.addItem(sliderMenuItem) + menu.addItem(NSMenuItem.separator()) + menu.addItem(enableButton) + menu.addItem(NSMenuItem.separator()) + menu.addItem(NSMenuItem(title: "Preferences...", action: #selector(openPreferences), keyEquivalent: "P")) + menu.addItem(NSMenuItem.separator()) + menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")) + menu.item(withTitle: "Preferences...")?.target = self + return menu + } + + @objc private func toggleEnable() { + DimManager.sharedInstance.setting.isEnabled.toggle() + DimManager.sharedInstance.dim(runningApplication: DimManager.sharedInstance.getFrontMostApplication()) + } + + @objc func openPreferences() { + window.makeKeyAndOrderFront(nil) + } +} diff --git a/BlurredLauncher/AppDelegate.swift b/BlurredLauncher/AppDelegate.swift new file mode 100644 index 0000000..5a3d3a7 --- /dev/null +++ b/BlurredLauncher/AppDelegate.swift @@ -0,0 +1,43 @@ +// +// AppDelegate.swift +// dimmerBarLauncher +// +// Created by phucld on 1/7/20. +// Copyright © 2020 Dwarves Foundation. All rights reserved. +// + +import Cocoa + + +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate { + + @objc func terminate() { + NSApp.terminate(nil) + } + + func applicationDidFinishLaunching(_ aNotification: Notification) { + let mainAppIdentifier = "foundation.dwarves.blurred" + let runningApps = NSWorkspace.shared.runningApplications + let isRunning = !runningApps.filter { $0.bundleIdentifier == mainAppIdentifier }.isEmpty + + if !isRunning { + DistributedNotificationCenter.default().addObserver(self, + selector: #selector(self.terminate), + name: Notification.Name("killLauncher"), + object: mainAppIdentifier) + + let path = Bundle.main.bundlePath as NSString + var components = path.pathComponents + components.removeLast(3) + components.append("MacOS") + let appName = "Blurred" + components.append(appName) //main app name + let newPath = NSString.path(withComponents: components) + NSWorkspace.shared.launchApplication(newPath) + } + else { + self.terminate() + } + } +} diff --git a/BlurredLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json b/BlurredLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2db2b1c --- /dev/null +++ b/BlurredLauncher/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/BlurredLauncher/Assets.xcassets/Contents.json b/BlurredLauncher/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/BlurredLauncher/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/BlurredLauncher/Base.lproj/Main.storyboard b/BlurredLauncher/Base.lproj/Main.storyboard new file mode 100644 index 0000000..277d766 --- /dev/null +++ b/BlurredLauncher/Base.lproj/Main.storyboard @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BlurredLauncher/BlurredLauncher.entitlements b/BlurredLauncher/BlurredLauncher.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/BlurredLauncher/BlurredLauncher.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/BlurredLauncher/Info.plist b/BlurredLauncher/Info.plist new file mode 100644 index 0000000..7595588 --- /dev/null +++ b/BlurredLauncher/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2020 Dwarves Foundation. All rights reserved. + NSMainStoryboardFile + Main + NSPrincipalClass + NSApplication + NSSupportsAutomaticTermination + + NSSupportsSuddenTermination + + LSBackgroundOnly + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a45764 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +### Dimmer Bar + +This App Inspired from: +https://github.com/tannerc/spf + +We are add focus mode by undimmed current active Windows + +A macOS utility that helps reduce distraction by dimming your inactive noise + +