diff --git a/octopus.xcodeproj/project.pbxproj b/octopus.xcodeproj/project.pbxproj index 290e6eb..543d614 100644 --- a/octopus.xcodeproj/project.pbxproj +++ b/octopus.xcodeproj/project.pbxproj @@ -17,8 +17,6 @@ CE8CEAFB1E646B2C00E3B034 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE8CEAFA1E646B2C00E3B034 /* Assets.xcassets */; }; CE8CEAFE1E646B2D00E3B034 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE8CEAFC1E646B2D00E3B034 /* MainMenu.xib */; }; CEA25A931E68A227008FB6A6 /* KeyCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA25A921E68A227008FB6A6 /* KeyCode.swift */; }; - CEF932C71E869C4E00C4839F /* Metrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF932C61E869C4E00C4839F /* Metrics.swift */; }; - CEF932C91E86A46600C4839F /* OutputString.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF932C81E86A46600C4839F /* OutputString.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -34,8 +32,6 @@ CE8CEAFD1E646B2D00E3B034 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; CE8CEAFF1E646B2D00E3B034 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CEA25A921E68A227008FB6A6 /* KeyCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyCode.swift; sourceTree = ""; }; - CEF932C61E869C4E00C4839F /* Metrics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Metrics.swift; sourceTree = ""; }; - CEF932C81E86A46600C4839F /* OutputString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutputString.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -74,9 +70,7 @@ CE6CFE971E771C9B0024C8EE /* KeyToKey.swift */, CE6CFE951E771C840024C8EE /* KeyOverlaidModifier.swift */, CE6CFE911E771C0D0024C8EE /* Modal.swift */, - CEF932C61E869C4E00C4839F /* Metrics.swift */, CE6CFE931E771C5C0024C8EE /* KeyEvent.swift */, - CEF932C81E86A46600C4839F /* OutputString.swift */, CE6CFE991E7721440024C8EE /* CaplockMonitor.swift */, CE8CEAFA1E646B2C00E3B034 /* Assets.xcassets */, CE8CEAFC1E646B2D00E3B034 /* MainMenu.xib */, @@ -112,7 +106,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0810; - LastUpgradeCheck = 0820; + LastUpgradeCheck = 1150; ORGANIZATIONNAME = Betafabric; TargetAttributes = { CE8CEAF41E646B2C00E3B034 = { @@ -158,11 +152,9 @@ buildActionMask = 2147483647; files = ( CE6CFE9A1E7721440024C8EE /* CaplockMonitor.swift in Sources */, - CEF932C91E86A46600C4839F /* OutputString.swift in Sources */, CE6CFE981E771C9B0024C8EE /* KeyToKey.swift in Sources */, CE6CFE9C1E7721750024C8EE /* Keyboard.swift in Sources */, CE6CFE941E771C5C0024C8EE /* KeyEvent.swift in Sources */, - CEF932C71E869C4E00C4839F /* Metrics.swift in Sources */, CEA25A931E68A227008FB6A6 /* KeyCode.swift in Sources */, CE6CFE921E771C0D0024C8EE /* Modal.swift in Sources */, CE8CEAF91E646B2C00E3B034 /* AppDelegate.swift in Sources */, @@ -193,15 +185,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_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_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -225,12 +225,13 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -243,15 +244,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_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_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; @@ -269,10 +278,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.15; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -280,12 +290,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = octopus/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.betafabric.octopus; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; }; name = Debug; @@ -294,12 +305,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = octopus/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.betafabric.octopus; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; }; name = Release; diff --git a/octopus/AppDelegate.swift b/octopus/AppDelegate.swift index c8dffb3..bf1f728 100644 --- a/octopus/AppDelegate.swift +++ b/octopus/AppDelegate.swift @@ -28,11 +28,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { var launchbar: KeyToKey? var launchbarShift: KeyToKey? var capsLockMonitor: CapsLockMonitor? - var metrics: Metrics? func applicationDidFinishLaunching(_ aNotification: Notification) { - statusItem.title = "Octopus" + statusItem.button?.title = "Octopus" statusItem.menu = statusMenu // Insert code here to initialize your application // func acquirePrivileges() -> Bool { @@ -67,15 +66,6 @@ class AppDelegate: NSObject, NSApplicationDelegate { func startTapping () { class TabMode: Modal { - override var redZone: Double { - get { - return 0.0 - } - set { - self.redZone = 0.0 - } - } - override func entered () { super.entered() Keyboard.keyDown(key: .command) @@ -89,6 +79,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { self.tabMode = TabMode( name: "Tabmode", + redZone: 0.0, statusIndicator: tabmodeIndicator, trigger: KeyEvent(key: .tab, modifiers: []), bindings: [ @@ -122,6 +113,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { self.homerowMode = Modal( name: "HomerowMode", + redZone: 0.05, statusIndicator: homerowmodeIndicator, trigger: KeyEvent(key: .space, modifiers: []), bindings: [ diff --git a/octopus/KeyOverlaidModifier.swift b/octopus/KeyOverlaidModifier.swift index 02f121b..df33874 100644 --- a/octopus/KeyOverlaidModifier.swift +++ b/octopus/KeyOverlaidModifier.swift @@ -14,10 +14,10 @@ class KeyOverlaidModifier: Hashable { var triggerPressedTimestamp = Date().timeIntervalSince1970 var wasUsed = false - var hashValue: Int { - return overlay.rawValue.hashValue ^ to.hashValue + func hash(into hasher: inout Hasher) { + hasher.combine(overlay.rawValue) + hasher.combine(to) } - static func == (lhs: KeyOverlaidModifier, rhs: KeyOverlaidModifier) -> Bool { return lhs.overlay == rhs.overlay && lhs.to == rhs.to } diff --git a/octopus/Metrics.swift b/octopus/Metrics.swift deleted file mode 100644 index e7ea96c..0000000 --- a/octopus/Metrics.swift +++ /dev/null @@ -1,94 +0,0 @@ -// -// Modal.swift -// octopus -// -// Created by user on 13/03/17. -// Copyright © 2017 Betafabric. All rights reserved. -// - -import Foundation -import Cocoa - - -func getCharacter(event: CGEvent) -> String { - var length = 0 - var chars = Array(repeating: UniChar(0), count: 1) - event.keyboardGetUnicodeString(maxStringLength: 1, actualStringLength: &length, unicodeString: &chars) - return NSString(characters:chars, length: length) as String -} - -class Metrics { - var isSpacePressed = false - var spaceTimeStamp = Date().timeIntervalSince1970 - var lastKeyPressedTimestamp = Date().timeIntervalSince1970 - var lastKeyPressed = "" - var spaceKeyCode = Int64(KeyCode.space.rawValue) - var pressCount = 0 - var overlapCount = 0 - - - var runLoopSource: CFRunLoopSource? = nil - let outputFile: OutputStream - - - - init() { - let fileURL = try! FileManager.default.url(for: .desktopDirectory, in: .userDomainMask, appropriateFor: nil, create: false) - .appendingPathComponent("space-overlap.txt") - - outputFile = OutputStream(url: fileURL, append: true)! - outputFile.open() - func myCGEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, userInfo: UnsafeMutableRawPointer?) -> Unmanaged? { - - let myself = Unmanaged.fromOpaque(userInfo!).takeUnretainedValue() - - let keyCode = event.getIntegerValueField(.keyboardEventKeycode) - - if type == .keyDown { - myself.pressCount += 1 - } - - if keyCode == myself.spaceKeyCode && type == .keyDown { - myself.spaceTimeStamp = Date().timeIntervalSince1970 - myself.isSpacePressed = true - } else if keyCode == myself.spaceKeyCode && type == .keyUp { - myself.isSpacePressed = false - } else if myself.isSpacePressed && type == .keyDown { - myself.overlapCount += 1 - let timeSinceSpacePress = Date().timeIntervalSince1970 - myself.spaceTimeStamp - let timeSinceLastKeyPress = myself.spaceTimeStamp - myself.lastKeyPressedTimestamp - let char = getCharacter(event: event) - let text = "Overlap #\(myself.overlapCount)(\(myself.pressCount)): '\(char)' \(timeSinceSpacePress)s after space | '\(myself.lastKeyPressed)' \(timeSinceLastKeyPress)s before space \n" - let _ = myself.outputFile.write(text) - } else { - myself.lastKeyPressedTimestamp = Date().timeIntervalSince1970 - myself.lastKeyPressed = getCharacter(event: event) - } - - return Unmanaged.passRetained(event) - } - - let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue) - guard let eventTap = CGEvent.tapCreate( - tap: .cgSessionEventTap, - place: .headInsertEventTap, - options: .defaultTap, - eventsOfInterest: CGEventMask(eventMask), - callback: myCGEventCallback, - userInfo: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) - ) else { - print("failed to create event tap") - return - } - - self.runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) - CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) - CGEvent.tapEnable(tap: eventTap, enable: true) - CFRunLoopRun() - - } - -} - - - diff --git a/octopus/Modal.swift b/octopus/Modal.swift index 1b7a795..34c0203 100644 --- a/octopus/Modal.swift +++ b/octopus/Modal.swift @@ -107,13 +107,14 @@ class Modal { fieldsString = fieldsString + "| eventSourceStateID: " + String(event.getIntegerValueField(.eventSourceStateID)) return fieldsString } - init(name: String, statusIndicator: NSButton? = nil, trigger: KeyEvent, bindings: [KeyEvent: KeyEvent], overlaidModifiers: [KeyEvent: KeyOverlaidModifier] = [:]) { + init(name: String, redZone: Double, statusIndicator: NSButton? = nil, trigger: KeyEvent, bindings: [KeyEvent: KeyEvent], overlaidModifiers: [KeyEvent: KeyOverlaidModifier] = [:]) { self.name = name self.trigger = trigger self.bindings = bindings self.overlaidModifiers = overlaidModifiers self.statusIndicator = statusIndicator - + self.redZone = redZone + func myCGEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, userInfo: UnsafeMutableRawPointer?) -> Unmanaged? { let keyCode = event.getIntegerValueField(.keyboardEventKeycode) let thisModal = Unmanaged.fromOpaque(userInfo!).takeUnretainedValue() diff --git a/octopus/OutputString.swift b/octopus/OutputString.swift deleted file mode 100644 index b84e166..0000000 --- a/octopus/OutputString.swift +++ /dev/null @@ -1,48 +0,0 @@ -// -// OutputString.swift -// spaceoverlaptest -// -// Created by user on 20/03/2017. -// Copyright © 2017 user. All rights reserved. -// - -import Foundation - -extension OutputStream { - - /// Write `String` to `OutputStream` - /// - /// - parameter string: The `String` to write. - /// - parameter encoding: The `String.Encoding` to use when writing the string. This will default to `.utf8`. - /// - parameter allowLossyConversion: Whether to permit lossy conversion when writing the string. Defaults to `false`. - /// - /// - returns: Return total number of bytes written upon success. Return `-1` upon failure. - - func write(_ string: String, encoding: String.Encoding = .utf8, allowLossyConversion: Bool = false) -> Int { - - if let data = string.data(using: encoding, allowLossyConversion: allowLossyConversion) { - return data.withUnsafeBytes { (bytes: UnsafePointer) -> Int in - var pointer = bytes - var bytesRemaining = data.count - var totalBytesWritten = 0 - - while bytesRemaining > 0 { - let bytesWritten = self.write(pointer, maxLength: bytesRemaining) - if bytesWritten < 0 { - print(self.streamError?.localizedDescription) - return -1 - } - - bytesRemaining -= bytesWritten - pointer += bytesWritten - totalBytesWritten += bytesWritten - } - - return totalBytesWritten - } - } - - return -1 - } - -}