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