From a318a19fe25c40e464f58b842b278dedbbc6667f Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 22 Feb 2026 22:04:20 +0200 Subject: [PATCH] LibGUI/WindowServer: Add fullscreen events When window's fullscreen state changes we now generate events! --- userspace/libraries/LibGUI/Window.cpp | 4 ++ .../libraries/LibGUI/include/LibGUI/Packet.h | 9 +++++ .../libraries/LibGUI/include/LibGUI/Window.h | 38 ++++++++++--------- .../programs/WindowServer/WindowServer.cpp | 33 ++++++++++++++-- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/userspace/libraries/LibGUI/Window.cpp b/userspace/libraries/LibGUI/Window.cpp index 163011d2..5357ab7e 100644 --- a/userspace/libraries/LibGUI/Window.cpp +++ b/userspace/libraries/LibGUI/Window.cpp @@ -348,6 +348,10 @@ namespace LibGUI if (m_window_focus_event_callback) m_window_focus_event_callback(TRY_OR_BREAK(EventPacket::WindowFocusEvent::deserialize(packet_data.span())).event); break; + case PacketType::WindowFullscreenEvent: + if (m_window_fullscreen_event_callback) + m_window_fullscreen_event_callback(TRY_OR_BREAK(EventPacket::WindowFullscreenEvent::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 8ebcc4dc..31a6e6d8 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Packet.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Packet.h @@ -219,6 +219,7 @@ namespace LibGUI ResizeWindowEvent, WindowShownEvent, WindowFocusEvent, + WindowFullscreenEvent, KeyEvent, MouseButtonEvent, MouseMoveEvent, @@ -345,6 +346,14 @@ namespace LibGUI event_t, event ); + DEFINE_PACKET_EXTRA( + WindowFullscreenEvent, + struct event_t { + bool fullscreen; + }, + 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 1a31c4c3..a3ea642c 100644 --- a/userspace/libraries/LibGUI/include/LibGUI/Window.h +++ b/userspace/libraries/LibGUI/include/LibGUI/Window.h @@ -68,15 +68,16 @@ namespace LibGUI void wait_events(); void poll_events(); - void set_socket_error_callback(BAN::Function callback) { m_socket_error_callback = callback; } - void set_close_window_event_callback(BAN::Function callback) { m_close_window_event_callback = callback; } - void set_resize_window_event_callback(BAN::Function callback) { m_resize_window_event_callback = callback; } - void set_key_event_callback(BAN::Function callback) { m_key_event_callback = callback; } - void set_mouse_button_event_callback(BAN::Function callback) { m_mouse_button_event_callback = callback; } - 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; } + void set_socket_error_callback(BAN::Function callback) { m_socket_error_callback = callback; } + void set_close_window_event_callback(BAN::Function callback) { m_close_window_event_callback = callback; } + void set_resize_window_event_callback(BAN::Function callback) { m_resize_window_event_callback = callback; } + void set_key_event_callback(BAN::Function callback) { m_key_event_callback = callback; } + void set_mouse_button_event_callback(BAN::Function callback) { m_mouse_button_event_callback = callback; } + 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; } + void set_window_fullscreen_event_callback(BAN::Function callback) { m_window_fullscreen_event_callback = callback; } int server_fd() const { return m_server_fd; } @@ -107,15 +108,16 @@ namespace LibGUI Texture m_texture; BAN::RefPtr m_root_widget; - BAN::Function m_socket_error_callback; - 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; - BAN::Function m_mouse_scroll_event_callback; + BAN::Function m_socket_error_callback; + 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_window_fullscreen_event_callback; + BAN::Function m_key_event_callback; + BAN::Function m_mouse_button_event_callback; + BAN::Function m_mouse_move_event_callback; + BAN::Function m_mouse_scroll_event_callback; friend class BAN::UniqPtr; }; diff --git a/userspace/programs/WindowServer/WindowServer.cpp b/userspace/programs/WindowServer/WindowServer.cpp index 6bcb20fe..b2ab1dda 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.shown && packet.attributes.focusable) + if (packet.attributes.shown && packet.attributes.focusable && m_state == State::Normal) 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]); @@ -173,9 +173,15 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket:: if ((!packet.attributes.focusable || !packet.attributes.shown) && m_focused_window == target_window) { + if (m_state == State::Fullscreen && m_focused_window->get_attributes().resizable) + { + if (!resize_window(m_focused_window, m_non_full_screen_rect.width, m_non_full_screen_rect.height)) + return; + m_focused_window->set_position({ m_non_full_screen_rect.x, m_non_full_screen_rect.y }); + } + m_focused_window = nullptr; - if (m_state == State::Moving || m_state == State::Resizing) - m_state = State::Normal; + m_state = State::Normal; for (size_t i = m_client_windows.size(); i > 0; i--) { auto& window = m_client_windows[i - 1]; @@ -198,7 +204,7 @@ 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) + if (packet.attributes.focusable && packet.attributes.shown && m_state == State::Normal) set_focused_window(target_window); } @@ -298,6 +304,13 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket:: return; m_focused_window->set_position({ m_non_full_screen_rect.x, m_non_full_screen_rect.y }); } + + auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent { + .event = { .fullscreen = false } + }; + if (auto ret = event_packet.send_serialized(m_focused_window->client_fd()); ret.is_error()) + dwarnln("could not send window fullscreen event: {}", ret.error()); + m_state = State::Normal; invalidate(m_framebuffer.area()); return; @@ -327,6 +340,12 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket:: m_non_full_screen_rect = old_area; } + auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent { + .event = { .fullscreen = true } + }; + if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error()) + dwarnln("could not send window fullscreen event: {}", ret.error()); + m_state = State::Fullscreen; set_focused_window(target_window); invalidate(m_framebuffer.area()); @@ -483,6 +502,12 @@ void WindowServer::on_key_event(LibInput::KeyEvent event) m_state = State::Fullscreen; } + auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent { + .event = { .fullscreen = (m_state == State::Fullscreen) } + }; + if (auto ret = event_packet.send_serialized(m_focused_window->client_fd()); ret.is_error()) + dwarnln("could not send window fullscreen event: {}", ret.error()); + invalidate(m_framebuffer.area()); return; }