mirror of
https://github.com/RGBCube/serenity
synced 2025-05-29 20:15:11 +00:00
LibGUI+WindowServer+Apps: Replace Accessory Windows
with the CaptureInput WindowMode. This mode will serve the same function as accessories: redirecting input while allowing parent windows to remain active.
This commit is contained in:
parent
0d4fd4e2a6
commit
4c7f95e2f8
13 changed files with 23 additions and 91 deletions
|
@ -66,7 +66,6 @@ HelpWindow::HelpWindow(GUI::Window* parent)
|
|||
resize(530, 365);
|
||||
set_title("Spreadsheet Functions Help");
|
||||
set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-help.png"sv).release_value_but_fixme_should_propagate_errors());
|
||||
set_accessory(true);
|
||||
|
||||
auto& widget = set_main_widget<GUI::Widget>();
|
||||
widget.set_layout<GUI::VerticalBoxLayout>();
|
||||
|
|
|
@ -109,7 +109,7 @@ ComboBox::ComboBox()
|
|||
|
||||
m_list_window = add<Window>(window());
|
||||
m_list_window->set_frameless(true);
|
||||
m_list_window->set_accessory(true);
|
||||
m_list_window->set_window_mode(WindowMode::CaptureInput);
|
||||
m_list_window->on_active_input_change = [this](bool is_active_input) {
|
||||
if (!is_active_input) {
|
||||
m_open_button->set_enabled(false);
|
||||
|
|
|
@ -731,7 +731,7 @@ bool Widget::is_focused() const
|
|||
auto* win = window();
|
||||
if (!win)
|
||||
return false;
|
||||
// Accessory windows are not active despite being the active
|
||||
// Capturing modals are not active despite being the active
|
||||
// input window. So we can have focus if either we're the active
|
||||
// input window or we're the active window
|
||||
if (win->is_active_input() || win->is_active())
|
||||
|
|
|
@ -153,7 +153,6 @@ void Window::show()
|
|||
m_fullscreen,
|
||||
m_frameless,
|
||||
m_forced_shadow,
|
||||
m_accessory,
|
||||
m_opacity_when_windowless,
|
||||
m_alpha_hit_threshold,
|
||||
m_base_size,
|
||||
|
|
|
@ -124,9 +124,6 @@ public:
|
|||
bool is_active() const;
|
||||
bool is_active_input() const { return m_is_active_input; }
|
||||
|
||||
bool is_accessory() const { return m_accessory; }
|
||||
void set_accessory(bool accessory) { m_accessory = accessory; }
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
virtual void close();
|
||||
|
@ -306,7 +303,6 @@ private:
|
|||
bool m_layout_pending { false };
|
||||
bool m_visible_for_timer_purposes { true };
|
||||
bool m_visible { false };
|
||||
bool m_accessory { false };
|
||||
bool m_moved_by_client { false };
|
||||
};
|
||||
|
||||
|
|
|
@ -564,7 +564,7 @@ Window* ConnectionFromClient::window_from_id(i32 window_id)
|
|||
|
||||
void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect,
|
||||
bool auto_position, bool has_alpha_channel, bool minimizable, bool closeable, bool resizable,
|
||||
bool fullscreen, bool frameless, bool forced_shadow, bool accessory, float opacity,
|
||||
bool fullscreen, bool frameless, bool forced_shadow, float opacity,
|
||||
float alpha_hit_threshold, Gfx::IntSize const& base_size, Gfx::IntSize const& size_increment,
|
||||
Gfx::IntSize const& minimum_size, Optional<Gfx::IntSize> const& resize_aspect_ratio, i32 type, i32 mode,
|
||||
String const& title, i32 parent_window_id, Gfx::IntRect const& launch_origin_rect)
|
||||
|
@ -597,7 +597,7 @@ void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect
|
|||
return;
|
||||
}
|
||||
|
||||
auto window = Window::construct(*this, (WindowType)type, (WindowMode)mode, window_id, minimizable, closeable, frameless, resizable, fullscreen, accessory, parent_window);
|
||||
auto window = Window::construct(*this, (WindowType)type, (WindowMode)mode, window_id, minimizable, closeable, frameless, resizable, fullscreen, parent_window);
|
||||
|
||||
window->set_forced_shadow(forced_shadow);
|
||||
|
||||
|
@ -646,13 +646,6 @@ void ConnectionFromClient::destroy_window(Window& window, Vector<i32>& destroyed
|
|||
destroy_window(*child_window, destroyed_window_ids);
|
||||
}
|
||||
|
||||
for (auto& accessory_window : window.accessory_windows()) {
|
||||
if (!accessory_window)
|
||||
continue;
|
||||
VERIFY(accessory_window->window_id() != window.window_id());
|
||||
destroy_window(*accessory_window, destroyed_window_ids);
|
||||
}
|
||||
|
||||
destroyed_window_ids.append(window.window_id());
|
||||
|
||||
if (window.type() == WindowType::Applet)
|
||||
|
|
|
@ -101,7 +101,7 @@ private:
|
|||
virtual void update_menu_item(i32, i32, i32, String const&, bool, bool, bool, bool, String const&, Gfx::ShareableBitmap const&) override;
|
||||
virtual void remove_menu_item(i32 menu_id, i32 identifier) override;
|
||||
virtual void flash_menubar_menu(i32, i32) 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, float, float, Gfx::IntSize const&, Gfx::IntSize const&, Gfx::IntSize const&,
|
||||
Optional<Gfx::IntSize> const&, i32, i32, String const&, i32, Gfx::IntRect const&) override;
|
||||
virtual Messages::WindowServer::DestroyWindowResponse destroy_window(i32) override;
|
||||
|
|
|
@ -90,7 +90,7 @@ Window::Window(Core::Object& parent, WindowType type)
|
|||
frame().window_was_constructed({});
|
||||
}
|
||||
|
||||
Window::Window(ConnectionFromClient& client, WindowType window_type, WindowMode window_mode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window)
|
||||
Window::Window(ConnectionFromClient& client, WindowType window_type, WindowMode window_mode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, Window* parent_window)
|
||||
: Core::Object(&client)
|
||||
, m_client(&client)
|
||||
, m_type(window_type)
|
||||
|
@ -100,7 +100,6 @@ Window::Window(ConnectionFromClient& client, WindowType window_type, WindowMode
|
|||
, m_frameless(frameless)
|
||||
, m_resizable(resizable)
|
||||
, m_fullscreen(fullscreen)
|
||||
, m_accessory(accessory)
|
||||
, m_window_id(window_id)
|
||||
, m_client_id(client.client_id())
|
||||
, m_icon(default_window_icon())
|
||||
|
@ -974,19 +973,11 @@ void Window::add_child_window(Window& child_window)
|
|||
m_child_windows.append(child_window);
|
||||
}
|
||||
|
||||
void Window::add_accessory_window(Window& accessory_window)
|
||||
{
|
||||
m_accessory_windows.append(accessory_window);
|
||||
}
|
||||
|
||||
void Window::set_parent_window(Window& parent_window)
|
||||
{
|
||||
VERIFY(!m_parent_window);
|
||||
m_parent_window = parent_window;
|
||||
if (m_accessory)
|
||||
parent_window.add_accessory_window(*this);
|
||||
else
|
||||
parent_window.add_child_window(*this);
|
||||
parent_window.add_child_window(*this);
|
||||
}
|
||||
|
||||
Window* Window::modeless_ancestor()
|
||||
|
@ -1000,21 +991,9 @@ Window* Window::modeless_ancestor()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool Window::is_accessory() const
|
||||
bool Window::is_capturing_active_input_from(Window const& window) const
|
||||
{
|
||||
if (!m_accessory)
|
||||
return false;
|
||||
if (parent_window() != nullptr)
|
||||
return true;
|
||||
|
||||
// If accessory window was unparented, convert to a regular window
|
||||
const_cast<Window*>(this)->set_accessory(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Window::is_accessory_of(Window& window) const
|
||||
{
|
||||
if (!is_accessory())
|
||||
if (!is_capturing_input())
|
||||
return false;
|
||||
return parent_window() == &window;
|
||||
}
|
||||
|
@ -1030,14 +1009,9 @@ void Window::set_progress(Optional<int> progress)
|
|||
|
||||
bool Window::is_descendant_of(Window& window) const
|
||||
{
|
||||
for (auto* parent = parent_window(); parent; parent = parent->parent_window()) {
|
||||
for (auto* parent = parent_window(); parent; parent = parent->parent_window())
|
||||
if (parent == &window)
|
||||
return true;
|
||||
for (auto& accessory : parent->accessory_windows()) {
|
||||
if (accessory == &window)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,9 @@ public:
|
|||
bool is_passive() { return m_mode == WindowMode::Passive; }
|
||||
bool is_rendering_above() { return m_mode == WindowMode::RenderAbove; }
|
||||
|
||||
bool is_capturing_input() const { return m_mode == WindowMode::CaptureInput; }
|
||||
bool is_capturing_active_input_from(Window const&) const;
|
||||
|
||||
bool is_blocking() const { return m_mode == WindowMode::Blocking; }
|
||||
Window* blocking_modal_window();
|
||||
|
||||
|
@ -308,15 +311,8 @@ public:
|
|||
Vector<WeakPtr<Window>>& child_windows() { return m_child_windows; }
|
||||
Vector<WeakPtr<Window>> const& child_windows() const { return m_child_windows; }
|
||||
|
||||
Vector<WeakPtr<Window>>& accessory_windows() { return m_accessory_windows; }
|
||||
Vector<WeakPtr<Window>> const& accessory_windows() const { return m_accessory_windows; }
|
||||
|
||||
bool is_descendant_of(Window&) const;
|
||||
|
||||
void set_accessory(bool accessory) { m_accessory = accessory; }
|
||||
bool is_accessory() const;
|
||||
bool is_accessory_of(Window&) const;
|
||||
|
||||
void set_frameless(bool);
|
||||
bool is_frameless() const { return m_frameless; }
|
||||
|
||||
|
@ -383,14 +379,13 @@ public:
|
|||
bool is_stealable_by_client(i32 client_id) const { return m_stealable_by_client_ids.contains_slow(client_id); }
|
||||
|
||||
private:
|
||||
Window(ConnectionFromClient&, WindowType, WindowMode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, bool accessory, Window* parent_window = nullptr);
|
||||
Window(ConnectionFromClient&, WindowType, WindowMode, int window_id, bool minimizable, bool closeable, bool frameless, bool resizable, bool fullscreen, Window* parent_window = nullptr);
|
||||
Window(Core::Object&, WindowType);
|
||||
|
||||
virtual void event(Core::Event&) override;
|
||||
void handle_mouse_event(MouseEvent const&);
|
||||
void handle_keydown_event(KeyEvent const&);
|
||||
void add_child_window(Window&);
|
||||
void add_accessory_window(Window&);
|
||||
void ensure_window_menu();
|
||||
void update_window_menu_items();
|
||||
void modal_unparented();
|
||||
|
@ -399,7 +394,6 @@ private:
|
|||
|
||||
WeakPtr<Window> m_parent_window;
|
||||
Vector<WeakPtr<Window>> m_child_windows;
|
||||
Vector<WeakPtr<Window>> m_accessory_windows;
|
||||
|
||||
Menubar m_menubar;
|
||||
|
||||
|
@ -426,7 +420,6 @@ private:
|
|||
Optional<Gfx::IntSize> m_resize_aspect_ratio {};
|
||||
WindowMinimizedState m_minimized_state { WindowMinimizedState::None };
|
||||
bool m_fullscreen { false };
|
||||
bool m_accessory { false };
|
||||
bool m_destroyed { false };
|
||||
bool m_default_positioned { false };
|
||||
bool m_have_taskbar_rect { false };
|
||||
|
|
|
@ -278,7 +278,7 @@ Gfx::WindowTheme::WindowState WindowFrame::window_state_for_theme() const
|
|||
return Gfx::WindowTheme::WindowState::Highlighted;
|
||||
if (&m_window == wm.m_move_window)
|
||||
return Gfx::WindowTheme::WindowState::Moving;
|
||||
if (wm.is_active_window_or_accessory(m_window))
|
||||
if (wm.is_active_window_or_capturing_modal(m_window))
|
||||
return Gfx::WindowTheme::WindowState::Active;
|
||||
return Gfx::WindowTheme::WindowState::Inactive;
|
||||
}
|
||||
|
|
|
@ -343,25 +343,8 @@ void WindowManager::add_window(Window& window)
|
|||
void WindowManager::move_to_front_and_make_active(Window& window)
|
||||
{
|
||||
auto move_window_to_front = [&](Window& wnd, bool make_active, bool make_input) {
|
||||
if (wnd.is_accessory()) {
|
||||
auto* parent = wnd.parent_window();
|
||||
do_move_to_front(*parent, true, false);
|
||||
make_active = false;
|
||||
|
||||
for (auto& accessory_window : parent->accessory_windows()) {
|
||||
if (accessory_window && accessory_window.ptr() != &wnd)
|
||||
do_move_to_front(*accessory_window, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
do_move_to_front(wnd, make_active, make_input);
|
||||
};
|
||||
|
||||
// If a window that is currently blocked by a modal child is being
|
||||
// brought to the front, bring the entire stack of modal windows
|
||||
// to the front and activate the modal window. Also set the
|
||||
// active input window to that same window (which would pull
|
||||
// active input from any accessory window)
|
||||
for_each_window_in_modal_stack(window, [&](auto& w, bool is_stack_top) {
|
||||
move_window_to_front(w, is_stack_top, is_stack_top);
|
||||
return IterationDecision::Continue;
|
||||
|
@ -379,7 +362,7 @@ void WindowManager::do_move_to_front(Window& window, bool make_active, bool make
|
|||
|
||||
if (m_switcher->is_visible()) {
|
||||
m_switcher->refresh();
|
||||
if (!window.is_accessory()) {
|
||||
if (!window.is_modal()) {
|
||||
m_switcher->select_window(window);
|
||||
set_highlight_window(&window);
|
||||
}
|
||||
|
@ -655,7 +638,7 @@ bool WindowManager::pick_new_active_window(Window* previous_active)
|
|||
return IterationDecision::Continue;
|
||||
if (previous_active != first_candidate)
|
||||
first_candidate = &candidate;
|
||||
if ((!previous_active && !candidate.is_accessory()) || (previous_active && !candidate.is_accessory_of(*previous_active))) {
|
||||
if ((!previous_active && !candidate.is_capturing_input()) || (previous_active && !candidate.is_capturing_active_input_from(*previous_active))) {
|
||||
set_active_window(&candidate);
|
||||
new_window_picked = true;
|
||||
return IterationDecision::Break;
|
||||
|
@ -1460,10 +1443,6 @@ bool WindowManager::is_window_in_modal_stack(Window& window_in_modal_stack, Wind
|
|||
auto result = for_each_window_in_modal_stack(window_in_modal_stack, [&](auto& window, auto) {
|
||||
if (&other_window == &window)
|
||||
return IterationDecision::Break;
|
||||
for (auto& accessory : window.accessory_windows()) {
|
||||
if (accessory.ptr() == &other_window)
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
return result == IterationDecision::Break;
|
||||
|
@ -1786,9 +1765,9 @@ void WindowManager::set_highlight_window(Window* new_highlight_window)
|
|||
Compositor::the().invalidate_occlusions();
|
||||
}
|
||||
|
||||
bool WindowManager::is_active_window_or_accessory(Window& window) const
|
||||
bool WindowManager::is_active_window_or_capturing_modal(Window& window) const
|
||||
{
|
||||
if (window.is_accessory())
|
||||
if (window.is_capturing_input())
|
||||
return window.parent_window()->is_active();
|
||||
|
||||
return window.is_active();
|
||||
|
@ -1857,9 +1836,9 @@ void WindowManager::set_active_window(Window* new_active_window, bool make_input
|
|||
}
|
||||
|
||||
auto* new_active_input_window = new_active_window;
|
||||
if (new_active_window && new_active_window->is_accessory()) {
|
||||
// The parent of an accessory window is always the active
|
||||
// window, but input is routed to the accessory window
|
||||
if (new_active_window && new_active_window->is_capturing_input()) {
|
||||
// The parent of a capturing modal is always the active
|
||||
// window, but input is routed to the capturing window
|
||||
new_active_window = new_active_window->parent_window();
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ public:
|
|||
void tell_wms_super_digit_key_pressed(u8);
|
||||
void tell_wms_current_window_stack_changed();
|
||||
|
||||
bool is_active_window_or_accessory(Window&) const;
|
||||
bool is_active_window_or_capturing_modal(Window&) const;
|
||||
|
||||
void check_hide_geometry_overlay(Window&);
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ endpoint WindowServer
|
|||
bool fullscreen,
|
||||
bool frameless,
|
||||
bool forced_shadow,
|
||||
bool accessory,
|
||||
float opacity,
|
||||
float alpha_hit_threshold,
|
||||
Gfx::IntSize base_size,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue