Skip to content

Commit a93b816

Browse files
committed
(#18) Fixed error in moveWindow on macOS caused by not passing a CGPoint, updated window tests
1 parent 08edf8b commit a93b816

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

src/macos/window_manager.mm

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "../window_manager.h"
22
#import <AppKit/AppKit.h>
3+
#import <AppKit/NSAccessibility.h>
34
#import <ApplicationServices/ApplicationServices.h>
45
#import <CoreGraphics/CGWindow.h>
56
#import <Foundation/Foundation.h>
@@ -27,6 +28,44 @@
2728
return nullptr;
2829
}
2930

31+
AXUIElementRef getWindowByHandle(const WindowHandle windowHandle, pid_t *outPid) {
32+
// Collect list of on-screen windows
33+
CGWindowListOption listOptions =
34+
kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements;
35+
CFArrayRef windowList =
36+
CGWindowListCopyWindowInfo(listOptions, kCGNullWindowID);
37+
38+
AXUIElementRef targetWindow = nullptr;
39+
// Look for matching window
40+
for (NSDictionary *info in (NSArray *) windowList) {
41+
NSNumber *windowNumber = info[(id) kCGWindowNumber];
42+
if ([windowNumber intValue] == windowHandle) {
43+
*outPid = [info[(id) kCGWindowOwnerPID] intValue];
44+
AXUIElementRef app = AXUIElementCreateApplication(*outPid);
45+
46+
CFArrayRef windowArray;
47+
AXError error = AXUIElementCopyAttributeValue(app, kAXWindowsAttribute, (CFTypeRef *) &windowArray);
48+
if (error == kAXErrorSuccess) {
49+
CFIndex count = CFArrayGetCount(windowArray);
50+
for (CFIndex i = 0; i < count; i++) {
51+
auto window = static_cast<AXUIElementRef>(CFArrayGetValueAtIndex(windowArray, i));
52+
// Your logic here to match the window with the handle
53+
// Set targetWindow = window if it matches
54+
}
55+
CFRelease(windowArray);
56+
}
57+
CFRelease(app);
58+
break;
59+
}
60+
}
61+
62+
if (windowList) {
63+
CFRelease(windowList);
64+
}
65+
66+
return targetWindow;
67+
}
68+
3069
WindowHandle getActiveWindow() {
3170
CGWindowListOption listOptions =
3271
kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements;
@@ -278,8 +317,9 @@ bool moveWindow(const WindowHandle windowHandle, const MMPoint newOrigin) {
278317
if (error == kAXErrorSuccess) {
279318

280319
// Create AXValue objects for position and size
320+
CGPoint point = CGPointMake(newOrigin.x, newOrigin.y);
281321
AXValueRef positionValue = AXValueCreate((AXValueType) kAXValueCGPointType,
282-
(const void *) &newOrigin);
322+
(const void *) &point);
283323

284324
// Set new position and size
285325
AXUIElementSetAttributeValue(window, kAXPositionAttribute, positionValue);

test/window-integration-tests/test.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,8 @@ describe("getActiveWindow", () => {
6969
// WHEN
7070
const activeWindowHandle = libnut.getActiveWindow();
7171
libnut.moveWindow(activeWindowHandle, {x: xPosition, y: yPosition});
72-
await sleep(10000);
72+
await sleep(100);
7373
const activeWindowRect = libnut.getWindowRect(activeWindowHandle);
74-
console.log(activeWindowRect);
7574

7675
// THEN
7776
expect(activeWindowRect.x).toBe(xPosition);
@@ -86,9 +85,8 @@ describe("getActiveWindow", () => {
8685
// WHEN
8786
const activeWindowHandle = libnut.getActiveWindow();
8887
libnut.resizeWindow(activeWindowHandle, {width: newWidth, height: newHeight});
89-
await sleep(1000);
88+
await sleep(100);
9089
const activeWindowRect = libnut.getWindowRect(activeWindowHandle);
91-
console.log(activeWindowRect);
9290

9391
// THEN
9492
expect(activeWindowRect.width).toBe(newWidth);

0 commit comments

Comments
 (0)