From 24d299c9c8c7719f172eca7d6c23eb5387d7c963 Mon Sep 17 00:00:00 2001 From: thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> Date: Thu, 17 Nov 2022 10:00:07 -0500 Subject: [PATCH] LibGUI+WindowServer+Applets+Taskbar: Remove active input concepts and the CaptureInput mode. They are a source of unneeded complexity in WindowServer and have proven prone to regressions, so this patch replaces them with a simple input preemption scheme using Popups. Popup windows now have ergonomics similar to menus: When open, a popup preempts all mouse and key events for the entire window stack; however, they are fragile and will close after WindowServer swallows the first event outside them. This is similar to how combo box windows and popups work in the classic Windows DE and has the added benefit of letting the user click anywhere to dismiss a popup without having to worry about unwanted interactions with other widgets. --- Userland/Applets/Audio/main.cpp | 4 - Userland/Libraries/LibGUI/ComboBox.cpp | 9 - Userland/Libraries/LibGUI/CommandPalette.cpp | 6 - Userland/Libraries/LibGUI/CommonActions.cpp | 1 - .../LibGUI/ConnectionToWindowServer.cpp | 2 +- .../Libraries/LibGUI/EmojiInputDialog.cpp | 6 - Userland/Libraries/LibGUI/Widget.cpp | 5 +- Userland/Libraries/LibGUI/Window.h | 6 +- Userland/Services/Taskbar/ClockWidget.cpp | 4 - Userland/Services/WindowServer/Window.cpp | 9 +- Userland/Services/WindowServer/Window.h | 5 +- .../Services/WindowServer/WindowFrame.cpp | 8 +- .../Services/WindowServer/WindowManager.cpp | 174 ++++++------------ .../Services/WindowServer/WindowManager.h | 16 +- Userland/Services/WindowServer/WindowMode.h | 4 +- .../Services/WindowServer/WindowStack.cpp | 3 - Userland/Services/WindowServer/WindowStack.h | 5 - 17 files changed, 76 insertions(+), 191 deletions(-) diff --git a/Userland/Applets/Audio/main.cpp b/Userland/Applets/Audio/main.cpp index a4b3d2b98c..6d4d7e3e00 100644 --- a/Userland/Applets/Audio/main.cpp +++ b/Userland/Applets/Audio/main.cpp @@ -81,10 +81,6 @@ private: m_slider_window->set_frameless(true); m_slider_window->set_resizable(false); m_slider_window->set_minimizable(false); - m_slider_window->on_active_input_change = [this](bool is_active_input) { - if (!is_active_input) - close(); - }; m_root_container = TRY(m_slider_window->try_set_main_widget()); m_root_container->set_fill_with_background_color(true); diff --git a/Userland/Libraries/LibGUI/ComboBox.cpp b/Userland/Libraries/LibGUI/ComboBox.cpp index f7dd1f8711..a85c48a56b 100644 --- a/Userland/Libraries/LibGUI/ComboBox.cpp +++ b/Userland/Libraries/LibGUI/ComboBox.cpp @@ -115,15 +115,6 @@ ComboBox::ComboBox() m_list_window = add(window()); m_list_window->set_window_type(GUI::WindowType::Popup); - m_list_window->set_frameless(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); - close(); - } - m_open_button->set_enabled(true); - }; m_list_view = m_list_window->set_main_widget(); m_list_view->set_should_hide_unnecessary_scrollbars(true); diff --git a/Userland/Libraries/LibGUI/CommandPalette.cpp b/Userland/Libraries/LibGUI/CommandPalette.cpp index 1b05e6e276..380e0dc26e 100644 --- a/Userland/Libraries/LibGUI/CommandPalette.cpp +++ b/Userland/Libraries/LibGUI/CommandPalette.cpp @@ -223,12 +223,6 @@ CommandPalette::CommandPalette(GUI::Window& parent_window, ScreenPosition screen }; m_text_box->set_focus(true); - - on_active_input_change = [this](bool is_active_input) { - if (!is_active_input) - close(); - }; - } void CommandPalette::collect_actions(GUI::Window& parent_window) diff --git a/Userland/Libraries/LibGUI/CommonActions.cpp b/Userland/Libraries/LibGUI/CommonActions.cpp index 9af53e8690..aae1a8bc90 100644 --- a/Userland/Libraries/LibGUI/CommonActions.cpp +++ b/Userland/Libraries/LibGUI/CommonActions.cpp @@ -202,7 +202,6 @@ NonnullRefPtr make_command_palette_action(Window* window) { auto action = Action::create("&Commands...", { Mod_Ctrl | Mod_Shift, Key_A }, MUST(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/find.png"sv)), [=](auto&) { auto command_palette = CommandPalette::construct(*window); - command_palette->set_window_mode(GUI::WindowMode::CaptureInput); if (command_palette->exec() != GUI::Dialog::ExecResult::OK) return; auto* action = command_palette->selected_action(); diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp index e658dab496..bd2796705c 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp @@ -170,7 +170,7 @@ static Action* action_for_shortcut(Window& window, Shortcut const& shortcut) } // NOTE: Application-global shortcuts are ignored while a blocking modal window is up. - if (!window.is_blocking() && !window.is_capturing_input()) { + if (!window.is_blocking() && !window.is_popup()) { if (auto* action = Application::the()->action_for_shortcut(shortcut)) { dbgln_if(KEYBOARD_SHORTCUTS_DEBUG, " > Asked application, got action: {} {} (enabled: {}, shortcut: {}, alt-shortcut: {})", action, action->text(), action->is_enabled(), action->shortcut().to_string(), action->alternate_shortcut().to_string()); return action; diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp index 51f36164fc..4d2c2b011b 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp @@ -100,7 +100,6 @@ EmojiInputDialog::EmojiInputDialog(Window* parent_window) set_frameless(true); set_blocks_emoji_input(true); - set_window_mode(GUI::WindowMode::CaptureInput); resize(400, 300); auto& scrollable_container = *main_widget.find_descendant_of_type_named("scrollable_container"sv); @@ -139,11 +138,6 @@ EmojiInputDialog::EmojiInputDialog(Window* parent_window) scrollable_container.horizontal_scrollbar().set_visible(false); update_displayed_emoji(); - on_active_input_change = [this](bool is_active_input) { - if (!is_active_input) - close(); - }; - m_search_box->on_change = [this]() { update_displayed_emoji(); }; diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index b92e0e6a98..add0f8b41c 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -752,10 +752,7 @@ bool Widget::is_focused() const auto* win = window(); if (!win) return false; - // 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()) + if (win->is_focusable()) return win->focused_widget() == this; return false; } diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index 3597dc539e..2c8d8ec8ad 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -37,8 +37,8 @@ public: bool is_modal() const { return m_window_mode != WindowMode::Modeless; } bool is_blocking() const { return m_window_mode == WindowMode::Blocking; } - bool is_capturing_input() const { return m_window_mode == WindowMode::CaptureInput; } + bool is_popup() const { return m_window_type == WindowType::Popup; } bool is_autocomplete() const { return m_window_type == WindowType::Autocomplete; } bool is_fullscreen() const { return m_fullscreen; } @@ -96,7 +96,6 @@ public: Function on_close; Function on_close_request; - Function on_active_input_change; Function on_input_preemption_change; Function on_active_window_change; @@ -130,7 +129,7 @@ public: bool is_visible() const; bool is_active() const; - bool is_active_input() const { return m_is_active_input; } + bool is_focusable() const { return is_active() || is_popup() || is_autocomplete(); } void show(); void hide(); @@ -304,7 +303,6 @@ private: WindowMode m_window_mode { WindowMode::Modeless }; AK::Variant> m_cursor { Gfx::StandardCursor::None }; AK::Variant> m_effective_cursor { Gfx::StandardCursor::None }; - bool m_is_active_input { false }; bool m_has_alpha_channel { false }; bool m_double_buffering_enabled { true }; bool m_resizable { true }; diff --git a/Userland/Services/Taskbar/ClockWidget.cpp b/Userland/Services/Taskbar/ClockWidget.cpp index 539e728cc2..28e4943ae2 100644 --- a/Userland/Services/Taskbar/ClockWidget.cpp +++ b/Userland/Services/Taskbar/ClockWidget.cpp @@ -41,10 +41,6 @@ ClockWidget::ClockWidget() m_calendar_window->set_frameless(true); m_calendar_window->set_resizable(false); m_calendar_window->set_minimizable(false); - m_calendar_window->on_active_input_change = [this](bool is_active_input) { - if (!is_active_input) - close(); - }; auto& root_container = m_calendar_window->set_main_widget(); root_container.set_fill_with_background_color(true); diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index 3d41d061bd..9b4183536f 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -450,7 +450,7 @@ void Window::event(Core::Event& event) return; } - if (blocking_modal_window()) { + if (blocking_modal_window() && type() != WindowType::Popup) { // Allow windows to process their inactivity after being blocked if (event.type() != Event::WindowDeactivated && event.type() != Event::WindowInputPreempted) return; @@ -980,13 +980,6 @@ Window* Window::modeless_ancestor() return nullptr; } -bool Window::is_capturing_active_input_from(Window const& window) const -{ - if (!is_capturing_input()) - return false; - return parent_window() == &window; -} - void Window::set_progress(Optional progress) { if (m_progress == progress) diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h index 72304153da..082f554cf4 100644 --- a/Userland/Services/WindowServer/Window.h +++ b/Userland/Services/WindowServer/Window.h @@ -106,7 +106,7 @@ public: bool is_closeable() const { return m_closeable; } void set_closeable(bool); - bool is_resizable() const { return m_resizable && !m_fullscreen; } + bool is_resizable() const { return m_type != WindowType::Popup && m_resizable && !m_fullscreen; } void set_resizable(bool); bool is_maximized() const { return m_tile_type == WindowTileType::Maximized; } @@ -182,9 +182,6 @@ 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(); diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp index b68321ba35..8ea1f4be6c 100644 --- a/Userland/Services/WindowServer/WindowFrame.cpp +++ b/Userland/Services/WindowServer/WindowFrame.cpp @@ -221,6 +221,12 @@ MultiScaleBitmaps const* WindowFrame::shadow_bitmap() const return nullptr; case WindowType::WindowSwitcher: return nullptr; + case WindowType::Popup: + if (!WindowManager::the().system_effects().window_shadow()) + return nullptr; + if (!m_window.has_forced_shadow()) + return nullptr; + return s_active_window_shadow; default: if (!WindowManager::the().system_effects().window_shadow()) return nullptr; @@ -280,7 +286,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_capturing_modal(m_window)) + if (m_window.is_active()) return Gfx::WindowTheme::WindowState::Active; return Gfx::WindowTheme::WindowState::Inactive; } diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 7c52705e26..bae6c6c10a 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -330,6 +330,9 @@ void WindowManager::add_window(Window& window) if (window.type() != WindowType::Desktop || is_first_window) set_active_window(&window); + if (window.type() == WindowType::Popup) + notify_active_window_input_preempted(); + if (m_switcher->is_visible() && window.type() != WindowType::WindowSwitcher) m_switcher->refresh(); @@ -350,18 +353,16 @@ void WindowManager::move_to_front_and_make_active(Window& window) if (auto* blocker = window.blocking_modal_window()) { blocker->window_stack().move_to_front(*blocker); - set_active_window(blocker, true); + set_active_window(blocker); } else { window.window_stack().move_to_front(window); - set_active_window(&window, true); + set_active_window(&window); for (auto& child : window.child_windows()) { if (!child || !child->is_modal()) continue; if (child->is_rendering_above()) child->window_stack().move_to_front(*child); - if (child->is_capturing_input()) - set_active_input_window(child); } } @@ -380,12 +381,14 @@ void WindowManager::remove_window(Window& window) { check_hide_geometry_overlay(window); auto* active = active_window(); - auto* active_input = active_input_window(); bool was_modal = window.is_modal(); // This requires the window to be on a window stack still! 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))) + if (active == &window) pick_new_active_window(&window); + if (window.type() == WindowType::Popup) + notify_active_window_input_restored(); + window.invalidate_last_rendered_screen_rects_now(); if (m_switcher->is_visible() && window.type() != WindowType::WindowSwitcher) @@ -429,8 +432,6 @@ void WindowManager::tell_wm_about_window(WMConnectionFromClient& conn, Window& w return; if (window.is_internal()) return; - if (window.is_capturing_input()) - return; if (window.blocking_modal_window()) return; @@ -652,7 +653,7 @@ void WindowManager::pick_new_active_window(Window* previous_active) return IterationDecision::Continue; if (candidate.is_destroyed()) return IterationDecision::Continue; - if ((!previous_active && !candidate.is_capturing_input()) || (previous_active && !candidate.is_capturing_active_input_from(*previous_active))) { + if (!previous_active || previous_active != &candidate) { set_active_window(&candidate); return IterationDecision::Break; } @@ -1249,7 +1250,7 @@ void WindowManager::process_mouse_event_for_window(HitTestResult& result, MouseE set_active_window(&window); } - if (blocking_modal_window) { + if (blocking_modal_window && window.type() != WindowType::Popup) { if (event.type() == Event::Type::MouseDown) { // We're clicking on something that's blocked by a modal window. // Flash the modal window to let the user know about it. @@ -1343,6 +1344,15 @@ void WindowManager::process_mouse_event(MouseEvent& event) if (!result.has_value()) return; + auto* event_window = result.value().window.ptr(); + if (auto* popup_window = foremost_popup_window()) { + if (event_window == popup_window) + process_mouse_event_for_window(result.value(), event); + else if (event.buttons()) + popup_window->request_close(); + return; + } + process_mouse_event_for_window(result.value(), event); } @@ -1468,7 +1478,6 @@ void WindowManager::switch_to_window_stack(WindowStack& window_stack, Window* ca for_each_visible_window_from_back_to_front([&](Window& window) { if (is_stationary_window_type(window.type())) return IterationDecision::Continue; - if (&window.window_stack() != &carry_window->window_stack()) return IterationDecision::Continue; if (&window == carry_window || is_window_in_modal_chain(*carry_window, window)) @@ -1478,29 +1487,23 @@ void WindowManager::switch_to_window_stack(WindowStack& window_stack, Window* ca &from_stack); auto* from_active_window = from_stack.active_window(); - auto* from_active_input_window = from_stack.active_input_window(); bool did_carry_active_window = false; - bool did_carry_active_input_window = false; for (auto& window : m_carry_window_to_new_stack) { if (window == from_active_window) did_carry_active_window = true; - if (window == from_active_input_window) - did_carry_active_input_window = true; window->set_moving_to_another_stack(true); VERIFY(&window->window_stack() == &from_stack); from_stack.remove(*window); window_stack.add(*window); } // Before we change to the new stack, find a new active window on the stack we're switching from - if (did_carry_active_window || did_carry_active_input_window) + if (did_carry_active_window) pick_new_active_window(from_active_window); // Now switch to the new stack m_current_window_stack = &window_stack; if (did_carry_active_window && from_active_window) - set_active_window(from_active_window, from_active_input_window == from_active_window); - if (did_carry_active_input_window && from_active_input_window && from_active_input_window != from_active_window) - set_active_input_window(from_active_input_window); + set_active_window(from_active_window); // Because we moved windows between stacks we need to invalidate occlusions Compositor::the().invalidate_occlusions(); @@ -1535,13 +1538,7 @@ void WindowManager::did_switch_window_stack(Badge, WindowStack& prev } auto* previous_stack_active_window = previous_stack.active_window(); - auto* previous_stack_active_input_window = previous_stack.active_input_window(); auto* new_stack_active_window = new_stack.active_window(); - auto* new_stack_active_input_window = new_stack.active_input_window(); - if (previous_stack_active_input_window && previous_stack_active_input_window != new_stack_active_input_window) - notify_previous_active_input_window(*previous_stack_active_input_window); - if (new_stack_active_input_window && previous_stack_active_input_window != new_stack_active_input_window) - notify_new_active_input_window(*new_stack_active_input_window); if (previous_stack_active_window != new_stack_active_window) { if (previous_stack_active_window && is_stationary_window_type(previous_stack_active_window->type())) notify_previous_active_window(*previous_stack_active_window); @@ -1549,7 +1546,7 @@ void WindowManager::did_switch_window_stack(Badge, WindowStack& prev notify_new_active_window(*new_stack_active_window); } - if (!new_stack_active_input_window) + if (!new_stack_active_window) pick_new_active_window(nullptr); reevaluate_hover_state_for_window(); @@ -1618,6 +1615,7 @@ void WindowManager::process_key_event(KeyEvent& event) m_switcher->show(WindowSwitcher::Mode::ShowCurrentDesktop); } if (m_switcher->is_visible()) { + request_close_fragile_windows(); m_switcher->on_key_event(event); return; } @@ -1658,6 +1656,7 @@ void WindowManager::process_key_event(KeyEvent& event) } }; if (handle_window_stack_switch_key()) { + request_close_fragile_windows(); Window* carry_window = nullptr; auto& new_window_stack = m_window_stacks[row][column]; if (&new_window_stack != ¤t_stack) { @@ -1671,8 +1670,10 @@ void WindowManager::process_key_event(KeyEvent& event) } } - auto* active_input_window = current_window_stack().active_input_window(); - if (!active_input_window) + auto* event_window = current_window_stack().active_window(); + if (auto* popup_window = foremost_popup_window()) + event_window = popup_window; + if (!event_window) return; if (event.type() == Event::KeyDown && event.modifiers() == Mod_Super) { @@ -1681,71 +1682,71 @@ void WindowManager::process_key_event(KeyEvent& event) Compositor::the().invalidate_cursor(); return; } - if (active_input_window->type() != WindowType::Desktop) { + if (event_window->type() != WindowType::Desktop) { if (event.key() == Key_Down) { - if (active_input_window->is_resizable() && active_input_window->is_maximized()) { - maximize_windows(*active_input_window, false); + if (event_window->is_resizable() && event_window->is_maximized()) { + maximize_windows(*event_window, false); return; } - if (active_input_window->is_minimizable() && !active_input_window->is_modal()) - minimize_windows(*active_input_window, true); + if (event_window->is_minimizable() && !event_window->is_modal()) + minimize_windows(*event_window, true); return; } - if (active_input_window->is_resizable()) { + if (event_window->is_resizable()) { if (event.key() == Key_Up) { - maximize_windows(*active_input_window, !active_input_window->is_maximized()); + maximize_windows(*event_window, !event_window->is_maximized()); return; } if (event.key() == Key_Left) { - if (active_input_window->tile_type() == WindowTileType::Left) { - active_input_window->set_untiled(); + if (event_window->tile_type() == WindowTileType::Left) { + event_window->set_untiled(); return; } - if (active_input_window->is_maximized()) - maximize_windows(*active_input_window, false); - active_input_window->set_tiled(WindowTileType::Left); + if (event_window->is_maximized()) + maximize_windows(*event_window, false); + event_window->set_tiled(WindowTileType::Left); return; } if (event.key() == Key_Right) { - if (active_input_window->tile_type() == WindowTileType::Right) { - active_input_window->set_untiled(); + if (event_window->tile_type() == WindowTileType::Right) { + event_window->set_untiled(); return; } - if (active_input_window->is_maximized()) - maximize_windows(*active_input_window, false); - active_input_window->set_tiled(WindowTileType::Right); + if (event_window->is_maximized()) + maximize_windows(*event_window, false); + event_window->set_tiled(WindowTileType::Right); return; } } } } - if (event.type() == Event::KeyDown && event.modifiers() == (Mod_Super | Mod_Alt) && active_input_window->type() != WindowType::Desktop) { - if (active_input_window->is_resizable()) { + if (event.type() == Event::KeyDown && event.modifiers() == (Mod_Super | Mod_Alt) && event_window->type() != WindowType::Desktop) { + if (event_window->is_resizable()) { if (event.key() == Key_Right || event.key() == Key_Left) { - if (active_input_window->tile_type() == WindowTileType::HorizontallyMaximized) { - active_input_window->set_untiled(); + if (event_window->tile_type() == WindowTileType::HorizontallyMaximized) { + event_window->set_untiled(); return; } - if (active_input_window->is_maximized()) - maximize_windows(*active_input_window, false); - active_input_window->set_tiled(WindowTileType::HorizontallyMaximized); + if (event_window->is_maximized()) + maximize_windows(*event_window, false); + event_window->set_tiled(WindowTileType::HorizontallyMaximized); return; } if (event.key() == Key_Up || event.key() == Key_Down) { - if (active_input_window->tile_type() == WindowTileType::VerticallyMaximized) { - active_input_window->set_untiled(); + if (event_window->tile_type() == WindowTileType::VerticallyMaximized) { + event_window->set_untiled(); return; } - if (active_input_window->is_maximized()) - maximize_windows(*active_input_window, false); - active_input_window->set_tiled(WindowTileType::VerticallyMaximized); + if (event_window->is_maximized()) + maximize_windows(*event_window, false); + event_window->set_tiled(WindowTileType::VerticallyMaximized); return; } } } - active_input_window->dispatch_event(event); + event_window->dispatch_event(event); } void WindowManager::set_highlight_window(Window* new_highlight_window) @@ -1774,78 +1775,24 @@ void WindowManager::set_highlight_window(Window* new_highlight_window) Compositor::the().invalidate_occlusions(); } -bool WindowManager::is_active_window_or_capturing_modal(Window& window) const -{ - if (window.is_capturing_input()) - return window.parent_window()->is_active(); - - return window.is_active(); -} - static bool window_type_can_become_active(WindowType type) { return type == WindowType::Normal || type == WindowType::Desktop; } -void WindowManager::restore_active_input_window(Window* window) -{ - // If the previous active input window is gone, fall back to the - // current active window - if (!window) - window = active_window(); - // If the current active window is also gone, pick some other window - if (!window) { - pick_new_active_window(nullptr); - return; - } - - if (window && !window->is_minimized() && window->is_visible()) - set_active_input_window(window); - else - set_active_input_window(nullptr); -} - -Window* WindowManager::set_active_input_window(Window* window) -{ - auto& window_stack = current_window_stack(); - auto* previous_input_window = window_stack.active_input_window(); - if (window == previous_input_window) - return window; - - if (previous_input_window) - notify_previous_active_input_window(*previous_input_window); - - window_stack.set_active_input_window(window); - if (window) - notify_new_active_input_window(*window); - - return previous_input_window; -} - -void WindowManager::set_active_window(Window* new_active_window, bool make_input) +void WindowManager::set_active_window(Window* new_active_window) { if (new_active_window) { if (auto* blocker = new_active_window->blocking_modal_window()) { VERIFY(blocker->is_modal()); VERIFY(blocker != new_active_window); new_active_window = blocker; - make_input = true; } if (!window_type_can_become_active(new_active_window->type())) return; } - auto* new_active_input_window = new_active_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(); - } - - if (make_input) - set_active_input_window(new_active_input_window); - auto& window_stack = current_window_stack(); if (new_active_window == window_stack.active_window()) return; @@ -1857,6 +1804,7 @@ void WindowManager::set_active_window(Window* new_active_window, bool make_input } if (new_active_window) { + request_close_fragile_windows(); window_stack.set_active_window(new_active_window); notify_new_active_window(*new_active_window); reevaluate_hover_state_for_window(new_active_window); diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 763dd2fbca..efad2a6529 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -100,16 +100,6 @@ public: Window* foremost_popup_window(WindowStack& stack = WindowManager::the().current_window_stack()); void request_close_fragile_windows(WindowStack& stack = WindowManager::the().current_window_stack()); - Window* active_input_window() - { - VERIFY(m_current_window_stack); - return m_current_window_stack->active_input_window(); - } - Window const* active_input_window() const - { - VERIFY(m_current_window_stack); - return m_current_window_stack->active_input_window(); - } ConnectionFromClient const* active_client() const; @@ -164,9 +154,7 @@ public: void set_buttons_switched(bool); bool get_buttons_switched() const; - Window* set_active_input_window(Window*); - void restore_active_input_window(Window*); - void set_active_window(Window*, bool make_input = true); + void set_active_window(Window*); void set_hovered_button(Button*); Button const* cursor_tracking_button() const { return m_cursor_tracking_button.ptr(); } @@ -188,8 +176,6 @@ public: void tell_wms_super_digit_key_pressed(u8); void tell_wms_current_window_stack_changed(); - bool is_active_window_or_capturing_modal(Window&) const; - void check_hide_geometry_overlay(Window&); void start_window_resize(Window&, Gfx::IntPoint const&, MouseButton, ResizeDirection); diff --git a/Userland/Services/WindowServer/WindowMode.h b/Userland/Services/WindowServer/WindowMode.h index c70e821337..e6c7930adc 100644 --- a/Userland/Services/WindowServer/WindowMode.h +++ b/Userland/Services/WindowServer/WindowMode.h @@ -13,13 +13,11 @@ namespace WindowServer { // - Modeless: No modal effect (default mode for parentless windows) // - Passive: Joins the modal chain but has no modal effect (default mode for child windows) // - RenderAbove: Renders above its parent -// - CaptureInput: Captures input from its parent -// - Blocking: Preempts all interaction with its modal chain excepting descendants (default mode for Dialogs) +// - Blocking: Preempts all interaction with its modal chain excepting descendants and popups (default mode for Dialogs) enum class WindowMode { Modeless = 0, Passive, RenderAbove, - CaptureInput, Blocking, _Count, }; diff --git a/Userland/Services/WindowServer/WindowStack.cpp b/Userland/Services/WindowServer/WindowStack.cpp index 60a1fca855..f4c2de6cbb 100644 --- a/Userland/Services/WindowServer/WindowStack.cpp +++ b/Userland/Services/WindowServer/WindowStack.cpp @@ -38,8 +38,6 @@ void WindowStack::remove(Window& window) window.set_window_stack({}, nullptr); if (m_active_window == &window) m_active_window = nullptr; - if (m_active_input_window == &window) - m_active_input_window = nullptr; } void WindowStack::move_to_front(Window& window) @@ -99,7 +97,6 @@ void WindowStack::move_all_windows(WindowStack& new_window_stack, Vector hit_test(Gfx::IntPoint const&) const; unsigned row() const { return m_row; } @@ -79,7 +75,6 @@ public: private: WeakPtr m_active_window; - WeakPtr m_active_input_window; Window::List m_windows; unsigned m_row { 0 };