diff --git a/LibGUI/GMenu.cpp b/LibGUI/GMenu.cpp index 3aab5feaba4..aad2732f47b 100644 --- a/LibGUI/GMenu.cpp +++ b/LibGUI/GMenu.cpp @@ -50,6 +50,16 @@ void GMenu::popup(const Point& screen_position) GEventLoop::post_message_to_server(request); } +void GMenu::dismiss() +{ + if (!m_menu_id) + return; + WSAPI_ClientMessage request; + request.type = WSAPI_ClientMessage::Type::DismissMenu; + request.menu.menu_id = m_menu_id; + GEventLoop::post_message_to_server(request); +} + int GMenu::realize_menu() { WSAPI_ClientMessage request; diff --git a/LibGUI/GMenu.h b/LibGUI/GMenu.h index 3c9ffa7814d..981e7102bad 100644 --- a/LibGUI/GMenu.h +++ b/LibGUI/GMenu.h @@ -20,6 +20,7 @@ public: void add_separator(); void popup(const Point& screen_position); + void dismiss(); Function on_item_activation; diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 5ba2e28895f..c7c7dc6345d 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -195,6 +195,7 @@ struct WSAPI_ClientMessage { SetWindowOverrideCursor, WM_SetActiveWindow, PopupMenu, + DismissMenu, SetWindowIcon, }; Type type { Invalid }; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 7df858b25e8..bda8da4431a 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -236,6 +236,18 @@ void WSClientConnection::handle_request(const WSAPIPopupMenuRequest& request) menu.popup(position); } +void WSClientConnection::handle_request(const WSAPIDismissMenuRequest& request) +{ + int menu_id = request.menu_id(); + auto it = m_menus.find(menu_id); + if (it == m_menus.end()) { + post_error("WSAPIDismissMenuRequest: Bad menu ID"); + return; + } + auto& menu = *(*it).value; + menu.close(); +} + void WSClientConnection::handle_request(const WSAPIUpdateMenuItemRequest& request) { int menu_id = request.menu_id(); @@ -655,6 +667,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast(request)); case WSMessage::APIPopupMenuRequest: return handle_request(static_cast(request)); + case WSMessage::APIDismissMenuRequest: + return handle_request(static_cast(request)); default: break; } diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index ff1fda9c995..3cf9a0b8616 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -72,6 +72,7 @@ private: void handle_request(const WSAPISetWindowOverrideCursorRequest&); void handle_request(const WSWMAPISetActiveWindowRequest&); void handle_request(const WSAPIPopupMenuRequest&); + void handle_request(const WSAPIDismissMenuRequest&); void post_error(const String&); diff --git a/Servers/WindowServer/WSMessage.h b/Servers/WindowServer/WSMessage.h index 628f113ffa7..385b3afd445 100644 --- a/Servers/WindowServer/WSMessage.h +++ b/Servers/WindowServer/WSMessage.h @@ -59,6 +59,7 @@ public: APISetWindowOverrideCursorRequest, WMAPISetActiveWindowRequest, APIPopupMenuRequest, + APIDismissMenuRequest, __End_API_Client_Requests, }; @@ -208,6 +209,19 @@ private: Point m_position; }; +class WSAPIDismissMenuRequest : public WSAPIClientRequest { +public: + WSAPIDismissMenuRequest(int client_id, int menu_id) + : WSAPIClientRequest(WSMessage::APIDismissMenuRequest, client_id) + , m_menu_id(menu_id) + { + } + + int menu_id() const { return m_menu_id; } + +private: + int m_menu_id; +}; class WSAPICreateMenuRequest : public WSAPIClientRequest { public: diff --git a/Servers/WindowServer/WSMessageLoop.cpp b/Servers/WindowServer/WSMessageLoop.cpp index 938a65b1b00..b98937ae99c 100644 --- a/Servers/WindowServer/WSMessageLoop.cpp +++ b/Servers/WindowServer/WSMessageLoop.cpp @@ -293,6 +293,9 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess case WSAPI_ClientMessage::Type::PopupMenu: post_message(client, make(client_id, message.menu.menu_id, message.menu.position)); break; + case WSAPI_ClientMessage::Type::DismissMenu: + post_message(client, make(client_id, message.menu.menu_id)); + break; case WSAPI_ClientMessage::Type::SetWindowIcon: ASSERT(message.text_length < (ssize_t)sizeof(message.text)); post_message(client, make(client_id, message.window_id, String(message.text, message.text_length)));