diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp index e9060080b9c..60b03b1192f 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.cpp @@ -120,16 +120,16 @@ void ConnectionToWindowServer::window_deactivated(i32 window_id) Core::EventLoop::current().post_event(*window, make(Event::WindowBecameInactive)); } -void ConnectionToWindowServer::window_input_entered(i32 window_id) +void ConnectionToWindowServer::window_input_preempted(i32 window_id) { if (auto* window = Window::from_window_id(window_id)) - Core::EventLoop::current().post_event(*window, make(Event::WindowInputEntered)); + Core::EventLoop::current().post_event(*window, make(Event::WindowInputPreempted)); } -void ConnectionToWindowServer::window_input_left(i32 window_id) +void ConnectionToWindowServer::window_input_restored(i32 window_id) { if (auto* window = Window::from_window_id(window_id)) - Core::EventLoop::current().post_event(*window, make(Event::WindowInputLeft)); + Core::EventLoop::current().post_event(*window, make(Event::WindowInputRestored)); } void ConnectionToWindowServer::window_close_request(i32 window_id) diff --git a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h index 6b2970bd0ac..19965ae59f9 100644 --- a/Userland/Libraries/LibGUI/ConnectionToWindowServer.h +++ b/Userland/Libraries/LibGUI/ConnectionToWindowServer.h @@ -37,8 +37,8 @@ private: virtual void key_up(i32, u32, u32, u32, u32) override; virtual void window_activated(i32) override; virtual void window_deactivated(i32) override; - virtual void window_input_entered(i32) override; - virtual void window_input_left(i32) override; + virtual void window_input_preempted(i32) override; + virtual void window_input_restored(i32) override; virtual void window_close_request(i32) override; virtual void window_resized(i32, Gfx::IntRect const&) override; virtual void window_moved(i32, Gfx::IntRect const&) override; diff --git a/Userland/Libraries/LibGUI/Event.h b/Userland/Libraries/LibGUI/Event.h index 9d9597df126..7f07f21a7c3 100644 --- a/Userland/Libraries/LibGUI/Event.h +++ b/Userland/Libraries/LibGUI/Event.h @@ -42,8 +42,8 @@ public: WindowLeft, WindowBecameInactive, WindowBecameActive, - WindowInputEntered, - WindowInputLeft, + WindowInputPreempted, + WindowInputRestored, FocusIn, FocusOut, WindowCloseRequest, diff --git a/Userland/Libraries/LibGUI/Widget.h b/Userland/Libraries/LibGUI/Widget.h index 04567e6f057..677b6edef42 100644 --- a/Userland/Libraries/LibGUI/Widget.h +++ b/Userland/Libraries/LibGUI/Widget.h @@ -214,6 +214,9 @@ public: bool is_focused() const; void set_focus(bool, FocusSource = FocusSource::Programmatic); + bool focus_preempted() const { return m_focus_preempted; } + void set_focus_preempted(bool b) { m_focus_preempted = b; } + Function on_focus_change; // Returns true if this widget or one of its descendants is focused. @@ -440,6 +443,7 @@ private: bool m_visible { true }; bool m_greedy_for_hits { false }; bool m_auto_focusable { true }; + bool m_focus_preempted { false }; bool m_enabled { true }; bool m_updates_enabled { true }; bool m_accepts_command_palette { true }; diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index bff99026532..8dd89c7e134 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -522,15 +522,14 @@ void Window::handle_resize_event(ResizeEvent& event) m_main_widget->set_relative_rect({ {}, new_size }); } -void Window::handle_input_entered_or_left_event(Core::Event& event) +void Window::handle_input_preemption_event(Core::Event& event) { - m_is_active_input = event.type() == Event::WindowInputEntered; - if (on_active_input_change) - on_active_input_change(m_is_active_input); - if (m_main_widget) - m_main_widget->dispatch_event(event, this); - if (m_focused_widget) - m_focused_widget->update(); + if (on_input_preemption_change) + on_input_preemption_change(event.type() == Event::WindowInputPreempted); + if (!m_focused_widget) + return; + m_focused_widget->set_focus_preempted(event.type() == Event::WindowInputPreempted); + m_focused_widget->update(); } void Window::handle_became_active_or_inactive_event(Core::Event& event) @@ -543,8 +542,11 @@ void Window::handle_became_active_or_inactive_event(Core::Event& event) on_active_window_change(event.type() == Event::WindowBecameActive); if (m_main_widget) m_main_widget->dispatch_event(event, this); - if (m_focused_widget) + if (m_focused_widget) { + if (event.type() == Event::WindowBecameActive) + m_focused_widget->set_focus_preempted(false); m_focused_widget->update(); + } } void Window::handle_close_request() @@ -678,8 +680,8 @@ void Window::event(Core::Event& event) if (event.type() == Event::WindowBecameActive || event.type() == Event::WindowBecameInactive) return handle_became_active_or_inactive_event(event); - if (event.type() == Event::WindowInputEntered || event.type() == Event::WindowInputLeft) - return handle_input_entered_or_left_event(event); + if (event.type() == Event::WindowInputPreempted || event.type() == Event::WindowInputRestored) + return handle_input_preemption_event(event); if (event.type() == Event::WindowCloseRequest) return handle_close_request(); diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index 44f10d98801..bacb09346c8 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -97,6 +97,7 @@ public: Function on_close; Function on_close_request; Function on_active_input_change; + Function on_input_preemption_change; Function on_active_window_change; Function on_input_preemption; @@ -259,7 +260,7 @@ private: void handle_multi_paint_event(MultiPaintEvent&); void handle_key_event(KeyEvent&); void handle_resize_event(ResizeEvent&); - void handle_input_entered_or_left_event(Core::Event&); + void handle_input_preemption_event(Core::Event&); void handle_became_active_or_inactive_event(Core::Event&); void handle_close_request(); void handle_theme_change_event(ThemeChangeEvent&); diff --git a/Userland/Services/WindowServer/Event.h b/Userland/Services/WindowServer/Event.h index 9114db8ad43..dbacf547a66 100644 --- a/Userland/Services/WindowServer/Event.h +++ b/Userland/Services/WindowServer/Event.h @@ -31,8 +31,8 @@ public: KeyUp, WindowActivated, WindowDeactivated, - WindowInputEntered, - WindowInputLeft, + WindowInputPreempted, + WindowInputRestored, WindowCloseRequest, WindowResized, WindowMoved, diff --git a/Userland/Services/WindowServer/Window.cpp b/Userland/Services/WindowServer/Window.cpp index c1938f609a8..3d41d061bd3 100644 --- a/Userland/Services/WindowServer/Window.cpp +++ b/Userland/Services/WindowServer/Window.cpp @@ -452,7 +452,7 @@ void Window::event(Core::Event& event) if (blocking_modal_window()) { // Allow windows to process their inactivity after being blocked - if (event.type() != Event::WindowDeactivated && event.type() != Event::WindowInputLeft) + if (event.type() != Event::WindowDeactivated && event.type() != Event::WindowInputPreempted) return; } @@ -482,11 +482,11 @@ void Window::event(Core::Event& event) case Event::WindowDeactivated: m_client->async_window_deactivated(m_window_id); break; - case Event::WindowInputEntered: - m_client->async_window_input_entered(m_window_id); + case Event::WindowInputPreempted: + m_client->async_window_input_preempted(m_window_id); break; - case Event::WindowInputLeft: - m_client->async_window_input_left(m_window_id); + case Event::WindowInputRestored: + m_client->async_window_input_restored(m_window_id); break; case Event::WindowCloseRequest: m_client->async_window_close_request(m_window_id); diff --git a/Userland/Services/WindowServer/WindowClient.ipc b/Userland/Services/WindowServer/WindowClient.ipc index ec902f17b34..686d70c3ae1 100644 --- a/Userland/Services/WindowServer/WindowClient.ipc +++ b/Userland/Services/WindowServer/WindowClient.ipc @@ -13,8 +13,8 @@ endpoint WindowClient mouse_wheel(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y) =| window_entered(i32 window_id) =| window_left(i32 window_id) =| - window_input_entered(i32 window_id) =| - window_input_left(i32 window_id) =| + window_input_preempted(i32 window_id) =| + window_input_restored(i32 window_id) =| key_down(i32 window_id, u32 code_point, u32 key, u32 modifiers, u32 scancode) =| key_up(i32 window_id, u32 code_point, u32 key, u32 modifiers, u32 scancode) =| window_activated(i32 window_id) =| diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 0e68aee5ecf..dbfeb45a9f2 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -1828,20 +1828,6 @@ Window* WindowManager::set_active_input_window(Window* window) return previous_input_window; } -void WindowManager::notify_new_active_input_window(Window& new_input_window) -{ - Core::EventLoop::current().post_event(new_input_window, make(Event::WindowInputEntered)); - if (new_input_window.is_capturing_input() && !new_input_window.is_frameless()) - new_input_window.invalidate(true, true); -} - -void WindowManager::notify_previous_active_input_window(Window& previous_input_window) -{ - Core::EventLoop::current().post_event(previous_input_window, make(Event::WindowInputLeft)); - if (previous_input_window.is_capturing_input() && !previous_input_window.is_frameless()) - previous_input_window.invalidate(true, true); -} - void WindowManager::set_active_window(Window* new_active_window, bool make_input) { if (new_active_window) { @@ -1905,6 +1891,18 @@ void WindowManager::notify_previous_active_window(Window& previously_active_wind tell_wms_window_state_changed(previously_active_window); } +void WindowManager::notify_active_window_input_preempted() +{ + if (active_window()) + Core::EventLoop::current().post_event(*active_window(), make(Event::WindowInputPreempted)); +} + +void WindowManager::notify_active_window_input_restored() +{ + if (active_window()) + Core::EventLoop::current().post_event(*active_window(), make(Event::WindowInputRestored)); +} + bool WindowManager::set_hovered_window(Window* window) { if (m_hovered_window == window) diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index a92ad93f6b7..a6598e72153 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -341,9 +341,9 @@ private: explicit WindowManager(Gfx::PaletteImpl const&); void notify_new_active_window(Window&); - void notify_new_active_input_window(Window&); void notify_previous_active_window(Window&); - void notify_previous_active_input_window(Window&); + void notify_active_window_input_preempted(); + void notify_active_window_input_restored(); void process_mouse_event(MouseEvent&); void process_event_for_doubleclick(Window& window, MouseEvent& event);