x11_util.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_BASE_X_X11_UTIL_H_
  5. #define UI_BASE_X_X11_UTIL_H_
  6. // This file declares utility functions for X11 (Linux only).
  7. #include <cstddef>
  8. #include <cstdint>
  9. #include <memory>
  10. #include <string>
  11. #include <unordered_map>
  12. #include <vector>
  13. #include "base/component_export.h"
  14. #include "base/containers/flat_set.h"
  15. #include "base/memory/raw_ptr.h"
  16. #include "base/memory/ref_counted_memory.h"
  17. #include "base/memory/scoped_refptr.h"
  18. #include "base/synchronization/lock.h"
  19. #include "build/build_config.h"
  20. #include "third_party/abseil-cpp/absl/types/optional.h"
  21. #include "third_party/skia/include/core/SkColorType.h"
  22. #include "ui/base/x/x11_cursor.h"
  23. #include "ui/gfx/icc_profile.h"
  24. #include "ui/gfx/image/image_skia.h"
  25. #include "ui/gfx/x/connection.h"
  26. #include "ui/gfx/x/future.h"
  27. #include "ui/gfx/x/xproto.h"
  28. typedef unsigned long Cursor;
  29. class SkPixmap;
  30. namespace base {
  31. template <typename T>
  32. struct DefaultSingletonTraits;
  33. }
  34. namespace gfx {
  35. class Point;
  36. } // namespace gfx
  37. namespace ui {
  38. enum WmState : uint32_t {
  39. WM_STATE_WITHDRAWN = 0,
  40. WM_STATE_NORMAL = 1,
  41. WM_STATE_ICONIC = 3,
  42. };
  43. enum SizeHintsFlags : int32_t {
  44. SIZE_HINT_US_POSITION = 1 << 0,
  45. SIZE_HINT_US_SIZE = 1 << 1,
  46. SIZE_HINT_P_POSITION = 1 << 2,
  47. SIZE_HINT_P_SIZE = 1 << 3,
  48. SIZE_HINT_P_MIN_SIZE = 1 << 4,
  49. SIZE_HINT_P_MAX_SIZE = 1 << 5,
  50. SIZE_HINT_P_RESIZE_INC = 1 << 6,
  51. SIZE_HINT_P_ASPECT = 1 << 7,
  52. SIZE_HINT_BASE_SIZE = 1 << 8,
  53. SIZE_HINT_P_WIN_GRAVITY = 1 << 9,
  54. };
  55. struct SizeHints {
  56. // User specified flags
  57. int32_t flags;
  58. // User-specified position
  59. int32_t x, y;
  60. // User-specified size
  61. int32_t width, height;
  62. // Program-specified minimum size
  63. int32_t min_width, min_height;
  64. // Program-specified maximum size
  65. int32_t max_width, max_height;
  66. // Program-specified resize increments
  67. int32_t width_inc, height_inc;
  68. // Program-specified minimum aspect ratios
  69. int32_t min_aspect_num, min_aspect_den;
  70. // Program-specified maximum aspect ratios
  71. int32_t max_aspect_num, max_aspect_den;
  72. // Program-specified base size
  73. int32_t base_width, base_height;
  74. // Program-specified window gravity
  75. uint32_t win_gravity;
  76. };
  77. enum WmHintsFlags : uint32_t {
  78. WM_HINT_INPUT = 1L << 0,
  79. WM_HINT_STATE = 1L << 1,
  80. WM_HINT_ICON_PIXMAP = 1L << 2,
  81. WM_HINT_ICON_WINDOW = 1L << 3,
  82. WM_HINT_ICON_POSITION = 1L << 4,
  83. WM_HINT_ICON_MASK = 1L << 5,
  84. WM_HINT_WINDOW_GROUP = 1L << 6,
  85. // 1L << 7 doesn't have any defined meaning
  86. WM_HINT_X_URGENCY = 1L << 8
  87. };
  88. struct WmHints {
  89. // Marks which fields in this structure are defined
  90. int32_t flags;
  91. // Does this application rely on the window manager to get keyboard input?
  92. uint32_t input;
  93. // See below
  94. int32_t initial_state;
  95. // Pixmap to be used as icon
  96. x11::Pixmap icon_pixmap;
  97. // Window to be used as icon
  98. x11::Window icon_window;
  99. // Initial position of icon
  100. int32_t icon_x, icon_y;
  101. // Icon mask bitmap
  102. x11::Pixmap icon_mask;
  103. // Identifier of related window group
  104. x11::Window window_group;
  105. };
  106. // These functions use the default display and this /must/ be called from
  107. // the UI thread. Thus, they don't support multiple displays.
  108. COMPONENT_EXPORT(UI_BASE_X)
  109. bool GetWmNormalHints(x11::Window window, SizeHints* hints);
  110. COMPONENT_EXPORT(UI_BASE_X)
  111. void SetWmNormalHints(x11::Window window, const SizeHints& hints);
  112. COMPONENT_EXPORT(UI_BASE_X)
  113. bool GetWmHints(x11::Window window, WmHints* hints);
  114. COMPONENT_EXPORT(UI_BASE_X)
  115. void SetWmHints(x11::Window window, const WmHints& hints);
  116. COMPONENT_EXPORT(UI_BASE_X)
  117. void WithdrawWindow(x11::Window window);
  118. COMPONENT_EXPORT(UI_BASE_X)
  119. void RaiseWindow(x11::Window window);
  120. COMPONENT_EXPORT(UI_BASE_X)
  121. void LowerWindow(x11::Window window);
  122. COMPONENT_EXPORT(UI_BASE_X)
  123. void DefineCursor(x11::Window window, x11::Cursor cursor);
  124. COMPONENT_EXPORT(UI_BASE_X)
  125. size_t RowBytesForVisualWidth(const x11::Connection::VisualInfo& visual_info,
  126. int width);
  127. // Draws an SkPixmap on |drawable| using the given |gc|, converting to the
  128. // server side visual as needed.
  129. COMPONENT_EXPORT(UI_BASE_X)
  130. void DrawPixmap(x11::Connection* connection,
  131. x11::VisualId visual,
  132. x11::Drawable drawable,
  133. x11::GraphicsContext gc,
  134. const SkPixmap& skia_pixmap,
  135. int src_x,
  136. int src_y,
  137. int dst_x,
  138. int dst_y,
  139. int width,
  140. int height);
  141. // These functions cache their results ---------------------------------
  142. // Returns true if the system supports XINPUT2.
  143. COMPONENT_EXPORT(UI_BASE_X) bool IsXInput2Available();
  144. // Return true iff the display supports MIT-SHM.
  145. COMPONENT_EXPORT(UI_BASE_X) bool QueryShmSupport();
  146. // Coalesce all pending motion events (touch or mouse) that are at the top of
  147. // the queue, and return the number eliminated, storing the last one in
  148. // |last_event|.
  149. COMPONENT_EXPORT(UI_BASE_X)
  150. int CoalescePendingMotionEvents(const x11::Event& xev, x11::Event* last_event);
  151. // Sets whether |window| should use the OS window frame.
  152. COMPONENT_EXPORT(UI_BASE_X)
  153. void SetUseOSWindowFrame(x11::Window window, bool use_os_window_frame);
  154. // These functions do not cache their results --------------------------
  155. // Returns true if the shape extension is supported.
  156. COMPONENT_EXPORT(UI_BASE_X) bool IsShapeExtensionAvailable();
  157. // Get the X window id for the default root window
  158. COMPONENT_EXPORT(UI_BASE_X) x11::Window GetX11RootWindow();
  159. // Returns the user's current desktop.
  160. COMPONENT_EXPORT(UI_BASE_X) bool GetCurrentDesktop(int32_t* desktop);
  161. enum HideTitlebarWhenMaximized : uint32_t {
  162. SHOW_TITLEBAR_WHEN_MAXIMIZED = 0,
  163. HIDE_TITLEBAR_WHEN_MAXIMIZED = 1,
  164. };
  165. // Sets _GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED on |window|.
  166. COMPONENT_EXPORT(UI_BASE_X)
  167. void SetHideTitlebarWhenMaximizedProperty(x11::Window window,
  168. HideTitlebarWhenMaximized property);
  169. // Returns the raw bytes from a property with minimal
  170. // interpretation. |out_data| should be freed by XFree() after use.
  171. COMPONENT_EXPORT(UI_BASE_X)
  172. bool GetRawBytesOfProperty(x11::Window window,
  173. x11::Atom property,
  174. scoped_refptr<base::RefCountedMemory>* out_data,
  175. x11::Atom* out_type);
  176. // Sets the WM_CLASS attribute for a given X11 window.
  177. COMPONENT_EXPORT(UI_BASE_X)
  178. void SetWindowClassHint(x11::Connection* connection,
  179. x11::Window window,
  180. const std::string& res_name,
  181. const std::string& res_class);
  182. // Sets the WM_WINDOW_ROLE attribute for a given X11 window.
  183. COMPONENT_EXPORT(UI_BASE_X)
  184. void SetWindowRole(x11::Window window, const std::string& role);
  185. // Sends a message to the x11 window manager, enabling or disabling the
  186. // states |state1| and |state2|.
  187. COMPONENT_EXPORT(UI_BASE_X)
  188. void SetWMSpecState(x11::Window window,
  189. bool enabled,
  190. x11::Atom state1,
  191. x11::Atom state2);
  192. // Sends a NET_WM_MOVERESIZE message to the x11 window manager, enabling the
  193. // move/resize mode. As per NET_WM_MOVERESIZE spec, |location| is the position
  194. // in pixels (relative to the root window) of mouse button press, and
  195. // |direction| indicates whether this is a move or resize event, and if it is a
  196. // resize event, which edges of the window the size grip applies to.
  197. COMPONENT_EXPORT(UI_BASE_X)
  198. void DoWMMoveResize(x11::Connection* connection,
  199. x11::Window root_window,
  200. x11::Window window,
  201. const gfx::Point& location_px,
  202. int direction);
  203. // Checks if the window manager has set a specific state.
  204. COMPONENT_EXPORT(UI_BASE_X)
  205. bool HasWMSpecProperty(const base::flat_set<x11::Atom>& properties,
  206. x11::Atom atom);
  207. // Determine whether we should default to native decorations or the custom
  208. // frame based on the currently-running window manager.
  209. COMPONENT_EXPORT(UI_BASE_X) bool GetCustomFramePrefDefault();
  210. static const int32_t kAllDesktops = -1;
  211. // Queries the desktop |window| is on, kAllDesktops if sticky. Returns false if
  212. // property not found.
  213. COMPONENT_EXPORT(UI_BASE_X)
  214. bool GetWindowDesktop(x11::Window window, int32_t* desktop);
  215. enum WindowManagerName {
  216. WM_OTHER, // We were able to obtain the WM's name, but there is
  217. // no corresponding entry in this enum.
  218. WM_UNNAMED, // Either there is no WM or there is no way to obtain
  219. // the WM name.
  220. WM_AWESOME,
  221. WM_BLACKBOX,
  222. WM_COMPIZ,
  223. WM_ENLIGHTENMENT,
  224. WM_FLUXBOX,
  225. WM_I3,
  226. WM_ICE_WM,
  227. WM_ION3,
  228. WM_KWIN,
  229. WM_MATCHBOX,
  230. WM_METACITY,
  231. WM_MUFFIN,
  232. WM_MUTTER,
  233. WM_NOTION,
  234. WM_OPENBOX,
  235. WM_QTILE,
  236. WM_RATPOISON,
  237. WM_STUMPWM,
  238. WM_WMII,
  239. WM_XFWM4,
  240. WM_XMONAD,
  241. };
  242. // Attempts to guess the window maager. Returns WM_OTHER or WM_UNNAMED
  243. // if we can't determine it for one reason or another.
  244. COMPONENT_EXPORT(UI_BASE_X) WindowManagerName GuessWindowManager();
  245. // The same as GuessWindowManager(), but returns the raw string. If we
  246. // can't determine it, return "Unknown".
  247. COMPONENT_EXPORT(UI_BASE_X) std::string GuessWindowManagerName();
  248. // These values are persisted to logs. Entries should not be renumbered and
  249. // numeric values should never be reused.
  250. //
  251. // Append new window managers before kMaxValue and update LinuxWindowManagerName
  252. // in tools/metrics/histograms/enums.xml accordingly.
  253. //
  254. // See also tools/metrics/histograms/README.md#enum-histograms
  255. enum class UMALinuxWindowManager {
  256. kOther = 0,
  257. kBlackbox = 1,
  258. kChromeOS = 2, // Deprecated.
  259. kCompiz = 3,
  260. kEnlightenment = 4,
  261. kIceWM = 5,
  262. kKWin = 6,
  263. kMetacity = 7,
  264. kMuffin = 8,
  265. kMutter = 9,
  266. kOpenbox = 10,
  267. kXfwm4 = 11,
  268. kAwesome = 12,
  269. kI3 = 13,
  270. kIon3 = 14,
  271. kMatchbox = 15,
  272. kNotion = 16,
  273. kQtile = 17,
  274. kRatpoison = 18,
  275. kStumpWM = 19,
  276. kWmii = 20,
  277. kFluxbox = 21,
  278. kXmonad = 22,
  279. kUnnamed = 23,
  280. kMaxValue = kUnnamed
  281. };
  282. COMPONENT_EXPORT(UI_BASE_X) UMALinuxWindowManager GetWindowManagerUMA();
  283. // Returns a buest-effort guess as to whether |window_manager| is tiling (true)
  284. // or stacking (false).
  285. COMPONENT_EXPORT(UI_BASE_X) bool IsWmTiling(WindowManagerName window_manager);
  286. // Returns true if a compositing manager is present.
  287. COMPONENT_EXPORT(UI_BASE_X) bool IsCompositingManagerPresent();
  288. // Returns true if a given window is in full-screen mode.
  289. COMPONENT_EXPORT(UI_BASE_X) bool IsX11WindowFullScreen(x11::Window window);
  290. // Suspends or resumes the X screen saver, and returns whether the operation was
  291. // successful. Must be called on the UI thread. If called multiple times with
  292. // |suspend| set to true, the screen saver is not un-suspended until this method
  293. // is called an equal number of times with |suspend| set to false.
  294. COMPONENT_EXPORT(UI_BASE_X) bool SuspendX11ScreenSaver(bool suspend);
  295. // Returns true if the window manager supports the given hint.
  296. COMPONENT_EXPORT(UI_BASE_X) bool WmSupportsHint(x11::Atom atom);
  297. // Returns the ICCProfile corresponding to |monitor| using XGetWindowProperty.
  298. COMPONENT_EXPORT(UI_BASE_X)
  299. gfx::ICCProfile GetICCProfileForMonitor(int monitor);
  300. // Return true if the display supports SYNC extension.
  301. COMPONENT_EXPORT(UI_BASE_X) bool IsSyncExtensionAvailable();
  302. // Returns the preferred Skia colortype for an X11 visual. Returns
  303. // kUnknown_SkColorType if there isn't a suitable colortype.
  304. COMPONENT_EXPORT(UI_BASE_X)
  305. SkColorType ColorTypeForVisual(x11::VisualId visual_id);
  306. COMPONENT_EXPORT(UI_BASE_X)
  307. x11::Future<void> SendClientMessage(
  308. x11::Window window,
  309. x11::Window target,
  310. x11::Atom type,
  311. const std::array<uint32_t, 5> data,
  312. x11::EventMask event_mask = x11::EventMask::SubstructureNotify |
  313. x11::EventMask::SubstructureRedirect);
  314. // Return true if VulkanSurface is supported.
  315. COMPONENT_EXPORT(UI_BASE_X) bool IsVulkanSurfaceSupported();
  316. // Returns whether ARGB visuals are supported.
  317. COMPONENT_EXPORT(UI_BASE_X) bool DoesVisualHaveAlphaForTest();
  318. // Returns an icon for a native window referred by |target_window_id|. Can be
  319. // any window on screen.
  320. COMPONENT_EXPORT(UI_BASE_X)
  321. gfx::ImageSkia GetNativeWindowIcon(intptr_t target_window_id);
  322. // --------------------------------------------------------------------------
  323. // Selects a visual with a preference for alpha support on compositing window
  324. // managers.
  325. class COMPONENT_EXPORT(UI_BASE_X) XVisualManager {
  326. public:
  327. static XVisualManager* GetInstance();
  328. // Picks the best argb or opaque visual given |want_argb_visual|.
  329. void ChooseVisualForWindow(bool want_argb_visual,
  330. x11::VisualId* visual_id,
  331. uint8_t* depth,
  332. x11::ColorMap* colormap,
  333. bool* visual_has_alpha);
  334. bool GetVisualInfo(x11::VisualId visual_id,
  335. uint8_t* depth,
  336. x11::ColorMap* colormap,
  337. bool* visual_has_alpha);
  338. // Are all of the system requirements met for using transparent visuals?
  339. bool ArgbVisualAvailable() const;
  340. XVisualManager(const XVisualManager&) = delete;
  341. XVisualManager& operator=(const XVisualManager&) = delete;
  342. ~XVisualManager();
  343. private:
  344. friend struct base::DefaultSingletonTraits<XVisualManager>;
  345. class XVisualData {
  346. public:
  347. XVisualData(x11::Connection* connection,
  348. uint8_t depth,
  349. const x11::VisualType* info);
  350. ~XVisualData();
  351. x11::ColorMap GetColormap();
  352. const uint8_t depth;
  353. const raw_ptr<const x11::VisualType> info;
  354. private:
  355. x11::ColorMap colormap_{};
  356. };
  357. XVisualManager();
  358. std::unordered_map<x11::VisualId, std::unique_ptr<XVisualData>> visuals_;
  359. x11::VisualId opaque_visual_id_{};
  360. x11::VisualId transparent_visual_id_{};
  361. };
  362. } // namespace ui
  363. #endif // UI_BASE_X_X11_UTIL_H_