keyboardGetUnicodeString returns carrier return

See the following code. Everytime i press a key together with the control key, keyboardGetUnicodeString will return '\r' only... How can i make the keyboardGetUnicodeString return the correct String?

import Foundation

func eventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, context: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
  var length = 0
  event.keyboardGetUnicodeString(maxStringLength: 0, actualStringLength: &length, unicodeString: nil)
  var chars = [UniChar](repeating: 0, count: length)
   
  event.keyboardGetUnicodeString(maxStringLength: chars.count, actualStringLength: &length, unicodeString: &chars)
  print("key: \(String(utf16CodeUnits: chars, count: length).uppercased())")
   
  return Unmanaged.passRetained(event)
}

let runLoop = CFRunLoopGetCurrent()
let eventMask = CGEventMask(1 << CGEventType.keyDown.rawValue)
let eventTap = CGEvent.tapCreate(tap: .cgSessionEventTap, place: .headInsertEventTap, options: .listenOnly, eventsOfInterest: eventMask, callback: eventCallback, userInfo: nil)

let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
CFRunLoopAddSource(runLoop, runLoopSource, .commonModes)
CGEvent.tapEnable(tap: eventTap!, enable: true)
CFRunLoopRun()

keyboardGetUnicodeString will return '\r' only... 

As far as I tried, I could not find the behavior that return '\r' only. How did you checked it? Your code is not capable of showing control characters.

Please try changing print to debugPrint and tell us what you see.

Okay i was able to fix my problem. The problem was not shown in the code of the original post. As the comment of OOPer correctly stated, the output '\r' was actually to be expected (when CTRL + M is pressed). My goal was to print the key without modifier keys. The code for this would be (create new event where i'd expect that the modifiers are NOT beeing printed):

 let keycode = CGKeyCode(event.getIntegerValueField(.keyboardEventKeycode))
 let keycodeEvent = CGEvent.init(keyboardEventSource: nil, virtualKey: keycode, keyDown: true)
var length = 0
  keycodeEvent!.keyboardGetUnicodeString(maxStringLength: 0, actualStringLength: &length, unicodeString: nil)
  var chars = [UniChar](repeating: 0, count: length)
   
  keycodeEvent!.keyboardGetUnicodeString(maxStringLength: chars.count, actualStringLength: &length, unicodeString: &chars)
   
  debugPrint("keycode \(keycode) -> \(String(utf16CodeUnits: chars, count: length).uppercased())")

However the problem is that this would still print '\r' ... the solution is as follows: Replace line 2 with:

let keycodeEvent = CGEvent.init(keyboardEventSource: .init(stateID: .privateState), virtualKey: keycode, keyDown: true)

Without .privateState, the modifier states seem to be carried over...

keyboardGetUnicodeString returns carrier return
 
 
Q