From 6813c331d46e14aac8c8c01704df3af46614350c Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 02:04:13 +0900 Subject: [PATCH 01/18] Modfy codes in order to corresponding to Swift 4.2 in Xcode 10.1. --- Podfile.lock | 29 +++-- QBlocker.xcodeproj/project.pbxproj | 122 +++++++++++++----- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ QBlocker/AccessibilityViewController.swift | 6 +- QBlocker/AccessibilityWindowController.swift | 2 +- QBlocker/App.swift | 6 +- QBlocker/AppDelegate.swift | 24 ++-- QBlocker/AtLogin.swift | 8 +- QBlocker/Base.lproj/Main.storyboard | 39 ++++-- QBlocker/Delay.swift | 26 ++-- ...ewController + NSTableViewDataSource.swift | 2 +- ...ViewController + NSTableViewDelegate.swift | 6 +- QBlocker/ExcludeViewController.swift | 20 +-- QBlocker/ExcludeWindowController.swift | 4 +- QBlocker/FirstRunViewController.swift | 4 +- QBlocker/HUDAlert.swift | 24 ++-- QBlocker/HUDView.swift | 6 +- QBlocker/KeyListener.swift | 89 ++++++------- QBlocker/KeyListenerError.swift | 4 +- QBlocker/ListMode.swift | 4 +- QBlocker/QBlocker.entitlements | 5 + QBlocker/StatusMenuController.swift | 18 +-- QBlocker/TabBarController.swift | 4 +- 24 files changed, 285 insertions(+), 183 deletions(-) mode change 100755 => 100644 QBlocker.xcodeproj/project.pbxproj create mode 100644 QBlocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 QBlocker.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 QBlocker/QBlocker.entitlements diff --git a/Podfile.lock b/Podfile.lock index 4b34dd2..381bad8 100755 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,10 +1,10 @@ PODS: - - DevMateKit (1.7.1) - - Realm (0.101.0): - - Realm/Headers (= 0.101.0) - - Realm/Headers (0.101.0) - - RealmSwift (0.101.0): - - Realm (= 0.101.0) + - DevMateKit (1.9.2) + - Realm (3.12.0): + - Realm/Headers (= 3.12.0) + - Realm/Headers (3.12.0) + - RealmSwift (3.12.0): + - Realm (= 3.12.0) - SRTabBarController (0.1.0) DEPENDENCIES: @@ -12,10 +12,19 @@ DEPENDENCIES: - RealmSwift - SRTabBarController +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - DevMateKit + - Realm + - RealmSwift + - SRTabBarController + SPEC CHECKSUMS: - DevMateKit: 3ba77083f5faa40266e0d2d70776de2a82c71dd0 - Realm: b21596d6d7e1c054f6fae967d27263d2593ca309 - RealmSwift: 5247501bcd68b9db3a718cba808e1ce45ba67034 + DevMateKit: 7900fa17efc254d318d5637559d96f7769dd0a2e + Realm: cdaef23c4ddb36ab1ddffed23f5a7f3332fc5585 + RealmSwift: 5576324033f0aa5ef1e0a839a3da2281dff47a7f SRTabBarController: aeb73a975a47aff9e14f3546da2394fce8271b09 -COCOAPODS: 0.39.0 +PODFILE CHECKSUM: e90d90b5d784e26dd1db066a4e0cafe16e142f9f + +COCOAPODS: 1.5.3 diff --git a/QBlocker.xcodeproj/project.pbxproj b/QBlocker.xcodeproj/project.pbxproj old mode 100755 new mode 100644 index edbba97..23bfec1 --- a/QBlocker.xcodeproj/project.pbxproj +++ b/QBlocker.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 07F0E51805F533AB1219CC1A /* Pods_QBlocker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AE2D0BFC44767B8D2FE86C2 /* Pods_QBlocker.framework */; }; 13FA35AC1CF623C400A29767 /* ListMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FA35AB1CF623C400A29767 /* ListMode.swift */; }; 280140151CDA9D5200BC2E78 /* AtLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280140141CDA9D5200BC2E78 /* AtLogin.swift */; }; 2832CA361CD688E9001D3373 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2832CA351CD688E9001D3373 /* AppDelegate.swift */; }; @@ -29,12 +30,10 @@ 28DEC8041CD950450012B5E3 /* HUDAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8031CD950450012B5E3 /* HUDAlert.swift */; }; 28DEC8061CD954EA0012B5E3 /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8051CD954EA0012B5E3 /* HUDView.swift */; }; 28F40A711CFB61EB006719C8 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F40A701CFB61EB006719C8 /* TabBarController.swift */; }; - 89B8C5D3D02D89463E1239E8 /* Pods_QBlocker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1CE05FBCE54008C441D3CA3 /* Pods_QBlocker.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 13FA35AB1CF623C400A29767 /* ListMode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListMode.swift; sourceTree = ""; }; - 18D302062F0781EB95263F14 /* Pods-QBlocker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.release.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.release.xcconfig"; sourceTree = ""; }; 280140141CDA9D5200BC2E78 /* AtLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtLogin.swift; sourceTree = ""; }; 2832CA321CD688E9001D3373 /* QBlocker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QBlocker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2832CA351CD688E9001D3373 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -59,8 +58,10 @@ 28DEC8031CD950450012B5E3 /* HUDAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HUDAlert.swift; sourceTree = ""; }; 28DEC8051CD954EA0012B5E3 /* HUDView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HUDView.swift; sourceTree = ""; }; 28F40A701CFB61EB006719C8 /* TabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; - C1CE05FBCE54008C441D3CA3 /* Pods_QBlocker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QBlocker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - EAE265B701E85E6B909B8E2C /* Pods-QBlocker.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.debug.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.debug.xcconfig"; sourceTree = ""; }; + 55B461F5EE3BE302188BAC0C /* Pods-QBlocker.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.debug.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.debug.xcconfig"; sourceTree = ""; }; + 9AE2D0BFC44767B8D2FE86C2 /* Pods_QBlocker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QBlocker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A3F762D47D17E2933604A226 /* Pods-QBlocker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.release.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.release.xcconfig"; sourceTree = ""; }; + B12B3DD321AEF3AC00BAE6B6 /* QBlocker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = QBlocker.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -68,7 +69,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 89B8C5D3D02D89463E1239E8 /* Pods_QBlocker.framework in Frameworks */, + 07F0E51805F533AB1219CC1A /* Pods_QBlocker.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -99,8 +100,8 @@ children = ( 2832CA341CD688E9001D3373 /* QBlocker */, 2832CA331CD688E9001D3373 /* Products */, - 38D42208756B276FCDCB321A /* Pods */, - C44CD8B7A74F8347ECBD8138 /* Frameworks */, + 67690C1FE916FDD1AE76C543 /* Pods */, + C81D9C17284A4C49E807ED9E /* Frameworks */, ); sourceTree = ""; }; @@ -115,6 +116,7 @@ 2832CA341CD688E9001D3373 /* QBlocker */ = { isa = PBXGroup; children = ( + B12B3DD321AEF3AC00BAE6B6 /* QBlocker.entitlements */, 28A518591CDE415100BE7ED1 /* Preferences */, 280140161CDA9D9000BC2E78 /* Utility */, 280140131CDA9B4600BC2E78 /* First Launch */, @@ -164,19 +166,19 @@ name = Preferences; sourceTree = ""; }; - 38D42208756B276FCDCB321A /* Pods */ = { + 67690C1FE916FDD1AE76C543 /* Pods */ = { isa = PBXGroup; children = ( - EAE265B701E85E6B909B8E2C /* Pods-QBlocker.debug.xcconfig */, - 18D302062F0781EB95263F14 /* Pods-QBlocker.release.xcconfig */, + 55B461F5EE3BE302188BAC0C /* Pods-QBlocker.debug.xcconfig */, + A3F762D47D17E2933604A226 /* Pods-QBlocker.release.xcconfig */, ); name = Pods; sourceTree = ""; }; - C44CD8B7A74F8347ECBD8138 /* Frameworks */ = { + C81D9C17284A4C49E807ED9E /* Frameworks */ = { isa = PBXGroup; children = ( - C1CE05FBCE54008C441D3CA3 /* Pods_QBlocker.framework */, + 9AE2D0BFC44767B8D2FE86C2 /* Pods_QBlocker.framework */, ); name = Frameworks; sourceTree = ""; @@ -188,12 +190,12 @@ isa = PBXNativeTarget; buildConfigurationList = 2832CA411CD688E9001D3373 /* Build configuration list for PBXNativeTarget "QBlocker" */; buildPhases = ( - E382C6621D20D82AD3EE2371 /* Check Pods Manifest.lock */, + 845AE1320B9F2B12371D62FC /* [CP] Check Pods Manifest.lock */, 2832CA2E1CD688E9001D3373 /* Sources */, 2832CA2F1CD688E9001D3373 /* Frameworks */, 2832CA301CD688E9001D3373 /* Resources */, - A5F3978DEF0056344662D1D8 /* Embed Pods Frameworks */, - D83C7FD3BC174A7B11207BD0 /* Copy Pods Resources */, + A029F5A304AA443AB8C88A1B /* [CP] Embed Pods Frameworks */, + 9F8D02250EDD9278A6FB76B5 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -211,13 +213,17 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0730; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = "Cocoon Development Ltd"; TargetAttributes = { 2832CA311CD688E9001D3373 = { CreatedOnToolsVersion = 7.3; - DevelopmentTeam = B598AEF9ZM; + DevelopmentTeam = 89282N6UM7; + ProvisioningStyle = Automatic; SystemCapabilities = { + com.apple.HardenedRuntime = { + enabled = 0; + }; com.apple.Sandbox = { enabled = 0; }; @@ -257,49 +263,76 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - A5F3978DEF0056344662D1D8 /* Embed Pods Frameworks */ = { + 845AE1320B9F2B12371D62FC /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "Embed Pods Frameworks"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-QBlocker-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - D83C7FD3BC174A7B11207BD0 /* Copy Pods Resources */ = { + 9F8D02250EDD9278A6FB76B5 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker-resources.sh", + "${PODS_ROOT}/DevMateKit/DevMateKit.framework", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( ); - name = "Copy Pods Resources"; outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/DevMateKit.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker-resources.sh\"\n"; showEnvVarsInLog = 0; }; - E382C6621D20D82AD3EE2371 /* Check Pods Manifest.lock */ = { + A029F5A304AA443AB8C88A1B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker-frameworks.sh", + "${PODS_ROOT}/DevMateKit/DevMateKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/SRTabBarController/SRTabBarController.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( ); - name = "Check Pods Manifest.lock"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DevMateKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SRTabBarController.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -354,13 +387,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -387,6 +430,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -399,13 +443,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = 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_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_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -424,37 +478,47 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 4.2; }; name = Release; }; 2832CA421CD688E9001D3373 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAE265B701E85E6B909B8E2C /* Pods-QBlocker.debug.xcconfig */; + baseConfigurationReference = 55B461F5EE3BE302188BAC0C /* Pods-QBlocker.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 89282N6UM7; INFOPLIST_FILE = QBlocker/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_BUNDLE_IDENTIFIER = uk.co.wearecocoon.QBlocker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/QBlocker/Bridge.h"; }; name = Debug; }; 2832CA431CD688E9001D3373 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 18D302062F0781EB95263F14 /* Pods-QBlocker.release.xcconfig */; + baseConfigurationReference = A3F762D47D17E2933604A226 /* Pods-QBlocker.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Developer ID Application"; + CODE_SIGN_IDENTITY = "Mac Developer"; + CODE_SIGN_INJECT_BASE_ENTITLEMENTS = YES; + CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 89282N6UM7; INFOPLIST_FILE = QBlocker/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; PRODUCT_BUNDLE_IDENTIFIER = uk.co.wearecocoon.QBlocker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/QBlocker/Bridge.h"; }; name = Release; diff --git a/QBlocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/QBlocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/QBlocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/QBlocker.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/QBlocker.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/QBlocker.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/QBlocker/AccessibilityViewController.swift b/QBlocker/AccessibilityViewController.swift index cdd2d36..23bfe1f 100644 --- a/QBlocker/AccessibilityViewController.swift +++ b/QBlocker/AccessibilityViewController.swift @@ -10,14 +10,14 @@ import Cocoa class AccessibilityViewController: NSViewController { - @IBAction func openPreferences(sender: AnyObject) { + @IBAction func openPreferences(_ sender: AnyObject) { - guard let scriptPath = NSBundle.mainBundle().pathForResource("OpenPreferences", ofType: "scpt") else { + guard let scriptPath = Bundle.main.path(forResource: "OpenPreferences", ofType: "scpt") else { print("Could not find applescript") return } - let task = NSTask() + let task = Process() task.launchPath = "/usr/bin/osascript" task.arguments = [scriptPath] task.launch() diff --git a/QBlocker/AccessibilityWindowController.swift b/QBlocker/AccessibilityWindowController.swift index 64a50f7..15821d2 100644 --- a/QBlocker/AccessibilityWindowController.swift +++ b/QBlocker/AccessibilityWindowController.swift @@ -13,7 +13,7 @@ class AccessibilityWindowController: NSWindowController { override func windowDidLoad() { super.windowDidLoad() - window?.level = Int(CGWindowLevelForKey(CGWindowLevelKey.PopUpMenuWindowLevelKey)) + window?.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.popUpMenuWindow))) window?.titlebarAppearsTransparent = true window?.backgroundColor = NSColor(calibratedHue:0.00, saturation:0.00, brightness:0.90, alpha:1.00) } diff --git a/QBlocker/App.swift b/QBlocker/App.swift index bbc05f5..1ca9d67 100644 --- a/QBlocker/App.swift +++ b/QBlocker/App.swift @@ -11,13 +11,13 @@ import RealmSwift class App: Object { /// The name of the app that will be displayed as a label - dynamic var name = "" + @objc dynamic var name = "" /// The bundle ID of the app. e.g. uk.co.wearecocoon.QBlocker - dynamic var bundleID = "" + @objc dynamic var bundleID = "" override static func primaryKey() -> String? { return "bundleID" } -} \ No newline at end of file +} diff --git a/QBlocker/AppDelegate.swift b/QBlocker/AppDelegate.swift index 933ccd8..347b6ec 100644 --- a/QBlocker/AppDelegate.swift +++ b/QBlocker/AppDelegate.swift @@ -14,18 +14,18 @@ class AppDelegate: NSObject, NSApplicationDelegate { private var accessibilityWindowController: NSWindowController? private var firstRunWindowController: NSWindowController? private lazy var preferencesWindowController: NSWindowController = { - return NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("preferences window") as! NSWindowController + return NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "preferences window") as! NSWindowController }() class var sharedDelegate: AppDelegate? { - return NSApplication.sharedApplication().delegate as? AppDelegate + return NSApplication.shared.delegate as? AppDelegate } // MARK: - Instantiation override init() { super.init() - NSUserDefaults.standardUserDefaults().registerDefaults([ + UserDefaults.standard.register(defaults: [ "accidentalQuits": 0, "firstRunComplete": false, "listMode": 0, @@ -35,12 +35,12 @@ class AppDelegate: NSObject, NSApplicationDelegate { // MARK: - NSApplicationDelegate - func applicationDidFinishLaunching(aNotification: NSNotification) { + func applicationDidFinishLaunching(_ notification: Notification) { setupDevMate() let promptFlag = kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString - let myDict: CFDictionary = [promptFlag: false] + let myDict: CFDictionary = [promptFlag: false] as CFDictionary if AXIsProcessTrustedWithOptions(myDict) { do { try KeyListener.sharedKeyListener.start() @@ -51,7 +51,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { showFirstRunWindowIfRequired() } else { - if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("accessibility window") as? NSWindowController { + if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "accessibility window") as? NSWindowController { accessibilityWindowController = windowController accessibilityWindowController?.showWindow(self) accessibilityWindowController?.window?.makeKeyAndOrderFront(self) @@ -66,16 +66,16 @@ class AppDelegate: NSObject, NSApplicationDelegate { Show the first run screen if the NSUserDefault stating it has already be run isn't set */ func showFirstRunWindowIfRequired() { - guard !NSUserDefaults.standardUserDefaults().boolForKey("firstRunComplete") else { + guard !UserDefaults.standard.bool(forKey: "firstRunComplete") else { return } - if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("first run window") as? NSWindowController { + if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "first run window") as? NSWindowController { firstRunWindowController = windowController firstRunWindowController?.showWindow(self) firstRunWindowController?.window?.makeKeyAndOrderFront(self) - NSUserDefaults.standardUserDefaults().setBool(true, forKey: "firstRunComplete") + UserDefaults.standard.set(true, forKey: "firstRunComplete") } } @@ -83,7 +83,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { Bring the app into foreground and show the preferences window */ func showPreferencesWindow() { - NSApplication.sharedApplication().activateIgnoringOtherApps(true) + NSApplication.shared.activate(ignoringOtherApps: true) self.preferencesWindowController.showWindow(nil) } @@ -93,8 +93,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { func setupDevMate() { DevMateKit.sendTrackingReport(nil, delegate: nil) DevMateKit.setupIssuesController(nil, reportingUnhandledIssues: true) - DM_SUUpdater.sharedUpdater().automaticallyChecksForUpdates = true - DM_SUUpdater.sharedUpdater().automaticallyDownloadsUpdates = true + DM_SUUpdater.shared().automaticallyChecksForUpdates = true + DM_SUUpdater.shared().automaticallyDownloadsUpdates = true } } diff --git a/QBlocker/AtLogin.swift b/QBlocker/AtLogin.swift index 22394ca..64892bc 100644 --- a/QBlocker/AtLogin.swift +++ b/QBlocker/AtLogin.swift @@ -26,7 +26,7 @@ struct AtLogin { /// The launch item that's stored in LSSharedFileList private static var launchItem: LSSharedFileListItem? { - let appUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().bundlePath) + let appUrl = NSURL(fileURLWithPath: Bundle.main.bundlePath) guard let loginItemsRef = LSSharedFileListCreate(nil, kLSSharedFileListSessionLoginItems.takeRetainedValue(), nil) else { return nil @@ -36,7 +36,7 @@ struct AtLogin { for item in loginItems as NSArray { // Ensure that the item is a LSSharedFileListItem - guard CFGetTypeID(item) == LSSharedFileListItemGetTypeID() else { + guard CFGetTypeID(item as CFTypeRef) == LSSharedFileListItemGetTypeID() else { continue } @@ -64,10 +64,10 @@ struct AtLogin { if enabled { // remove it from the startup LSSharedFileListItemRemove(loginItems.takeRetainedValue(), launchItem) } else { // add it to the startup - let appUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().bundlePath) + let appUrl = NSURL(fileURLWithPath: Bundle.main.bundlePath) LSSharedFileListInsertItemURL(loginItems.takeRetainedValue(), kLSSharedFileListItemBeforeFirst.takeUnretainedValue(), nil, nil, appUrl as CFURL, nil, nil) } } -} \ No newline at end of file +} diff --git a/QBlocker/Base.lproj/Main.storyboard b/QBlocker/Base.lproj/Main.storyboard index 6793a6a..a75fb17 100644 --- a/QBlocker/Base.lproj/Main.storyboard +++ b/QBlocker/Base.lproj/Main.storyboard @@ -1,7 +1,9 @@ - - + + - + + + @@ -153,7 +155,7 @@ - + @@ -161,6 +163,9 @@ + + + @@ -246,11 +251,14 @@ - - + + + + + @@ -306,14 +314,14 @@ - + - + @@ -325,7 +333,7 @@ - + @@ -370,7 +378,7 @@ - + @@ -395,6 +403,7 @@ + @@ -415,7 +424,6 @@ - @@ -459,7 +467,7 @@ - + @@ -467,7 +475,7 @@ - + @@ -510,7 +518,7 @@ - + @@ -518,6 +526,9 @@ + + + diff --git a/QBlocker/Delay.swift b/QBlocker/Delay.swift index 806a851..d573c10 100644 --- a/QBlocker/Delay.swift +++ b/QBlocker/Delay.swift @@ -7,26 +7,22 @@ import Foundation -typealias dispatch_cancelable_closure = (cancel : Bool) -> Void +typealias dispatch_cancelable_closure = (_ cancel : Bool) -> Void +typealias DispatchBlock = () -> Void -func delay(time:NSTimeInterval, closure:()->Void) -> dispatch_cancelable_closure? { +func delay(time:TimeInterval, closure:@escaping ()->Void) -> dispatch_cancelable_closure? { - func dispatch_later(clsr:()->Void) { - dispatch_after( - dispatch_time( - DISPATCH_TIME_NOW, - Int64(time * Double(NSEC_PER_SEC)) - ), - dispatch_get_main_queue(), clsr) + func dispatch_later(clsr:@escaping ()->Void) { + DispatchQueue.main.asyncAfter(deadline: .now() + time * Double(NSEC_PER_SEC), execute: clsr) } - - var closure:dispatch_block_t? = closure + + var closure:DispatchBlock? = closure var cancelableClosure:dispatch_cancelable_closure? let delayedClosure:dispatch_cancelable_closure = { cancel in if closure != nil { if (cancel == false) { - dispatch_async(dispatch_get_main_queue(), closure!); + DispatchQueue.main.async(execute: closure!) } } closure = nil @@ -37,7 +33,7 @@ func delay(time:NSTimeInterval, closure:()->Void) -> dispatch_cancelable_closur dispatch_later { if let delayedClosure = cancelableClosure { - delayedClosure(cancel: false) + delayedClosure(false) } } @@ -47,6 +43,6 @@ func delay(time:NSTimeInterval, closure:()->Void) -> dispatch_cancelable_closur func cancel_delay(closure:dispatch_cancelable_closure?) { if closure != nil { - closure!(cancel: true) + closure!(true) } -} \ No newline at end of file +} diff --git a/QBlocker/ExcludeViewController + NSTableViewDataSource.swift b/QBlocker/ExcludeViewController + NSTableViewDataSource.swift index b112812..219a579 100644 --- a/QBlocker/ExcludeViewController + NSTableViewDataSource.swift +++ b/QBlocker/ExcludeViewController + NSTableViewDataSource.swift @@ -10,7 +10,7 @@ import Cocoa extension ExcludeViewController: NSTableViewDataSource { - func numberOfRowsInTableView(tableView: NSTableView) -> Int { + func numberOfRows(in tableView: NSTableView) -> Int { return KeyListener.sharedKeyListener.list?.count ?? 0 } diff --git a/QBlocker/ExcludeViewController + NSTableViewDelegate.swift b/QBlocker/ExcludeViewController + NSTableViewDelegate.swift index d3be561..710d5d0 100644 --- a/QBlocker/ExcludeViewController + NSTableViewDelegate.swift +++ b/QBlocker/ExcludeViewController + NSTableViewDelegate.swift @@ -10,9 +10,9 @@ import Cocoa extension ExcludeViewController: NSTableViewDelegate { - func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - guard let cell = tableView.makeViewWithIdentifier("app name cell", owner: nil) as? NSTableCellView, + guard let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "app name cell"), owner: nil) as? NSTableCellView, let app = KeyListener.sharedKeyListener.list?[row] else { return nil } @@ -21,4 +21,4 @@ extension ExcludeViewController: NSTableViewDelegate { return cell } -} \ No newline at end of file +} diff --git a/QBlocker/ExcludeViewController.swift b/QBlocker/ExcludeViewController.swift index 52025ec..13120b6 100644 --- a/QBlocker/ExcludeViewController.swift +++ b/QBlocker/ExcludeViewController.swift @@ -15,7 +15,7 @@ class ExcludeViewController: NSViewController { // MARK: - Actions - @IBAction func addClicked(sender: AnyObject) { + @IBAction func addClicked(_ sender: AnyObject) { let panel = NSOpenPanel() panel.title = "Choose a .app" panel.canChooseDirectories = false @@ -23,26 +23,26 @@ class ExcludeViewController: NSViewController { panel.canCreateDirectories = false panel.allowsMultipleSelection = true panel.allowedFileTypes = ["app"] - panel.beginSheetModalForWindow(view.window!) { response in - if (response == NSFileHandlingPanelOKButton) { - for url in panel.URLs { - guard let bundle = NSBundle(URL: url)?.bundleIdentifier, path = url.path else { + panel.beginSheetModal(for: view.window!) { response in + if (response.rawValue == NSFileHandlingPanelOKButton) { + for url in panel.urls { + guard let bundle = Bundle(url: url)?.bundleIdentifier else { continue } - let name = NSFileManager.defaultManager().displayNameAtPath(path) + let name = FileManager.default.displayName(atPath: url.path) let app = App() app.name = name app.bundleID = bundle - KeyListener.sharedKeyListener.addExcludedApp(app) + KeyListener.sharedKeyListener.addExcludedApp(app: app) } self.tableView.reloadData() } } } - @IBAction func removeClicked(sender: AnyObject) { + @IBAction func removeClicked(_ sender: AnyObject) { guard tableView.selectedRowIndexes.count > 0, let apps = KeyListener.sharedKeyListener.list else { print("Nothing selected") @@ -50,12 +50,12 @@ class ExcludeViewController: NSViewController { } var toRemove = [App]() - tableView.selectedRowIndexes.enumerateIndexesUsingBlock { index, stop in + tableView.selectedRowIndexes.forEach { index in toRemove.append(apps[index]) } for app in toRemove { - KeyListener.sharedKeyListener.removeExcludedApp(app) + KeyListener.sharedKeyListener.removeExcludedApp(app: app) } tableView.reloadData() diff --git a/QBlocker/ExcludeWindowController.swift b/QBlocker/ExcludeWindowController.swift index 8e6ff04..3b322a8 100644 --- a/QBlocker/ExcludeWindowController.swift +++ b/QBlocker/ExcludeWindowController.swift @@ -14,8 +14,8 @@ class ExcludeWindowController: NSWindowController { super.windowDidLoad() window?.titlebarAppearsTransparent = true - window?.titleVisibility = .Hidden - window?.movableByWindowBackground = true + window?.titleVisibility = .hidden + window?.isMovableByWindowBackground = true } } diff --git a/QBlocker/FirstRunViewController.swift b/QBlocker/FirstRunViewController.swift index 003e12f..3352236 100644 --- a/QBlocker/FirstRunViewController.swift +++ b/QBlocker/FirstRunViewController.swift @@ -10,11 +10,11 @@ import Cocoa class FirstRunViewController: NSViewController { - @IBAction func dismissWindow(sender: AnyObject) { + @IBAction func dismissWindow(_ sender: AnyObject) { view.window?.orderOut(self) } - @IBAction func showExcludeApps(sender: AnyObject) { + @IBAction func showExcludeApps(_ sender: AnyObject) { AppDelegate.sharedDelegate?.showPreferencesWindow() view.window?.orderOut(self) } diff --git a/QBlocker/HUDAlert.swift b/QBlocker/HUDAlert.swift index 5c121a5..6e3e64e 100644 --- a/QBlocker/HUDAlert.swift +++ b/QBlocker/HUDAlert.swift @@ -20,36 +20,36 @@ class HUDAlert { var delayer: dispatch_cancelable_closure? init() { - window = NSWindow(contentRect: NSMakeRect(0, 0, 426, 79), styleMask: NSBorderlessWindowMask, backing: .Buffered, defer: false) - window?.level = Int(CGWindowLevelForKey(CGWindowLevelKey.AssistiveTechHighWindowLevelKey)) - window?.opaque = false - window?.backgroundColor = NSColor.clearColor() + window = NSWindow(contentRect: NSMakeRect(0, 0, 426, 79), styleMask: .borderless, backing: .buffered, defer: false) + window?.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.assistiveTechHighWindow))) + window?.isOpaque = false + window?.backgroundColor = NSColor.clear - let vc = NSStoryboard(name: "Main", bundle: nil).instantiateControllerWithIdentifier("Alert") - window?.contentView? = vc.view + let vc = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "Alert") + window?.contentView? = (vc as AnyObject).view window?.contentView?.wantsLayer = true - window?.makeKeyWindow() + window?.makeKey() } /** Show the HUD window */ - func showHUD(delayTime: NSTimeInterval? = nil) { + func showHUD(delayTime: TimeInterval? = nil) { - guard let screenRect = NSScreen.mainScreen()?.visibleFrame else { + guard let screenRect = NSScreen.main?.visibleFrame else { print("Could not get screen frame") return } - cancel_delay(delayer) + cancel_delay(closure: delayer) let newRect = NSMakeRect((screenRect.size.width - 426) * 0.5, (screenRect.size.height - 79) * 0.5, 426, 79) window?.setFrame(newRect, display: true) window?.makeKeyAndOrderFront(self) if let delayTime = delayTime { - delayer = delay(delayTime) { + delayer = delay(time: delayTime) { self.dismissHUD() } } @@ -75,4 +75,4 @@ class HUDAlert { } -} \ No newline at end of file +} diff --git a/QBlocker/HUDView.swift b/QBlocker/HUDView.swift index be612a9..8aa4481 100644 --- a/QBlocker/HUDView.swift +++ b/QBlocker/HUDView.swift @@ -10,11 +10,11 @@ import Cocoa class HUDView: NSView { - override func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) wantsLayer = true - layer?.backgroundColor = NSColor(deviceHue: 0, saturation: 0, brightness: 0, alpha: 0.5).CGColor + layer?.backgroundColor = NSColor(deviceHue: 0, saturation: 0, brightness: 0, alpha: 0.5).cgColor layer?.cornerRadius = 12 } diff --git a/QBlocker/KeyListener.swift b/QBlocker/KeyListener.swift index 92eff10..f711d63 100644 --- a/QBlocker/KeyListener.swift +++ b/QBlocker/KeyListener.swift @@ -8,23 +8,23 @@ import RealmSwift -private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, ptr: UnsafeMutablePointer) -> Unmanaged? { +private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, ptr: UnsafeMutableRawPointer?) -> Unmanaged? { // If the command key wasn't used we can pass the event on - let flags = CGEventGetFlags(event) - guard (flags.rawValue & CGEventFlags.MaskCommand.rawValue) != 0 else { + let flags = event.flags + guard (flags.rawValue & CGEventFlags.maskCommand.rawValue) != 0 else { print("command not clicked") return Unmanaged.passUnretained(event) } // If the shift key was held down we should ignore the event as it breaks the systemwide logout shortcut - guard (flags.rawValue & CGEventFlags.MaskShift.rawValue) == 0 else { + guard (flags.rawValue & CGEventFlags.maskShift.rawValue) == 0 else { print("shift clicked") return Unmanaged.passUnretained(event) } // If the q key wasn't clicked we can ignore the event too - guard KeyListener.keyValueForEvent(event)?.lowercaseString == "q" else { + guard KeyListener.keyValueForEvent(event: event)?.lowercased() == "q" else { print("q not clicked") return Unmanaged.passUnretained(event) } @@ -35,7 +35,7 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C } // get the current active app - guard let app = NSWorkspace.sharedWorkspace().menuBarOwningApplication else { + guard let app = NSWorkspace.shared.menuBarOwningApplication else { print("could not get menubar owning app") return Unmanaged.passUnretained(event) } @@ -51,14 +51,14 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C } // check that the app has CMD Q enabled - guard KeyListener.cmdQActiveForApp(app) else { + guard KeyListener.cmdQActiveForApp(app: app) else { print("\(app.bundleIdentifier) does not use cmd+q") return nil } if KeyListener.sharedKeyListener.canQuit && KeyListener.sharedKeyListener.tries <= KeyListener.delay { print("showing HUD") - HUDAlert.sharedHUDAlert.showHUD(1) + HUDAlert.sharedHUDAlert.showHUD(delayTime: 1) } KeyListener.sharedKeyListener.tries += 1 @@ -66,29 +66,29 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C print("quit successful") KeyListener.sharedKeyListener.tries = 0 KeyListener.sharedKeyListener.canQuit = false - HUDAlert.sharedHUDAlert.dismissHUD(false) + HUDAlert.sharedHUDAlert.dismissHUD(fade: false) return Unmanaged.passUnretained(event) } return nil } -private func keyUpCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, ptr: UnsafeMutablePointer) -> Unmanaged? { +private func keyUpCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, ptr: UnsafeMutableRawPointer?) -> Unmanaged? { // If the command key wasn't used we can pass the event on - let flags = CGEventGetFlags(event) - guard (flags.rawValue & CGEventFlags.MaskCommand.rawValue) != 0 else { + let flags = event.flags + guard (flags.rawValue & CGEventFlags.maskCommand.rawValue) != 0 else { return Unmanaged.passUnretained(event) } // If the shift key was held down we should ignore the event as it breaks the systemwide logout shortcut - guard (flags.rawValue & CGEventFlags.MaskShift.rawValue) == 0 else { + guard (flags.rawValue & CGEventFlags.maskShift.rawValue) == 0 else { print("shift clicked") return Unmanaged.passUnretained(event) } // If the q key wasn't clicked we can ignore the event too - guard KeyListener.keyValueForEvent(event)?.lowercaseString == "q" else { + guard KeyListener.keyValueForEvent(event: event)?.lowercased() == "q" else { return Unmanaged.passUnretained(event) } @@ -112,7 +112,7 @@ class KeyListener { /// How long the Q key needs to be held before you can quit static var delay: Int { - return NSUserDefaults.standardUserDefaults().integerForKey("delay") ?? 4 + return UserDefaults.standard.integer(forKey: "delay") } /// Reference to our default Realm @@ -140,12 +140,12 @@ class KeyListener { /// The number of accidental quits that have been saved by QBlocker var accidentalQuits: Int { - return NSUserDefaults.standardUserDefaults().integerForKey("accidentalQuits") + return UserDefaults.standard.integer(forKey: "accidentalQuits") } /// Array of apps to be ignored/allowed (depending on the setting) by QBlocker var list: Results? { - return realm?.objects(App).sorted("name") + return realm?.objects(App.self).sorted(byKeyPath: "name") } /// The bundle identifiers of all apps from list @@ -172,29 +172,30 @@ class KeyListener { */ func start() throws { - keyDown = CGEventTapCreate(CGEventTapLocation.CGHIDEventTap, - CGEventTapPlacement.HeadInsertEventTap, - CGEventTapOptions.Default, - CGEventMask((1 << CGEventType.KeyDown.rawValue)), - keyDownCallback, - UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())) + keyDown = CGEvent.tapCreate(tap: .cghidEventTap, + place: .headInsertEventTap, + options: .defaultTap, + eventsOfInterest: CGEventMask((1 << CGEventType.keyDown.rawValue)), + callback: keyDownCallback, + userInfo: + Unmanaged.passUnretained(self).toOpaque()) - keyUp = CGEventTapCreate(CGEventTapLocation.CGHIDEventTap, - CGEventTapPlacement.HeadInsertEventTap, - CGEventTapOptions.Default, - CGEventMask((1 << CGEventType.KeyUp.rawValue)), - keyUpCallback, - UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())) + keyUp = CGEvent.tapCreate(tap: .cghidEventTap, + place: .headInsertEventTap, + options: .defaultTap, + eventsOfInterest: CGEventMask((1 << CGEventType.keyUp.rawValue)), + callback: keyUpCallback, + userInfo: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())) guard keyDown != nil else { throw KeyListenerError.AccessibilityPermissionDenied } keyDownRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, keyDown, 0) - CFRunLoopAddSource(CFRunLoopGetCurrent(), keyDownRunLoopSource, kCFRunLoopCommonModes) + CFRunLoopAddSource(CFRunLoopGetCurrent(), keyDownRunLoopSource, CFRunLoopMode.commonModes) keyUpRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, keyUp, 0) - CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSource, kCFRunLoopCommonModes) + CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSource, CFRunLoopMode.commonModes) } @@ -203,7 +204,7 @@ class KeyListener { */ func logAccidentalQuit() { let quits = accidentalQuits + 1 - NSUserDefaults.standardUserDefaults().setInteger(quits, forKey: "accidentalQuits") + UserDefaults.standard.set(quits, forKey: "accidentalQuits") } /** @@ -213,9 +214,9 @@ class KeyListener { */ class func cmdQActiveForApp(app: NSRunningApplication) -> Bool { - let app = AXUIElementCreateApplication(app.processIdentifier).takeRetainedValue() + let app = AXUIElementCreateApplication(app.processIdentifier) var menuBar: AnyObject? - AXUIElementCopyAttributeValue(app, kAXMenuBarAttribute, &menuBar) + AXUIElementCopyAttributeValue(app, kAXMenuBarAttribute as CFString, &menuBar) // If we can't get the menubar then exit guard menuBar != nil else { @@ -225,35 +226,35 @@ class KeyListener { // Get the toplevel menu items let menu = menuBar as! AXUIElement var children: AnyObject? - AXUIElementCopyAttributeValue(menu, kAXChildrenAttribute, &children) + AXUIElementCopyAttributeValue(menu, kAXChildrenAttribute as CFString, &children) - guard let items = children as? NSArray where items.count > 0 else { + guard let items = children as? NSArray, items.count > 0 else { return false } // Get the submenus of the first item var subMenus: AnyObject? let title = items[1] as! AXUIElement // subscript 0 is the apple menu - AXUIElementCopyAttributeValue(title, kAXChildrenAttribute, &subMenus) + AXUIElementCopyAttributeValue(title, kAXChildrenAttribute as CFString, &subMenus) - guard let menus = subMenus as? NSArray where menus.count > 0 else { + guard let menus = subMenus as? NSArray, menus.count > 0 else { return false } // Get the entries of the submenu var entries: AnyObject? let submenu = menus[0] as! AXUIElement - AXUIElementCopyAttributeValue(submenu, kAXChildrenAttribute, &entries) + AXUIElementCopyAttributeValue(submenu, kAXChildrenAttribute as CFString, &entries) - guard let menuItems = entries as? NSArray where menuItems.count > 0 else { + guard let menuItems = entries as? NSArray, menuItems.count > 0 else { return false } // Loop through the menu items and check if CMD + Q is the shortcut for item in menuItems { var cmdChar: AnyObject? - AXUIElementCopyAttributeValue(item as! AXUIElement, kAXMenuItemCmdCharAttribute, &cmdChar) - if let char = cmdChar as? String where char == "Q" { + AXUIElementCopyAttributeValue(item as! AXUIElement, kAXMenuItemCmdCharAttribute as CFString, &cmdChar) + if let char = cmdChar as? String, char == "Q" { return true } } @@ -269,7 +270,7 @@ class KeyListener { - returns: The characters clicked */ class func keyValueForEvent(event: CGEvent) -> String? { - return NSEvent(CGEvent: event)?.charactersIgnoringModifiers + return NSEvent(cgEvent: event)?.charactersIgnoringModifiers } -} \ No newline at end of file +} diff --git a/QBlocker/KeyListenerError.swift b/QBlocker/KeyListenerError.swift index 675ebba..6c154fd 100644 --- a/QBlocker/KeyListenerError.swift +++ b/QBlocker/KeyListenerError.swift @@ -8,8 +8,8 @@ import Foundation -enum KeyListenerError: ErrorType { +enum KeyListenerError: Error { case AccessibilityPermissionDenied -} \ No newline at end of file +} diff --git a/QBlocker/ListMode.swift b/QBlocker/ListMode.swift index ee01f4d..7ba35ed 100644 --- a/QBlocker/ListMode.swift +++ b/QBlocker/ListMode.swift @@ -11,10 +11,10 @@ enum ListMode: Int { case Whitelist = 1 static var selectedMode: ListMode { - return ListMode(rawValue: NSUserDefaults.standardUserDefaults().integerForKey("listMode")) ?? .Whitelist + return ListMode(rawValue: UserDefaults.standard.integer(forKey: "listMode")) ?? .Whitelist } func select() { - NSUserDefaults.standardUserDefaults().setInteger(self.rawValue, forKey: "listMode") + UserDefaults.standard.set(self.rawValue, forKey: "listMode") } } diff --git a/QBlocker/QBlocker.entitlements b/QBlocker/QBlocker.entitlements new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/QBlocker/QBlocker.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/QBlocker/StatusMenuController.swift b/QBlocker/StatusMenuController.swift index 1b222a0..ea99fcf 100644 --- a/QBlocker/StatusMenuController.swift +++ b/QBlocker/StatusMenuController.swift @@ -12,7 +12,7 @@ import CoreServices class StatusMenuController: NSObject, NSMenuDelegate { /// The icon added to the menu bar - let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSVariableStatusItemLength) + let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) /// Reference to the storyboard @IBOutlet weak var statusMenu: NSMenu! @@ -20,14 +20,14 @@ class StatusMenuController: NSObject, NSMenuDelegate { override func awakeFromNib() { statusMenu.delegate = self statusItem.image = NSImage(named: "Menu Bar") - statusItem.image?.template = true + statusItem.image?.isTemplate = true statusItem.menu = statusMenu } // MARK: - Actions - @IBAction func quitItemClicked(sender: AnyObject) { - NSApplication.sharedApplication().terminate(self) + @IBAction func quitItemClicked(_ sender: AnyObject) { + NSApplication.shared.terminate(self) } /** @@ -35,20 +35,20 @@ class StatusMenuController: NSObject, NSMenuDelegate { - parameter sender: The menu item */ - @IBAction func openAtLogin(sender: NSMenuItem) { + @IBAction func openAtLogin(_ sender: NSMenuItem) { AtLogin.toggle() } - @IBAction func showPreferences(sender: AnyObject) { + @IBAction func showPreferences(_ sender: AnyObject) { AppDelegate.sharedDelegate?.showPreferencesWindow() } // MARK: - NSMenuDelegate - func menuWillOpen(menu: NSMenu) { - statusMenu.itemAtIndex(0)?.title = String(format: "%d Quits Blocked", arguments: [KeyListener.sharedKeyListener.accidentalQuits]) - statusMenu.itemAtIndex(4)?.state = (AtLogin.enabled) ? 1 : 0 + func menuWillOpen(_ menu: NSMenu) { + statusMenu.item(at: 0)?.title = String(format: "%d Quits Blocked", arguments: [KeyListener.sharedKeyListener.accidentalQuits]) + statusMenu.item(at: 4)?.state = NSControl.StateValue(rawValue: (AtLogin.enabled) ? 1 : 0) } } diff --git a/QBlocker/TabBarController.swift b/QBlocker/TabBarController.swift index 99ec6fb..c80b5a8 100644 --- a/QBlocker/TabBarController.swift +++ b/QBlocker/TabBarController.swift @@ -16,8 +16,8 @@ class TabBarController: SRTabBarController { tabBarLocation = .Top - tabBar?.material = .Titlebar - tabBar?.blendingMode = .WithinWindow + tabBar?.material = .titlebar + tabBar?.blendingMode = .withinWindow tabBar?.translucent = true } From 55687600a1ee96db353516e828cafb61bfca475b Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 02:35:26 +0900 Subject: [PATCH 02/18] Support Dark mode. --- QBlocker.xcodeproj/project.pbxproj | 4 ++++ QBlocker/AccessibilityView.swift | 24 ++++++++++++++++++++++ QBlocker/AccessibilityViewController.swift | 3 --- QBlocker/AppDelegate.swift | 4 ++-- QBlocker/Base.lproj/Main.storyboard | 6 +++--- 5 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 QBlocker/AccessibilityView.swift diff --git a/QBlocker.xcodeproj/project.pbxproj b/QBlocker.xcodeproj/project.pbxproj index 23bfec1..f648af6 100644 --- a/QBlocker.xcodeproj/project.pbxproj +++ b/QBlocker.xcodeproj/project.pbxproj @@ -30,6 +30,7 @@ 28DEC8041CD950450012B5E3 /* HUDAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8031CD950450012B5E3 /* HUDAlert.swift */; }; 28DEC8061CD954EA0012B5E3 /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8051CD954EA0012B5E3 /* HUDView.swift */; }; 28F40A711CFB61EB006719C8 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F40A701CFB61EB006719C8 /* TabBarController.swift */; }; + B1F349A621AF0824005DC323 /* AccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F349A521AF0824005DC323 /* AccessibilityView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -62,6 +63,7 @@ 9AE2D0BFC44767B8D2FE86C2 /* Pods_QBlocker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QBlocker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A3F762D47D17E2933604A226 /* Pods-QBlocker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.release.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.release.xcconfig"; sourceTree = ""; }; B12B3DD321AEF3AC00BAE6B6 /* QBlocker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = QBlocker.entitlements; sourceTree = ""; }; + B1F349A521AF0824005DC323 /* AccessibilityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,6 +85,7 @@ 28BEB6871CDBEB8200E693D3 /* AccessibilityViewController.swift */, 2883C1E41CDE36B10007AC47 /* FirstRunViewController.swift */, 28BEB6851CDBEB4F00E693D3 /* OpenPreferences.scpt */, + B1F349A521AF0824005DC323 /* AccessibilityView.swift */, ); name = "First Launch"; sourceTree = ""; @@ -347,6 +350,7 @@ 28A518631CDE91C200BE7ED1 /* ExcludeViewController + NSTableViewDataSource.swift in Sources */, 2853B63B1CD92D9700F186CE /* StatusMenuController.swift in Sources */, 28A5185B1CDE416800BE7ED1 /* ExcludeWindowController.swift in Sources */, + B1F349A621AF0824005DC323 /* AccessibilityView.swift in Sources */, 28BEB6831CDBE79D00E693D3 /* AccessibilityWindowController.swift in Sources */, 2880C4531CD7B3A000545E1F /* KeyListener.swift in Sources */, 28A5185F1CDE87A300BE7ED1 /* App.swift in Sources */, diff --git a/QBlocker/AccessibilityView.swift b/QBlocker/AccessibilityView.swift new file mode 100644 index 0000000..fa97367 --- /dev/null +++ b/QBlocker/AccessibilityView.swift @@ -0,0 +1,24 @@ +// +// AccessibilityView.swift +// QBlocker +// +// Created by Tomohiro Kumagai on 11/29/30 H. +// Copyright © 30 Heisei Cocoon Development Ltd. All rights reserved. +// + +import Cocoa + +class AccessibilityView: NSView { + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + + let path = NSBezierPath() + + NSColor.windowBackgroundColor.setFill() + + path.appendRect(dirtyRect) + path.fill() + } + +} diff --git a/QBlocker/AccessibilityViewController.swift b/QBlocker/AccessibilityViewController.swift index 23bfe1f..310cad5 100644 --- a/QBlocker/AccessibilityViewController.swift +++ b/QBlocker/AccessibilityViewController.swift @@ -25,7 +25,4 @@ class AccessibilityViewController: NSViewController { // Quit the app NSApp.terminate(self) } - - - } diff --git a/QBlocker/AppDelegate.swift b/QBlocker/AppDelegate.swift index 347b6ec..c97b5c4 100644 --- a/QBlocker/AppDelegate.swift +++ b/QBlocker/AppDelegate.swift @@ -11,7 +11,7 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - private var accessibilityWindowController: NSWindowController? + private var accessibilityWindowController: AccessibilityWindowController? private var firstRunWindowController: NSWindowController? private lazy var preferencesWindowController: NSWindowController = { return NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "preferences window") as! NSWindowController @@ -51,7 +51,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { showFirstRunWindowIfRequired() } else { - if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "accessibility window") as? NSWindowController { + if let windowController = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "accessibility window") as? AccessibilityWindowController { accessibilityWindowController = windowController accessibilityWindowController?.showWindow(self) accessibilityWindowController?.window?.makeKeyAndOrderFront(self) diff --git a/QBlocker/Base.lproj/Main.storyboard b/QBlocker/Base.lproj/Main.storyboard index a75fb17..5449b02 100644 --- a/QBlocker/Base.lproj/Main.storyboard +++ b/QBlocker/Base.lproj/Main.storyboard @@ -179,7 +179,7 @@ - + @@ -227,7 +227,7 @@ - + @@ -554,7 +554,7 @@ - + From 83463f7e35f0d066d5c37e389206efc1cc3eb809 Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 03:24:32 +0900 Subject: [PATCH 03/18] Fix auto layout. --- QBlocker/Base.lproj/Main.storyboard | 336 +++++++++++++++------------- QBlocker/KeyListener.swift | 2 +- 2 files changed, 178 insertions(+), 160 deletions(-) diff --git a/QBlocker/Base.lproj/Main.storyboard b/QBlocker/Base.lproj/Main.storyboard index 5449b02..144c635 100644 --- a/QBlocker/Base.lproj/Main.storyboard +++ b/QBlocker/Base.lproj/Main.storyboard @@ -129,9 +129,6 @@ - - - @@ -191,54 +188,56 @@ - - - - - - - - - QBlocker uses OS X's accessibility features to block accidental quits. Please enable accessibility features for QBlocker in System Preferences and then re-open the app. - - - - - - - + + + + + + + + + + + + + + + + QBlocker uses OS X's accessibility features to block accidental quits. Please enable accessibility features for QBlocker in System Preferences and then re-open the app. + + + + + + - - + + + + + + + + + + - - - - - - + - - - - - + + - + @@ -302,12 +301,8 @@ - - - - - - + + @@ -320,12 +315,8 @@ - + - - - - @@ -333,12 +324,8 @@ - - - - - - + + @@ -350,6 +337,8 @@ + + @@ -401,9 +390,8 @@ - - - + + @@ -411,6 +399,11 @@ + + + + + @@ -438,35 +431,44 @@ - - + + - - + + + + + + + + + + - - - - - - - - - + + @@ -474,7 +476,7 @@ - + @@ -489,18 +491,15 @@ + - - - - - + - + @@ -546,18 +545,83 @@ - - + + + + + + + + + + + + + + + + + + + You're all set. QBlocker will stop accidental quits by forcing you to hold ⌘Q instead. If you want to, you can set some rules or let QBlocker work its magic on everything. + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + - - - - - - + @@ -566,59 +630,13 @@ - - - - - - - - - You're all set. QBlocker will stop accidental quits by forcing you to hold ⌘Q instead. If you want to, you can set some rules or let QBlocker work its magic on everything. - - - - - - - - + + + - - - - - - diff --git a/QBlocker/KeyListener.swift b/QBlocker/KeyListener.swift index f711d63..6d93a6b 100644 --- a/QBlocker/KeyListener.swift +++ b/QBlocker/KeyListener.swift @@ -52,7 +52,7 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C // check that the app has CMD Q enabled guard KeyListener.cmdQActiveForApp(app: app) else { - print("\(app.bundleIdentifier) does not use cmd+q") + print("\(app.bundleIdentifier ?? String(describing: app)) does not use cmd+q") return nil } From 2a37771dc5a6ce18c5f7607d41244f3c0e0cf0d2 Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 03:28:48 +0900 Subject: [PATCH 04/18] Rename `sharedKeyListener` property. --- QBlocker/AppDelegate.swift | 2 +- ...ewController + NSTableViewDataSource.swift | 2 +- ...ViewController + NSTableViewDelegate.swift | 2 +- QBlocker/ExcludeViewController.swift | 6 ++--- QBlocker/KeyListener.swift | 24 +++++++++---------- QBlocker/StatusMenuController.swift | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/QBlocker/AppDelegate.swift b/QBlocker/AppDelegate.swift index c97b5c4..894f09c 100644 --- a/QBlocker/AppDelegate.swift +++ b/QBlocker/AppDelegate.swift @@ -43,7 +43,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { let myDict: CFDictionary = [promptFlag: false] as CFDictionary if AXIsProcessTrustedWithOptions(myDict) { do { - try KeyListener.sharedKeyListener.start() + try KeyListener.shared.start() } catch { NSLog("Could not launch listener") } diff --git a/QBlocker/ExcludeViewController + NSTableViewDataSource.swift b/QBlocker/ExcludeViewController + NSTableViewDataSource.swift index 219a579..9905147 100644 --- a/QBlocker/ExcludeViewController + NSTableViewDataSource.swift +++ b/QBlocker/ExcludeViewController + NSTableViewDataSource.swift @@ -11,7 +11,7 @@ import Cocoa extension ExcludeViewController: NSTableViewDataSource { func numberOfRows(in tableView: NSTableView) -> Int { - return KeyListener.sharedKeyListener.list?.count ?? 0 + return KeyListener.shared.list?.count ?? 0 } } diff --git a/QBlocker/ExcludeViewController + NSTableViewDelegate.swift b/QBlocker/ExcludeViewController + NSTableViewDelegate.swift index 710d5d0..9acb28d 100644 --- a/QBlocker/ExcludeViewController + NSTableViewDelegate.swift +++ b/QBlocker/ExcludeViewController + NSTableViewDelegate.swift @@ -13,7 +13,7 @@ extension ExcludeViewController: NSTableViewDelegate { func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { guard let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "app name cell"), owner: nil) as? NSTableCellView, - let app = KeyListener.sharedKeyListener.list?[row] else { + let app = KeyListener.shared.list?[row] else { return nil } diff --git a/QBlocker/ExcludeViewController.swift b/QBlocker/ExcludeViewController.swift index 13120b6..9157453 100644 --- a/QBlocker/ExcludeViewController.swift +++ b/QBlocker/ExcludeViewController.swift @@ -35,7 +35,7 @@ class ExcludeViewController: NSViewController { let app = App() app.name = name app.bundleID = bundle - KeyListener.sharedKeyListener.addExcludedApp(app: app) + KeyListener.shared.addExcludedApp(app: app) } self.tableView.reloadData() } @@ -44,7 +44,7 @@ class ExcludeViewController: NSViewController { @IBAction func removeClicked(_ sender: AnyObject) { guard tableView.selectedRowIndexes.count > 0, - let apps = KeyListener.sharedKeyListener.list else { + let apps = KeyListener.shared.list else { print("Nothing selected") return } @@ -55,7 +55,7 @@ class ExcludeViewController: NSViewController { } for app in toRemove { - KeyListener.sharedKeyListener.removeExcludedApp(app: app) + KeyListener.shared.removeExcludedApp(app: app) } tableView.reloadData() diff --git a/QBlocker/KeyListener.swift b/QBlocker/KeyListener.swift index 6d93a6b..844b3fd 100644 --- a/QBlocker/KeyListener.swift +++ b/QBlocker/KeyListener.swift @@ -29,7 +29,7 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C return Unmanaged.passUnretained(event) } - guard KeyListener.sharedKeyListener.canQuit else { + guard KeyListener.shared.canQuit else { print("not allowed to quit yet") return nil } @@ -42,7 +42,7 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C // Check if the current app is in the list if let bundleId = app.bundleIdentifier { - let isIdentifierListed = KeyListener.sharedKeyListener.listedBundleIdentifiers.contains(bundleId) + let isIdentifierListed = KeyListener.shared.listedBundleIdentifiers.contains(bundleId) print(ListMode.selectedMode) if (ListMode.selectedMode == .Blacklist && isIdentifierListed) || (ListMode.selectedMode == .Whitelist && !isIdentifierListed) { print("App is excluded") @@ -56,16 +56,16 @@ private func keyDownCallback(proxy: CGEventTapProxy, type: CGEventType, event: C return nil } - if KeyListener.sharedKeyListener.canQuit && KeyListener.sharedKeyListener.tries <= KeyListener.delay { + if KeyListener.shared.canQuit && KeyListener.shared.tries <= KeyListener.delay { print("showing HUD") HUDAlert.sharedHUDAlert.showHUD(delayTime: 1) } - KeyListener.sharedKeyListener.tries += 1 - if KeyListener.sharedKeyListener.tries > KeyListener.delay { + KeyListener.shared.tries += 1 + if KeyListener.shared.tries > KeyListener.delay { print("quit successful") - KeyListener.sharedKeyListener.tries = 0 - KeyListener.sharedKeyListener.canQuit = false + KeyListener.shared.tries = 0 + KeyListener.shared.canQuit = false HUDAlert.sharedHUDAlert.dismissHUD(fade: false) return Unmanaged.passUnretained(event) } @@ -92,14 +92,14 @@ private func keyUpCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGE return Unmanaged.passUnretained(event) } - if KeyListener.sharedKeyListener.tries <= KeyListener.delay { - KeyListener.sharedKeyListener.logAccidentalQuit() + if KeyListener.shared.tries <= KeyListener.delay { + KeyListener.shared.logAccidentalQuit() } else { HUDAlert.sharedHUDAlert.dismissHUD() } - KeyListener.sharedKeyListener.tries = 0 - KeyListener.sharedKeyListener.canQuit = true + KeyListener.shared.tries = 0 + KeyListener.shared.canQuit = true return Unmanaged.passUnretained(event) } @@ -108,7 +108,7 @@ private func keyUpCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGE class KeyListener { /// Shared instance of the key listener - static let sharedKeyListener = KeyListener() + static let shared = KeyListener() /// How long the Q key needs to be held before you can quit static var delay: Int { diff --git a/QBlocker/StatusMenuController.swift b/QBlocker/StatusMenuController.swift index ea99fcf..5a237e2 100644 --- a/QBlocker/StatusMenuController.swift +++ b/QBlocker/StatusMenuController.swift @@ -47,7 +47,7 @@ class StatusMenuController: NSObject, NSMenuDelegate { // MARK: - NSMenuDelegate func menuWillOpen(_ menu: NSMenu) { - statusMenu.item(at: 0)?.title = String(format: "%d Quits Blocked", arguments: [KeyListener.sharedKeyListener.accidentalQuits]) + statusMenu.item(at: 0)?.title = String(format: "%d Quits Blocked", arguments: [KeyListener.shared.accidentalQuits]) statusMenu.item(at: 4)?.state = NSControl.StateValue(rawValue: (AtLogin.enabled) ? 1 : 0) } From fbd865e2beef1ef8d3d21a2f3d9bf09f64497e03 Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 03:37:39 +0900 Subject: [PATCH 05/18] Fix detaching HUD window. --- QBlocker/Base.lproj/Main.storyboard | 2 +- QBlocker/Delay.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/QBlocker/Base.lproj/Main.storyboard b/QBlocker/Base.lproj/Main.storyboard index 144c635..8f6e3ff 100644 --- a/QBlocker/Base.lproj/Main.storyboard +++ b/QBlocker/Base.lproj/Main.storyboard @@ -131,7 +131,7 @@ - + diff --git a/QBlocker/Delay.swift b/QBlocker/Delay.swift index d573c10..bd6fab8 100644 --- a/QBlocker/Delay.swift +++ b/QBlocker/Delay.swift @@ -13,7 +13,7 @@ typealias DispatchBlock = () -> Void func delay(time:TimeInterval, closure:@escaping ()->Void) -> dispatch_cancelable_closure? { func dispatch_later(clsr:@escaping ()->Void) { - DispatchQueue.main.asyncAfter(deadline: .now() + time * Double(NSEC_PER_SEC), execute: clsr) + DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: clsr) } var closure:DispatchBlock? = closure From 908b4936d59657d01bfe297cea930656a5015244 Mon Sep 17 00:00:00 2001 From: Tomohiro Kumagai Date: Thu, 29 Nov 2018 08:44:43 +0900 Subject: [PATCH 06/18] Refine code around dark mode. --- QBlocker.xcodeproj/project.pbxproj | 4 ---- QBlocker/AccessibilityView.swift | 24 -------------------- QBlocker/AccessibilityWindowController.swift | 2 -- QBlocker/Base.lproj/Main.storyboard | 6 ++--- 4 files changed, 3 insertions(+), 33 deletions(-) delete mode 100644 QBlocker/AccessibilityView.swift diff --git a/QBlocker.xcodeproj/project.pbxproj b/QBlocker.xcodeproj/project.pbxproj index f648af6..23bfec1 100644 --- a/QBlocker.xcodeproj/project.pbxproj +++ b/QBlocker.xcodeproj/project.pbxproj @@ -30,7 +30,6 @@ 28DEC8041CD950450012B5E3 /* HUDAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8031CD950450012B5E3 /* HUDAlert.swift */; }; 28DEC8061CD954EA0012B5E3 /* HUDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DEC8051CD954EA0012B5E3 /* HUDView.swift */; }; 28F40A711CFB61EB006719C8 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28F40A701CFB61EB006719C8 /* TabBarController.swift */; }; - B1F349A621AF0824005DC323 /* AccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1F349A521AF0824005DC323 /* AccessibilityView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -63,7 +62,6 @@ 9AE2D0BFC44767B8D2FE86C2 /* Pods_QBlocker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QBlocker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A3F762D47D17E2933604A226 /* Pods-QBlocker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QBlocker.release.xcconfig"; path = "Pods/Target Support Files/Pods-QBlocker/Pods-QBlocker.release.xcconfig"; sourceTree = ""; }; B12B3DD321AEF3AC00BAE6B6 /* QBlocker.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = QBlocker.entitlements; sourceTree = ""; }; - B1F349A521AF0824005DC323 /* AccessibilityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,7 +83,6 @@ 28BEB6871CDBEB8200E693D3 /* AccessibilityViewController.swift */, 2883C1E41CDE36B10007AC47 /* FirstRunViewController.swift */, 28BEB6851CDBEB4F00E693D3 /* OpenPreferences.scpt */, - B1F349A521AF0824005DC323 /* AccessibilityView.swift */, ); name = "First Launch"; sourceTree = ""; @@ -350,7 +347,6 @@ 28A518631CDE91C200BE7ED1 /* ExcludeViewController + NSTableViewDataSource.swift in Sources */, 2853B63B1CD92D9700F186CE /* StatusMenuController.swift in Sources */, 28A5185B1CDE416800BE7ED1 /* ExcludeWindowController.swift in Sources */, - B1F349A621AF0824005DC323 /* AccessibilityView.swift in Sources */, 28BEB6831CDBE79D00E693D3 /* AccessibilityWindowController.swift in Sources */, 2880C4531CD7B3A000545E1F /* KeyListener.swift in Sources */, 28A5185F1CDE87A300BE7ED1 /* App.swift in Sources */, diff --git a/QBlocker/AccessibilityView.swift b/QBlocker/AccessibilityView.swift deleted file mode 100644 index fa97367..0000000 --- a/QBlocker/AccessibilityView.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// AccessibilityView.swift -// QBlocker -// -// Created by Tomohiro Kumagai on 11/29/30 H. -// Copyright © 30 Heisei Cocoon Development Ltd. All rights reserved. -// - -import Cocoa - -class AccessibilityView: NSView { - - override func draw(_ dirtyRect: NSRect) { - super.draw(dirtyRect) - - let path = NSBezierPath() - - NSColor.windowBackgroundColor.setFill() - - path.appendRect(dirtyRect) - path.fill() - } - -} diff --git a/QBlocker/AccessibilityWindowController.swift b/QBlocker/AccessibilityWindowController.swift index 15821d2..f9d5e82 100644 --- a/QBlocker/AccessibilityWindowController.swift +++ b/QBlocker/AccessibilityWindowController.swift @@ -15,7 +15,5 @@ class AccessibilityWindowController: NSWindowController { window?.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.popUpMenuWindow))) window?.titlebarAppearsTransparent = true - window?.backgroundColor = NSColor(calibratedHue:0.00, saturation:0.00, brightness:0.90, alpha:1.00) } - } diff --git a/QBlocker/Base.lproj/Main.storyboard b/QBlocker/Base.lproj/Main.storyboard index 8f6e3ff..a0a38b0 100644 --- a/QBlocker/Base.lproj/Main.storyboard +++ b/QBlocker/Base.lproj/Main.storyboard @@ -176,7 +176,7 @@ - + @@ -434,7 +434,7 @@ - -