Skip to content

Commit

Permalink
🐛 #35 Don't activate Loop when Caps Lock key is enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
MrKai77 committed Sep 16, 2023
2 parents 5acf0ed + f013d99 commit ed40079
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 57 deletions.
10 changes: 6 additions & 4 deletions Loop/Managers/LoopManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,16 @@ class LoopManager {
}

private func handleLoopKeypress(_ event: NSEvent) {
if event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) {
self.closeLoop(forceClose: true)
return
}
if event.keyCode == Defaults[.triggerKey].keycode {

let useTriggerDelay = Defaults[.triggerDelay] > 0.1
let useDoubleClickTrigger = Defaults[.doubleClickToTrigger]

if event.modifierFlags.rawValue == 256 {
if useTriggerDelay {
self.cancelTriggerDelayTimer()
}
if event.modifierFlags.rawValue == 256 {
self.closeLoop()
} else {
if useDoubleClickTrigger {
Expand Down Expand Up @@ -130,6 +131,7 @@ class LoopManager {
private func closeLoop(forceClose: Bool = false) {
var willResizeWindow: Bool = false

self.cancelTriggerDelayTimer()
radialMenuController.close()
previewController.close()

Expand Down
26 changes: 21 additions & 5 deletions Loop/Settings/KeybindingSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,33 @@ struct KeybindingSettingsView: View {

let loopTriggerKeyOptions = TriggerKey.options
@State var suggestAddingTriggerDelay: Bool = false
@State var suggestDisablingCapsLock: Bool = false

var body: some View {
Form {
Section("Keybindings") {
VStack(alignment: .leading) {
Keycorder("Trigger Key", key: self.$triggerKey, onChange: { event in
for key in TriggerKey.options where key.keycode == event.keyCode {
return key
HStack {
Text("Trigger Key")
Spacer()
Keycorder(key: self.$triggerKey) { event in
if event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) {
self.suggestDisablingCapsLock = true
return nil
} else {
self.suggestDisablingCapsLock = false
}

for key in TriggerKey.options where key.keycode == event.keyCode {
return key
}
return nil
}
return nil
})
.popover(isPresented: $suggestDisablingCapsLock, arrowEdge: .bottom, content: {
Text("Your Caps Lock key is on! Disable it to correctly assign a key.")
.padding(8)
})
}

if triggerKey.keycode == .kVK_RightControl {
Text("Tip: To use caps lock, remap it to control in System Settings!")
Expand Down
87 changes: 39 additions & 48 deletions Loop/Utilities/Keycorder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import SwiftUI

struct Keycorder: View {
private let label: String
@State private var validCurrentKey: Binding<TriggerKey>
private let onChange: (NSEvent) -> TriggerKey?

Expand All @@ -20,10 +19,8 @@ struct Keycorder: View {
@State private var isActive: Bool = false

init(
_ label: String,
key: Binding<TriggerKey>,
onChange: @escaping (NSEvent) -> (TriggerKey?)) {
self.label = label
self.validCurrentKey = key
self.selectionKey = key.wrappedValue
self.onChange = onChange
Expand All @@ -33,70 +30,63 @@ struct Keycorder: View {
let noAnimation = Animation.linear(duration: 0)

var body: some View {
HStack(spacing: 5) {
Text(label)

Spacer()

Button(action: {
self.selectionKey = nil
}, label: {
HStack(spacing: 5) {
if let symbol = selectionKey?.symbol {
Image(systemName: symbol)
}
Text(self.selectionKey?.name ?? "Click a modifier key...")

Image(systemName: "xmark")
.fontWeight(.bold)
.scaleEffect(0.7)
.foregroundStyle(.white)
.padding(1)
.background {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(.quaternary)
.opacity(!(self.isHovering || self.isActive) ? 1 : 0)
}
Button(action: {
self.selectionKey = nil
}, label: {
HStack(spacing: 5) {
if let symbol = selectionKey?.symbol {
Image(systemName: symbol)
}
.padding(2)
.padding(.leading, 5)
.background {
RoundedRectangle(cornerRadius: 6)
.foregroundStyle(.secondary.shadow(.inner(color: .white, radius: 0, x: 0, y: 0.5)))
.shadow(color: .black, radius: 0.5, x: 0, y: 1)
.opacity(0.5)
.opacity(isActive ? 0.5 : 1)
.animation(isActive ? activeAnimation : noAnimation, value: isActive)
.opacity((self.isHovering || self.isActive) ? 1 : 0)
}
})
.modifier(ShakeEffect(shakes: self.shouldShake ? 2 : 0))
.animation(Animation.default, value: shouldShake)
.onHover { hovering in
self.isHovering = hovering
Text(self.selectionKey?.name ?? "Click a modifier key...")

Image(systemName: "xmark")
.fontWeight(.bold)
.scaleEffect(0.7)
.foregroundStyle(.white)
.padding(1)
.background {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(.quaternary)
.opacity(!(self.isHovering || self.isActive) ? 1 : 0)
}
}
.padding(2)
.padding(.leading, 5)
.background {
RoundedRectangle(cornerRadius: 6)
.foregroundStyle(.secondary.shadow(.inner(color: .white, radius: 0, x: 0, y: 0.5)))
.shadow(color: .black, radius: 0.5, x: 0, y: 1)
.opacity(0.5)
.opacity(isActive ? 0.5 : 1)
.animation(isActive ? activeAnimation : noAnimation, value: isActive)
.opacity((self.isHovering || self.isActive) ? 1 : 0)
}
})
.modifier(ShakeEffect(shakes: self.shouldShake ? 2 : 0))
.animation(Animation.default, value: shouldShake)
.onHover { hovering in
self.isHovering = hovering
}
.buttonStyle(.plain)
.onChange(of: self.selectionKey) { _ in
if self.selectionKey == nil {
self.isActive = true
self.startObservingKeys()
}
}
}

func startObservingKeys() {
self.isActive = true
self.eventMonitor = NSEventMonitor(scope: .local, eventMask: .flagsChanged) { event in
self.selectionKey = self.onChange(event)
let keyUp = 256
let keyUpValue = 256

if event.modifierFlags.rawValue == keyUp && self.selectionKey != nil {
self.isActive = false
if event.modifierFlags.rawValue == keyUpValue && self.selectionKey != nil {
self.finishedObservingKeys()
return
}

if event.modifierFlags.rawValue != keyUp && self.selectionKey == nil {
if event.modifierFlags.rawValue != keyUpValue && self.selectionKey == nil {
self.shouldShake.toggle()
}

Expand All @@ -109,6 +99,7 @@ struct Keycorder: View {
}

func finishedObservingKeys() {
self.isActive = false
self.eventMonitor?.stop()
self.eventMonitor = nil
}
Expand Down

0 comments on commit ed40079

Please sign in to comment.