diff --git a/Userland/Services/WindowServer/Compositor.cpp b/Userland/Services/WindowServer/Compositor.cpp index d8240972e4eb5c..9430e116772e58 100644 --- a/Userland/Services/WindowServer/Compositor.cpp +++ b/Userland/Services/WindowServer/Compositor.cpp @@ -142,7 +142,7 @@ Gfx::IntPoint Compositor::window_transition_offset(Window& window) if (window.is_moving_to_another_stack()) return {}; - return window.outer_stack()->transition_offset(); + return window.window_stack().transition_offset(); } void Compositor::compose() @@ -1152,7 +1152,7 @@ void Compositor::recompute_occlusions() // This window should not be occluded while the window switcher is interested in it (depending // on the mode it's in). If it isn't then determine occlusions based on whether the window // rect has any visible areas at all. - w.set_occluded(never_occlude(*w.outer_stack()) ? false : visible_window_rects.is_empty()); + w.set_occluded(never_occlude(w.window_stack()) ? false : visible_window_rects.is_empty()); if (!m_overlay_rects.is_empty() && m_overlay_rects.intersects(visible_opaque)) { // In order to render overlays flicker-free we need to force these area into the diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index c070e3bf273395..1cd62b4c6bd6e5 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -664,9 +664,12 @@ void Window::clear_dirty_rects() bool Window::is_active() const { - if (!outer_stack()) + if (!m_window_stack) { + // This may be called while destroying a window as part of + // determining what the render rectangle is! return false; - return outer_stack()->active_window() == this; + } + return m_window_stack->active_window() == this; } Window* Window::blocking_modal_window() diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index 8af13a8a5bc105..3d75b77d55ddfb 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -319,9 +319,18 @@ class Window final : public Core::Object { const Menubar* menubar() const { return m_menubar; } void set_menubar(Menubar*); - WindowStack* outer_stack() { return m_outer_stack; } - WindowStack const* outer_stack() const { return m_outer_stack; } - void set_outer_stack(Badge, WindowStack* stack) { m_outer_stack = stack; } + WindowStack& window_stack() + { + VERIFY(m_window_stack); + return *m_window_stack; + } + WindowStack const& window_stack() const + { + VERIFY(m_window_stack); + return *m_window_stack; + } + bool is_on_any_window_stack(Badge) const { return m_window_stack != nullptr; } + void set_window_stack(Badge, WindowStack* stack) { m_window_stack = stack; } const Vector& screens() const { return m_screens; } Vector& screens() { return m_screens; } @@ -416,7 +425,7 @@ class Window final : public Core::Object { MenuItem* m_window_menu_menubar_visibility_item { nullptr }; Optional m_progress; bool m_should_show_menubar { true }; - WindowStack* m_outer_stack { nullptr }; + WindowStack* m_window_stack { nullptr }; RefPtr m_animation; public: diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index edc0edde213d91..146ef50cbabf84 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -308,10 +308,8 @@ WindowStack& WindowManager::window_stack_for_window(Window& window) { if (is_stationary_window_type(window.type())) return m_window_stacks[0][0]; - if (auto* parent = window.parent_window(); parent && !is_stationary_window_type(parent->type())) { - if (auto* parent_window_stack = parent->outer_stack()) - return *parent_window_stack; - } + if (auto* parent = window.parent_window(); parent && !is_stationary_window_type(parent->type())) + return parent->window_stack(); return current_window_stack(); } @@ -373,9 +371,7 @@ void WindowManager::move_to_front_and_make_active(Window& window) void WindowManager::do_move_to_front(Window& window, bool make_active, bool make_input) { - auto* window_stack = window.outer_stack(); - VERIFY(window_stack); - window_stack->move_to_front(window); + window.window_stack().move_to_front(window); if (make_active) set_active_window(&window, make_input); @@ -399,8 +395,7 @@ void WindowManager::remove_window(Window& window) check_hide_geometry_overlay(window); auto* active = active_window(); auto* active_input = active_input_window(); - if (auto* window_stack = window.outer_stack()) - window_stack->remove(window); + window.window_stack().remove(window); if (active == &window || active_input == &window || (active && window.is_descendant_of(*active)) || (active_input && active_input != active && window.is_descendant_of(*active_input))) pick_new_active_window(&window); @@ -450,12 +445,8 @@ void WindowManager::tell_wm_about_window(WMClientConnection& conn, Window& windo if (window.is_internal()) return; auto* parent = window.parent_window(); - auto* window_stack = ¤t_window_stack(); - if (!is_stationary_window_type(window.type())) { - if (auto* stack = window.outer_stack()) - window_stack = stack; - } - conn.async_window_state_changed(conn.window_id(), window.client_id(), window.window_id(), parent ? parent->client_id() : -1, parent ? parent->window_id() : -1, window_stack->row(), window_stack->column(), window.is_active(), window.is_minimized(), window.is_modal_dont_unparent(), window.is_frameless(), (i32)window.type(), window.computed_title(), window.rect(), window.progress()); + auto& window_stack = is_stationary_window_type(window.type()) ? current_window_stack() : window.window_stack(); + conn.async_window_state_changed(conn.window_id(), window.client_id(), window.window_id(), parent ? parent->client_id() : -1, parent ? parent->window_id() : -1, window_stack.row(), window_stack.column(), window.is_active(), window.is_minimized(), window.is_modal_dont_unparent(), window.is_frameless(), (i32)window.type(), window.computed_title(), window.rect(), window.progress()); } void WindowManager::tell_wm_about_window_rect(WMClientConnection& conn, Window& window) @@ -1422,15 +1413,15 @@ void WindowManager::switch_to_window_stack(WindowStack& window_stack, Window* ca { m_carry_window_to_new_stack.clear(); m_switching_to_window_stack = &window_stack; - if (carry_window && !is_stationary_window_type(carry_window->type()) && carry_window->outer_stack() != &window_stack) { - auto& from_stack = *carry_window->outer_stack(); + if (carry_window && !is_stationary_window_type(carry_window->type()) && &carry_window->window_stack() != &window_stack) { + auto& from_stack = carry_window->window_stack(); auto* blocking_modal = carry_window->blocking_modal_window(); for_each_visible_window_from_back_to_front([&](Window& window) { if (is_stationary_window_type(window.type())) return IterationDecision::Continue; - if (window.outer_stack() != carry_window->outer_stack()) + if (&window.window_stack() != &carry_window->window_stack()) return IterationDecision::Continue; if (&window == carry_window || ((carry_window->is_modal() || blocking_modal) && is_window_in_modal_stack(*carry_window, window))) m_carry_window_to_new_stack.append(window); @@ -1448,7 +1439,7 @@ void WindowManager::switch_to_window_stack(WindowStack& window_stack, Window* ca if (window == from_active_input_window) did_carry_active_input_window = true; window->set_moving_to_another_stack(true); - VERIFY(window->outer_stack() == &from_stack); + VERIFY(&window->window_stack() == &from_stack); from_stack.remove(*window); window_stack.add(*window); } diff --git a/Userland/Services/WindowServer/WindowStack.cpp b/Userland/Services/WindowServer/WindowStack.cpp index 261f2bb6df5fdf..057b4ef695ef5f 100644 --- a/Userland/Services/WindowServer/WindowStack.cpp +++ b/Userland/Services/WindowServer/WindowStack.cpp @@ -21,23 +21,23 @@ WindowStack::~WindowStack() void WindowStack::add(Window& window) { - VERIFY(window.outer_stack() == nullptr); + VERIFY(!window.is_on_any_window_stack({})); m_windows.append(window); - window.set_outer_stack({}, this); + window.set_window_stack({}, this); } void WindowStack::add_to_back(Window& window) { - VERIFY(window.outer_stack() == nullptr); + VERIFY(!window.is_on_any_window_stack({})); m_windows.prepend(window); - window.set_outer_stack({}, this); + window.set_window_stack({}, this); } void WindowStack::remove(Window& window) { - VERIFY(window.outer_stack() == this); + VERIFY(&window.window_stack() == this); m_windows.remove(window); - window.set_outer_stack({}, nullptr); + window.set_window_stack({}, nullptr); if (m_active_window == &window) m_active_window = nullptr; if (m_active_input_window == &window) @@ -59,13 +59,13 @@ void WindowStack::move_all_windows(WindowStack& new_window_stack, Vectorset_outer_stack({}, nullptr); + window->set_window_stack({}, nullptr); new_window_stack.add(*window); windows_moved.append(window); } } else { while (auto* window = m_windows.take_last()) { - window->set_outer_stack({}, nullptr); + window->set_window_stack({}, nullptr); new_window_stack.add_to_back(*window); windows_moved.append(window); } @@ -87,7 +87,7 @@ Window* WindowStack::window_at(Gfx::IntPoint const& position, IncludeWindowFrame Window* WindowStack::highlight_window() const { - if (auto* window = WindowManager::the().highlight_window(); window && window->outer_stack() == this) + if (auto* window = WindowManager::the().highlight_window(); window && &window->window_stack() == this) return window; return nullptr; } diff --git a/Userland/Services/WindowServer/WindowSwitcher.cpp b/Userland/Services/WindowServer/WindowSwitcher.cpp index 26d29325e50943..fc67e2c59a64aa 100644 --- a/Userland/Services/WindowServer/WindowSwitcher.cpp +++ b/Userland/Services/WindowServer/WindowSwitcher.cpp @@ -137,8 +137,8 @@ void WindowSwitcher::select_window_at_index(int index) VERIFY(highlight_window); auto& wm = WindowManager::the(); if (m_mode == Mode::ShowAllWindows) { - if (auto* window_stack = highlight_window->outer_stack(); window_stack != &wm.current_window_stack()) - wm.switch_to_window_stack(*window_stack, nullptr, false); + if (auto& window_stack = highlight_window->window_stack(); &window_stack != &wm.current_window_stack()) + wm.switch_to_window_stack(window_stack, nullptr, false); } wm.set_highlight_window(highlight_window); redraw(); @@ -191,7 +191,7 @@ void WindowSwitcher::draw() painter.fill_rect(icon_rect, palette.window()); painter.blit(icon_rect.location(), window.icon(), window.icon().rect()); painter.draw_text(item_rect.translated(thumbnail_width() + 12, 0), window.computed_title(), WindowManager::the().window_title_font(), Gfx::TextAlignment::CenterLeft, text_color); - auto window_details = m_windows_on_multiple_stacks ? String::formatted("{} on {}:{}", window.rect().to_string(), window.outer_stack()->row() + 1, window.outer_stack()->column() + 1) : window.rect().to_string(); + auto window_details = m_windows_on_multiple_stacks ? String::formatted("{} on {}:{}", window.rect().to_string(), window.window_stack().row() + 1, window.window_stack().column() + 1) : window.rect().to_string(); painter.draw_text(item_rect, window_details, Gfx::TextAlignment::CenterRight, rect_text_color); } } @@ -221,10 +221,11 @@ void WindowSwitcher::refresh() if (selected_window == &window) m_selected_index = m_windows.size(); m_windows.append(window); + auto& window_stack = window.window_stack(); if (!last_added_on_window_stack) { - last_added_on_window_stack = window.outer_stack(); - } else if (last_added_on_window_stack != window.outer_stack()) { - last_added_on_window_stack = window.outer_stack(); + last_added_on_window_stack = &window_stack; + } else if (last_added_on_window_stack != &window_stack) { + last_added_on_window_stack = &window_stack; m_windows_on_multiple_stacks = true; } return IterationDecision::Continue;