1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 02:07:35 +00:00

WindowServer: Allow each WindowStack to have an active window

A window with an inner stack needs to keep track of which inner window
is active.
This commit is contained in:
Andreas Kling 2021-06-17 20:11:07 +02:00
parent 2b0e0b602c
commit e4e94cd43d
5 changed files with 44 additions and 37 deletions

View file

@ -592,7 +592,9 @@ void Window::clear_dirty_rects()
bool Window::is_active() const bool Window::is_active() const
{ {
return WindowManager::the().active_window() == this; if (!outer_stack())
return false;
return outer_stack()->active_window() == this;
} }
Window* Window::blocking_modal_window() Window* Window::blocking_modal_window()

View file

@ -1306,13 +1306,10 @@ void WindowManager::set_highlight_window(Window* new_highlight_window)
bool WindowManager::is_active_window_or_accessory(Window& window) const bool WindowManager::is_active_window_or_accessory(Window& window) const
{ {
if (m_active_window == &window) if (window.is_accessory())
return true; return window.parent_window()->is_active();
if (!window.is_accessory()) return window.is_active();
return false;
return m_active_window == window.parent_window();
} }
static bool window_type_can_become_active(WindowType type) static bool window_type_can_become_active(WindowType type)
@ -1355,52 +1352,50 @@ Window* WindowManager::set_active_input_window(Window* window)
return previous_input_window; return previous_input_window;
} }
void WindowManager::set_active_window(Window* window, bool make_input) void WindowManager::set_active_window(Window* new_active_window, bool make_input)
{ {
if (window) { if (new_active_window) {
if (auto* modal_window = window->blocking_modal_window()) { if (auto* modal_window = new_active_window->blocking_modal_window()) {
VERIFY(modal_window->is_modal()); VERIFY(modal_window->is_modal());
VERIFY(modal_window != window); VERIFY(modal_window != new_active_window);
window = modal_window; new_active_window = modal_window;
make_input = true; make_input = true;
} }
if (!window_type_can_become_active(window->type())) if (!window_type_can_become_active(new_active_window->type()))
return; return;
} }
auto* new_active_input_window = window; auto* new_active_input_window = new_active_window;
if (window && window->is_accessory()) { if (new_active_window && new_active_window->is_accessory()) {
// The parent of an accessory window is always the active // The parent of an accessory window is always the active
// window, but input is routed to the accessory window // window, but input is routed to the accessory window
window = window->parent_window(); new_active_window = new_active_window->parent_window();
} }
if (make_input) if (make_input)
set_active_input_window(new_active_input_window); set_active_input_window(new_active_input_window);
if (window == m_active_window) if (new_active_window == m_window_stack.active_window())
return; return;
auto* previously_active_window = m_active_window.ptr(); if (auto* previously_active_window = m_window_stack.active_window()) {
if (previously_active_window) {
for (auto& child_window : previously_active_window->child_windows()) { for (auto& child_window : previously_active_window->child_windows()) {
if (child_window && child_window->type() == WindowType::Tooltip) if (child_window && child_window->type() == WindowType::Tooltip)
child_window->request_close(); child_window->request_close();
} }
Core::EventLoop::current().post_event(*previously_active_window, make<Event>(Event::WindowDeactivated)); Core::EventLoop::current().post_event(*previously_active_window, make<Event>(Event::WindowDeactivated));
previously_active_window->invalidate(true, true); previously_active_window->invalidate(true, true);
m_active_window = nullptr; m_window_stack.set_active_window(nullptr);
m_active_input_tracking_window = nullptr; m_active_input_tracking_window = nullptr;
tell_wms_window_state_changed(*previously_active_window); tell_wms_window_state_changed(*previously_active_window);
} }
if (window) { if (new_active_window) {
m_active_window = *window; m_window_stack.set_active_window(new_active_window);
Core::EventLoop::current().post_event(*m_active_window, make<Event>(Event::WindowActivated)); Core::EventLoop::current().post_event(*new_active_window, make<Event>(Event::WindowActivated));
m_active_window->invalidate(true, true); new_active_window->invalidate(true, true);
tell_wms_window_state_changed(*m_active_window); tell_wms_window_state_changed(*new_active_window);
} }
// Window shapes may have changed (e.g. shadows for inactive/active windows) // Window shapes may have changed (e.g. shadows for inactive/active windows)
@ -1424,8 +1419,8 @@ bool WindowManager::set_hovered_window(Window* window)
ClientConnection const* WindowManager::active_client() const ClientConnection const* WindowManager::active_client() const
{ {
if (m_active_window) if (auto* window = m_window_stack.active_window())
return m_active_window->client(); return window->client();
return nullptr; return nullptr;
} }

View file

@ -90,8 +90,8 @@ public:
void start_dnd_drag(ClientConnection&, String const& text, Gfx::Bitmap const*, Core::MimeData const&); void start_dnd_drag(ClientConnection&, String const& text, Gfx::Bitmap const*, Core::MimeData const&);
void end_dnd_drag(); void end_dnd_drag();
Window* active_window() { return m_active_window.ptr(); } Window* active_window() { return m_window_stack.active_window(); }
Window const* active_window() const { return m_active_window.ptr(); } Window const* active_window() const { return m_window_stack.active_window(); }
Window* active_input_window() { return m_active_input_window.ptr(); } Window* active_input_window() { return m_active_input_window.ptr(); }
Window const* active_input_window() const { return m_active_input_window.ptr(); } Window const* active_input_window() const { return m_active_input_window.ptr(); }
ClientConnection const* active_client() const; ClientConnection const* active_client() const;
@ -166,17 +166,15 @@ public:
Window const* active_fullscreen_window() const Window const* active_fullscreen_window() const
{ {
if (m_active_window && m_active_window->is_fullscreen()) { if (active_window() && active_window()->is_fullscreen())
return m_active_window; return active_window();
}
return nullptr; return nullptr;
}; };
Window* active_fullscreen_window() Window* active_fullscreen_window()
{ {
if (m_active_window && m_active_window->is_fullscreen()) { if (active_window() && active_window()->is_fullscreen())
return m_active_window; return active_window();
}
return nullptr; return nullptr;
} }
@ -308,7 +306,6 @@ private:
int m_max_distance_for_double_click { 4 }; int m_max_distance_for_double_click { 4 };
bool m_previous_event_was_super_keydown { false }; bool m_previous_event_was_super_keydown { false };
WeakPtr<Window> m_active_window;
WeakPtr<Window> m_hovered_window; WeakPtr<Window> m_hovered_window;
WeakPtr<Window> m_active_input_window; WeakPtr<Window> m_active_input_window;
WeakPtr<Window> m_active_input_tracking_window; WeakPtr<Window> m_active_input_tracking_window;

View file

@ -46,4 +46,12 @@ void WindowStack::set_highlight_window(Window* window)
m_highlight_window = window->make_weak_ptr<Window>(); m_highlight_window = window->make_weak_ptr<Window>();
} }
void WindowStack::set_active_window(Window* window)
{
if (!window)
m_active_window = nullptr;
else
m_active_window = window->make_weak_ptr<Window>();
}
} }

View file

@ -40,8 +40,13 @@ public:
Window const* highlight_window() const { return m_highlight_window; } Window const* highlight_window() const { return m_highlight_window; }
void set_highlight_window(Window*); void set_highlight_window(Window*);
Window* active_window() { return m_active_window; }
Window const* active_window() const { return m_active_window; }
void set_active_window(Window*);
private: private:
WeakPtr<Window> m_highlight_window; WeakPtr<Window> m_highlight_window;
WeakPtr<Window> m_active_window;
Window::List m_windows; Window::List m_windows;
}; };