diff options
Diffstat (limited to 'Servers/WindowServer')
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.cpp | 9 | ||||
-rw-r--r-- | Servers/WindowServer/WSEvent.h | 5 | ||||
-rw-r--r-- | Servers/WindowServer/WSEventLoop.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.cpp | 3 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 7 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowFrame.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 30 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.h | 3 |
9 files changed, 49 insertions, 13 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 2f54a0beaa..071c138e81 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -264,6 +264,7 @@ struct WSAPI_ClientMessage { bool has_alpha_channel; bool modal; bool resizable; + bool fullscreen; WSAPI_WindowType type; float opacity; WSAPI_Size base_size; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 81ba62134d..6f3a3da9aa 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -413,6 +413,10 @@ void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request return; } auto& window = *(*it).value; + if (window.is_fullscreen()) { + dbgprintf("WSClientConnection: Ignoring SetWindowRect request for fullscreen window\n"); + return; + } window.set_rect(request.rect()); window.request_update(request.rect()); } @@ -474,11 +478,12 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&) void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request) { int window_id = m_next_window_id++; - auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal(), request.is_resizable()); + auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal(), request.is_resizable(), request.is_fullscreen()); window->set_background_color(request.background_color()); window->set_has_alpha_channel(request.has_alpha_channel()); window->set_title(request.title()); - window->set_rect(request.rect()); + if (!request.is_fullscreen()) + window->set_rect(request.rect()); window->set_opacity(request.opacity()); window->set_size_increment(request.size_increment()); window->set_base_size(request.base_size()); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 72cd89c2f0..8f8fe983bc 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -581,7 +581,7 @@ private: class WSAPICreateWindowRequest : public WSAPIClientRequest { public: - WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color) + WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, bool fullscreen, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color) : WSAPIClientRequest(WSEvent::APICreateWindowRequest, client_id) , m_rect(rect) , m_title(title) @@ -589,6 +589,7 @@ public: , m_has_alpha_channel(has_alpha_channel) , m_modal(modal) , m_resizable(resizable) + , m_fullscreen(fullscreen) , m_size_increment(size_increment) , m_base_size(base_size) , m_window_type(window_type) @@ -601,6 +602,7 @@ public: bool has_alpha_channel() const { return m_has_alpha_channel; } bool is_modal() const { return m_modal; } bool is_resizable() const { return m_resizable; } + bool is_fullscreen() const { return m_fullscreen; } float opacity() const { return m_opacity; } Size size_increment() const { return m_size_increment; } Size base_size() const { return m_base_size; } @@ -614,6 +616,7 @@ private: bool m_has_alpha_channel { false }; bool m_modal { false }; bool m_resizable { false }; + bool m_fullscreen { false }; Size m_size_increment; Size m_base_size; WSWindowType m_window_type; diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp index e32ec7343f..904dfca2fc 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -185,7 +185,7 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag break; case WSAPI_ClientMessage::Type::CreateWindow: ASSERT(message.text_length < (ssize_t)sizeof(message.text)); - post_event(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type), Color::from_rgba(message.window.background_color))); + post_event(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.fullscreen, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type), Color::from_rgba(message.window.background_color))); break; case WSAPI_ClientMessage::Type::DestroyWindow: post_event(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id)); diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 88561122c8..a6a85ff79b 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -28,11 +28,12 @@ WSWindow::WSWindow(CObject& internal_owner, WSWindowType type) WSWindowManager::the().add_window(*this); } -WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal, bool resizable) +WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal, bool resizable, bool fullscreen) : m_client(&client) , m_type(window_type) , m_modal(modal) , m_resizable(resizable) + , m_fullscreen(fullscreen) , m_window_id(window_id) , m_icon(default_window_icon()) , m_icon_path(default_window_icon_path()) diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index 5c9fad376b..7ef0e27608 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -16,7 +16,7 @@ class WSMouseEvent; class WSWindow final : public CObject, public InlineLinkedListNode<WSWindow> { public: - WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool resizable); + WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool resizable, bool fullscreen); WSWindow(CObject&, WSWindowType); virtual ~WSWindow() override; @@ -32,6 +32,8 @@ public: bool is_maximized() const { return m_maximized; } void set_maximized(bool); + bool is_fullscreen() const { return m_fullscreen; } + WSWindowFrame& frame() { return m_frame; } const WSWindowFrame& frame() const { return m_frame; } @@ -63,7 +65,7 @@ public: bool is_modal() const { return m_modal; } - bool is_resizable() const { return m_resizable; } + bool is_resizable() const { return m_resizable && !m_fullscreen; } Rect rect() const { return m_rect; } void set_rect(const Rect&); @@ -155,6 +157,7 @@ private: bool m_listens_to_wm_events { false }; bool m_minimized { false }; bool m_maximized { false }; + bool m_fullscreen { false }; RetainPtr<GraphicsBitmap> m_backing_store; RetainPtr<GraphicsBitmap> m_last_backing_store; int m_window_id { -1 }; diff --git a/Servers/WindowServer/WSWindowFrame.cpp b/Servers/WindowServer/WSWindowFrame.cpp index 14e58319d9..ebe9ef3aef 100644 --- a/Servers/WindowServer/WSWindowFrame.cpp +++ b/Servers/WindowServer/WSWindowFrame.cpp @@ -254,6 +254,8 @@ void WSWindowFrame::notify_window_rect_changed(const Rect& old_rect, const Rect& void WSWindowFrame::on_mouse_event(const WSMouseEvent& event) { + ASSERT(!m_window.is_fullscreen()); + auto& wm = WSWindowManager::the(); if (m_window.type() != WSWindowType::Normal) return; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 1dc166d217..d3e893c43d 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -311,6 +311,12 @@ void WSWindowManager::add_window(WSWindow& window) { m_windows.set(&window); m_windows_in_order.append(&window); + + if (window.is_fullscreen()) { + WSEventLoop::the().post_event(window, make<WSResizeEvent>(window.rect(), m_screen_rect)); + window.set_rect(m_screen_rect); + } + set_active_window(&window); if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) m_switcher.refresh(); @@ -792,7 +798,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere // First check if we should initiate a drag or resize (Logo+LMB or Logo+RMB). // In those cases, the event is swallowed by the window manager. if (window.type() == WSWindowType::Normal) { - if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) { + if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) { hovered_window = &window; start_window_drag(window, event); return IterationDecision::Abort; @@ -913,7 +919,7 @@ void WSWindowManager::compose() m_back_painter->blit(dirty_rect.location(), *m_wallpaper, dirty_rect); } - for_each_visible_window_from_back_to_front([&] (WSWindow& window) { + auto compose_window = [&] (WSWindow& window) -> IterationDecision { if (!any_dirty_rect_intersects_window(window)) return IterationDecision::Continue; PainterStateSaver saver(*m_back_painter); @@ -926,7 +932,8 @@ void WSWindowManager::compose() m_back_painter->add_clip_rect(dirty_rect); if (!backing_store) m_back_painter->fill_rect(dirty_rect, window.background_color()); - window.frame().paint(*m_back_painter); + if (!window.is_fullscreen()) + window.frame().paint(*m_back_painter); if (!backing_store) continue; Rect dirty_rect_in_window_coordinates = Rect::intersection(dirty_rect, window.rect()); @@ -949,10 +956,19 @@ void WSWindowManager::compose() } } return IterationDecision::Continue; - }); + }; + + if (auto* fullscreen_window = active_fullscreen_window()) { + compose_window(*fullscreen_window); + } else { + for_each_visible_window_from_back_to_front([&] (WSWindow& window) { + return compose_window(window); + }); + + draw_geometry_label(); + draw_menubar(); + } - draw_geometry_label(); - draw_menubar(); draw_cursor(); if (m_flash_flush) { @@ -977,6 +993,8 @@ void WSWindowManager::invalidate_cursor() Rect WSWindowManager::menubar_rect() const { + if (active_fullscreen_window()) + return { }; return { 0, 0, m_screen_rect.width(), 18 }; } diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 4c11c5e95f..cddb2fe714 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -122,6 +122,9 @@ public: void start_window_resize(WSWindow&, const Point&, MouseButton); void start_window_resize(WSWindow&, const WSMouseEvent&); + const WSWindow* active_fullscreen_window() const { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; } + WSWindow* active_fullscreen_window() { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; } + private: void process_mouse_event(WSMouseEvent&, WSWindow*& hovered_window); void deliver_mouse_event(WSWindow& window, WSMouseEvent& event); |