Skip to content

Commit

Permalink
Merge pull request #18 from creasty/improve_stability
Browse files Browse the repository at this point in the history
Improve stability
  • Loading branch information
creasty authored Jun 1, 2020
2 parents 824d543 + 63baffe commit 2149f7e
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Keyboard
========

[![Build Status](https://travis-ci.org/creasty/Keyboard.svg?branch=master)](https://travis-ci.org/creasty/Keyboard)
[![Build Status](https://travis-ci.com/creasty/Keyboard.svg?branch=master)](https://travis-ci.com/creasty/Keyboard)
[![GitHub release](https://img.shields.io/github/release/creasty/Keyboard.svg)](https://github.com/creasty/Keyboard/releases)
[![License](https://img.shields.io/github/license/creasty/Keyboard.svg)](./LICENSE)

Expand Down
29 changes: 24 additions & 5 deletions keyboard/AppComponent.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import Cocoa

final class AppComponent {
private(set) lazy var emitter: EmitterType = Emitter()
// Needs to be globally accesible
var _eventManager: EventManagerType?
var _eventTap: CFMachPort?

final class AppComponent {
let nsWorkspace = NSWorkspace.shared

let fileManager = FileManager.default

let eventTapCallback: CGEventTapCallBack = { (proxy, type, event, _) in
switch type {
case .tapDisabledByTimeout:
if let tap = _eventTap {
CGEvent.tapEnable(tap: tap, enable: true) // Re-enable
}
case .keyUp, .keyDown:
if let manager = _eventManager {
return manager.handle(proxy: proxy, cgEvent: event)
}
default:
break
}
return Unmanaged.passRetained(event)
}

private(set) var emitter: EmitterType = Emitter()

func navigationHandler() -> Handler {
return NavigationHandler(
workspace: nsWorkspace,
Expand All @@ -28,11 +47,11 @@ final class AppComponent {
}

func appSwitchHandler() -> Handler {
return AppSwitchHandler(workspace: nsWorkspace, emitter: emitter)
return AppSwitchHandler(workspace: nsWorkspace)
}

func inputMethodHandler() -> Handler {
return InputSourceHandler(emitter: emitter)
return InputSourceHandler()
}

func appQuithHandler() -> Handler {
Expand Down
10 changes: 3 additions & 7 deletions keyboard/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import Cocoa

// Needs to be globally accesible
var eventManager: EventManagerType?

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
private lazy var statusItem: NSStatusItem = {
Expand Down Expand Up @@ -39,7 +36,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}

private func setupEventManager() {
eventManager = appComponent.eventManager()
_eventManager = appComponent.eventManager()
}

private func trapKeyEvents() {
Expand All @@ -50,13 +47,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
place: .headInsertEventTap,
options: .defaultTap,
eventsOfInterest: CGEventMask(eventMask),
callback: { (_, _, event, _) -> Unmanaged<CGEvent>? in
return eventManager!.handle(cgEvent: event)
},
callback: appComponent.eventTapCallback,
userInfo: nil
) else {
fatalError("Failed to create event tap")
}
_eventTap = eventTap

let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
Expand Down
19 changes: 9 additions & 10 deletions keyboard/Core/Emitter.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Cocoa

protocol EmitterType {
func setProxy(_ proxy: CGEventTapProxy?)
func emit(code: KeyCode)
func emit(code: KeyCode, flags: CGEventFlags)
func emit(code: KeyCode, action: Emitter.Action)
func emit(code: KeyCode, flags: CGEventFlags, action: Emitter.Action)
}

struct Emitter: EmitterType {
class Emitter: EmitterType {
struct Const {
static let noremapFlag: CGEventFlags = .maskAlphaShift
static let pauseInterval: UInt32 = 1000
}

Expand All @@ -30,12 +30,10 @@ struct Emitter: EmitterType {
}
}

static func checkAndRemoveNoremapFlag(cgEvent: CGEvent) -> Bool {
if cgEvent.flags.contains(Const.noremapFlag) {
cgEvent.flags.remove(Const.noremapFlag)
return true
}
return false
private var proxy: CGEventTapProxy?

func setProxy(_ proxy: CGEventTapProxy?) {
self.proxy = proxy
}

func emit(code: KeyCode) {
Expand All @@ -61,8 +59,9 @@ struct Emitter: EmitterType {
virtualKey: code.rawValue,
keyDown: $0
)
e?.flags = flags.union(Const.noremapFlag)
e?.post(tap: .cghidEventTap)
e?.flags = flags
e?.tapPostEvent(proxy)
}
}
}

9 changes: 4 additions & 5 deletions keyboard/Core/EventManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Cocoa

protocol EventManagerType {
func register(handler: Handler)
func handle(cgEvent: CGEvent) -> Unmanaged<CGEvent>?
func handle(proxy: CGEventTapProxy, cgEvent: CGEvent) -> Unmanaged<CGEvent>?
}

final class EventManager: EventManagerType {
Expand All @@ -25,10 +25,9 @@ final class EventManager: EventManagerType {
}
}

func handle(cgEvent: CGEvent) -> Unmanaged<CGEvent>? {
guard !Emitter.checkAndRemoveNoremapFlag(cgEvent: cgEvent) else {
return Unmanaged.passRetained(cgEvent)
}
func handle(proxy: CGEventTapProxy, cgEvent: CGEvent) -> Unmanaged<CGEvent>? {
emitter.setProxy(proxy)

guard let event = NSEvent(cgEvent: cgEvent) else {
return Unmanaged.passRetained(cgEvent)
}
Expand Down
4 changes: 1 addition & 3 deletions keyboard/Handlers/AppSwitchHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ extension ApplicationLaunchable {
//
final class AppSwitchHandler: Handler, ApplicationLaunchable {
let workspace: NSWorkspace
private let emitter: EmitterType

init(workspace: NSWorkspace, emitter: EmitterType) {
init(workspace: NSWorkspace) {
self.workspace = workspace
self.emitter = emitter
}

func activateSuperKeys() -> [KeyCode] {
Expand Down
5 changes: 1 addition & 4 deletions keyboard/Handlers/InputSourceHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ import InputMethodKit
// Ctrl-; Select next source in the input menu
//
final class InputSourceHandler: Handler {
private let emitter: EmitterType
private let inputSources: [TISInputSource]

init(emitter: EmitterType) {
self.emitter = emitter

init() {
let inputSourceNSArray = TISCreateInputSourceList(nil, false).takeRetainedValue() as NSArray
let inputSourceList = inputSourceNSArray as! [TISInputSource]
self.inputSources = inputSourceList.filter { $0.isKeyboardInputSource && $0.isSelectable }
Expand Down

0 comments on commit 2149f7e

Please sign in to comment.