Strange behavior when publishing CGEvent on PSN

EDIT - Don't get a lot of input into this, so it's skinny here. I am sending keyboard events to PSN. Then I will switch to another window, posting a few more events (this time tat session level) and return to the first window. When I go to PSN again, nothing happens. Until I move the mouse wheel or scroll wheel. Why is this and how can I get around this (if not corrected)?

ORIGINAL - If I set up a loop that places some keyboard events on the PSN, I find that it works fine, except when it was first run. The event seems to be published when I do something with the mouse manually - even moving it slightly. Here are the details if they help.

The external application has a window for list of text strings, which I read by sending copy commands (and checking cardboard). Unfortunately, this is the only way to get this text.

Sometimes an application distracts focus from a list that I can detect. When this happens, the most reliable way to get the focus back is to send a mouse event to click on the text box directly above the list, and then send the tab event to shift the focus to the list.

So, when you start the loop works fine, scrolling through the list and copying the text. When the focus is shifted, its detection is beautiful, and events are sent to move the focus back to the list. But nothing happens. The loop continues to detect that the focus has changed, but events only work after moving the mouse. Or just use the scroll wheel. It’s strange.

As soon as this happened for the first time, it works fine - every time the focus moves, PSN events change it, without me doing nothing.

Here the code that works in the loop is checked as working:

//copy to pasteboard - CMD-V e3 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, true); CGEventSetFlags(e3, kCGEventFlagMaskCommand); CGEventPostToPSN(&psn, e3); CFRelease(e3); e4 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, false); CGEventPostToPSN(&psn, e4); CFRelease(e4); //move cursor down e1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)125, true); CGEventPostToPSN(&psn, e1); CFRelease(e1); e2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)125, false); CGEventPostToPSN(&psn, e2); CFRelease(e2); 

And here, where I switch focus, I also work (except when necessary):

  //click in text input box - point is derived earlier e6 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, 0); CGEventPostToPSN(&psn, e6); CFRelease(e6); e7 = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, point, 0); CGEventPostToPSN(&psn, e7); CFRelease(e7); //press tab key to move to chat log table CGEventRef e = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)48, true); //CGEventPost(kCGSessionEventTap, e); CGEventPostToPSN(&psn, e); CFRelease(e); CGEventRef e11 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)48, false); CGEventPostToPSN(&psn, e11); CFRelease(e11); 
+4
source share
2 answers

Hey, I know that this is not what you want to hear, but applescript works much better for this kind of thing - reading text fields by publishing copy commands, setting focus by sending click events to neighboring elements, and then sending tab events is really isn't the best way to do this.

The problem with simulating events is that generating them is not the whole story. They become only “events” if the target application interprets them correctly. Did you know that the target application is a cocoa application?

For example, in your second bit of code, you create 4 events. The target application needs to start an event loop with which you do not have much control and check for events in the queue. If this were done, he would have detected a simultaneous mouse, mouse, key, up key. You want him to interpret these simultaneous events as a mouse click and then a key press, but who will say that?

You may be able to get this to work by adding a combination of queue queues to the mix, getting the target application by running runloop , throw some pauses between the simulated events and messing around with timestamps - but it probably won't be that reliable.

In Applescript, you can get the text of row 3 of a table in another application

 tell application "System Events" tell process targetAppName set frontmost to true tell window named windowTitle tell table 1 set value of attribute "AXFocused" to true set txtField to first text field of row 3 return value of txtField end tell end tell end tell end tell 

In a cocoa application, you can execute String as Applescript, you can call functions in different scripts, pass variables, return values, etc.

+2
source

Instead of creating an event with a null CGEventSourceRef, try creating an input source like this:

 CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); 

Based on this mailing list message , this seems to be the secret to success in posting events with CGEventCreateXXXEvent. A Google search shows that many developers have problems with this, but this is the only successful post I found and the correct CGEventSourceRef (instead of NULL) seems to be one of the differences in this example from all the others. we found. He solved my problems with publishing keyboard events.

+1
source

Source: https://habr.com/ru/post/1309648/


All Articles