From 50f8df44b3762e10a3feb351a45a44e24a45f348 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:03:52 -0400 Subject: [PATCH 01/13] update key code style --- key/keycode_c.h | 108 +++++++++++++++++++++++------------------------ key/keypress_c.h | 24 ++++------- 2 files changed, 62 insertions(+), 70 deletions(-) diff --git a/key/keycode_c.h b/key/keycode_c.h index 13be2a9..75f7c73 100644 --- a/key/keycode_c.h +++ b/key/keycode_c.h @@ -62,74 +62,74 @@ struct XSpecialCharacterMapping XSpecialCharacterTable[] = { #endif -MMKeyCode keyCodeForChar(const char c) -{ -#if defined(IS_MACOSX) - /* OS X does not appear to have a built-in function for this, so instead we - * have to write our own. */ - static CFMutableDictionaryRef charToCodeDict = NULL; - CGKeyCode code; - UniChar character = c; - CFStringRef charStr = NULL; +MMKeyCode keyCodeForChar(const char c){ + #if defined(IS_MACOSX) + /* OS X does not appear to have a built-in function for this, so instead we + * have to write our own. */ + static CFMutableDictionaryRef charToCodeDict = NULL; + CGKeyCode code; + UniChar character = c; + CFStringRef charStr = NULL; - /* Generate table of keycodes and characters. */ - if (charToCodeDict == NULL) { - size_t i; - charToCodeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, - 128, - &kCFCopyStringDictionaryKeyCallBacks, - NULL); - if (charToCodeDict == NULL) return UINT16_MAX; + /* Generate table of keycodes and characters. */ + if (charToCodeDict == NULL) { + size_t i; + charToCodeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, + 128, + &kCFCopyStringDictionaryKeyCallBacks, + NULL); + if (charToCodeDict == NULL) return UINT16_MAX; - /* Loop through every keycode (0 - 127) to find its current mapping. */ - for (i = 0; i < 128; ++i) { - CFStringRef string = createStringForKey((CGKeyCode)i); - if (string != NULL) { - CFDictionaryAddValue(charToCodeDict, string, (const void *)i); - CFRelease(string); + /* Loop through every keycode (0 - 127) to find its current mapping. */ + for (i = 0; i < 128; ++i) { + CFStringRef string = createStringForKey((CGKeyCode)i); + if (string != NULL) { + CFDictionaryAddValue(charToCodeDict, string, (const void *)i); + CFRelease(string); + } } } - } - charStr = CFStringCreateWithCharacters(kCFAllocatorDefault, &character, 1); + charStr = CFStringCreateWithCharacters(kCFAllocatorDefault, &character, 1); - /* Our values may be NULL (0), so we need to use this function. */ - if (!CFDictionaryGetValueIfPresent(charToCodeDict, charStr, - (const void **)&code)) { - code = UINT16_MAX; /* Error */ - } + /* Our values may be NULL (0), so we need to use this function. */ + if (!CFDictionaryGetValueIfPresent(charToCodeDict, charStr, + (const void **)&code)) { + code = UINT16_MAX; /* Error */ + } - CFRelease(charStr); - return (MMKeyCode)code; -#elif defined(IS_WINDOWS) - return VkKeyScan(c); -#elif defined(USE_X11) - MMKeyCode code; + CFRelease(charStr); + return (MMKeyCode)code; + #elif defined(IS_WINDOWS) + return VkKeyScan(c); + #elif defined(USE_X11) + MMKeyCode code; - char buf[2]; - buf[0] = c; - buf[1] = '\0'; + char buf[2]; + buf[0] = c; + buf[1] = '\0'; - code = XStringToKeysym(buf); - if (code == NoSymbol) { - /* Some special keys are apparently not handled properly by - * XStringToKeysym() on some systems, so search for them instead in our - * mapping table. */ - size_t i; - const size_t specialCharacterCount = - sizeof(XSpecialCharacterTable) / sizeof(XSpecialCharacterTable[0]); - for (i = 0; i < specialCharacterCount; ++i) { - if (c == XSpecialCharacterTable[i].name) { - code = XSpecialCharacterTable[i].code; - break; + code = XStringToKeysym(buf); + if (code == NoSymbol) { + /* Some special keys are apparently not handled properly by + * XStringToKeysym() on some systems, so search for them instead in our + * mapping table. */ + size_t i; + const size_t specialCharacterCount = + sizeof(XSpecialCharacterTable) / sizeof(XSpecialCharacterTable[0]); + for (i = 0; i < specialCharacterCount; ++i) { + if (c == XSpecialCharacterTable[i].name) { + code = XSpecialCharacterTable[i].code; + break; + } } } - } - return code; -#endif + return code; + #endif } + #if defined(IS_MACOSX) CFStringRef createStringForKey(CGKeyCode keyCode){ diff --git a/key/keypress_c.h b/key/keypress_c.h index d44e7da..0a62afc 100644 --- a/key/keypress_c.h +++ b/key/keypress_c.h @@ -29,8 +29,7 @@ #endif #if defined(IS_MACOSX) -static io_connect_t _getAuxiliaryKeyDriver(void) -{ +static io_connect_t _getAuxiliaryKeyDriver(void){ static mach_port_t sEventDrvrRef = 0; mach_port_t masterPort, service, iter; kern_return_t kr; @@ -52,13 +51,11 @@ static io_connect_t _getAuxiliaryKeyDriver(void) #endif #if defined(IS_WINDOWS) -void win32KeyEvent(int key, MMKeyFlags flags) -{ +void win32KeyEvent(int key, MMKeyFlags flags){ int scan = MapVirtualKey(key & 0xff, MAPVK_VK_TO_VSC); /* Set the scan code for extended keys */ - switch (key) - { + switch (key){ case VK_RCONTROL: case VK_SNAPSHOT: /* Print Screen */ case VK_RMENU: /* Right Alt / Alt Gr */ @@ -106,8 +103,7 @@ void win32KeyEvent(int key, MMKeyFlags flags) } #endif -void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags) -{ +void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags){ #if defined(IS_MACOSX) /* The media keys all have 1000 added to them to help us detect them. */ if (code >= 1000) { @@ -156,14 +152,12 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags) #endif } -void tapKeyCode(MMKeyCode code, MMKeyFlags flags) -{ +void tapKeyCode(MMKeyCode code, MMKeyFlags flags){ toggleKeyCode(code, true, flags); toggleKeyCode(code, false, flags); } -void toggleKey(char c, const bool down, MMKeyFlags flags) -{ +void toggleKey(char c, const bool down, MMKeyFlags flags){ MMKeyCode keyCode = keyCodeForChar(c); //Prevent unused variable warning for Mac and Linux. @@ -185,15 +179,13 @@ void toggleKey(char c, const bool down, MMKeyFlags flags) toggleKeyCode(keyCode, down, flags); } -void tapKey(char c, MMKeyFlags flags) -{ +void tapKey(char c, MMKeyFlags flags){ toggleKey(c, true, flags); toggleKey(c, false, flags); } #if defined(IS_MACOSX) -void toggleUnicode(UniChar ch, const bool down) -{ +void toggleUnicode(UniChar ch, const bool down){ /* This function relies on the convenient * CGEventKeyboardSetUnicodeString(), which allows us to not have to * convert characters to a keycode, but does not support adding modifier From 75ace53123e1947279d9fc281c49d5c8ee4fcfb9 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:05:20 -0400 Subject: [PATCH 02/13] update robotgo unix export getXidFromPid --- robotgo_unix.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/robotgo_unix.go b/robotgo_unix.go index 60fd26f..a762446 100644 --- a/robotgo_unix.go +++ b/robotgo_unix.go @@ -43,9 +43,9 @@ func ActivePIDC(pid int32, args ...int) { } } - xid, err := getXidFromPid(xu, pid) + xid, err := GetXidFromPid(xu, pid) if err != nil { - log.Println("getXidFromPid errors is: ", err) + log.Println("GetXidFromPid errors is: ", err) return } @@ -73,7 +73,7 @@ func ActivePID(pid int32, args ...int) error { return nil } - xid, err := getXidFromPid(xu, pid) + xid, err := GetXidFromPid(xu, pid) if err != nil { return err } @@ -86,7 +86,8 @@ func ActivePID(pid int32, args ...int) error { return nil } -func getXidFromPid(xu *xgbutil.XUtil, pid int32) (xproto.Window, error) { +// GetXidFromPid get the xide from pid +func GetXidFromPid(xu *xgbutil.XUtil, pid int32) (xproto.Window, error) { windows, err := ewmh.ClientListGet(xu) if err != nil { return 0, err From c91af647e4a61221d4c869543287ad4a73b88718 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:09:20 -0400 Subject: [PATCH 03/13] add getBounds to win_sys.h [ci skip] --- window/win_sys.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 window/win_sys.h diff --git a/window/win_sys.h b/window/win_sys.h new file mode 100644 index 0000000..637ce58 --- /dev/null +++ b/window/win_sys.h @@ -0,0 +1,88 @@ +// #include "../base/os.h" + +struct _Bounds{ + int32 X; // Top left X coordinate + int32 Y; // Top left Y coordinate + int32 W; // Total bounds width + int32 H; // Total bounds height +}; + +typedef struct _Bounds Bounds; + +Bounds get_bounds(uintptr pid, uintptr isHwnd){ + // Check if the window is valid + Bounds bounds; + if (!IsValid()) { return bounds; } + + #if defined(IS_MACOSX) + + // Bounds bounds; + AXValueRef axp = NULL; + AXValueRef axs = NULL; + AXUIElementRef AxID = AXUIElementCreateApplication(pid); + + // Determine the current point of the window + if (AXUIElementCopyAttributeValue(AxID, + kAXPositionAttribute, (CFTypeRef*) &axp) + != kAXErrorSuccess || axp == NULL){ + goto exit; + } + + // Determine the current size of the window + if (AXUIElementCopyAttributeValue(AxID, + kAXSizeAttribute, (CFTypeRef*) &axs) + != kAXErrorSuccess || axs == NULL){ + goto exit; + } + + CGPoint p; CGSize s; + // Attempt to convert both values into atomic types + if (AXValueGetValue(axp, kAXValueCGPointType, &p) && + AXValueGetValue(axs, kAXValueCGSizeType, &s)){ + bounds.X = p.x; + bounds.Y = p.y; + bounds.W = s.width; + bounds.H = s.height; + } + + exit: + if (axp != NULL) { CFRelease(axp); } + if (axs != NULL) { CFRelease(axs); } + + return bounds; + + #elif defined(USE_X11) + + // Ignore X errors + XDismissErrors(); + + Bounds client = GetClient(); + Bounds frame = GetFrame((Window)pid); + + bounds.X = client.X - frame.X; + bounds.Y = client.Y - frame.Y; + bounds.W = client.W + frame.W; + bounds.H = client.H + frame.H; + + return bounds; + + #elif defined(IS_WINDOWS) + HWND hwnd; + if (isHwnd == 0) { + hwnd= GetHwndByPId(pid); + } else { + hwnd = (HWND)pid; + } + + RECT rect = { 0 }; + GetWindowRect(hwnd, &rect); + + bounds.X = rect.left; + bounds.Y = rect.top; + bounds.W = rect.right - rect.left; + bounds.H = rect.bottom - rect.top; + + return bounds; + + #endif +} \ No newline at end of file From 56bc179c39877fae4644ccfab8dce878ee6584f9 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:10:54 -0400 Subject: [PATCH 04/13] add getFrame to pub.h [ci skip] --- window/goWindow.h | 1 + window/pub.h | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/window/goWindow.h b/window/goWindow.h index 5c0d135..c70795b 100644 --- a/window/goWindow.h +++ b/window/goWindow.h @@ -11,6 +11,7 @@ #include "alert_c.h" #include "window.h" #include "win32.h" +#include "win_sys.h" int show_alert(const char *title, const char *msg, const char *defaultButton, const char *cancelButton){ diff --git a/window/pub.h b/window/pub.h index f3a2c0d..47689bf 100644 --- a/window/pub.h +++ b/window/pub.h @@ -255,6 +255,30 @@ MData mData; } } + static Bounds GetFrame(MData win){ + Bounds frame; + // Retrieve frame bounds + if (WM_EXTENTS != None) { + long* result; uint32 nItems = 0; + // Get the window extents property + result = (long*) GetWindowProperty(win, WM_EXTENTS, &nItems); + + // Verify the results + if (result != NULL) { + if (nItems == 4) { + frame.X = (int32) result[0]; + frame.Y = (int32) result[2] + frame.W = (int32) result[0] + (int32) result[1]; + frame.H = (int32) result[2] + (int32) result[3]; + } + + XFree(result); + } + } + + return frame; + } + #elif defined(IS_WINDOWS) // From 751af33b71e1fc104ec449154d0a1f98b72580a4 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:17:16 -0400 Subject: [PATCH 05/13] add Bounds to pub.h [ci skip] --- window/pub.h | 9 +++++++++ window/win_sys.h | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/window/pub.h b/window/pub.h index 47689bf..5688eb2 100644 --- a/window/pub.h +++ b/window/pub.h @@ -26,6 +26,15 @@ typedef struct _MData MData; MData mData; +struct _Bounds{ + int32 X; // Top left X coordinate + int32 Y; // Top left Y coordinate + int32 W; // Total bounds width + int32 H; // Total bounds height +}; + +typedef struct _Bounds Bounds; + #if defined(IS_MACOSX) static Boolean(*gAXIsProcessTrustedWithOptions) (CFDictionaryRef); diff --git a/window/win_sys.h b/window/win_sys.h index 637ce58..b11eb10 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -1,14 +1,5 @@ // #include "../base/os.h" -struct _Bounds{ - int32 X; // Top left X coordinate - int32 Y; // Top left Y coordinate - int32 W; // Total bounds width - int32 H; // Total bounds height -}; - -typedef struct _Bounds Bounds; - Bounds get_bounds(uintptr pid, uintptr isHwnd){ // Check if the window is valid Bounds bounds; From fd7080b0eaab5e2681780826039c01f8d730b663 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:24:17 -0400 Subject: [PATCH 06/13] add get client C_func and fix getFrame args --- window/win_sys.h | 82 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/window/win_sys.h b/window/win_sys.h index b11eb10..81889a7 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -46,9 +46,11 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){ // Ignore X errors XDismissErrors(); + MData win; + win.XWin = (Window)pid; Bounds client = GetClient(); - Bounds frame = GetFrame((Window)pid); + Bounds frame = GetFrame(win); bounds.X = client.X - frame.X; bounds.Y = client.Y - frame.Y; @@ -76,4 +78,82 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){ return bounds; #endif +} + +Bounds get_client(uintptr pid, uintptr isHwnd){ + // Check if the window is valid + Bounds bounds; + if (!IsValid()) { return bounds; } + + #if defined(IS_MACOSX) + + return GetBounds(pid, isHwnd); + + #elif defined(USE_X11) + + // Ignore X errors + XDismissErrors(); + MData win; + win.XWin = (Window)pid; + + // Property variables + MData root, parent; + MData* children; + unsigned int count; + int32 x = 0, y = 0; + + // Check if the window is the root + XQueryTree(rDisplay, win, + &root, &parent, &children, &count); + if (children) { XFree(children); } + + // Retrieve window attributes + XWindowAttributes attr = { 0 }; + XGetWindowAttributes(rDisplay, win, &attr); + + // Coordinates must be translated + if (parent != attr.root){ + XTranslateCoordinates(rDisplay, win, attr.root, attr.x, + attr.y, &x, &y, &parent); + } + // Coordinates can be left alone + else { + x = attr.x; + y = attr.y; + } + + // Return resulting window bounds + bounds.X = x; + bounds.Y = y; + bounds.W = attr.width; + bounds.H = attr.height; + return bounds; + + #elif defined(IS_WINDOWS) + HWND hwnd; + if (isHwnd == 0) { + hwnd= GetHwndByPId(pid); + } else { + hwnd = (HWND)pid; + } + + + RECT rect = { 0 }; + GetClientRect(hwnd, &rect); + + POINT point; + point.x = rect.left; + point.y = rect.top; + + // Convert the client point to screen + ClientToScreen(hwnd, &point); + + bounds.X = point.x; + bounds.Y = point.y; + bounds.W = rect.right - rect.left; + bounds.H = rect.bottom - rect.top; + + return bounds; + + #endif } \ No newline at end of file From fa1051211bdaf7253c38740ee4aba6a087ffac60 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 08:53:49 -0400 Subject: [PATCH 07/13] Fixed error and update code style --- window/pub.h | 2 +- window/win_sys.h | 10 ++++++---- window/window.h | 18 +++++++++--------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/window/pub.h b/window/pub.h index 5688eb2..2cf99d2 100644 --- a/window/pub.h +++ b/window/pub.h @@ -276,7 +276,7 @@ typedef struct _Bounds Bounds; if (result != NULL) { if (nItems == 4) { frame.X = (int32) result[0]; - frame.Y = (int32) result[2] + frame.Y = (int32) result[2]; frame.W = (int32) result[0] + (int32) result[1]; frame.H = (int32) result[2] + (int32) result[3]; } diff --git a/window/win_sys.h b/window/win_sys.h index 81889a7..177c9f5 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -49,7 +49,7 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){ MData win; win.XWin = (Window)pid; - Bounds client = GetClient(); + Bounds client = get_client(pid, isHwnd); Bounds frame = GetFrame(win); bounds.X = client.X - frame.X; @@ -91,6 +91,8 @@ Bounds get_client(uintptr pid, uintptr isHwnd){ #elif defined(USE_X11) + Display *rDisplay = XOpenDisplay(NULL); + // Ignore X errors XDismissErrors(); MData win; @@ -103,17 +105,17 @@ Bounds get_client(uintptr pid, uintptr isHwnd){ int32 x = 0, y = 0; // Check if the window is the root - XQueryTree(rDisplay, win, + XQueryTree(rDisplay, win.XWin, &root, &parent, &children, &count); if (children) { XFree(children); } // Retrieve window attributes XWindowAttributes attr = { 0 }; - XGetWindowAttributes(rDisplay, win, &attr); + XGetWindowAttributes(rDisplay, win.XWin, &attr); // Coordinates must be translated if (parent != attr.root){ - XTranslateCoordinates(rDisplay, win, attr.root, attr.x, + XTranslateCoordinates(rDisplay, win.XWin, attr.root, attr.x, attr.y, &x, &y, &parent); } // Coordinates can be left alone diff --git a/window/window.h b/window/window.h index 7ebfc58..60dd530 100644 --- a/window/window.h +++ b/window/window.h @@ -275,7 +275,7 @@ bool IsMinimized(void){ // Ignore X errors // XDismissErrors(); - // return GetState (mData.XWin, STATE_MINIMIZE); + // return GetState(mData.XWin, STATE_MINIMIZE); #elif defined(IS_WINDOWS) @@ -298,7 +298,7 @@ bool IsMaximized(void){ // Ignore X errors // XDismissErrors(); - // return GetState (mData.XWin, STATE_MAXIMIZE); + // return GetState(mData.XWin, STATE_MAXIMIZE); #elif defined(IS_WINDOWS) @@ -447,7 +447,7 @@ MData GetActive(void){ // Get the current active window result.XWin = XDefaultRootWindow(rDisplay); - void* active = GetWindowProperty(result,WM_ACTIVE,NULL); + void* active = GetWindowProperty(result, WM_ACTIVE, NULL); // Check result value if (active != NULL) { @@ -607,8 +607,9 @@ char *GetTitle(){ #elif defined(IS_WINDOWS) - return GetWindowText - (mData.HWnd, mData.Title, 512) > 0 ? mData.Title : ""; + return GetWindowText( + mData.HWnd, mData.Title, 512) > 0 ? + mData.Title : ""; // return GetWindowText // (mData.HWnd, name, 512) > 0 ? // _UTF8Encode(name) : "null"; @@ -624,10 +625,9 @@ int32 WGetPID(void){ pid_t pid = 0; // Attempt to retrieve the window pid - if (AXUIElementGetPid(mData.AxID, &pid) - == kAXErrorSuccess) { - return pid; - } + if (AXUIElementGetPid(mData.AxID, &pid)== kAXErrorSuccess) { + return pid; + } return 0; From e1769c70dca7c976fe4988ceb521b14bbbb83620 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 09:11:45 -0400 Subject: [PATCH 08/13] update set handle return and add getBounds func [ci skip] --- robotgo.go | 11 +++++++++++ window/window.h | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/robotgo.go b/robotgo.go index 240d33d..36b538b 100644 --- a/robotgo.go +++ b/robotgo.go @@ -1398,6 +1398,17 @@ func GetPID() int32 { return int32(pid) } +// GetBounds get the window bounds +func GetBounds(pid int32, args ...int) (int, int, int, int) { + var hwnd int + if len(args) > 0 { + hwnd = args[0] + } + + bounds := C.get_bounds(C.uintptr(pid), C.uintptr(hwnd)) + return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H) +} + // Pids get the all process id func Pids() ([]int32, error) { var ret []int32 diff --git a/window/window.h b/window/window.h index 60dd530..a7569ca 100644 --- a/window/window.h +++ b/window/window.h @@ -170,8 +170,8 @@ bool setHandle(uintptr handle){ mData.AxID = 0; if (handle == 0){ - return 0; - // return true; + // return 0; + return true; } // Retrieve the window element From 5c7cc1fb1d21ff1aeb679250418059255c37cb83 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 09:35:45 -0400 Subject: [PATCH 09/13] fix x11 error --- window/win_sys.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/window/win_sys.h b/window/win_sys.h index 177c9f5..9eae232 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -1,4 +1,5 @@ // #include "../base/os.h" +Bounds get_client(uintptr pid, uintptr isHwnd); Bounds get_bounds(uintptr pid, uintptr isHwnd){ // Check if the window is valid @@ -99,8 +100,8 @@ Bounds get_client(uintptr pid, uintptr isHwnd){ win.XWin = (Window)pid; // Property variables - MData root, parent; - MData* children; + Window root, parent; + Window* children; unsigned int count; int32 x = 0, y = 0; From 8f8937daad7759aeea13dece016c601171e412b5 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 09:57:24 -0400 Subject: [PATCH 10/13] add internalGetBounds and x11 getXidFromPid to GetBounds --- robotgo.go | 9 ++------- robotgo_mac_win.go | 10 ++++++++++ robotgo_unix.go | 30 +++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/robotgo.go b/robotgo.go index 36b538b..1705b21 100644 --- a/robotgo.go +++ b/robotgo.go @@ -1398,13 +1398,8 @@ func GetPID() int32 { return int32(pid) } -// GetBounds get the window bounds -func GetBounds(pid int32, args ...int) (int, int, int, int) { - var hwnd int - if len(args) > 0 { - hwnd = args[0] - } - +// internalGetBounds get the window bounds +func internalGetBounds(pid int32, hwnd int) (int, int, int, int) { bounds := C.get_bounds(C.uintptr(pid), C.uintptr(hwnd)) return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H) } diff --git a/robotgo_mac_win.go b/robotgo_mac_win.go index 81c653d..3acc163 100644 --- a/robotgo_mac_win.go +++ b/robotgo_mac_win.go @@ -12,6 +12,16 @@ package robotgo +// GetBounds get the window bounds +func GetBounds(pid int32, args ...int) (int, int, int, int) { + var hwnd int + if len(args) > 0 { + hwnd = args[0] + } + + return internalGetBounds(pid, hwnd) +} + // ActivePID active the window by PID, // If args[0] > 0 on the Windows platform via a window handle to active func ActivePID(pid int32, args ...int) error { diff --git a/robotgo_unix.go b/robotgo_unix.go index a762446..62ffaf6 100644 --- a/robotgo_unix.go +++ b/robotgo_unix.go @@ -23,6 +23,33 @@ import ( var xu *xgbutil.XUtil +// GetBounds get the window bounds +func GetBounds(pid int32, args ...int) (int, int, int, int) { + var hwnd int + if len(args) > 0 { + hwnd = args[0] + + return internalGetBounds(pid, hwnd) + } + + if xu == nil { + var err error + xu, err = xgbutil.NewConn() + if err != nil { + log.Println("xgbutil.NewConn errors is: ", err) + return 0, 0, 0, 0 + } + } + + xid, err := GetXidFromPid(xu, pid) + if err != nil { + log.Println("GetXidFromPid errors is: ", err) + return 0, 0, 0, 0 + } + + internalGetBounds(int32(xid), hwnd) +} + // ActivePIDC active the window by PID, // If args[0] > 0 on the unix platform via a xid to active func ActivePIDC(pid int32, args ...int) { @@ -73,6 +100,7 @@ func ActivePID(pid int32, args ...int) error { return nil } + // get xid from pid xid, err := GetXidFromPid(xu, pid) if err != nil { return err @@ -103,5 +131,5 @@ func GetXidFromPid(xu *xgbutil.XUtil, pid int32) (xproto.Window, error) { } } - return 0, errors.New("failed to find a window with a matching pid") + return 0, errors.New("failed to find a window with a matching pid.") } From 5984aad7bc0d39677c9e92c0ca5d10577b84ec86 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 10:05:18 -0400 Subject: [PATCH 11/13] update c call func --- window/win_sys.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/window/win_sys.h b/window/win_sys.h index 9eae232..cf1aa5d 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -88,7 +88,7 @@ Bounds get_client(uintptr pid, uintptr isHwnd){ #if defined(IS_MACOSX) - return GetBounds(pid, isHwnd); + return get_bounds(pid, isHwnd); #elif defined(USE_X11) From b4fffb3d06efcc0a4532fab9c111393103e9d366 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 10:40:31 -0400 Subject: [PATCH 12/13] optimize robot unix getxid func --- robotgo_unix.go | 37 +++++++++++++++++-------------------- window/win_sys.h | 10 +++++----- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/robotgo_unix.go b/robotgo_unix.go index 62ffaf6..774ff23 100644 --- a/robotgo_unix.go +++ b/robotgo_unix.go @@ -32,16 +32,7 @@ func GetBounds(pid int32, args ...int) (int, int, int, int) { return internalGetBounds(pid, hwnd) } - if xu == nil { - var err error - xu, err = xgbutil.NewConn() - if err != nil { - log.Println("xgbutil.NewConn errors is: ", err) - return 0, 0, 0, 0 - } - } - - xid, err := GetXidFromPid(xu, pid) + xid, err := GetXId(xu, pid) if err != nil { log.Println("GetXidFromPid errors is: ", err) return 0, 0, 0, 0 @@ -61,16 +52,7 @@ func ActivePIDC(pid int32, args ...int) { return } - if xu == nil { - var err error - xu, err = xgbutil.NewConn() - if err != nil { - log.Println("xgbutil.NewConn errors is: ", err) - return - } - } - - xid, err := GetXidFromPid(xu, pid) + xid, err := GetXId(xu, pid) if err != nil { log.Println("GetXidFromPid errors is: ", err) return @@ -114,6 +96,21 @@ func ActivePID(pid int32, args ...int) error { return nil } +// GetXId get the xid +func GetXId(xu *xgbutil.XUtil, pid int32) (xproto.Window, error) { + if xu == nil { + var err error + xu, err = xgbutil.NewConn() + if err != nil { + // log.Println("xgbutil.NewConn errors is: ", err) + return 0, err + } + } + + xid, err := GetXidFromPid(xu, pid) + return xid, err +} + // GetXidFromPid get the xide from pid func GetXidFromPid(xu *xgbutil.XUtil, pid int32) (xproto.Window, error) { windows, err := ewmh.ClientListGet(xu) diff --git a/window/win_sys.h b/window/win_sys.h index cf1aa5d..de4b020 100644 --- a/window/win_sys.h +++ b/window/win_sys.h @@ -15,14 +15,14 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){ // Determine the current point of the window if (AXUIElementCopyAttributeValue(AxID, - kAXPositionAttribute, (CFTypeRef*) &axp) + kAXPositionAttribute, (CFTypeRef*) &axp) != kAXErrorSuccess || axp == NULL){ goto exit; } // Determine the current size of the window if (AXUIElementCopyAttributeValue(AxID, - kAXSizeAttribute, (CFTypeRef*) &axs) + kAXSizeAttribute, (CFTypeRef*) &axs) != kAXErrorSuccess || axs == NULL){ goto exit; } @@ -36,9 +36,9 @@ Bounds get_bounds(uintptr pid, uintptr isHwnd){ bounds.W = s.width; bounds.H = s.height; } - - exit: - if (axp != NULL) { CFRelease(axp); } + + exit: + if (axp != NULL) { CFRelease(axp); } if (axs != NULL) { CFRelease(axs); } return bounds; From 77d07f690749b10d5fa4ed82fa89d9d92fc2df07 Mon Sep 17 00:00:00 2001 From: vcaesar Date: Mon, 13 Aug 2018 10:42:22 -0400 Subject: [PATCH 13/13] fix return error --- robotgo_unix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robotgo_unix.go b/robotgo_unix.go index 774ff23..eadd56f 100644 --- a/robotgo_unix.go +++ b/robotgo_unix.go @@ -38,7 +38,7 @@ func GetBounds(pid int32, args ...int) (int, int, int, int) { return 0, 0, 0, 0 } - internalGetBounds(int32(xid), hwnd) + return internalGetBounds(int32(xid), hwnd) } // ActivePIDC active the window by PID,