From 02f8102d385af71a967c2c320d0feb28cc070daa Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 4 Feb 2024 13:35:50 +0100 Subject: [PATCH] wind+libui+taskbar: Add a request for setting special window attributes This lets the taskbar window stay unfocused even when it's clicked. --- apps/taskbar.cpp | 1 + libui/include/ui/Window.h | 2 ++ libui/include/ui/ipc/Server.h | 13 +++++++++++++ libui/src/Window.cpp | 8 ++++++++ wind/Client.h | 1 + wind/IPC.cpp | 21 +++++++++++++++++++++ wind/Mouse.cpp | 2 +- wind/Window.h | 1 + wind/main.cpp | 3 ++- 9 files changed, 50 insertions(+), 2 deletions(-) diff --git a/apps/taskbar.cpp b/apps/taskbar.cpp index cf770c12..6e595770 100644 --- a/apps/taskbar.cpp +++ b/apps/taskbar.cpp @@ -60,6 +60,7 @@ Result luna_main(int, char**) app.set_main_window(window); window->set_background(TASKBAR_COLOR); + window->set_special_attributes(ui::UNFOCUSEABLE); ui::HorizontalLayout layout(ui::Margins { 0, 0, 0, 0 }, ui::AdjustHeight::Yes, ui::AdjustWidth::No); window->set_main_widget(layout); diff --git a/libui/include/ui/Window.h b/libui/include/ui/Window.h index d0bbdeaa..b2fea178 100644 --- a/libui/include/ui/Window.h +++ b/libui/include/ui/Window.h @@ -54,6 +54,8 @@ namespace ui void close(); + void set_special_attributes(WindowAttributes attributes); + Result draw(); Result handle_mouse_leave(); Result handle_mouse_move(ui::Point position); diff --git a/libui/include/ui/ipc/Server.h b/libui/include/ui/ipc/Server.h index 0039b834..d054a07d 100644 --- a/libui/include/ui/ipc/Server.h +++ b/libui/include/ui/ipc/Server.h @@ -80,4 +80,17 @@ namespace ui int window; int height; }; + + enum WindowAttributes : u8 + { + UNFOCUSEABLE = 1, + }; + + struct SetSpecialWindowAttributesRequest + { + static constexpr u8 ID = SET_SPECIAL_WINDOW_ATTRIBUTES_ID; + + int window; + WindowAttributes attributes; + }; } diff --git a/libui/src/Window.cpp b/libui/src/Window.cpp index 18af4f3b..ce99d21b 100644 --- a/libui/src/Window.cpp +++ b/libui/src/Window.cpp @@ -117,6 +117,14 @@ namespace ui app.unregister_window(this, {}); } + void Window::set_special_attributes(WindowAttributes attributes) + { + ui::SetSpecialWindowAttributesRequest request; + request.window = m_id; + request.attributes = attributes; + App::the().client().send_async(request); + } + Result Window::draw() { if (m_background.has_value()) m_window_canvas.fill(*m_background); diff --git a/wind/Client.h b/wind/Client.h index 031c6d0d..ad3a0a7e 100644 --- a/wind/Client.h +++ b/wind/Client.h @@ -8,6 +8,7 @@ struct Client OwnedPtr conn; Vector windows; const bool privileged { false }; + bool should_be_disconnected { false }; Client(OwnedPtr&& client, bool priv) #ifdef CLIENT_IMPLEMENTATION diff --git a/wind/IPC.cpp b/wind/IPC.cpp index 142d582a..e20dd30c 100644 --- a/wind/IPC.cpp +++ b/wind/IPC.cpp @@ -160,6 +160,26 @@ static Result handle_set_titlebar_height_message(Client& client) return {}; } +static Result handle_set_special_window_attributes_message(Client& client) +{ + ui::SetSpecialWindowAttributesRequest request; + if (!TRY(client.conn->read_message(request))) return {}; + + if (!client.privileged) + { + os::eprintln( + "wind: Unprivileged client trying to call privileged request (SetSpecialWindowAttributes), disconnecting!"); + client.should_be_disconnected = true; + return {}; + } + + CHECK_WINDOW_ID(request); + + client.windows[request.window]->attributes = request.attributes; + + return {}; +} + namespace wind { void handle_ipc_message(os::IPC::ClientConnection&, u8 id, void* c) @@ -174,6 +194,7 @@ namespace wind case ui::CLOSE_WINDOW_ID: handle_close_window_message(client); break; case ui::GET_SCREEN_RECT_ID: handle_get_screen_rect_message(client); break; case ui::SET_TITLEBAR_HEIGHT_ID: handle_set_titlebar_height_message(client); break; + case ui::SET_SPECIAL_WINDOW_ATTRIBUTES_ID: handle_set_special_window_attributes_message(client); break; default: os::eprintln("wind: Invalid IPC message from client!"); return; } } diff --git a/wind/Mouse.cpp b/wind/Mouse.cpp index 64379cc9..31526930 100644 --- a/wind/Mouse.cpp +++ b/wind/Mouse.cpp @@ -64,7 +64,7 @@ void Mouse::update(const moon::MousePacket& packet) { if (window->surface.contains(m_position)) { - window->focus(); + if (!(window->attributes & ui::UNFOCUSEABLE)) window->focus(); if (window->surface.absolute(window->titlebar).contains(m_position)) { diff --git a/wind/Window.h b/wind/Window.h index 70d5c26c..8b9aac92 100644 --- a/wind/Window.h +++ b/wind/Window.h @@ -18,6 +18,7 @@ struct Window : public LinkedListNode bool dirty { false }; Client* client; int id; + ui::WindowAttributes attributes { 0 }; Window(ui::Rect, String&&); ~Window(); diff --git a/wind/main.cpp b/wind/main.cpp index 34604f4a..fd67eb75 100644 --- a/wind/main.cpp +++ b/wind/main.cpp @@ -183,7 +183,8 @@ Result luna_main(int argc, char** argv) for (usize i = 0; i < clients.size(); i++) { if (fds[i + 4].revents & POLLIN) clients[i]->conn->check_for_messages(); - if (fds[i + 4].revents & POLLHUP) + if (fds[i + 4].revents & POLLHUP) clients[i]->should_be_disconnected = true; + if (clients[i]->should_be_disconnected) { os::println("wind: Client %d disconnected", i); fds.remove_at(i + 4);