From 51581c21fca245be7677d61282fe6fc7b6e69ca1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 1 Jun 2019 20:10:37 +0200 Subject: [PATCH] WindowServer+LibGUI: Add a way to bring a window to the front. GWindow::move_to_front() can now be used to move a window to the top of the window stack. We use this in Terminal to bring the settings window to the front if it already exists when it's requested, in case it's hiding behind something. --- Applications/Terminal/main.cpp | 1 + LibGUI/GWindow.cpp | 11 +++++++++++ LibGUI/GWindow.h | 1 + Servers/WindowServer/WSAPITypes.h | 1 + Servers/WindowServer/WSClientConnection.cpp | 14 ++++++++++++++ Servers/WindowServer/WSClientConnection.h | 1 + Servers/WindowServer/WSEvent.h | 15 +++++++++++++++ Servers/WindowServer/WSEventLoop.cpp | 3 +++ 8 files changed, 47 insertions(+) diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 561b0a596d..2ca46803ef 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -174,6 +174,7 @@ int main(int argc, char** argv) settings_window = create_settings_window(terminal, config)->make_weak_ptr(); settings_window->show(); + settings_window->move_to_front(); })); app_menu->add_action(GAction::create("Quit", { Mod_Alt, Key_F4 }, [] (const GAction&) { dbgprintf("Terminal: Quit menu activated!\n"); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index cccb2fda24..0e7b94e3f0 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -49,6 +49,17 @@ void GWindow::close() delete_later(); } +void GWindow::move_to_front() +{ + if (!m_window_id) + return; + + WSAPI_ClientMessage request; + request.type = WSAPI_ClientMessage::Type::MoveWindowToFront; + request.window_id = m_window_id; + GEventLoop::post_message_to_server(request); +} + void GWindow::show() { if (m_window_id) diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index 200bec1a77..3178e1820b 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -79,6 +79,7 @@ public: void show(); void hide(); void close(); + void move_to_front(); void start_wm_resize(); diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index fe3a194cd5..ddc6248de8 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -232,6 +232,7 @@ struct WSAPI_ClientMessage { DismissMenu, SetWindowIcon, SetWindowHasAlphaChannel, + MoveWindowToFront, }; Type type { Invalid }; int window_id { -1 }; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index c913cba1cd..8a5c3346cc 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -329,6 +329,18 @@ void WSClientConnection::handle_request(const WSAPIAddMenuSeparatorRequest& requ post_message(response); } +void WSClientConnection::handle_request(const WSAPIMoveWindowToFrontRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("WSAPIMoveWindowToFrontRequest: Bad window ID"); + return; + } + auto& window = *(*it).value; + WSWindowManager::the().move_to_front_and_make_active(window); +} + void WSClientConnection::handle_request(const WSAPISetWindowOpacityRequest& request) { int window_id = request.window_id(); @@ -786,6 +798,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast(request)); case WSEvent::APISetWindowHasAlphaChannelRequest: return handle_request(static_cast(request)); + case WSEvent::APIMoveWindowToFrontRequest: + return handle_request(static_cast(request)); default: break; } diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index e2d1025e8c..dd44d8d53f 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -80,6 +80,7 @@ private: void handle_request(const WSAPIPopupMenuRequest&); void handle_request(const WSAPIDismissMenuRequest&); void handle_request(const WSAPISetWindowHasAlphaChannelRequest&); + void handle_request(const WSAPIMoveWindowToFrontRequest&); void post_error(const String&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 95276d642a..bd6e5ec17e 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -64,6 +64,7 @@ public: APIGetWallpaperRequest, APISetWindowOverrideCursorRequest, APISetWindowHasAlphaChannelRequest, + APIMoveWindowToFrontRequest, WMAPISetActiveWindowRequest, WMAPISetWindowMinimizedRequest, WMAPIStartWindowResizeRequest, @@ -460,6 +461,20 @@ private: int m_window_id { 0 }; }; +class WSAPIMoveWindowToFrontRequest final : public WSAPIClientRequest { +public: + explicit WSAPIMoveWindowToFrontRequest(int client_id, int window_id) + : WSAPIClientRequest(WSEvent::APIMoveWindowToFrontRequest, client_id) + , m_window_id(window_id) + { + } + + int window_id() const { return m_window_id; } + +private: + int m_window_id { 0 }; +}; + class WSAPISetClipboardContentsRequest final : public WSAPIClientRequest { public: explicit WSAPISetClipboardContentsRequest(int client_id, int shared_buffer_id, int size) diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp index 976068fdcf..ab59c03afd 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -309,6 +309,9 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag case WSAPI_ClientMessage::Type::WM_StartWindowResize: post_event(client, make(client_id, message.wm.client_id, message.wm.window_id)); break; + case WSAPI_ClientMessage::Type::MoveWindowToFront: + post_event(client, make(client_id, message.window_id)); + break; default: break; }