wind+libui+taskbar: Add GetScreenRect IPC, non-decorated windows, taskbar
This commit is contained in:
parent
4d068beaaf
commit
5703faf50f
@ -42,3 +42,5 @@ luna_app(touch.cpp touch)
|
||||
luna_app(free.cpp free)
|
||||
luna_app(gclient.cpp gclient)
|
||||
target_link_libraries(gclient PUBLIC ui)
|
||||
luna_app(taskbar.cpp taskbar)
|
||||
target_link_libraries(taskbar PUBLIC ui)
|
||||
|
23
apps/taskbar.cpp
Normal file
23
apps/taskbar.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include <ui/App.h>
|
||||
#include <ui/Layout.h>
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
ui::App app;
|
||||
TRY(app.init(argc, argv));
|
||||
|
||||
ui::Rect screen = app.screen_rect();
|
||||
|
||||
ui::Rect bar = ui::Rect { ui::Point { 0, screen.height - 50 }, screen.width, 50 };
|
||||
|
||||
auto window = TRY(ui::Window::create(bar, false));
|
||||
app.set_main_window(window);
|
||||
window->set_background(ui::GRAY);
|
||||
|
||||
ui::HorizontalLayout layout(ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
||||
window->set_main_widget(layout);
|
||||
|
||||
window->draw();
|
||||
|
||||
return app.run();
|
||||
}
|
4
base/etc/user/00-taskbar
Normal file
4
base/etc/user/00-taskbar
Normal file
@ -0,0 +1,4 @@
|
||||
Name=taskbar
|
||||
Description=Start the taskbar.
|
||||
Command=/usr/bin/taskbar
|
||||
Restart=true
|
@ -23,6 +23,8 @@ namespace ui
|
||||
Result<void> init(int, char**);
|
||||
Result<int> run();
|
||||
|
||||
Rect screen_rect();
|
||||
|
||||
os::LocalClient& client()
|
||||
{
|
||||
return *m_client;
|
||||
|
@ -19,7 +19,7 @@ namespace ui
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
static Result<Window*> create(Rect rect);
|
||||
static Result<Window*> create(Rect rect, bool decorated = true);
|
||||
|
||||
void set_title(StringView title);
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace ui
|
||||
CREATE_WINDOW_RESPONSE_ID,
|
||||
WINDOW_CLOSE_REQUEST_ID,
|
||||
MOUSE_EVENT_REQUEST_ID,
|
||||
GET_SCREEN_RECT_RESPONSE_ID
|
||||
};
|
||||
|
||||
struct CreateWindowResponse
|
||||
@ -44,4 +45,11 @@ namespace ui
|
||||
Point position;
|
||||
int buttons;
|
||||
};
|
||||
|
||||
struct GetScreenRectResponse
|
||||
{
|
||||
static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID;
|
||||
|
||||
Rect rect;
|
||||
};
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ namespace ui
|
||||
SET_WINDOW_TITLE_ID,
|
||||
INVALIDATE_ID,
|
||||
CLOSE_WINDOW_ID,
|
||||
GET_SCREEN_RECT_ID,
|
||||
};
|
||||
|
||||
struct CreateWindowRequest
|
||||
@ -30,6 +31,7 @@ namespace ui
|
||||
static constexpr u8 ID = CREATE_WINDOW_ID;
|
||||
|
||||
ui::Rect rect;
|
||||
bool decorated;
|
||||
};
|
||||
|
||||
struct SetWindowTitleRequest
|
||||
@ -53,4 +55,12 @@ namespace ui
|
||||
|
||||
int window;
|
||||
};
|
||||
|
||||
struct GetScreenRectRequest
|
||||
{
|
||||
using ResponseType = GetScreenRectResponse;
|
||||
static constexpr u8 ID = GET_SCREEN_RECT_ID;
|
||||
|
||||
int _shadow; // Unused.
|
||||
};
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <os/IPC.h>
|
||||
#include <ui/App.h>
|
||||
#include <ui/ipc/Client.h>
|
||||
#include <ui/ipc/Server.h>
|
||||
|
||||
Result<void> handle_ipc_client_event(os::LocalClient&, u8 id)
|
||||
{
|
||||
@ -60,6 +61,13 @@ namespace ui
|
||||
return *s_app;
|
||||
}
|
||||
|
||||
Rect App::screen_rect()
|
||||
{
|
||||
ui::GetScreenRectRequest request {};
|
||||
auto response = os::IPC::send_sync<ui::GetScreenRectResponse>(*m_client, request).release_value();
|
||||
return response.rect;
|
||||
}
|
||||
|
||||
Result<void> App::register_window(OwnedPtr<Window>&& window, Badge<Window>)
|
||||
{
|
||||
int id = window->id();
|
||||
|
@ -39,12 +39,13 @@ static Result<u32*> create_shm_region(const char* path, int* outfd, ui::Rect rec
|
||||
|
||||
namespace ui
|
||||
{
|
||||
Result<Window*> Window::create(Rect rect)
|
||||
Result<Window*> Window::create(Rect rect, bool decorated)
|
||||
{
|
||||
auto window = TRY(make_owned<Window>());
|
||||
|
||||
ui::CreateWindowRequest request;
|
||||
request.rect = rect;
|
||||
request.decorated = decorated;
|
||||
auto response = TRY(os::IPC::send_sync<ui::CreateWindowResponse>(App::the().client(), request));
|
||||
|
||||
u32* pixels = TRY(create_shm_region(response.shm_path, nullptr, rect));
|
||||
|
24
wind/IPC.cpp
24
wind/IPC.cpp
@ -1,4 +1,5 @@
|
||||
#include "IPC.h"
|
||||
#include "Screen.h"
|
||||
#include <errno.h>
|
||||
#include <luna/Alignment.h>
|
||||
#include <luna/String.h>
|
||||
@ -87,11 +88,17 @@ static Result<void> handle_create_window_message(Client& client)
|
||||
READ_MESSAGE(request);
|
||||
|
||||
request.rect = request.rect.normalized();
|
||||
request.rect.height += Window::titlebar_height(); // Make sure we provide the full contents rect that was asked for.
|
||||
|
||||
if (request.decorated)
|
||||
{
|
||||
request.rect.height +=
|
||||
Window::titlebar_height(); // Make sure we provide the full contents rect that was asked for.
|
||||
request.rect.pos.y -= Window::titlebar_height(); // Adjust it so the contents begin at the expected coordinates.
|
||||
}
|
||||
|
||||
auto name = TRY(String::from_cstring("Window"));
|
||||
|
||||
auto* window = new (std::nothrow) Window(request.rect, move(name));
|
||||
auto* window = new (std::nothrow) Window(request.rect, move(name), request.decorated);
|
||||
if (!window)
|
||||
{
|
||||
os::IPC::send_error(client.conn, ENOMEM);
|
||||
@ -158,6 +165,18 @@ static Result<void> handle_close_window_message(Client& client)
|
||||
return {};
|
||||
}
|
||||
|
||||
static Result<void> handle_get_screen_rect_message(Client& client)
|
||||
{
|
||||
ui::GetScreenRectRequest request;
|
||||
READ_MESSAGE(request); // Kinda pointless, but required.
|
||||
|
||||
ui::GetScreenRectResponse response;
|
||||
response.rect = Screen::the().canvas().rect();
|
||||
os::IPC::send_async(client.conn, response);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace wind
|
||||
{
|
||||
Result<void> handle_ipc_message(Client& client, u8 id)
|
||||
@ -169,6 +188,7 @@ namespace wind
|
||||
case ui::SET_WINDOW_TITLE_ID: return handle_set_window_title_message(client);
|
||||
case ui::INVALIDATE_ID: return handle_invalidate_message(client);
|
||||
case ui::CLOSE_WINDOW_ID: return handle_close_window_message(client);
|
||||
case ui::GET_SCREEN_RECT_ID: return handle_get_screen_rect_message(client);
|
||||
default: os::eprintln("wind: Invalid IPC message from client!"); return err(EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
Result<Screen> Screen::open()
|
||||
Screen Screen::s_the;
|
||||
|
||||
Result<void> Screen::open()
|
||||
{
|
||||
int fd = ::open("/dev/fb0", O_RDWR);
|
||||
if (fd < 0) return err(errno);
|
||||
@ -23,7 +25,9 @@ Result<Screen> Screen::open()
|
||||
screen.m_canvas = ui::Canvas::create((u8*)p, width, height);
|
||||
screen.m_size = width * height * BYTES_PER_PIXEL;
|
||||
|
||||
return screen;
|
||||
s_the = screen;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void Screen::sync()
|
||||
|
@ -7,7 +7,7 @@ constexpr int BYTES_PER_PIXEL = 4;
|
||||
class Screen
|
||||
{
|
||||
public:
|
||||
static Result<Screen> open();
|
||||
static Result<void> open();
|
||||
|
||||
ui::Canvas& canvas()
|
||||
{
|
||||
@ -19,9 +19,16 @@ class Screen
|
||||
return m_size;
|
||||
}
|
||||
|
||||
static Screen& the()
|
||||
{
|
||||
return s_the;
|
||||
}
|
||||
|
||||
void sync();
|
||||
|
||||
private:
|
||||
ui::Canvas m_canvas;
|
||||
int m_size;
|
||||
|
||||
static Screen s_the;
|
||||
};
|
||||
|
@ -41,14 +41,15 @@ void Window::focus()
|
||||
g_windows.append(this);
|
||||
}
|
||||
|
||||
Window::Window(ui::Rect r, String&& n) : surface(r), name(move(n))
|
||||
Window::Window(ui::Rect r, String&& n, bool d) : surface(r), name(move(n)), decorated(d)
|
||||
{
|
||||
auto font = ui::Font::default_font();
|
||||
if (surface.width < 36) surface.width = 36;
|
||||
if (surface.height < (font->height() + 20)) surface.height = font->height() + 20;
|
||||
titlebar = ui::Rect { 0, 0, surface.width, font->height() + 20 };
|
||||
close_button = ui::Rect { surface.width - 26, 10, 16, 16 };
|
||||
contents = ui::Rect { 0, font->height() + 20, surface.width, surface.height - (font->height() + 20) };
|
||||
if (decorated && surface.width < 36) surface.width = 36;
|
||||
if (decorated && surface.height < (font->height() + 20)) surface.height = font->height() + 20;
|
||||
titlebar = decorated ? ui::Rect { 0, 0, surface.width, font->height() + 20 } : ui::Rect { 0, 0, 0, 0 };
|
||||
close_button = decorated ? ui::Rect { surface.width - 26, 10, 16, 16 } : ui::Rect { 0, 0, 0, 0 };
|
||||
contents = decorated ? ui::Rect { 0, font->height() + 20, surface.width, surface.height - (font->height() + 20) }
|
||||
: ui::Rect { 0, 0, surface.width, surface.height };
|
||||
g_windows.append(this);
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,11 @@ struct Window : public LinkedListNode<Window>
|
||||
bool dirty { false };
|
||||
Client* client;
|
||||
int id;
|
||||
bool decorated;
|
||||
|
||||
static int titlebar_height();
|
||||
|
||||
Window(ui::Rect, String&&);
|
||||
Window(ui::Rect, String&&, bool);
|
||||
~Window();
|
||||
|
||||
void focus();
|
||||
|
@ -49,7 +49,8 @@ Result<int> luna_main(int argc, char** argv)
|
||||
keyboard->set_buffer(os::File::NotBuffered);
|
||||
keyboard->set_close_on_exec();
|
||||
|
||||
auto screen = TRY(Screen::open());
|
||||
TRY(Screen::open());
|
||||
auto& screen = Screen::the();
|
||||
|
||||
Mouse mouse_pointer { screen.canvas() };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user