// #include "../base/os.h" Bounds get_client(uintptr pid, uintptr isHwnd); 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(); MData win; win.XWin = (Window)pid; Bounds client = get_client(pid, isHwnd); Bounds frame = GetFrame(win); 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 } Bounds get_client(uintptr pid, uintptr isHwnd){ // Check if the window is valid Bounds bounds; if (!IsValid()) { return bounds; } #if defined(IS_MACOSX) return get_bounds(pid, isHwnd); #elif defined(USE_X11) Display *rDisplay = XOpenDisplay(NULL); // Ignore X errors XDismissErrors(); MData win; win.XWin = (Window)pid; // Property variables Window root, parent; Window* children; unsigned int count; int32 x = 0, y = 0; // Check if the window is the root XQueryTree(rDisplay, win.XWin, &root, &parent, &children, &count); if (children) { XFree(children); } // Retrieve window attributes XWindowAttributes attr = { 0 }; XGetWindowAttributes(rDisplay, win.XWin, &attr); // Coordinates must be translated if (parent != attr.root){ XTranslateCoordinates(rDisplay, win.XWin, 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 }