1

I am trying to post a command + mouse drag event to a specific window.

  • Create an NSEvent
  • Post the underline cgevent

It does not work whether with postToPid or post. What I want to achieve is that: there are maybe multiple window at the same position, I just want to drag the window that I care about to a new position.


let windowNumber = 20 // should be a specific window number
let position = CGPoint(x: 10, y: 10)
let newLoc = CGPoint(x: 20, y:20)
let downNSEvent = NSEvent.mouseEvent(
    with: .leftMouseDown,
    location: position,
    modifierFlags: .command,
    timestamp: TimeInterval(),
    windowNumber: Int(windowNumber),
    context: nil, eventNumber: 0, clickCount: 1, pressure: 1.0
)
let downEvent = downNSEvent?.cgEvent
let flags = CGEventFlags.maskCommand
let eventSource = CGEventSource(event: downEvent)
downEvent?.flags = flags
downEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointer, value: windowNumber)
downEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointerThatCanHandleThisEvent, value: windowNumber)
downEvent?.post(tap: .cghidEventTap)
//        downEvent?.postToPid(sourcePid!)

usleep(500_000)

// drag event
var newLoc: CGPoint = CGPoint(x: position.x, y: position.y)
if left {
    newLoc.x = destinationBounds.minX - 10
} else {
    print("To right")
    newLoc.x = destinationBounds.maxX + 10
}

print("Move to position: \(newLoc)")

let dragNSEvent = NSEvent.mouseEvent(
    with: .leftMouseDragged,
    location: newLoc,
    modifierFlags: .command,
    timestamp: TimeInterval(),
    windowNumber: Int(windowNumber),
    context: nil, eventNumber: 1, clickCount: 1, pressure: 1.0
)
let dragEvent = dragNSEvent?.cgEvent

dragEvent?.flags = flags
dragEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointer, value: windowNumber)
dragEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointerThatCanHandleThisEvent, value: windowNumber)
dragEvent?.post(tap: .cghidEventTap)
//        dragEvent?.postToPid(sourcePid!)
guard dragEvent != nil else {return}

usleep(500_000)

let upNSEvent = NSEvent.mouseEvent(
    with: .leftMouseUp,
    location: newLoc,
    modifierFlags: .command,
    timestamp: TimeInterval(),
    windowNumber: Int(windowNumber),
    context: nil, eventNumber: 2, clickCount: 1, pressure: 1.0
)

let upEvent = upNSEvent?.cgEvent

upEvent?.flags = flags
upEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointer, value: windowNumber)
upEvent?.setIntegerValueField(.mouseEventWindowUnderMousePointerThatCanHandleThisEvent, value: windowNumber)
upEvent?.post(tap: .cghidEventTap)
//        upEvent?.postToPid(sourcePid!)

I have searched the web and so, found no available solutions.

chunyang.wen
  • 204
  • 1
  • 9
  • How about activating the window first? Do you want to move a window or is a drag event required? – Willeke Feb 20 '23 at 16:34
  • Actually it is an icon on the menubar. I want to use command + drag to move it around. I try to activate it first, for it seems not working. – chunyang.wen Feb 20 '23 at 22:14
  • Is a status item? Do you have multiple icons at the same position? – Willeke Feb 21 '23 at 06:52
  • What I want to do is that: When we open an app, it will have its menu. It may hide certain status item icon. I want to trigger some mouse event to drag target item to other places to make it visible. – chunyang.wen Feb 21 '23 at 07:22
  • I can use `CGWindowListCopyWindowInfo` to get all window info(its rect, place etc). But if they are under the menu of others, mouse event cannot be triggered on the status item. – chunyang.wen Feb 21 '23 at 07:24
  • Is the window onscreen? I don't think you can send an event to a window. – Willeke Feb 21 '23 at 09:04
  • Yes. The key point. The window is not on screen. Do you have any idea how to handle those windows that are not on screen? The kCGWindowIsOnscreen value is nil. And after lots of trials, postToPid can be used only with keyboard events; post can be used with keyboard and mouse events. – chunyang.wen Feb 27 '23 at 23:57

0 Answers0