From 176155c695113cec5a2a13e9fc419061c5b2663a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 21 Oct 2021 09:09:58 -0400 Subject: [PATCH] LibGUI+WindowServer: Add option to hide a widow's close button This allows windows to be closed only programatically, and not from e.g. the user clicking the X button on the window frame. --- Userland/Libraries/LibGUI/Window.cpp | 1 + Userland/Libraries/LibGUI/Window.h | 4 ++++ Userland/Services/WindowServer/ClientConnection.cpp | 4 ++-- Userland/Services/WindowServer/ClientConnection.h | 2 +- Userland/Services/WindowServer/Window.cpp | 13 ++++++++++++- Userland/Services/WindowServer/Window.h | 6 +++++- Userland/Services/WindowServer/WindowFrame.cpp | 5 +++-- Userland/Services/WindowServer/WindowServer.ipc | 1 + 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 7995d73671..5dd3eb1ea9 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -142,6 +142,7 @@ void Window::show() m_has_alpha_channel, m_modal, m_minimizable, + m_closeable, m_resizable, m_fullscreen, m_frameless, diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index d406aea77b..e472873215 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -53,6 +53,9 @@ public: bool is_minimizable() const { return m_minimizable; } void set_minimizable(bool minimizable) { m_minimizable = minimizable; } + bool is_closeable() const { return m_closeable; } + void set_closeable(bool closeable) { m_closeable = closeable; } + void set_double_buffering_enabled(bool); void set_has_alpha_channel(bool); bool has_alpha_channel() const { return m_has_alpha_channel; } @@ -269,6 +272,7 @@ private: bool m_resizable { true }; Optional m_resize_aspect_ratio {}; bool m_minimizable { true }; + bool m_closeable { true }; bool m_maximized_when_windowless { false }; bool m_fullscreen { false }; bool m_frameless { false }; diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index 71c66b7c75..46604f5ce2 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/Userland/Services/WindowServer/ClientConnection.cpp @@ -481,7 +481,7 @@ Window* ClientConnection::window_from_id(i32 window_id) } void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect, - bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool resizable, + bool auto_position, bool has_alpha_channel, bool modal, bool minimizable, bool closeable, bool resizable, bool fullscreen, bool frameless, bool forced_shadow, bool accessory, float opacity, float alpha_hit_threshold, Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment, Gfx::IntSize const& minimum_size, Optional const& resize_aspect_ratio, i32 type, @@ -506,7 +506,7 @@ void ClientConnection::create_window(i32 window_id, Gfx::IntRect const& rect, return; } - auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, frameless, resizable, fullscreen, accessory, parent_window); + auto window = Window::construct(*this, (WindowType)type, window_id, modal, minimizable, closeable, frameless, resizable, fullscreen, accessory, parent_window); window->set_forced_shadow(forced_shadow); diff --git a/Userland/Services/WindowServer/ClientConnection.h b/Userland/Services/WindowServer/ClientConnection.h index 4a0cdab5c0..3e7def4af4 100644 --- a/Userland/Services/WindowServer/ClientConnection.h +++ b/Userland/Services/WindowServer/ClientConnection.h @@ -97,7 +97,7 @@ private: virtual void add_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&, bool) override; virtual void add_menu_separator(i32) override; virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&) override; - virtual void create_window(i32, Gfx::IntRect const&, bool, bool, bool, bool, + virtual void create_window(i32, Gfx::IntRect const&, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&, Optional const&, i32, String const&, i32, Gfx::IntRect const&) override; virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override; diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 72462a194a..6b7394c933 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -87,12 +87,13 @@ Window::Window(Core::Object& parent, WindowType type) WindowManager::the().add_window(*this); } -Window::Window(ClientConnection& client, WindowType window_type, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window) +Window::Window(ClientConnection& client, WindowType window_type, int window_id, bool modal, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window) : Core::Object(&client) , m_client(&client) , m_type(window_type) , m_modal(modal) , m_minimizable(minimizable) + , m_closeable(closeable) , m_frameless(frameless) , m_resizable(resizable) , m_fullscreen(fullscreen) @@ -282,6 +283,8 @@ void Window::update_window_menu_items() m_window_menu_maximize_item->set_text(m_maximized ? "&Restore" : "Ma&ximize"); m_window_menu_maximize_item->set_enabled(m_resizable); + m_window_menu_close_item->set_enabled(m_closeable); + m_window_menu_move_item->set_enabled(m_minimized_state == WindowMinimizedState::None && !m_maximized && !m_fullscreen); if (m_window_menu_pin_item) @@ -335,6 +338,14 @@ void Window::set_minimizable(bool minimizable) // TODO: Hide/show (or alternatively change enabled state of) window minimize button dynamically depending on value of m_minimizable } +void Window::set_closeable(bool closeable) +{ + if (m_closeable == closeable) + return; + m_closeable = closeable; + update_window_menu_items(); +} + void Window::set_taskbar_rect(const Gfx::IntRect& rect) { m_taskbar_rect = rect; diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index e3f66e9e70..760ce6ddb8 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -98,6 +98,9 @@ public: bool is_minimizable() const { return m_type == WindowType::Normal && m_minimizable; } void set_minimizable(bool); + bool is_closeable() const { return m_closeable; } + void set_closeable(bool); + bool is_resizable() const { return m_resizable && !m_fullscreen; } void set_resizable(bool); @@ -378,7 +381,7 @@ public: bool is_stealable_by_client(i32 client_id) const { return m_stealable_by_client_ids.contains_slow(client_id); } private: - Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window = nullptr); + Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window = nullptr); Window(Core::Object&, WindowType); virtual void event(Core::Event&) override; @@ -414,6 +417,7 @@ private: bool m_has_alpha_channel { false }; bool m_modal { false }; bool m_minimizable { false }; + bool m_closeable { false }; bool m_frameless { false }; bool m_forced_shadow { false }; bool m_resizable { false }; diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index c2e38e33b3..9d41ef5b90 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -71,7 +71,7 @@ WindowFrame::WindowFrame(Window& window) void WindowFrame::window_was_constructed(Badge) { - { + if (m_window.is_closeable()) { auto button = make