diff --git a/Libraries/LibGUI/GWindow.cpp b/Libraries/LibGUI/GWindow.cpp index d341bef2564..997b587e789 100644 --- a/Libraries/LibGUI/GWindow.cpp +++ b/Libraries/LibGUI/GWindow.cpp @@ -714,3 +714,18 @@ void GWindow::save_to(AK::JsonObject& json) json.set("size_increment", size_increment().to_string()); CObject::save_to(json); } + +void GWindow::set_fullscreen(bool fullscreen) +{ + if (m_fullscreen == fullscreen) + return; + m_fullscreen = fullscreen; + if (!m_window_id) + return; + + WSAPI_ClientMessage request; + request.type = WSAPI_ClientMessage::Type::SetFullscreen; + request.window_id = m_window_id; + request.value = fullscreen; + GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetFullscreen); +} diff --git a/Libraries/LibGUI/GWindow.h b/Libraries/LibGUI/GWindow.h index e563cb13229..7591a66ad8a 100644 --- a/Libraries/LibGUI/GWindow.h +++ b/Libraries/LibGUI/GWindow.h @@ -33,7 +33,7 @@ public: void set_modal(bool); bool is_fullscreen() const { return m_fullscreen; } - void set_fullscreen(bool fullscreen) { m_fullscreen = fullscreen; } + void set_fullscreen(bool); bool is_resizable() const { return m_resizable; } void set_resizable(bool resizable) { m_resizable = resizable; } diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 501ba20ba0a..bdb14ebf84c 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -113,6 +113,7 @@ struct WSAPI_ServerMessage { DidSetWindowHasAlphaChannel, ScreenRectChanged, ClipboardContentsChanged, + DidSetFullscreen, __Begin_WM_Events__, WM_WindowRemoved, @@ -237,6 +238,7 @@ struct WSAPI_ClientMessage { SetWindowHasAlphaChannel, MoveWindowToFront, SetWindowIconBitmap, + SetFullscreen, }; Type type { Invalid }; int window_id { -1 }; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index c583c304997..6bf2dae12fc 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -330,6 +330,9 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, cons case WSAPI_ClientMessage::Type::MoveWindowToFront: CEventLoop::current().post_event(*this, make(client_id(), message.window_id)); break; + case WSAPI_ClientMessage::Type::SetFullscreen: + CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.value)); + break; default: break; } @@ -544,6 +547,23 @@ void WSClientConnection::handle_request(const WSAPIMoveWindowToFrontRequest& req WSWindowManager::the().move_to_front_and_make_active(window); } +void WSClientConnection::handle_request(const WSAPISetFullscreenRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("WSAPISetFullscreenRequest: Bad window ID"); + return; + } + auto& window = *(*it).value; + window.set_fullscreen(request.fullscreen()); + + WSAPI_ServerMessage response; + response.type = WSAPI_ServerMessage::Type::DidSetFullscreen; + response.window_id = window_id; + post_message(response); +} + void WSClientConnection::handle_request(const WSAPISetWindowOpacityRequest& request) { int window_id = request.window_id(); @@ -1038,6 +1058,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast(request)); case WSEvent::APIMoveWindowToFrontRequest: return handle_request(static_cast(request)); + case WSEvent::APISetFullscreenRequest: + return handle_request(static_cast(request)); default: break; } diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index 65fc37de6a7..55cdec0bc32 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -84,6 +84,7 @@ private: void handle_request(const WSAPIDismissMenuRequest&); void handle_request(const WSAPISetWindowHasAlphaChannelRequest&); void handle_request(const WSAPIMoveWindowToFrontRequest&); + void handle_request(const WSAPISetFullscreenRequest&); void post_error(const String&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index d829b432158..0a6f556edac 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -65,6 +65,7 @@ public: APISetWindowOverrideCursorRequest, APISetWindowHasAlphaChannelRequest, APIMoveWindowToFrontRequest, + APISetFullscreenRequest, WMAPISetActiveWindowRequest, WMAPISetWindowMinimizedRequest, WMAPIStartWindowResizeRequest, @@ -502,6 +503,23 @@ private: int m_window_id { 0 }; }; +class WSAPISetFullscreenRequest final : public WSAPIClientRequest { +public: + explicit WSAPISetFullscreenRequest(int client_id, int window_id, bool fullscreen) + : WSAPIClientRequest(WSEvent::APISetFullscreenRequest, client_id) + , m_window_id(window_id) + , m_fullscreen(fullscreen) + { + } + + int window_id() const { return m_window_id; } + bool fullscreen() const { return m_fullscreen; } + +private: + int m_window_id { 0 }; + bool m_fullscreen; +}; + class WSAPISetClipboardContentsRequest final : public WSAPIClientRequest { public: explicit WSAPISetClipboardContentsRequest(int client_id, int shared_buffer_id, int size, const String& data_type) diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 93b037ce97a..18a235a1d6e 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -1,6 +1,7 @@ #include "WSWindow.h" #include "WSEvent.h" #include "WSEventLoop.h" +#include "WSScreen.h" #include "WSWindowManager.h" #include #include @@ -354,3 +355,19 @@ void WSWindow::request_close() WSEvent close_request(WSEvent::WindowCloseRequest); event(close_request); } + +void WSWindow::set_fullscreen(bool fullscreen) +{ + if (m_fullscreen == fullscreen) + return; + m_fullscreen = fullscreen; + Rect new_window_rect = m_rect; + if (m_fullscreen) { + m_saved_nonfullscreen_rect = m_rect; + new_window_rect = WSScreen::the().rect(); + } else if (!m_saved_nonfullscreen_rect.is_empty()) { + new_window_rect = m_saved_nonfullscreen_rect; + } + CEventLoop::current().post_event(*this, make(m_rect, new_window_rect)); + set_rect(new_window_rect); +} diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index aa01ae77312..c014c9df811 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -38,6 +38,7 @@ public: void set_maximized(bool); bool is_fullscreen() const { return m_fullscreen; } + void set_fullscreen(bool); bool show_titlebar() const { return m_show_titlebar; } void set_show_titlebar(bool show) { m_show_titlebar = show; } @@ -155,6 +156,7 @@ private: WSClientConnection* m_client { nullptr }; String m_title; Rect m_rect; + Rect m_saved_nonfullscreen_rect; WSWindowType m_type { WSWindowType::Normal }; bool m_global_cursor_tracking_enabled { false }; bool m_automatic_cursor_tracking_enabled { false };