Skip to content

Commit

Permalink
🔀 Merge pull request #360 from MrKai77/no-screen-recording
Browse files Browse the repository at this point in the history
✨ Better window animations + Remove Hyperkey conflicts + Fix window snapping on external screens
  • Loading branch information
MrKai77 committed May 24, 2024
2 parents 4ae4bd1 + 5c03850 commit 58235ac
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 351 deletions.
2 changes: 1 addition & 1 deletion Loop/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
NSApp.setActivationPolicy(.accessory)

// Check & ask for accessibility access
PermissionsManager.Accessibility.requestAccess()
AccessibilityManager.requestAccess()
UNUserNotificationCenter.current().delegate = self

AppDelegate.requestNotificationAuthorization()
Expand Down
21 changes: 9 additions & 12 deletions Loop/Extensions/CGGeometry+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ extension CGPoint {
* (from.y - comparisonPoint.y)
}

var flipY: CGPoint? {
guard let screen = NSScreen.main else { return nil }
return CGPoint(x: self.x, y: screen.frame.maxY - self.y)
func flipY(maxY: CGFloat) -> CGPoint {
CGPoint(x: self.x, y: maxY - self.y)
}

func flipY(screen: NSScreen) -> CGPoint {
return flipY(maxY: screen.frame.maxY)
}

func approximatelyEqual(to point: CGPoint, tolerance: CGFloat = 10) -> Bool {
Expand All @@ -52,18 +55,12 @@ extension CGSize {
}

extension CGRect {
var flipY: CGRect? {
guard let screen = NSScreen.main else { return nil }
return CGRect(
x: self.minX,
y: screen.frame.maxY - self.maxY,
width: self.width,
height: self.height
)
func flipY(screen: NSScreen) -> CGRect {
return flipY(maxY: screen.frame.maxY)
}

func flipY(maxY: CGFloat) -> CGRect {
return CGRect(
CGRect(
x: self.minX,
y: maxY - self.maxY,
width: self.width,
Expand Down
4 changes: 2 additions & 2 deletions Loop/Extensions/NSScreen+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension NSScreen {
let displayID = self.displayID
else {
print("ERROR: Failed to get NSScreen.displayID in NSScreen.safeScreenFrame")
return self.frame.flipY!
return self.frame.flipY(screen: self)
}

let screenFrame = CGDisplayBounds(displayID)
Expand Down Expand Up @@ -68,7 +68,7 @@ extension NSScreen {
let displayID = self.displayID
else {
print("ERROR: Failed to get NSScreen.displayID in NSScreen.displayBounds")
return self.frame.flipY!
return self.frame.flipY(screen: self)
}

return CGDisplayBounds(displayID)
Expand Down
6 changes: 4 additions & 2 deletions Loop/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,7 @@
}
},
"Screen recording access" : {
"extractionState" : "stale",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
Expand All @@ -1741,7 +1742,7 @@
}
},
"Screen Recording Request: Content" : {
"extractionState" : "extracted_with_value",
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
Expand All @@ -1758,7 +1759,7 @@
}
},
"Screen Recording Request: Title" : {
"extractionState" : "extracted_with_value",
"extractionState" : "stale",
"localizations" : {
"en" : {
"stringUnit" : {
Expand Down Expand Up @@ -1945,6 +1946,7 @@
}
},
"This is only needed to animate windows being resized." : {
"extractionState" : "stale",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
Expand Down
76 changes: 37 additions & 39 deletions Loop/Managers/KeybindMonitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,42 +26,46 @@ class KeybindMonitor {

func start() {
guard self.eventMonitor == nil,
PermissionsManager.Accessibility.getStatus() else {
AccessibilityManager.getStatus() else {
return
}

self.eventMonitor = CGEventMonitor(eventMask: [.keyDown, .keyUp]) { cgEvent in
if cgEvent.type == .keyDown || cgEvent.type == .keyUp,
let event = NSEvent(cgEvent: cgEvent) {
if event.type == .keyUp {
KeybindMonitor.shared.pressedKeys.remove(event.keyCode.baseKey)
} else if event.type == .keyDown {
KeybindMonitor.shared.pressedKeys.insert(event.keyCode.baseKey)
}
guard
cgEvent.type == .keyDown || cgEvent.type == .keyUp,
let event = NSEvent(cgEvent: cgEvent)
else {
return Unmanaged.passUnretained(cgEvent)
}

// Special events such as the emoji key
if self.specialEvents.contains(event.keyCode.baseKey) {
if self.canPassthroughSpecialEvents {
return Unmanaged.passRetained(cgEvent)
}
return nil
}
if event.type == .keyUp {
KeybindMonitor.shared.pressedKeys.remove(event.keyCode.baseKey)
} else if event.type == .keyDown {
KeybindMonitor.shared.pressedKeys.insert(event.keyCode.baseKey)
}

// If this is a valid event, don't passthrough
if self.performKeybind(event: event) {
return nil
// Special events such as the emoji key
if self.specialEvents.contains(event.keyCode.baseKey) {
if self.canPassthroughSpecialEvents {
return Unmanaged.passUnretained(cgEvent)
}
return nil
}

// If this wasn't, check if it was a system keybind (ex. screenshot), and
// in that case, passthrough and foce-close Loop
if CGKeyCode.systemKeybinds.contains(self.pressedKeys) {
Notification.Name.forceCloseLoop.post()
print("Detected system keybind, closing!")
return Unmanaged.passRetained(cgEvent)
}
// If this is a valid event, don't passthrough
if self.performKeybind(event: event) {
return nil
}

return Unmanaged.passRetained(cgEvent)
// If this wasn't, check if it was a system keybind (ex. screenshot), and
// in that case, passthrough and foce-close Loop
if CGKeyCode.systemKeybinds.contains(self.pressedKeys) {
Notification.Name.forceCloseLoop.post()
print("Detected system keybind, closing!")
return Unmanaged.passUnretained(cgEvent)
}

return Unmanaged.passUnretained(cgEvent)
}

self.flagsEventMonitor = CGEventMonitor(eventMask: .flagsChanged) { cgEvent in
Expand All @@ -75,7 +79,7 @@ class KeybindMonitor {

self.performKeybind(event: event)
}
return Unmanaged.passRetained(cgEvent)
return Unmanaged.passUnretained(cgEvent)
}

self.eventMonitor!.start()
Expand All @@ -86,11 +90,6 @@ class KeybindMonitor {
self.resetPressedKeys()
self.canPassthroughSpecialEvents = true

guard self.eventMonitor != nil &&
self.flagsEventMonitor != nil else {
return
}

self.eventMonitor?.stop()
self.eventMonitor = nil

Expand All @@ -100,17 +99,16 @@ class KeybindMonitor {

@discardableResult
private func performKeybind(event: NSEvent) -> Bool {
// If the current key up event is within 100 ms of the last key up event, return.
// This is used when the user is pressing 2+ keys so that it doesn't switch back
// to the one key direction when they're letting go of the keys.
if event.type == .keyUp ||
(event.type == .flagsChanged &&
!event.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.shift)) {
if (abs(lastKeyReleaseTime.timeIntervalSinceNow)) > 0.1 {
if event.type == .keyUp {
// If the current key up event is within 100 ms of the last key up event, return.
// This is used when the user is pressing 2+ keys so that it doesn't switch back
// to the one key direction when they're letting go of the keys.
if abs(lastKeyReleaseTime.timeIntervalSinceNow) < 0.1 {
print("performKeybind: returning true due to key release")
return true
}
lastKeyReleaseTime = Date.now
return false
}

if pressedKeys.contains(.kVK_Escape) {
Expand Down
Loading

0 comments on commit 58235ac

Please sign in to comment.