summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthankyouverycool <66646555+thankyouverycool@users.noreply.github.com>2022-08-25 11:28:01 -0400
committerAndreas Kling <kling@serenityos.org>2022-08-26 12:48:05 +0200
commit18b111b802751226559ac6e530fbede8104e47c1 (patch)
tree3dea1b307a5c7d683290566b8219cc1865a89397
parentbab8bd143f964c5a0ed3c831aad3e7fef1ab1d58 (diff)
downloadserenity-18b111b802751226559ac6e530fbede8104e47c1.zip
WindowServer: Ignore modal blocking if capturing input
This exception is necessary for ComboBoxes used in some blocking Dialogs. CaptureInput is now the only mode which can spawn from a blocking modal and it won't accept any children of its own.
-rw-r--r--Userland/Services/WindowServer/ConnectionFromClient.cpp2
-rw-r--r--Userland/Services/WindowServer/Window.cpp2
-rw-r--r--Userland/Services/WindowServer/WindowManager.cpp16
3 files changed, 11 insertions, 9 deletions
diff --git a/Userland/Services/WindowServer/ConnectionFromClient.cpp b/Userland/Services/WindowServer/ConnectionFromClient.cpp
index b533976ed8..d49463e242 100644
--- a/Userland/Services/WindowServer/ConnectionFromClient.cpp
+++ b/Userland/Services/WindowServer/ConnectionFromClient.cpp
@@ -576,7 +576,7 @@ void ConnectionFromClient::create_window(i32 window_id, Gfx::IntRect const& rect
did_misbehave("CreateWindow with bad parent_window_id");
return;
}
- if (parent_window->is_blocking() || (parent_window->is_capturing_input() && mode == (i32)WindowMode::CaptureInput)) {
+ if ((parent_window->is_blocking() && mode != (i32)WindowMode::CaptureInput) || parent_window->is_capturing_input()) {
did_misbehave("CreateWindow with forbidden parent mode");
return;
}
diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp
index 59d904bd92..fab5fc03ab 100644
--- a/Userland/Services/WindowServer/Window.cpp
+++ b/Userland/Services/WindowServer/Window.cpp
@@ -442,7 +442,7 @@ void Window::event(Core::Event& event)
return;
}
- if (blocking_modal_window()) {
+ if (blocking_modal_window() && !is_capturing_input()) {
// We still want to handle the WindowDeactivated event below when a new modal is
// created to notify its parent window, despite it being "blocked by modal window".
if (event.type() != Event::WindowDeactivated)
diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp
index 2a234343db..9f85e33507 100644
--- a/Userland/Services/WindowServer/WindowManager.cpp
+++ b/Userland/Services/WindowServer/WindowManager.cpp
@@ -342,7 +342,8 @@ void WindowManager::add_window(Window& window)
void WindowManager::move_to_front_and_make_active(Window& window)
{
- if (auto* blocker = window.blocking_modal_window()) {
+ auto* blocker = window.blocking_modal_window();
+ if (blocker && !window.is_capturing_input()) {
blocker->window_stack().move_to_front(*blocker);
set_active_window(blocker, true);
} else {
@@ -1221,7 +1222,7 @@ void WindowManager::process_mouse_event_for_window(HitTestResult& result, MouseE
// First check if we should initiate a move or resize (Super+LMB or Super+RMB).
// In those cases, the event is swallowed by the window manager.
- if (!blocking_modal_window && window.is_movable()) {
+ if ((!blocking_modal_window || window.is_capturing_input()) && window.is_movable()) {
if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Super && event.type() == Event::MouseDown && event.button() == MouseButton::Primary) {
start_window_move(window, event);
return;
@@ -1239,7 +1240,7 @@ void WindowManager::process_mouse_event_for_window(HitTestResult& result, MouseE
set_active_window(&window);
}
- if (blocking_modal_window) {
+ if (blocking_modal_window && !window.is_capturing_input()) {
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.
@@ -1826,10 +1827,11 @@ void WindowManager::notify_previous_active_input_window(Window& previous_input_w
void WindowManager::set_active_window(Window* new_active_window, bool make_input)
{
if (new_active_window) {
- if (auto* modal_window = new_active_window->blocking_modal_window()) {
- VERIFY(modal_window->is_modal());
- VERIFY(modal_window != new_active_window);
- new_active_window = modal_window;
+ auto* blocker = new_active_window->blocking_modal_window();
+ if (blocker && !new_active_window->is_capturing_input()) {
+ VERIFY(blocker->is_modal());
+ VERIFY(blocker != new_active_window);
+ new_active_window = blocker;
make_input = true;
}