diff --git a/Applications/Launcher/main.cpp b/Applications/Launcher/main.cpp index 4224730eac..2004da1a1b 100644 --- a/Applications/Launcher/main.cpp +++ b/Applications/Launcher/main.cpp @@ -65,8 +65,8 @@ GWindow* make_launcher_window() auto* window = new GWindow; window->set_title("Launcher"); - window->set_rect(50, 50, - 50, config->groups().size() * 55); + window->set_rect(50, 50, 50, config->groups().size() * 55 + 15); + window->set_show_titlebar(false); auto* widget = new GWidget; widget->set_fill_with_background_color(true); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index da6ea1fccd..2f6c0207fa 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -62,6 +62,7 @@ void GWindow::show() request.window.modal = m_modal; request.window.resizable = m_resizable; request.window.fullscreen = m_fullscreen; + request.window.show_titlebar = m_show_titlebar; request.window.opacity = m_opacity_when_windowless; request.window.background_color = m_background_color.value(); request.window.size_increment = m_size_increment; diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index b3f113d0df..c1b3d10cd3 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -46,6 +46,9 @@ public: String title() const; void set_title(const String&); + bool show_titlebar() const { return m_show_titlebar; }; + void set_show_titlebar(bool show) { m_show_titlebar = show; }; + Color background_color() const { return m_background_color; } void set_background_color(Color color) { m_background_color = color; } @@ -154,4 +157,5 @@ private: bool m_modal { false }; bool m_resizable { true }; bool m_fullscreen { false }; + bool m_show_titlebar { true }; }; diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 09c956d85b..9d2d9b6285 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -265,6 +265,7 @@ struct WSAPI_ClientMessage { bool modal; bool resizable; bool fullscreen; + bool show_titlebar; WSAPI_WindowType type; float opacity; WSAPI_Size base_size; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 42353a4a68..c913cba1cd 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -494,6 +494,7 @@ void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request) window->set_title(request.title()); if (!request.is_fullscreen()) window->set_rect(request.rect()); + window->set_show_titlebar(request.show_titlebar()); 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 8f8fe983bc..635f7bb6e6 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, bool fullscreen, 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, bool show_titlebar, 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) @@ -590,6 +590,7 @@ public: , m_modal(modal) , m_resizable(resizable) , m_fullscreen(fullscreen) + , m_show_titlebar(show_titlebar) , m_size_increment(size_increment) , m_base_size(base_size) , m_window_type(window_type) @@ -603,6 +604,7 @@ public: bool is_modal() const { return m_modal; } bool is_resizable() const { return m_resizable; } bool is_fullscreen() const { return m_fullscreen; } + bool show_titlebar() const { return m_show_titlebar; } float opacity() const { return m_opacity; } Size size_increment() const { return m_size_increment; } Size base_size() const { return m_base_size; } @@ -617,6 +619,7 @@ private: bool m_modal { false }; bool m_resizable { false }; bool m_fullscreen { false }; + bool m_show_titlebar { true }; 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 096ecf27d7..db4ffdfe5f 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -114,6 +114,7 @@ static WSWindowType from_api(WSAPI_WindowType api_type) case WSAPI_WindowType::Tooltip: return WSWindowType::Tooltip; default: + dbgprintf("Unknown WSAPI_WindowType: %d\n", api_type); ASSERT_NOT_REACHED(); } } @@ -206,7 +207,20 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag client.did_misbehave(); return false; } - post_event(client, make(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))); + post_event(client, + make(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.show_titlebar, + 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(client_id, message.window_id)); diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index 7ef0e27608..1f76a25c8a 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -34,6 +34,9 @@ public: bool is_fullscreen() const { return m_fullscreen; } + bool show_titlebar() const { return m_show_titlebar; } + void set_show_titlebar(bool show) { m_show_titlebar = show; } + WSWindowFrame& frame() { return m_frame; } const WSWindowFrame& frame() const { return m_frame; } @@ -158,6 +161,7 @@ private: bool m_minimized { false }; bool m_maximized { false }; bool m_fullscreen { false }; + bool m_show_titlebar { true }; RetainPtr m_backing_store; RetainPtr m_last_backing_store; int m_window_id { -1 }; diff --git a/Servers/WindowServer/WSWindowFrame.cpp b/Servers/WindowServer/WSWindowFrame.cpp index c4747e8b85..2defdd9035 100644 --- a/Servers/WindowServer/WSWindowFrame.cpp +++ b/Servers/WindowServer/WSWindowFrame.cpp @@ -195,6 +195,12 @@ void WSWindowFrame::paint(Painter& painter) middle_border_color = Color::MidGray; } + painter.draw_line(titlebar_rect.bottom_left().translated(0, 1), titlebar_rect.bottom_right().translated(0, 1), Color::LightGray); + StylePainter::paint_window_frame(painter, outer_rect); + + if (!window.show_titlebar()) + return; + auto leftmost_button_rect = m_buttons.is_empty() ? Rect() : m_buttons.last()->relative_rect(); painter.fill_rect_with_gradient(titlebar_rect, border_color, border_color2); @@ -202,8 +208,6 @@ void WSWindowFrame::paint(Painter& painter) painter.draw_line({ titlebar_title_rect.right() + 4, titlebar_inner_rect.y() + i }, { leftmost_button_rect.left() - 3, titlebar_inner_rect.y() + i }, border_color); } - painter.draw_line(titlebar_rect.bottom_left().translated(0, 1), titlebar_rect.bottom_right().translated(0, 1), Color::LightGray); - StylePainter::paint_window_frame(painter, outer_rect); // FIXME: The translated(0, 1) wouldn't be necessary if we could center text based on its baseline. painter.draw_text(titlebar_title_rect.translated(0, 1), window.title(), wm.window_title_font(), TextAlignment::CenterLeft, title_color); @@ -215,19 +219,30 @@ void WSWindowFrame::paint(Painter& painter) } } -static Rect frame_rect_for_window_type(WSWindowType type, const Rect& rect) +static Rect frame_rect_for_window(WSWindow& window, const Rect& rect) { + auto type = window.type(); + auto offset = !window.show_titlebar() ? window_titlebar_height : 0; + switch (type) { case WSWindowType::Normal: - return { rect.x() - 3, rect.y() - window_titlebar_height - 3, rect.width() + 6, rect.height() + 6 + window_titlebar_height }; + return { rect.x() - 3, + rect.y() - window_titlebar_height - 3 + offset, + rect.width() + 6, + rect.height() + 6 + window_titlebar_height - offset }; default: return rect; } } +static Rect frame_rect_for_window(WSWindow& window) +{ + return frame_rect_for_window(window, window.rect()); +} + Rect WSWindowFrame::rect() const { - return frame_rect_for_window_type(m_window.type(), m_window.rect()); + return frame_rect_for_window(m_window); } void WSWindowFrame::invalidate_title_bar() @@ -248,8 +263,8 @@ void WSWindowFrame::notify_window_rect_changed(const Rect& old_rect, const Rect& } auto& wm = WSWindowManager::the(); - wm.invalidate(frame_rect_for_window_type(m_window.type(), old_rect)); - wm.invalidate(frame_rect_for_window_type(m_window.type(), new_rect)); + wm.invalidate(frame_rect_for_window(m_window, old_rect)); + wm.invalidate(frame_rect_for_window(m_window, new_rect)); wm.notify_rect_changed(m_window, old_rect, new_rect); }