Event.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/StringBuilder.h>
  9. #include <AK/Vector.h>
  10. #include <Kernel/API/KeyCode.h>
  11. #include <LibCore/Event.h>
  12. #include <LibGUI/FocusSource.h>
  13. #include <LibGUI/Forward.h>
  14. #include <LibGUI/WindowType.h>
  15. #include <LibGfx/Bitmap.h>
  16. #include <LibGfx/Point.h>
  17. #include <LibGfx/Rect.h>
  18. namespace GUI {
  19. class Event : public Core::Event {
  20. public:
  21. enum Type {
  22. Show = 1000,
  23. Hide,
  24. Paint,
  25. MultiPaint,
  26. Resize,
  27. Move,
  28. MouseMove,
  29. MouseDown,
  30. MouseDoubleClick,
  31. MouseUp,
  32. MouseWheel,
  33. Enter,
  34. Leave,
  35. KeyDown,
  36. KeyUp,
  37. WindowEntered,
  38. WindowLeft,
  39. WindowBecameInactive,
  40. WindowBecameActive,
  41. WindowInputPreempted,
  42. WindowInputRestored,
  43. FocusIn,
  44. FocusOut,
  45. WindowCloseRequest,
  46. ContextMenu,
  47. EnabledChange,
  48. DragEnter,
  49. DragLeave,
  50. DragMove,
  51. Drop,
  52. ThemeChange,
  53. FontsChange,
  54. ScreenRectsChange,
  55. ActionEnter,
  56. ActionLeave,
  57. AppletAreaRectChange,
  58. __Begin_WM_Events,
  59. WM_WindowRemoved,
  60. WM_WindowStateChanged,
  61. WM_WindowRectChanged,
  62. WM_WindowIconBitmapChanged,
  63. WM_AppletAreaSizeChanged,
  64. WM_SuperKeyPressed,
  65. WM_SuperSpaceKeyPressed,
  66. WM_SuperDKeyPressed,
  67. WM_SuperDigitKeyPressed,
  68. WM_WorkspaceChanged,
  69. WM_KeymapChanged,
  70. __End_WM_Events,
  71. };
  72. Event() = default;
  73. explicit Event(Type type)
  74. : Core::Event(type)
  75. {
  76. }
  77. virtual ~Event() = default;
  78. bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
  79. bool is_paint_event() const { return type() == Paint; }
  80. };
  81. class WMEvent : public Event {
  82. public:
  83. WMEvent(Type type, int client_id, int window_id)
  84. : Event(type)
  85. , m_client_id(client_id)
  86. , m_window_id(window_id)
  87. {
  88. }
  89. int client_id() const { return m_client_id; }
  90. int window_id() const { return m_window_id; }
  91. private:
  92. int m_client_id { -1 };
  93. int m_window_id { -1 };
  94. };
  95. class WMSuperKeyPressedEvent : public WMEvent {
  96. public:
  97. explicit WMSuperKeyPressedEvent(int client_id)
  98. : WMEvent(Event::Type::WM_SuperKeyPressed, client_id, 0)
  99. {
  100. }
  101. };
  102. class WMSuperSpaceKeyPressedEvent : public WMEvent {
  103. public:
  104. explicit WMSuperSpaceKeyPressedEvent(int client_id)
  105. : WMEvent(Event::Type::WM_SuperSpaceKeyPressed, client_id, 0)
  106. {
  107. }
  108. };
  109. class WMSuperDKeyPressedEvent : public WMEvent {
  110. public:
  111. explicit WMSuperDKeyPressedEvent(int client_id)
  112. : WMEvent(Event::Type::WM_SuperDKeyPressed, client_id, 0)
  113. {
  114. }
  115. };
  116. class WMSuperDigitKeyPressedEvent : public WMEvent {
  117. public:
  118. WMSuperDigitKeyPressedEvent(int client_id, u8 digit)
  119. : WMEvent(Event::Type::WM_SuperDigitKeyPressed, client_id, 0)
  120. , m_digit(digit)
  121. {
  122. }
  123. u8 digit() const { return m_digit; }
  124. private:
  125. u8 m_digit { 0 };
  126. };
  127. class WMAppletAreaSizeChangedEvent : public WMEvent {
  128. public:
  129. explicit WMAppletAreaSizeChangedEvent(Gfx::IntSize size)
  130. : WMEvent(Event::Type::WM_AppletAreaSizeChanged, 0, 0)
  131. , m_size(size)
  132. {
  133. }
  134. Gfx::IntSize size() const { return m_size; }
  135. private:
  136. Gfx::IntSize m_size;
  137. };
  138. class WMWindowRemovedEvent : public WMEvent {
  139. public:
  140. WMWindowRemovedEvent(int client_id, int window_id)
  141. : WMEvent(Event::Type::WM_WindowRemoved, client_id, window_id)
  142. {
  143. }
  144. };
  145. class WMWindowStateChangedEvent : public WMEvent {
  146. public:
  147. WMWindowStateChangedEvent(int client_id, int window_id, StringView title, Gfx::IntRect const& rect, unsigned workspace_row, unsigned workspace_column, bool is_active, bool is_blocked, WindowType window_type, bool is_minimized, bool is_frameless, Optional<int> progress)
  148. : WMEvent(Event::Type::WM_WindowStateChanged, client_id, window_id)
  149. , m_title(title)
  150. , m_rect(rect)
  151. , m_window_type(window_type)
  152. , m_workspace_row(workspace_row)
  153. , m_workspace_column(workspace_column)
  154. , m_active(is_active)
  155. , m_blocked(is_blocked)
  156. , m_minimized(is_minimized)
  157. , m_frameless(is_frameless)
  158. , m_progress(progress)
  159. {
  160. }
  161. DeprecatedString const& title() const { return m_title; }
  162. Gfx::IntRect const& rect() const { return m_rect; }
  163. bool is_active() const { return m_active; }
  164. bool is_blocked() const { return m_blocked; }
  165. WindowType window_type() const { return m_window_type; }
  166. bool is_minimized() const { return m_minimized; }
  167. bool is_frameless() const { return m_frameless; }
  168. Optional<int> progress() const { return m_progress; }
  169. unsigned workspace_row() const { return m_workspace_row; }
  170. unsigned workspace_column() const { return m_workspace_column; }
  171. private:
  172. DeprecatedString m_title;
  173. Gfx::IntRect m_rect;
  174. WindowType m_window_type;
  175. unsigned m_workspace_row;
  176. unsigned m_workspace_column;
  177. bool m_active;
  178. bool m_blocked;
  179. bool m_minimized;
  180. bool m_frameless;
  181. Optional<int> m_progress;
  182. };
  183. class WMWindowRectChangedEvent : public WMEvent {
  184. public:
  185. WMWindowRectChangedEvent(int client_id, int window_id, Gfx::IntRect const& rect)
  186. : WMEvent(Event::Type::WM_WindowRectChanged, client_id, window_id)
  187. , m_rect(rect)
  188. {
  189. }
  190. Gfx::IntRect const& rect() const { return m_rect; }
  191. private:
  192. Gfx::IntRect m_rect;
  193. };
  194. class WMWindowIconBitmapChangedEvent : public WMEvent {
  195. public:
  196. WMWindowIconBitmapChangedEvent(int client_id, int window_id, Gfx::Bitmap const* bitmap)
  197. : WMEvent(Event::Type::WM_WindowIconBitmapChanged, client_id, window_id)
  198. , m_bitmap(move(bitmap))
  199. {
  200. }
  201. Gfx::Bitmap const* bitmap() const { return m_bitmap; }
  202. private:
  203. RefPtr<Gfx::Bitmap const> m_bitmap;
  204. };
  205. class WMWorkspaceChangedEvent : public WMEvent {
  206. public:
  207. explicit WMWorkspaceChangedEvent(int client_id, unsigned current_row, unsigned current_column)
  208. : WMEvent(Event::Type::WM_WorkspaceChanged, client_id, 0)
  209. , m_current_row(current_row)
  210. , m_current_column(current_column)
  211. {
  212. }
  213. unsigned current_row() const { return m_current_row; }
  214. unsigned current_column() const { return m_current_column; }
  215. private:
  216. unsigned const m_current_row;
  217. unsigned const m_current_column;
  218. };
  219. class WMKeymapChangedEvent : public WMEvent {
  220. public:
  221. explicit WMKeymapChangedEvent(int client_id, DeprecatedString const& keymap)
  222. : WMEvent(Event::Type::WM_KeymapChanged, client_id, 0)
  223. , m_keymap(keymap)
  224. {
  225. }
  226. DeprecatedString const& keymap() const { return m_keymap; }
  227. private:
  228. const DeprecatedString m_keymap;
  229. };
  230. class MultiPaintEvent final : public Event {
  231. public:
  232. explicit MultiPaintEvent(Vector<Gfx::IntRect, 32> rects, Gfx::IntSize window_size)
  233. : Event(Event::MultiPaint)
  234. , m_rects(move(rects))
  235. , m_window_size(window_size)
  236. {
  237. }
  238. Vector<Gfx::IntRect, 32> const& rects() const { return m_rects; }
  239. Gfx::IntSize window_size() const { return m_window_size; }
  240. private:
  241. Vector<Gfx::IntRect, 32> m_rects;
  242. Gfx::IntSize m_window_size;
  243. };
  244. class PaintEvent final : public Event {
  245. public:
  246. explicit PaintEvent(Gfx::IntRect const& rect, Gfx::IntSize window_size = {})
  247. : Event(Event::Paint)
  248. , m_rect(rect)
  249. , m_window_size(window_size)
  250. {
  251. }
  252. Gfx::IntRect const& rect() const { return m_rect; }
  253. Gfx::IntSize window_size() const { return m_window_size; }
  254. private:
  255. Gfx::IntRect m_rect;
  256. Gfx::IntSize m_window_size;
  257. };
  258. class ResizeEvent final : public Event {
  259. public:
  260. explicit ResizeEvent(Gfx::IntSize size)
  261. : Event(Event::Resize)
  262. , m_size(size)
  263. {
  264. }
  265. Gfx::IntSize size() const { return m_size; }
  266. private:
  267. Gfx::IntSize m_size;
  268. };
  269. class MoveEvent final : public Event {
  270. public:
  271. explicit MoveEvent(Gfx::IntPoint size)
  272. : Event(Event::Move)
  273. , m_position(size)
  274. {
  275. }
  276. Gfx::IntPoint position() const { return m_position; }
  277. private:
  278. Gfx::IntPoint m_position;
  279. };
  280. class ContextMenuEvent final : public Event {
  281. public:
  282. explicit ContextMenuEvent(Gfx::IntPoint position, Gfx::IntPoint screen_position)
  283. : Event(Event::ContextMenu)
  284. , m_position(position)
  285. , m_screen_position(screen_position)
  286. {
  287. }
  288. Gfx::IntPoint position() const { return m_position; }
  289. Gfx::IntPoint screen_position() const { return m_screen_position; }
  290. private:
  291. Gfx::IntPoint m_position;
  292. Gfx::IntPoint m_screen_position;
  293. };
  294. class ShowEvent final : public Event {
  295. public:
  296. ShowEvent()
  297. : Event(Event::Show)
  298. {
  299. }
  300. };
  301. class HideEvent final : public Event {
  302. public:
  303. HideEvent()
  304. : Event(Event::Hide)
  305. {
  306. }
  307. };
  308. enum MouseButton : u8 {
  309. None = 0,
  310. Primary = 1,
  311. Secondary = 2,
  312. Middle = 4,
  313. Backward = 8,
  314. Forward = 16,
  315. };
  316. class KeyEvent final : public Event {
  317. public:
  318. KeyEvent(Type type, KeyCode key, u8 modifiers, u32 code_point, u32 scancode)
  319. : Event(type)
  320. , m_key(key)
  321. , m_modifiers(modifiers)
  322. , m_code_point(code_point)
  323. , m_scancode(scancode)
  324. {
  325. }
  326. KeyCode key() const { return m_key; }
  327. bool ctrl() const { return m_modifiers & Mod_Ctrl; }
  328. bool alt() const { return m_modifiers & Mod_Alt; }
  329. bool altgr() const { return m_modifiers & Mod_AltGr; }
  330. bool shift() const { return m_modifiers & Mod_Shift; }
  331. bool super() const { return m_modifiers & Mod_Super; }
  332. u8 modifiers() const { return m_modifiers; }
  333. u32 code_point() const { return m_code_point; }
  334. DeprecatedString text() const
  335. {
  336. StringBuilder sb;
  337. sb.append_code_point(m_code_point);
  338. return sb.to_deprecated_string();
  339. }
  340. u32 scancode() const { return m_scancode; }
  341. DeprecatedString to_deprecated_string() const;
  342. bool is_arrow_key() const
  343. {
  344. switch (m_key) {
  345. case KeyCode::Key_Up:
  346. case KeyCode::Key_Down:
  347. case KeyCode::Key_Left:
  348. case KeyCode::Key_Right:
  349. return true;
  350. default:
  351. return false;
  352. }
  353. }
  354. private:
  355. friend class ConnectionToWindowServer;
  356. KeyCode m_key { KeyCode::Key_Invalid };
  357. u8 m_modifiers { 0 };
  358. u32 m_code_point { 0 };
  359. u32 m_scancode { 0 };
  360. };
  361. class MouseEvent final : public Event {
  362. public:
  363. MouseEvent(Type type, Gfx::IntPoint position, unsigned buttons, MouseButton button, unsigned modifiers, int wheel_delta_x, int wheel_delta_y, int wheel_raw_delta_x, int wheel_raw_delta_y)
  364. : Event(type)
  365. , m_position(position)
  366. , m_buttons(buttons)
  367. , m_button(button)
  368. , m_modifiers(modifiers)
  369. , m_wheel_delta_x(wheel_delta_x)
  370. , m_wheel_delta_y(wheel_delta_y)
  371. , m_wheel_raw_delta_x(wheel_raw_delta_x)
  372. , m_wheel_raw_delta_y(wheel_raw_delta_y)
  373. {
  374. }
  375. Gfx::IntPoint position() const { return m_position; }
  376. int x() const { return m_position.x(); }
  377. int y() const { return m_position.y(); }
  378. MouseButton button() const { return m_button; }
  379. unsigned buttons() const { return m_buttons; }
  380. bool ctrl() const { return m_modifiers & Mod_Ctrl; }
  381. bool alt() const { return m_modifiers & Mod_Alt; }
  382. bool shift() const { return m_modifiers & Mod_Shift; }
  383. bool super() const { return m_modifiers & Mod_Super; }
  384. unsigned modifiers() const { return m_modifiers; }
  385. int wheel_delta_x() const { return m_wheel_delta_x; }
  386. int wheel_delta_y() const { return m_wheel_delta_y; }
  387. int wheel_raw_delta_x() const { return m_wheel_raw_delta_x; }
  388. int wheel_raw_delta_y() const { return m_wheel_raw_delta_y; }
  389. private:
  390. Gfx::IntPoint m_position;
  391. unsigned m_buttons { 0 };
  392. MouseButton m_button { MouseButton::None };
  393. unsigned m_modifiers { 0 };
  394. int m_wheel_delta_x { 0 };
  395. int m_wheel_delta_y { 0 };
  396. int m_wheel_raw_delta_x { 0 };
  397. int m_wheel_raw_delta_y { 0 };
  398. };
  399. class DragEvent final : public Event {
  400. public:
  401. DragEvent(Type type, Gfx::IntPoint position, Vector<DeprecatedString> mime_types)
  402. : Event(type)
  403. , m_position(position)
  404. , m_mime_types(move(mime_types))
  405. {
  406. }
  407. Gfx::IntPoint position() const { return m_position; }
  408. Vector<DeprecatedString> const& mime_types() const { return m_mime_types; }
  409. private:
  410. Gfx::IntPoint m_position;
  411. Vector<DeprecatedString> m_mime_types;
  412. };
  413. class DropEvent final : public Event {
  414. public:
  415. DropEvent(Gfx::IntPoint, DeprecatedString const& text, NonnullRefPtr<Core::MimeData const> mime_data);
  416. ~DropEvent() = default;
  417. Gfx::IntPoint position() const { return m_position; }
  418. DeprecatedString const& text() const { return m_text; }
  419. Core::MimeData const& mime_data() const { return m_mime_data; }
  420. private:
  421. Gfx::IntPoint m_position;
  422. DeprecatedString m_text;
  423. NonnullRefPtr<Core::MimeData const> m_mime_data;
  424. };
  425. class ThemeChangeEvent final : public Event {
  426. public:
  427. ThemeChangeEvent()
  428. : Event(Type::ThemeChange)
  429. {
  430. }
  431. };
  432. class FontsChangeEvent final : public Event {
  433. public:
  434. FontsChangeEvent()
  435. : Event(Type::FontsChange)
  436. {
  437. }
  438. };
  439. class ScreenRectsChangeEvent final : public Event {
  440. public:
  441. explicit ScreenRectsChangeEvent(Vector<Gfx::IntRect, 4> const& rects, size_t main_screen_index)
  442. : Event(Type::ScreenRectsChange)
  443. , m_rects(rects)
  444. , m_main_screen_index(main_screen_index)
  445. {
  446. }
  447. Vector<Gfx::IntRect, 4> const& rects() const { return m_rects; }
  448. size_t main_screen_index() const { return m_main_screen_index; }
  449. private:
  450. Vector<Gfx::IntRect, 4> m_rects;
  451. size_t m_main_screen_index;
  452. };
  453. class AppletAreaRectChangeEvent final : public Event {
  454. public:
  455. explicit AppletAreaRectChangeEvent(Gfx::IntRect rect)
  456. : Event(Type::AppletAreaRectChange)
  457. , m_rect(rect)
  458. {
  459. }
  460. Gfx::IntRect rect() const { return m_rect; }
  461. private:
  462. Gfx::IntRect const m_rect;
  463. };
  464. class FocusEvent final : public Event {
  465. public:
  466. explicit FocusEvent(Type type, FocusSource source)
  467. : Event(type)
  468. , m_source(source)
  469. {
  470. }
  471. FocusSource source() const { return m_source; }
  472. private:
  473. FocusSource m_source { FocusSource::Programmatic };
  474. };
  475. class ActionEvent final : public Event {
  476. public:
  477. ActionEvent(Type, Action&);
  478. ~ActionEvent() = default;
  479. Action const& action() const { return *m_action; }
  480. Action& action() { return *m_action; }
  481. private:
  482. NonnullRefPtr<Action> m_action;
  483. };
  484. inline StringView mouse_button_to_string(MouseButton key)
  485. {
  486. switch (key) {
  487. case MouseButton::None:
  488. return "None"sv;
  489. case MouseButton::Primary:
  490. return "Primary"sv;
  491. case MouseButton::Secondary:
  492. return "Secondary"sv;
  493. case MouseButton::Middle:
  494. return "Middle"sv;
  495. case MouseButton::Backward:
  496. return "Backward"sv;
  497. case MouseButton::Forward:
  498. return "Forward"sv;
  499. default:
  500. VERIFY_NOT_REACHED();
  501. }
  502. }
  503. }