mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:07:35 +00:00
WSWindowManager: Ensure that we pick a single window to deliver a full stream of events to
This is effectively a mouse grab except that we don't require any client coordination to request it (which is probably OK, and certainly a lot simpler to implement). This prevents e.g. dragging the mouse cursor out of paint and over the terminal from selecting text unexpectedly.
This commit is contained in:
parent
d0a2668833
commit
8a1a9e78d7
2 changed files with 54 additions and 34 deletions
|
@ -703,6 +703,19 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
||||||
|
|
||||||
WSWindow* event_window_with_frame = nullptr;
|
WSWindow* event_window_with_frame = nullptr;
|
||||||
|
|
||||||
|
if (m_active_input_window) {
|
||||||
|
// At this point, we have delivered the start of an input sequence to a
|
||||||
|
// client application. We must keep delivering to that client
|
||||||
|
// application until the input sequence is done.
|
||||||
|
//
|
||||||
|
// This prevents e.g. dragging on one window out of the bounds starting
|
||||||
|
// a drag in that other unrelated window, and other silly shennanigans.
|
||||||
|
auto translated_event = event.translated(-m_active_input_window->position());
|
||||||
|
deliver_mouse_event(*m_active_input_window, translated_event);
|
||||||
|
if (event.type() == WSEvent::MouseUp && event.buttons() == 0) {
|
||||||
|
m_active_input_window = nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for_each_visible_window_from_front_to_back([&](WSWindow& window) {
|
for_each_visible_window_from_front_to_back([&](WSWindow& window) {
|
||||||
auto window_frame_rect = window.frame().rect();
|
auto window_frame_rect = window.frame().rect();
|
||||||
if (!window_frame_rect.contains(event.position()))
|
if (!window_frame_rect.contains(event.position()))
|
||||||
|
@ -724,6 +737,8 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
||||||
start_window_resize(window, event);
|
start_window_resize(window, event);
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseWheel) {
|
if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseWheel) {
|
||||||
float opacity_change = -event.wheel_delta() * 0.05f;
|
float opacity_change = -event.wheel_delta() * 0.05f;
|
||||||
float new_opacity = window.opacity() + opacity_change;
|
float new_opacity = window.opacity() + opacity_change;
|
||||||
|
@ -735,7 +750,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
||||||
window.invalidate();
|
window.invalidate();
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Well okay, let's see if we're hitting the frame or the window inside the frame.
|
// Well okay, let's see if we're hitting the frame or the window inside the frame.
|
||||||
if (window.rect().contains(event.position())) {
|
if (window.rect().contains(event.position())) {
|
||||||
if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown)
|
if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown)
|
||||||
|
@ -745,6 +760,9 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
||||||
if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window)) {
|
if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window)) {
|
||||||
auto translated_event = event.translated(-window.position());
|
auto translated_event = event.translated(-window.position());
|
||||||
deliver_mouse_event(window, translated_event);
|
deliver_mouse_event(window, translated_event);
|
||||||
|
if (event.type() == WSEvent::MouseDown) {
|
||||||
|
m_active_input_window = window.make_weak_ptr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
|
@ -754,6 +772,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
||||||
event_window_with_frame = &window;
|
event_window_with_frame = &window;
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (event_window_with_frame != m_resize_candidate.ptr())
|
if (event_window_with_frame != m_resize_candidate.ptr())
|
||||||
clear_resize_candidate();
|
clear_resize_candidate();
|
||||||
|
|
|
@ -220,6 +220,7 @@ private:
|
||||||
WeakPtr<WSWindow> m_active_window;
|
WeakPtr<WSWindow> m_active_window;
|
||||||
WeakPtr<WSWindow> m_hovered_window;
|
WeakPtr<WSWindow> m_hovered_window;
|
||||||
WeakPtr<WSWindow> m_highlight_window;
|
WeakPtr<WSWindow> m_highlight_window;
|
||||||
|
WeakPtr<WSWindow> m_active_input_window;
|
||||||
|
|
||||||
WeakPtr<WSWindow> m_drag_window;
|
WeakPtr<WSWindow> m_drag_window;
|
||||||
Point m_drag_origin;
|
Point m_drag_origin;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue