From f11bb082e46c2551cbd9fc89aed0cd30342d60e6 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Thu, 21 Aug 2025 03:01:25 +0300 Subject: [PATCH] WindowServer/LibGUI: Add window focus events --- userspace/libraries/LibGUI/Window.cpp | 4 +++ .../libraries/LibGUI/include/LibGUI/Packet.h | 9 +++++++ .../libraries/LibGUI/include/LibGUI/Window.h | 2 ++ .../programs/WindowServer/WindowServer.cpp | 27 ++++++++++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index 453f228b7b..4386967b4d 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -335,6 +335,10 @@ namespace LibGUI if (m_window_shown_event_callback) m_window_shown_event_callback(TRY_OR_BREAK(EventPacket::WindowShownEvent::deserialize(packet_data.span())).event); break; + case PacketType::WindowFocusEvent: + if (m_window_focus_event_callback) + m_window_focus_event_callback(TRY_OR_BREAK(EventPacket::WindowFocusEvent::deserialize(packet_data.span())).event); + break; case PacketType::KeyEvent: if (m_key_event_callback) m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event); diff --git a/userspace/libraries/LibGUI/include/LibGUI/Packet.h b/userspace/libraries/LibGUI/include/LibGUI/Packet.h index 67a06e292e..b56029a66b 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Packet.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Packet.h @@ -217,6 +217,7 @@ namespace LibGUI CloseWindowEvent, ResizeWindowEvent, WindowShownEvent, + WindowFocusEvent, KeyEvent, MouseButtonEvent, MouseMoveEvent, @@ -333,6 +334,14 @@ namespace LibGUI event_t, event ); + DEFINE_PACKET_EXTRA( + WindowFocusEvent, + struct event_t { + bool focused; + }, + event_t, event + ); + DEFINE_PACKET_EXTRA( KeyEvent, using event_t = LibInput::KeyEvent, diff --git a/userspace/libraries/LibGUI/include/LibGUI/Window.h b/userspace/libraries/LibGUI/include/LibGUI/Window.h index c29b031f34..456bd3ac93 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -76,6 +76,7 @@ namespace LibGUI void set_mouse_move_event_callback(BAN::Function callback) { m_mouse_move_event_callback = callback; } void set_mouse_scroll_event_callback(BAN::Function callback) { m_mouse_scroll_event_callback = callback; } void set_window_shown_event_callback(BAN::Function callback) { m_window_shown_event_callback = callback; } + void set_window_focus_event_callback(BAN::Function callback) { m_window_focus_event_callback = callback; } int server_fd() const { return m_server_fd; } @@ -108,6 +109,7 @@ namespace LibGUI BAN::Function m_close_window_event_callback; BAN::Function m_resize_window_event_callback; BAN::Function m_window_shown_event_callback; + BAN::Function m_window_focus_event_callback; BAN::Function m_key_event_callback; BAN::Function m_mouse_button_event_callback; BAN::Function m_mouse_move_event_callback; diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp index 7cf23ab5e6..0f98e41fb2 100644 --- a/userspace/programs/WindowServer/WindowServer.cpp +++ b/userspace/programs/WindowServer/WindowServer.cpp @@ -90,7 +90,7 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr window_popper.disable(); - if (packet.attributes.focusable) + if (packet.attributes.shown && packet.attributes.focusable) set_focused_window(window); else if (m_client_windows.size() > 1) BAN::swap(m_client_windows[m_client_windows.size() - 1], m_client_windows[m_client_windows.size() - 2]); @@ -197,6 +197,9 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket:: }; if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error()) dwarnln("could not send window shown event: {}", ret.error()); + + if (packet.attributes.focusable && packet.attributes.shown) + set_focused_window(target_window); } void WindowServer::on_window_set_mouse_relative(int fd, const LibGUI::WindowPacket::WindowSetMouseRelative& packet) @@ -781,6 +784,17 @@ void WindowServer::set_focused_window(BAN::RefPtr window) invalidate(cursor_area()); } + if (m_focused_window) + { + LibGUI::EventPacket::WindowFocusEvent packet; + packet.event.focused = false; + if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error()) + { + dwarnln("could not send window focus event: {}", ret.error()); + return; + } + } + for (size_t i = m_client_windows.size(); i > 0; i--) { if (m_client_windows[i - 1] == window) @@ -792,6 +806,17 @@ void WindowServer::set_focused_window(BAN::RefPtr window) break; } } + + if (m_focused_window) + { + LibGUI::EventPacket::WindowFocusEvent packet; + packet.event.focused = true; + if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error()) + { + dwarnln("could not send window focus event: {}", ret.error()); + return; + } + } } static uint32_t alpha_blend(uint32_t color_a, uint32_t color_b)