1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 00:47:34 +00:00

Taskbar: Start working on a taskbar app.

I originally thought I would do this inside WindowServer, but let's try to
make it as a standalone app that communicates with WindowServer instead.
That will allow us to use LibGUI. :^)
This commit is contained in:
Andreas Kling 2019-04-03 19:38:44 +02:00
parent 318db1e48e
commit a22774ee3f
31 changed files with 577 additions and 18 deletions

View file

@ -20,11 +20,10 @@ struct WSAPI_Rect {
WSAPI_Size size;
};
struct WSAPI_WindowParameters {
WSAPI_Rect rect;
Color background_color;
unsigned flags { 0 };
char title[128];
enum WSAPI_WindowType {
Invalid = 0,
Normal,
Taskbar,
};
struct WSAPI_WindowBackingStoreInfo {
@ -200,6 +199,7 @@ struct WSAPI_ClientMessage {
bool has_alpha_channel;
bool modal;
bool resizable;
WSAPI_WindowType type;
float opacity;
WSAPI_Size base_size;
WSAPI_Size size_increment;

View file

@ -311,6 +311,7 @@ void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request
}
auto& window = *(*it).value;
window.set_rect(request.rect());
post_paint_request(window, request.rect());
}
void WSClientConnection::handle_request(const WSAPIGetWindowRectRequest& request)
@ -370,7 +371,7 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&)
void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request)
{
int window_id = m_next_window_id++;
auto window = make<WSWindow>(*this, window_id, request.is_modal());
auto window = make<WSWindow>(*this, request.window_type(), window_id, request.is_modal());
window->set_has_alpha_channel(request.has_alpha_channel());
window->set_resizable(request.is_resizable());
window->set_title(request.title());
@ -399,6 +400,16 @@ void WSClientConnection::handle_request(const WSAPIDestroyWindowRequest& request
m_windows.remove(it);
}
void WSClientConnection::post_paint_request(const WSWindow& window, const Rect& rect)
{
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::Paint;
response.window_id = window.window_id();
response.paint.rect = rect;
response.paint.window_size = window.size();
post_message(response);
}
void WSClientConnection::handle_request(const WSAPIInvalidateRectRequest& request)
{
int window_id = request.window_id();
@ -408,12 +419,7 @@ void WSClientConnection::handle_request(const WSAPIInvalidateRectRequest& reques
return;
}
auto& window = *(*it).value;
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::Paint;
response.window_id = window_id;
response.paint.rect = request.rect();
response.paint.window_size = window.size();
post_message(response);
post_paint_request(window, request.rect());
}
void WSClientConnection::handle_request(const WSAPIDidFinishPaintingNotification& request)

View file

@ -37,6 +37,7 @@ public:
template<typename Callback> void for_each_window(Callback);
void notify_about_new_screen_rect(const Rect&);
void post_paint_request(const WSWindow&, const Rect&);
private:
virtual void on_message(const WSMessage&) override;

View file

@ -6,6 +6,7 @@
#include <AK/Types.h>
#include <Kernel/KeyCode.h>
#include <WindowServer/WSCursor.h>
#include <WindowServer/WSWindowType.h>
class WSMessage {
public:
@ -408,7 +409,7 @@ private:
class WSAPICreateWindowRequest : public WSAPIClientRequest {
public:
WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment)
WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type)
: WSAPIClientRequest(WSMessage::APICreateWindowRequest, client_id)
, m_rect(rect)
, m_title(title)
@ -418,6 +419,7 @@ public:
, m_resizable(resizable)
, m_size_increment(size_increment)
, m_base_size(base_size)
, m_window_type(window_type)
{
}
@ -429,6 +431,7 @@ public:
float opacity() const { return m_opacity; }
Size size_increment() const { return m_size_increment; }
Size base_size() const { return m_base_size; }
WSWindowType window_type() const { return m_window_type; }
private:
Rect m_rect;
@ -439,6 +442,7 @@ private:
bool m_resizable { false };
Size m_size_increment;
Size m_base_size;
WSWindowType m_window_type;
};
class WSAPIDestroyWindowRequest : public WSAPIClientRequest {

View file

@ -249,6 +249,18 @@ void WSMessageLoop::notify_client_disconnected(int client_id)
post_message(*client, make<WSClientDisconnectedNotification>(client_id));
}
static WSWindowType from_api(WSAPI_WindowType api_type)
{
switch (api_type) {
case WSAPI_WindowType::Normal:
return WSWindowType::Normal;
case WSAPI_WindowType::Taskbar:
return WSWindowType::Taskbar;
default:
ASSERT_NOT_REACHED();
}
}
void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessage& message)
{
WSClientConnection& client = *WSClientConnection::from_client_id(client_id);
@ -285,7 +297,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess
break;
case WSAPI_ClientMessage::Type::CreateWindow:
ASSERT(message.text_length < (ssize_t)sizeof(message.text));
post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment));
post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.modal, message.window.resizable, message.window.opacity, message.window.base_size, message.window.size_increment, from_api(message.window.type)));
break;
case WSAPI_ClientMessage::Type::DestroyWindow:
post_message(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id));

View file

@ -21,9 +21,9 @@ WSWindow::WSWindow(WSMessageReceiver& internal_owner, WSWindowType type)
WSWindowManager::the().add_window(*this);
}
WSWindow::WSWindow(WSClientConnection& client, int window_id, bool modal)
WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal)
: m_client(&client)
, m_type(WSWindowType::Normal)
, m_type(window_type)
, m_modal(modal)
, m_window_id(window_id)
, m_icon(default_window_icon())

View file

@ -14,7 +14,7 @@ class WSMouseEvent;
class WSWindow final : public WSMessageReceiver, public InlineLinkedListNode<WSWindow> {
public:
WSWindow(WSClientConnection&, int window_id, bool modal);
WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal);
WSWindow(WSMessageReceiver&, WSWindowType);
virtual ~WSWindow() override;

View file

@ -104,6 +104,8 @@ static inline Rect outer_window_rect(const WSWindow& window)
return menu_window_rect(window.rect());
if (window.type() == WSWindowType::WindowSwitcher)
return window.rect();
if (window.type() == WSWindowType::Taskbar)
return window.rect();
ASSERT(window.type() == WSWindowType::Normal);
return outer_window_rect(window.rect());
}
@ -418,6 +420,9 @@ void WSWindowManager::paint_window_frame(const WSWindow& window)
if (window.type() == WSWindowType::WindowSwitcher)
return;
if (window.type() == WSWindowType::Taskbar)
return;
auto titlebar_rect = title_bar_rect(window.rect());
auto titlebar_icon_rect = title_bar_icon_rect(window.rect());
auto titlebar_inner_rect = title_bar_text_rect(window.rect());
@ -1179,6 +1184,10 @@ void WSWindowManager::invalidate(const WSWindow& window)
invalidate(window.rect());
return;
}
if (window.type() == WSWindowType::Taskbar) {
invalidate(window.rect());
return;
}
ASSERT_NOT_REACHED();
}

View file

@ -228,6 +228,8 @@ IterationDecision WSWindowManager::for_each_visible_window_from_back_to_front(Ca
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Taskbar, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
return for_each_visible_window_of_type_from_back_to_front(WSWindowType::WindowSwitcher, callback);
}
@ -255,6 +257,8 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_front_to
template<typename Callback>
IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Callback callback)
{
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Taskbar, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, callback) == IterationDecision::Abort)

View file

@ -5,4 +5,5 @@ enum class WSWindowType {
Normal,
Menu,
WindowSwitcher,
Taskbar,
};