Safe to set CGEvent user data field?

115 views Asked by At

The CGEvent type allows setting integer values for a specified list CGEventFields, one of which is the eventSourceUserData field. Is it safe to set this field to any value as determined by the program sending the event?

Background / Use Case

A CGEventTap is setup and running on a CFRunLoop. On receiving an event, we might want to send multiple events rather than modifying the current event. For example, on receiving a keydown 'a' event, send 2x of keydown 'b' and keyup 'b' events so the output is 'abb'.

However, we don't want the events for 'b' to flow back through the CGEventTap. If they did, and we had another rule for sending 2x 'c' events on receiving a 'b' event then the output would be 'abccbcc' which is not what we want.

For the 'b' events being sent, we can set the eventSourceUserData field to some magic number. Then, when an event is received by the CGEventTap we can check the user data, and nullify the event if it contains the magic number.

Here's the pseudocode.

tap = CGEventTap(..., function(event) {
  if (event.eventSourceUserData == MAGIC) {
    event.setType(NULL)
    return
  }
  
  if (event.getType() == KEYDOWN && event.getKeycode() == 'a') {
    eventBDown = createEvent(KEYDOWN, 'b').withEventSourceUserData(MAGIC)
    eventBUp = createEvent(KEYUP, 'b').withEventSourceUserData(MAGIC)
    
    loop twice {
      eventBDown.post()
      eventBUp.post()
    }
  }
})

CFRunLoop.runWithTap(tap)
1

There are 1 answers

0
JWWalker On

In a similar situation, I’ve used the keyboard type event field to mark events that I created. I am not sure that’s safer than what you are doing.