auto-scene-switcher-nix.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include <X11/Xlib.h>
  2. #include <X11/Xatom.h>
  3. #include <X11/Xutil.h>
  4. #undef Bool
  5. #undef CursorShape
  6. #undef Expose
  7. #undef KeyPress
  8. #undef KeyRelease
  9. #undef FocusIn
  10. #undef FocusOut
  11. #undef FontChange
  12. #undef None
  13. #undef Status
  14. #undef Unsorted
  15. #include <util/platform.h>
  16. #include "auto-scene-switcher.hpp"
  17. using namespace std;
  18. static Display* xdisplay = 0;
  19. Display *disp()
  20. {
  21. if (!xdisplay)
  22. xdisplay = XOpenDisplay(NULL);
  23. return xdisplay;
  24. }
  25. void cleanupDisplay()
  26. {
  27. if (!xdisplay)
  28. return;
  29. XCloseDisplay(xdisplay);
  30. xdisplay = 0;
  31. }
  32. static bool ewmhIsSupported()
  33. {
  34. Display *display = disp();
  35. Atom netSupportingWmCheck = XInternAtom(display,
  36. "_NET_SUPPORTING_WM_CHECK", true);
  37. Atom actualType;
  38. int format = 0;
  39. unsigned long num = 0, bytes = 0;
  40. unsigned char *data = NULL;
  41. Window ewmh_window = 0;
  42. int status = XGetWindowProperty(
  43. display,
  44. DefaultRootWindow(display),
  45. netSupportingWmCheck,
  46. 0L,
  47. 1L,
  48. false,
  49. XA_WINDOW,
  50. &actualType,
  51. &format,
  52. &num,
  53. &bytes,
  54. &data);
  55. if (status == Success) {
  56. if (num > 0) {
  57. ewmh_window = ((Window*)data)[0];
  58. }
  59. if (data) {
  60. XFree(data);
  61. data = NULL;
  62. }
  63. }
  64. if (ewmh_window) {
  65. status = XGetWindowProperty(
  66. display,
  67. ewmh_window,
  68. netSupportingWmCheck,
  69. 0L,
  70. 1L,
  71. false,
  72. XA_WINDOW,
  73. &actualType,
  74. &format,
  75. &num,
  76. &bytes,
  77. &data);
  78. if (status != Success || num == 0 ||
  79. ewmh_window != ((Window*)data)[0]) {
  80. ewmh_window = 0;
  81. }
  82. if (status == Success && data) {
  83. XFree(data);
  84. }
  85. }
  86. return ewmh_window != 0;
  87. }
  88. static std::vector<Window> getTopLevelWindows()
  89. {
  90. std::vector<Window> res;
  91. res.resize(0);
  92. if (!ewmhIsSupported()) {
  93. return res;
  94. }
  95. Atom netClList = XInternAtom(disp(), "_NET_CLIENT_LIST", true);
  96. Atom actualType;
  97. int format;
  98. unsigned long num, bytes;
  99. Window* data = 0;
  100. for (int i = 0; i < ScreenCount(disp()); ++i) {
  101. Window rootWin = RootWindow(disp(), i);
  102. int status = XGetWindowProperty(
  103. disp(),
  104. rootWin,
  105. netClList,
  106. 0L,
  107. ~0L,
  108. false,
  109. AnyPropertyType,
  110. &actualType,
  111. &format,
  112. &num,
  113. &bytes,
  114. (uint8_t**)&data);
  115. if (status != Success) {
  116. continue;
  117. }
  118. for (unsigned long i = 0; i < num; ++i)
  119. res.emplace_back(data[i]);
  120. XFree(data);
  121. }
  122. return res;
  123. }
  124. static std::string GetWindowTitle(size_t i)
  125. {
  126. Window w = getTopLevelWindows().at(i);
  127. std::string windowTitle;
  128. char* name;
  129. int status = XFetchName(disp(), w, &name);
  130. if (status >= Success && name != nullptr)
  131. {
  132. std::string str(name);
  133. windowTitle = str;
  134. }
  135. XFree(name);
  136. return windowTitle;
  137. }
  138. void GetWindowList(vector<string> &windows)
  139. {
  140. windows.resize(0);
  141. for (size_t i = 0; i < getTopLevelWindows().size(); ++i){
  142. if (GetWindowTitle(i) != "")
  143. windows.emplace_back(GetWindowTitle(i));
  144. }
  145. }
  146. void GetCurrentWindowTitle(string &title)
  147. {
  148. if (!ewmhIsSupported()) {
  149. return;
  150. }
  151. Atom active = XInternAtom(disp(), "_NET_ACTIVE_WINDOW", true);
  152. Atom actualType;
  153. int format;
  154. unsigned long num, bytes;
  155. Window* data = 0;
  156. char* name;
  157. Window rootWin = RootWindow(disp(), 0);
  158. XGetWindowProperty(
  159. disp(),
  160. rootWin,
  161. active,
  162. 0L,
  163. ~0L,
  164. false,
  165. AnyPropertyType,
  166. &actualType,
  167. &format,
  168. &num,
  169. &bytes,
  170. (uint8_t**)&data);
  171. int status = XFetchName(disp(), data[0], &name);
  172. if (status >= Success && name != nullptr) {
  173. std::string str(name);
  174. title = str;
  175. }
  176. XFree(name);
  177. }