diff --git a/Userland/Libraries/LibGUI/Event.h b/Userland/Libraries/LibGUI/Event.h index aa2338f3d6..4443f0b59b 100644 --- a/Userland/Libraries/LibGUI/Event.h +++ b/Userland/Libraries/LibGUI/Event.h @@ -82,6 +82,7 @@ public: WM_WindowRectChanged, WM_WindowIconBitmapChanged, WM_AppletAreaSizeChanged, + WM_SuperKeyPressed, __End_WM_Events, }; @@ -113,6 +114,14 @@ private: int m_window_id { -1 }; }; +class WMSuperKeyPressedEvent : public WMEvent { +public: + explicit WMSuperKeyPressedEvent(int client_id) + : WMEvent(Event::Type::WM_SuperKeyPressed, client_id, 0) + { + } +}; + class WMAppletAreaSizeChangedEvent : public WMEvent { public: explicit WMAppletAreaSizeChangedEvent(const Gfx::IntSize& size) diff --git a/Userland/Libraries/LibGUI/WindowManagerServerConnection.cpp b/Userland/Libraries/LibGUI/WindowManagerServerConnection.cpp index 3e878ec477..c7cab033ec 100644 --- a/Userland/Libraries/LibGUI/WindowManagerServerConnection.cpp +++ b/Userland/Libraries/LibGUI/WindowManagerServerConnection.cpp @@ -74,4 +74,10 @@ void WindowManagerServerConnection::handle(const Messages::WindowManagerClient:: if (auto* window = Window::from_window_id(message.wm_id())) Core::EventLoop::current().post_event(*window, make(message.client_id(), message.window_id())); } + +void WindowManagerServerConnection::handle(const Messages::WindowManagerClient::SuperKeyPressed& message) +{ + if (auto* window = Window::from_window_id(message.wm_id())) + Core::EventLoop::current().post_event(*window, make(message.wm_id())); +} } diff --git a/Userland/Libraries/LibGUI/WindowManagerServerConnection.h b/Userland/Libraries/LibGUI/WindowManagerServerConnection.h index 3543c6f9bc..99da28aadd 100644 --- a/Userland/Libraries/LibGUI/WindowManagerServerConnection.h +++ b/Userland/Libraries/LibGUI/WindowManagerServerConnection.h @@ -52,6 +52,7 @@ private: virtual void handle(const Messages::WindowManagerClient::WindowIconBitmapChanged&) override; virtual void handle(const Messages::WindowManagerClient::WindowRectChanged&) override; virtual void handle(const Messages::WindowManagerClient::AppletAreaSizeChanged&) override; + virtual void handle(const Messages::WindowManagerClient::SuperKeyPressed&) override; }; } diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index e23a6058e1..4c6332338a 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -34,6 +34,7 @@ #include "Window.h" #include #include +#include #include #include #include @@ -377,6 +378,17 @@ void WindowManager::tell_wms_applet_area_size_changed(const Gfx::IntSize& size) }); } +void WindowManager::tell_wms_super_key_pressed() +{ + for_each_window_manager([](WMClientConnection& conn) { + if (conn.window_id() < 0) + return IterationDecision::Continue; + + conn.post_message(Messages::WindowManagerClient::SuperKeyPressed(conn.window_id())); + return IterationDecision::Continue; + }); +} + static bool window_type_has_title(WindowType type) { return type == WindowType::Normal || type == WindowType::ToolWindow; @@ -1182,6 +1194,9 @@ Gfx::IntRect WindowManager::arena_rect_for_type(WindowType type) const void WindowManager::event(Core::Event& event) { if (static_cast(event).is_mouse_event()) { + if (event.type() != Event::MouseMove) + m_previous_event_was_super_keydown = false; + Window* hovered_window = nullptr; process_mouse_event(static_cast(event), hovered_window); set_hovered_window(hovered_window); @@ -1211,7 +1226,17 @@ void WindowManager::event(Core::Event& event) return; } - if (MenuManager::the().current_menu()) { + if (key_event.type() == Event::KeyDown && key_event.key() == Key_Super) { + m_previous_event_was_super_keydown = true; + } else if (m_previous_event_was_super_keydown) { + m_previous_event_was_super_keydown = false; + if (!m_dnd_client && key_event.type() == Event::KeyUp && key_event.key() == Key_Super) { + tell_wms_super_key_pressed(); + return; + } + } + + if (MenuManager::the().current_menu() && key_event.key() != Key_Super) { MenuManager::the().dispatch_event(event); return; } diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 3124a6dde2..5c022af7a9 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -175,6 +175,7 @@ public: void tell_wms_window_icon_changed(Window&); void tell_wms_window_rect_changed(Window&); void tell_wms_applet_area_size_changed(const Gfx::IntSize&); + void tell_wms_super_key_pressed(); bool is_active_window_or_accessory(Window&) const; @@ -334,6 +335,7 @@ private: DoubleClickInfo m_double_click_info; int m_double_click_speed { 0 }; int m_max_distance_for_double_click { 4 }; + bool m_previous_event_was_super_keydown { false }; WeakPtr m_active_window; WeakPtr m_hovered_window; diff --git a/Userland/Services/WindowServer/WindowManagerClient.ipc b/Userland/Services/WindowServer/WindowManagerClient.ipc index 40a06e58f3..4c3c9c071d 100644 --- a/Userland/Services/WindowServer/WindowManagerClient.ipc +++ b/Userland/Services/WindowServer/WindowManagerClient.ipc @@ -5,4 +5,5 @@ endpoint WindowManagerClient = 1872 WindowIconBitmapChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::ShareableBitmap bitmap) =| WindowRectChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::IntRect rect) =| AppletAreaSizeChanged(i32 wm_id, Gfx::IntSize size) =| + SuperKeyPressed(i32 wm_id) =| }