win_sys.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // https://github.com/go-vgo/robotgo/blob/master/LICENSE
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. // #if defined(USE_X11)
  11. // #include <X11/Xresource.h>
  12. // #endif
  13. Bounds get_client(uintptr pid, int8_t isPid);
  14. Bounds get_bounds(uintptr pid, int8_t isPid){
  15. // Check if the window is valid
  16. Bounds bounds;
  17. if (!is_valid()) { return bounds; }
  18. #if defined(IS_MACOSX)
  19. // Bounds bounds;
  20. AXValueRef axp = NULL;
  21. AXValueRef axs = NULL;
  22. AXUIElementRef AxID = AXUIElementCreateApplication(pid);
  23. // Determine the current point of the window
  24. if (AXUIElementCopyAttributeValue(AxID, kAXPositionAttribute, (CFTypeRef*) &axp)
  25. != kAXErrorSuccess || axp == NULL){
  26. goto exit;
  27. }
  28. // Determine the current size of the window
  29. if (AXUIElementCopyAttributeValue(AxID, kAXSizeAttribute, (CFTypeRef*) &axs)
  30. != kAXErrorSuccess || axs == NULL){
  31. goto exit;
  32. }
  33. CGPoint p; CGSize s;
  34. // Attempt to convert both values into atomic types
  35. if (AXValueGetValue(axp, kAXValueCGPointType, &p) &&
  36. AXValueGetValue(axs, kAXValueCGSizeType, &s)){
  37. bounds.X = p.x;
  38. bounds.Y = p.y;
  39. bounds.W = s.width;
  40. bounds.H = s.height;
  41. }
  42. // return bounds;
  43. exit:
  44. if (axp != NULL) { CFRelease(axp); }
  45. if (axs != NULL) { CFRelease(axs); }
  46. return bounds;
  47. #elif defined(USE_X11)
  48. // Ignore X errors
  49. XDismissErrors();
  50. MData win;
  51. win.XWin = (Window)pid;
  52. Bounds client = get_client(pid, isPid);
  53. Bounds frame = GetFrame(win);
  54. bounds.X = client.X - frame.X;
  55. bounds.Y = client.Y - frame.Y;
  56. bounds.W = client.W + frame.W;
  57. bounds.H = client.H + frame.H;
  58. return bounds;
  59. #elif defined(IS_WINDOWS)
  60. HWND hwnd = getHwnd(pid, isPid);
  61. RECT rect = { 0 };
  62. GetWindowRect(hwnd, &rect);
  63. bounds.X = rect.left;
  64. bounds.Y = rect.top;
  65. bounds.W = rect.right - rect.left;
  66. bounds.H = rect.bottom - rect.top;
  67. return bounds;
  68. #endif
  69. }
  70. Bounds get_client(uintptr pid, int8_t isPid) {
  71. // Check if the window is valid
  72. Bounds bounds;
  73. if (!is_valid()) { return bounds; }
  74. #if defined(IS_MACOSX)
  75. return get_bounds(pid, isPid);
  76. #elif defined(USE_X11)
  77. Display *rDisplay = XOpenDisplay(NULL);
  78. // Ignore X errors
  79. XDismissErrors();
  80. MData win;
  81. win.XWin = (Window)pid;
  82. // Property variables
  83. Window root, parent;
  84. Window* children;
  85. unsigned int count;
  86. int32_t x = 0, y = 0;
  87. // Check if the window is the root
  88. XQueryTree(rDisplay, win.XWin, &root, &parent, &children, &count);
  89. if (children) { XFree(children); }
  90. // Retrieve window attributes
  91. XWindowAttributes attr = { 0 };
  92. XGetWindowAttributes(rDisplay, win.XWin, &attr);
  93. // Coordinates must be translated
  94. if (parent != attr.root) {
  95. XTranslateCoordinates(rDisplay, win.XWin, attr.root, attr.x, attr.y, &x, &y, &parent);
  96. } else {
  97. x = attr.x;
  98. y = attr.y;
  99. }
  100. // Return resulting window bounds
  101. bounds.X = x;
  102. bounds.Y = y;
  103. bounds.W = attr.width;
  104. bounds.H = attr.height;
  105. XCloseDisplay(rDisplay);
  106. return bounds;
  107. #elif defined(IS_WINDOWS)
  108. HWND hwnd = getHwnd(pid, isPid);
  109. RECT rect = { 0 };
  110. GetClientRect(hwnd, &rect);
  111. POINT point;
  112. point.x = rect.left;
  113. point.y = rect.top;
  114. // Convert the client point to screen
  115. ClientToScreen(hwnd, &point);
  116. bounds.X = point.x;
  117. bounds.Y = point.y;
  118. bounds.W = rect.right - rect.left;
  119. bounds.H = rect.bottom - rect.top;
  120. return bounds;
  121. #endif
  122. }