2

I'm working on an app which encoding input characters into another language (Vietnamese) and I've facing with some issue of Apple documentation.

My code to listen for keyboard events is:

func cgEventCallback (
    proxy: CGEventTapProxy,
    type: CGEventType,
    event: CGEvent,
    refcon: UnsafeMutableRawPointer?
) -> Unmanaged<CGEvent>? {
    switch type {
    case .keyDown:
        print(event.flags, CGEventFlags.maskCommand)

        if (event.flags == CGEventFlags.maskCommand) {
            print("Flag is Command")
        } else {
            print("Flag is not Command")
        }

    default:
        break
    }

    return Unmanaged.passRetained(event)
}

As they said, CGEvent's flags returns the event flags of a Quartz event. So I expect that when I type in Command + C then it should print out:

CGEventFlags(rawValue: 1048576) CGEventFlags(rawValue: 1048576)
Flag is Command

But the issue is that the printed out text is not the same as expected:

CGEventFlags(rawValue: 1048840) CGEventFlags(rawValue: 1048576)
Flag is not Command

Am I misunderstanding about something or is there any way which could help me know what is the current flag of the event?

Toan Quoc Ho
  • 3,266
  • 1
  • 14
  • 22

1 Answers1

1

event.flags is an OptionSet representing all flags for the current event. There can be more than one flag set, and that is what is happening in your case:

event.flags  = 1048840 (decimal) = 100108 (hex)
.maskCommand = 1048576 (decimal) = 100000 (hex)

So the correct test is

if event.flags.contains(.maskCommand) { ... }

instead of testing for equality.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks for your answer @Martin R, I just have a small concern about this is that if I want to know the flags is currently in another OptionSet, e.g: [.maskCommand, .maskControl], to know that user is entering Control key or Command key? – Toan Quoc Ho Jan 24 '21 at 13:40
  • @ToanQuocHo: You can do `event.flags.isSuperset(of: [.maskCommand, .maskControl])` to test if the event flags contain any of the given flags. Is that what you are looking for? – Martin R Jan 24 '21 at 13:49
  • Yeah, I think something like that @Martin R, but something included inside flags which I don't know what it is. When I enter `Command` + `C` I hope that `event.flags.isSuperset(of: [.maskCommand, .maskControl])` to be true, but it's not. – Toan Quoc Ho Jan 24 '21 at 13:54
  • Flags = 256(not sure what it is, default maybe?) + 8(`C` character) + 1048576(.maskCommand) = 1048840. That's interesting, I thought that flags is simply just the .maskCommand but it combined all the characters already. – Toan Quoc Ho Jan 24 '21 at 14:24
  • Nevermind @MartinR, I've changed the approach to use Set of CGEventFlags and then use contains method to check it already. Thank you so much for your answer. – Toan Quoc Ho Jan 24 '21 at 14:45
  • @ToanQuocHo https://stackoverflow.com/a/41929189/2303865 and https://stackoverflow.com/a/32447474/2303865 – Leo Dabus Jan 24 '21 at 14:54
  • Thanks @LeoDabus, sadly that I'm using CGEvent and seems like it's a bit different than NSEvent. – Toan Quoc Ho Jan 24 '21 at 15:00
  • 1
    @ToanQuocHo I never said to use it as it is. Just a reference on how to switch an OptionSet. – Leo Dabus Jan 24 '21 at 15:06
  • 1
    Got that @LeoDabus, I've tried with isDisjoint and it works in my case. It was inspired by your comment though, thank you so much :D – Toan Quoc Ho Jan 24 '21 at 15:17