diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index 86bf5c8b9f..0a4b406949 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -599,7 +599,7 @@ Gfx::IntRect Widget::window_relative_rect() const Gfx::IntRect Widget::screen_relative_rect() const { auto window_position = window()->window_type() == WindowType::MenuApplet - ? window()->rect_in_menubar().location() + ? window()->applet_rect_on_screen().location() : window()->rect().location(); return window_relative_rect().translated(window_position); } diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 23332112b1..e0ddab3d25 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -235,10 +235,10 @@ String Window::title() const return WindowServerConnection::the().send_sync(m_window_id)->title(); } -Gfx::IntRect Window::rect_in_menubar() const +Gfx::IntRect Window::applet_rect_on_screen() const { VERIFY(m_window_type == WindowType::MenuApplet); - return WindowServerConnection::the().send_sync(m_window_id)->rect(); + return WindowServerConnection::the().send_sync(m_window_id)->rect(); } Gfx::IntRect Window::rect() const diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index 306788d8e7..06bea7ef55 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -101,7 +101,7 @@ public: int height() const { return rect().height(); } Gfx::IntRect rect() const; - Gfx::IntRect rect_in_menubar() const; + Gfx::IntRect applet_rect_on_screen() const; Gfx::IntSize size() const { return rect().size(); } void set_rect(const Gfx::IntRect&); void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); } diff --git a/Userland/MenuApplets/Audio/main.cpp b/Userland/MenuApplets/Audio/main.cpp index 4bdcaa7d86..414f40bef2 100644 --- a/Userland/MenuApplets/Audio/main.cpp +++ b/Userland/MenuApplets/Audio/main.cpp @@ -189,7 +189,11 @@ private: VERIFY_NOT_REACHED(); } - void reposition_slider_window() { m_slider_window->set_rect(window()->rect_in_menubar().x() - 20, 19, 50, 100); } + void reposition_slider_window() + { + auto applet_rect = window()->applet_rect_on_screen(); + m_slider_window->set_rect(applet_rect.x() - 20, applet_rect.y() - 106, 50, 100); + } struct VolumeBitmapPair { int volume_threshold { 0 }; diff --git a/Userland/Services/WindowServer/AppletManager.cpp b/Userland/Services/WindowServer/AppletManager.cpp index cbe7723223..a2d2d648e3 100644 --- a/Userland/Services/WindowServer/AppletManager.cpp +++ b/Userland/Services/WindowServer/AppletManager.cpp @@ -27,6 +27,7 @@ #include "AppletManager.h" #include +#include #include #include @@ -60,21 +61,40 @@ void AppletManager::set_position(const Gfx::IntPoint& position) m_window->set_visible(true); } +void AppletManager::set_hovered_applet(Window* applet) +{ + if (m_hovered_applet == applet) + return; + + if (m_hovered_applet) + Core::EventLoop::current().post_event(*m_hovered_applet, make(Event::WindowLeft)); + + m_hovered_applet = applet; + + if (m_hovered_applet) + Core::EventLoop::current().post_event(*m_hovered_applet, make(Event::WindowEntered)); +} + void AppletManager::event(Core::Event& event) { + if (event.type() == Event::WindowLeft && m_hovered_applet) { + set_hovered_applet(nullptr); + return; + } + if (!is(event)) return; auto& mouse_event = static_cast(event); - dbgln("mouse_event: {}", mouse_event.position()); - for (auto& applet : m_applets) { if (!applet) continue; if (!applet->rect_in_applet_area().contains(mouse_event.position())) continue; auto local_event = mouse_event.translated(-applet->rect_in_applet_area().location()); - applet->dispatch_event(local_event); + set_hovered_applet(applet); + Core::EventLoop::current().post_event(*applet, make(local_event)); + return; } } diff --git a/Userland/Services/WindowServer/AppletManager.h b/Userland/Services/WindowServer/AppletManager.h index e55a14adfd..2b3cdd2757 100644 --- a/Userland/Services/WindowServer/AppletManager.h +++ b/Userland/Services/WindowServer/AppletManager.h @@ -54,9 +54,11 @@ public: private: void draw_applet(const Window& applet); + void set_hovered_applet(Window*); Vector> m_applets; RefPtr m_window; + WeakPtr m_hovered_applet; }; } diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp index b16b708d0f..77ff8e1ab7 100644 --- a/Userland/Services/WindowServer/ClientConnection.cpp +++ b/Userland/Services/WindowServer/ClientConnection.cpp @@ -475,15 +475,20 @@ OwnPtr ClientConnection::h return make(it->value->minimum_size()); } -OwnPtr ClientConnection::handle(const Messages::WindowServer::GetWindowRectInMenubar& message) +OwnPtr ClientConnection::handle(const Messages::WindowServer::GetAppletRectOnScreen& message) { int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { - did_misbehave("GetWindowRectInMenubar: Bad window ID"); + did_misbehave("GetAppletRectOnScreen: Bad window ID"); return {}; } - return make(it->value->rect_in_applet_area()); + + Gfx::IntRect applet_area_rect; + if (auto* applet_area_window = AppletManager::the().window()) + applet_area_rect = applet_area_window->rect(); + + return make(it->value->rect_in_applet_area().translated(applet_area_rect.location())); } Window* ClientConnection::window_from_id(i32 window_id) diff --git a/Userland/Services/WindowServer/ClientConnection.h b/Userland/Services/WindowServer/ClientConnection.h index 73650acc31..198775adc9 100644 --- a/Userland/Services/WindowServer/ClientConnection.h +++ b/Userland/Services/WindowServer/ClientConnection.h @@ -126,7 +126,7 @@ private: virtual OwnPtr handle(const Messages::WindowServer::GetWindowRect&) override; virtual OwnPtr handle(const Messages::WindowServer::SetWindowMinimumSize&) override; virtual OwnPtr handle(const Messages::WindowServer::GetWindowMinimumSize&) override; - virtual OwnPtr handle(const Messages::WindowServer::GetWindowRectInMenubar&) override; + virtual OwnPtr handle(const Messages::WindowServer::GetAppletRectOnScreen&) override; virtual void handle(const Messages::WindowServer::InvalidateRect&) override; virtual void handle(const Messages::WindowServer::DidFinishPainting&) override; virtual OwnPtr handle(const Messages::WindowServer::SetGlobalCursorTracking&) override; diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index 13618fb1ee..fa8d70462f 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -62,7 +62,7 @@ endpoint WindowServer = 2 SetWindowMinimumSize(i32 window_id, Gfx::IntSize size) => () GetWindowMinimumSize(i32 window_id) => (Gfx::IntSize size) - GetWindowRectInMenubar(i32 window_id) => (Gfx::IntRect rect) + GetAppletRectOnScreen(i32 window_id) => (Gfx::IntRect rect) StartWindowResize(i32 window_id) =|