diff --git a/Kernel/GUITypes.h b/Kernel/GUITypes.h index 3b25fe0a088..49b4de3fddb 100644 --- a/Kernel/GUITypes.h +++ b/Kernel/GUITypes.h @@ -80,7 +80,11 @@ struct GUI_Event { } mouse; struct { char character; - unsigned modifiers; + byte key; + byte modifiers; + bool ctrl : 1; + bool alt : 1; + bool shift : 1; } key; }; }; diff --git a/Kernel/ProcessGUI.cpp b/Kernel/ProcessGUI.cpp index 2fc30ea5781..8109ee42629 100644 --- a/Kernel/ProcessGUI.cpp +++ b/Kernel/ProcessGUI.cpp @@ -120,10 +120,10 @@ int Process::gui$invalidate_window(int window_id, const GUI_Rect* rect) dbgprintf("%s<%u> gui$invalidate_window (window_id=%d, rect={%d,%d %dx%d})\n", name().characters(), pid(), window_id, rect->location.x, rect->location.y, rect->size.width, rect->size.height); #endif auto& window = *(*it).value; - auto event = make(WSEvent::WM_Invalidate); + Rect invalidation_rect; if (rect) - event->set_rect(*rect); - WSEventLoop::the().post_event(&window, move(event)); + invalidation_rect = *rect; + WSEventLoop::the().post_event(&window, make(invalidation_rect)); WSEventLoop::the().server_process().request_wakeup(); return 0; } diff --git a/WindowServer/WSEvent.h b/WindowServer/WSEvent.h index dab48e24563..b94a937d403 100644 --- a/WindowServer/WSEvent.h +++ b/WindowServer/WSEvent.h @@ -49,24 +49,30 @@ public: const char* name() const { return WSEvent_names[(unsigned)m_type]; } - bool isMouseEvent() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; } - bool isKeyEvent() const { return m_type == KeyUp || m_type == KeyDown; } - bool isPaintEvent() const { return m_type == Paint; } - - Rect rect() const { return m_rect; } - void set_rect(const GUI_Rect& rect) - { - m_rect = rect; - } + bool is_mouse_event() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; } + bool is_key_event() const { return m_type == KeyUp || m_type == KeyDown; } + bool is_paint_event() const { return m_type == Paint; } private: Type m_type { Invalid }; +}; + +class WSWindowInvalidationEvent final : public WSEvent { +public: + explicit WSWindowInvalidationEvent(const Rect& rect = Rect()) + : WSEvent(WSEvent::WM_Invalidate) + , m_rect(rect) + { + } + + const Rect& rect() const { return m_rect; } +private: Rect m_rect; }; -class PaintEvent final : public WSEvent { +class WSPaintEvent final : public WSEvent { public: - explicit PaintEvent(const Rect& rect = Rect()) + explicit WSPaintEvent(const Rect& rect = Rect()) : WSEvent(WSEvent::Paint) , m_rect(rect) { @@ -85,21 +91,12 @@ enum class MouseButton : byte { Middle = 4, }; -enum KeyboardKey { - Invalid, - LeftArrow, - RightArrow, - UpArrow, - DownArrow, - Backspace, - Return, -}; - -class KeyEvent final : public WSEvent { +class WSKeyEvent final : public WSEvent { public: - KeyEvent(Type type, int key) + WSKeyEvent(Type type, int key, char character) : WSEvent(type) , m_key(key) + , m_character(character) { } @@ -107,7 +104,7 @@ public: bool ctrl() const { return m_ctrl; } bool alt() const { return m_alt; } bool shift() const { return m_shift; } - String text() const { return m_text; } + char character() const { return m_character; } private: friend class WSEventLoop; @@ -116,12 +113,12 @@ private: bool m_ctrl { false }; bool m_alt { false }; bool m_shift { false }; - String m_text; + char m_character { 0 }; }; -class MouseEvent final : public WSEvent { +class WSMouseEvent final : public WSEvent { public: - MouseEvent(Type type, const Point& position, unsigned buttons, MouseButton button = MouseButton::None) + WSMouseEvent(Type type, const Point& position, unsigned buttons, MouseButton button = MouseButton::None) : WSEvent(type) , m_position(position) , m_buttons(buttons) diff --git a/WindowServer/WSEventLoop.cpp b/WindowServer/WSEventLoop.cpp index 041e38b5819..948a1038810 100644 --- a/WindowServer/WSEventLoop.cpp +++ b/WindowServer/WSEventLoop.cpp @@ -80,14 +80,16 @@ void WSEventLoop::post_event(WSEventReceiver* receiver, OwnPtr&& event) #endif if (event->type() == WSEvent::WM_Invalidate) { + auto& invalidation_event = static_cast(*event); for (auto& queued_event : m_queued_events) { - if (receiver == queued_event.receiver - && queued_event.event->type() == WSEvent::WM_Invalidate - && (queued_event.event->rect().is_empty() || queued_event.event->rect().contains(event->rect()))) { + if (receiver == queued_event.receiver && queued_event.event->type() == WSEvent::WM_Invalidate) { + auto& queued_invalidation_event = static_cast(*queued_event.event); + if (queued_invalidation_event.rect().is_empty() || queued_invalidation_event.rect().contains(invalidation_event.rect())) { #ifdef WSEVENTLOOP_DEBUG - dbgprintf("Swallow WM_Invalidate\n"); + dbgprintf("Swallow WM_Invalidate\n"); #endif - return; + return; + } } } } diff --git a/WindowServer/WSScreen.cpp b/WindowServer/WSScreen.cpp index e74a36a2e85..2634f2b0188 100644 --- a/WindowServer/WSScreen.cpp +++ b/WindowServer/WSScreen.cpp @@ -47,7 +47,7 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ if (right_button) buttons |= (unsigned)MouseButton::Right; if (m_cursor_location != prev_location) { - auto event = make(WSEvent::MouseMove, m_cursor_location, buttons); + auto event = make(WSEvent::MouseMove, m_cursor_location, buttons); WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); } bool prev_left_button = m_left_mouse_button_pressed; @@ -55,38 +55,22 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ m_left_mouse_button_pressed = left_button; m_right_mouse_button_pressed = right_button; if (prev_left_button != left_button) { - auto event = make(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left); + auto event = make(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left); WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); } if (prev_right_button != right_button) { - auto event = make(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right); + auto event = make(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right); WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); } if (m_cursor_location != prev_location || prev_left_button != left_button) WSWindowManager::the().draw_cursor(); } -void WSScreen::on_receive_keyboard_data(Keyboard::Event key) +void WSScreen::on_receive_keyboard_data(Keyboard::Event kernel_event) { - auto event = make(key.is_press() ? WSEvent::KeyDown : WSEvent::KeyUp, 0); - int key_code = 0; - - switch (key.character) { - case 8: key_code = KeyboardKey::Backspace; break; - case 10: key_code = KeyboardKey::Return; break; - } - event->m_key = key_code; - - if (key.character) { - char buf[] = { 0, 0 }; - char& ch = buf[0]; - ch = key.character; - event->m_text = buf; - } - - event->m_shift = key.shift(); - event->m_ctrl = key.ctrl(); - event->m_alt = key.alt(); - + auto event = make(kernel_event.is_press() ? WSEvent::KeyDown : WSEvent::KeyUp, kernel_event.key, kernel_event.character); + event->m_shift = kernel_event.shift(); + event->m_ctrl = kernel_event.ctrl(); + event->m_alt = kernel_event.alt(); WSEventLoop::the().post_event(&WSWindowManager::the(), move(event)); } diff --git a/WindowServer/WSWindow.cpp b/WindowServer/WSWindow.cpp index 606fb1e24c2..4ae135863c8 100644 --- a/WindowServer/WSWindow.cpp +++ b/WindowServer/WSWindow.cpp @@ -55,32 +55,36 @@ void WSWindow::event(WSEvent& event) switch (event.type()) { case WSEvent::Paint: gui_event.type = GUI_Event::Type::Paint; - gui_event.paint.rect = static_cast(event).rect(); + gui_event.paint.rect = static_cast(event).rect(); break; case WSEvent::MouseMove: gui_event.type = GUI_Event::Type::MouseMove; - gui_event.mouse.position = static_cast(event).position(); + gui_event.mouse.position = static_cast(event).position(); gui_event.mouse.button = GUI_MouseButton::NoButton; - gui_event.mouse.buttons = static_cast(event).buttons(); + gui_event.mouse.buttons = static_cast(event).buttons(); break; case WSEvent::MouseDown: gui_event.type = GUI_Event::Type::MouseDown; - gui_event.mouse.position = static_cast(event).position(); - gui_event.mouse.button = to_api(static_cast(event).button()); - gui_event.mouse.buttons = static_cast(event).buttons(); + gui_event.mouse.position = static_cast(event).position(); + gui_event.mouse.button = to_api(static_cast(event).button()); + gui_event.mouse.buttons = static_cast(event).buttons(); break; case WSEvent::MouseUp: gui_event.type = GUI_Event::Type::MouseUp; - gui_event.mouse.position = static_cast(event).position(); - gui_event.mouse.button = to_api(static_cast(event).button()); - gui_event.mouse.buttons = static_cast(event).buttons(); + gui_event.mouse.position = static_cast(event).position(); + gui_event.mouse.button = to_api(static_cast(event).button()); + gui_event.mouse.buttons = static_cast(event).buttons(); break; case WSEvent::KeyDown: gui_event.type = GUI_Event::Type::KeyDown; - gui_event.key.character = static_cast(event).text()[0]; + gui_event.key.character = static_cast(event).character(); + gui_event.key.key = static_cast(event).key(); + gui_event.key.alt = static_cast(event).alt(); + gui_event.key.ctrl = static_cast(event).ctrl(); + gui_event.key.shift = static_cast(event).shift(); break; case WSEvent::WM_Invalidate: - WSWindowManager::the().invalidate(*this, event.rect()); + WSWindowManager::the().invalidate(*this, static_cast(event).rect()); return; case WSEvent::WindowActivated: gui_event.type = GUI_Event::Type::WindowActivated; diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index 2e9e15ec16f..f6e34dd1af0 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -231,7 +231,7 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect invalidate(outer_window_rect(new_rect)); } -void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, MouseEvent& event) +void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, WSMouseEvent& event) { if (event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) { #ifdef DRAG_DEBUG @@ -247,7 +247,7 @@ void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, MouseEvent& } } -void WSWindowManager::process_mouse_event(MouseEvent& event) +void WSWindowManager::process_mouse_event(WSMouseEvent& event) { if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) { if (m_drag_window) { @@ -294,7 +294,7 @@ void WSWindowManager::process_mouse_event(MouseEvent& event) } // FIXME: Should we just alter the coordinates of the existing MouseEvent and pass it through? Point position { event.x() - window->rect().x(), event.y() - window->rect().y() }; - auto local_event = make(event.type(), position, event.buttons(), event.button()); + auto local_event = make(event.type(), position, event.buttons(), event.button()); window->event(*local_event); return; } @@ -379,10 +379,10 @@ void WSWindowManager::event(WSEvent& event) { ASSERT_INTERRUPTS_ENABLED(); LOCKER(m_lock); - if (event.isMouseEvent()) - return process_mouse_event(static_cast(event)); + if (event.is_mouse_event()) + return process_mouse_event(static_cast(event)); - if (event.isKeyEvent()) { + if (event.is_key_event()) { // FIXME: This is a good place to hook key events globally. :) if (m_active_window) return m_active_window->event(event); diff --git a/WindowServer/WSWindowManager.h b/WindowServer/WSWindowManager.h index c695751d329..ead8d2e7db0 100644 --- a/WindowServer/WSWindowManager.h +++ b/WindowServer/WSWindowManager.h @@ -10,8 +10,8 @@ #include "WSEventReceiver.h" class WSScreen; -class MouseEvent; -class PaintEvent; +class WSMouseEvent; +class WSPaintEvent; class WSWindow; class CharacterBitmap; class GraphicsBitmap; @@ -43,8 +43,8 @@ private: WSWindowManager(); virtual ~WSWindowManager() override; - void process_mouse_event(MouseEvent&); - void handle_titlebar_mouse_event(WSWindow&, MouseEvent&); + void process_mouse_event(WSMouseEvent&); + void handle_titlebar_mouse_event(WSWindow&, WSMouseEvent&); void set_active_window(WSWindow*);