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
Notes: sideshowbarker 2024-07-19 14:50:04 +09:00
31 changed files with 577 additions and 18 deletions

BIN
Applications/Taskbar/About Executable file

Binary file not shown.

View file

@ -0,0 +1,33 @@
OBJS = \
TaskbarWindow.o \
TaskbarWidget.o \
main.o
APP = Taskbar
STANDARD_FLAGS = -std=c++17 -Wno-sized-deallocation
WARNING_FLAGS = -Wextra -Wall -Wundef -Wcast-qual -Wwrite-strings -Wimplicit-fallthrough
FLAVOR_FLAGS = -fno-exceptions -fno-rtti
OPTIMIZATION_FLAGS = -Os
INCLUDE_FLAGS = -I../.. -I. -I../../LibC
DEFINES = -DSERENITY -DSANITIZE_PTRS -DUSERLAND
CXXFLAGS = -MMD -MP $(WARNING_FLAGS) $(OPTIMIZATION_FLAGS) $(FLAVOR_FLAGS) $(STANDARD_FLAGS) $(INCLUDE_FLAGS) $(DEFINES)
CXX = i686-pc-serenity-g++
LD = i686-pc-serenity-g++
LDFLAGS = -L../../LibC -L../../LibGUI
all: $(APP)
$(APP): $(OBJS)
$(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -lc
.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
-include $(OBJS:%.o=%.d)
clean:
@echo "CLEAN"; rm -f $(APPS) $(OBJS) *.d

BIN
Applications/Taskbar/Taskbar Executable file

Binary file not shown.

View file

@ -0,0 +1,31 @@
#include "TaskbarWidget.h"
#include <LibGUI/GLabel.h>
#include <LibGUI/GButton.h>
#include <LibGUI/GBoxLayout.h>
#include <LibGUI/GPainter.h>
#include <stdio.h>
TaskbarWidget::TaskbarWidget(GWidget* parent)
: GFrame(parent)
{
set_fill_with_background_color(true);
set_layout(make<GBoxLayout>(Orientation::Vertical));
layout()->set_margins({ 0, 8, 0, 8 });
layout()->set_spacing(8);
set_frame_thickness(1);
set_frame_shape(GFrame::Shape::Panel);
set_frame_shadow(GFrame::Shadow::Raised);
}
TaskbarWidget::~TaskbarWidget()
{
}
void TaskbarWidget::paint_event(GPaintEvent& event)
{
GFrame::paint_event(event);
GPainter painter(*this);
painter.add_clip_rect(event.rect());
}

View file

@ -0,0 +1,133 @@
TaskbarWidget.o: TaskbarWidget.cpp TaskbarWidget.h ../../LibGUI/GFrame.h \
../../LibGUI/GWidget.h ../../LibGUI/GElapsedTimer.h ../../LibC/time.h \
../../LibC/sys/cdefs.h ../../LibC/sys/types.h ../../LibC/stdint.h \
../../LibGUI/GEvent.h ../../SharedGraphics/Point.h ../../AK/AKString.h \
../../AK/ByteBuffer.h ../../AK/Types.h ../../AK/StdLibExtras.h \
../../LibC/stdlib.h ../../LibC/stddef.h ../../LibC/string.h \
../../AK/Retainable.h ../../AK/Assertions.h ../../LibC/assert.h \
../../AK/RetainPtr.h ../../AK/Retained.h ../../AK/kmalloc.h \
../../AK/StringImpl.h ../../AK/Traits.h ../../AK/kstdio.h \
../../Kernel/kstdio.h ../../Kernel/kprintf.h ../../AK/HashFunctions.h \
../../AK/Vector.h ../../AK/OwnPtr.h ../../SharedGraphics/Rect.h \
../../SharedGraphics/Size.h ../../AK/WeakPtr.h ../../AK/Weakable.h \
../../Kernel/KeyCode.h ../../LibGUI/GObject.h \
../../SharedGraphics/Color.h ../../SharedGraphics/Font.h \
../../AK/MappedFile.h ../../AK/Badge.h ../../LibGUI/GLabel.h \
../../SharedGraphics/TextAlignment.h ../../LibGUI/GButton.h \
../../SharedGraphics/StylePainter.h ../../AK/Function.h \
../../SharedGraphics/GraphicsBitmap.h ../../LibC/SharedBuffer.h \
../../LibGUI/GBoxLayout.h ../../LibGUI/GLayout.h ../../LibGUI/GMargins.h \
../../LibGUI/GPainter.h ../../SharedGraphics/Painter.h \
../../LibC/stdio.h ../../LibC/stdarg.h ../../LibC/limits.h
TaskbarWidget.h:
../../LibGUI/GFrame.h:
../../LibGUI/GWidget.h:
../../LibGUI/GElapsedTimer.h:
../../LibC/time.h:
../../LibC/sys/cdefs.h:
../../LibC/sys/types.h:
../../LibC/stdint.h:
../../LibGUI/GEvent.h:
../../SharedGraphics/Point.h:
../../AK/AKString.h:
../../AK/ByteBuffer.h:
../../AK/Types.h:
../../AK/StdLibExtras.h:
../../LibC/stdlib.h:
../../LibC/stddef.h:
../../LibC/string.h:
../../AK/Retainable.h:
../../AK/Assertions.h:
../../LibC/assert.h:
../../AK/RetainPtr.h:
../../AK/Retained.h:
../../AK/kmalloc.h:
../../AK/StringImpl.h:
../../AK/Traits.h:
../../AK/kstdio.h:
../../Kernel/kstdio.h:
../../Kernel/kprintf.h:
../../AK/HashFunctions.h:
../../AK/Vector.h:
../../AK/OwnPtr.h:
../../SharedGraphics/Rect.h:
../../SharedGraphics/Size.h:
../../AK/WeakPtr.h:
../../AK/Weakable.h:
../../Kernel/KeyCode.h:
../../LibGUI/GObject.h:
../../SharedGraphics/Color.h:
../../SharedGraphics/Font.h:
../../AK/MappedFile.h:
../../AK/Badge.h:
../../LibGUI/GLabel.h:
../../SharedGraphics/TextAlignment.h:
../../LibGUI/GButton.h:
../../SharedGraphics/StylePainter.h:
../../AK/Function.h:
../../SharedGraphics/GraphicsBitmap.h:
../../LibC/SharedBuffer.h:
../../LibGUI/GBoxLayout.h:
../../LibGUI/GLayout.h:
../../LibGUI/GMargins.h:
../../LibGUI/GPainter.h:
../../SharedGraphics/Painter.h:
../../LibC/stdio.h:
../../LibC/stdarg.h:
../../LibC/limits.h:

View file

@ -0,0 +1,13 @@
#include <LibGUI/GFrame.h>
class TaskbarWidget final : public GFrame {
public:
TaskbarWidget(GWidget* parent = nullptr);
virtual ~TaskbarWidget() override;
virtual const char* class_name() const override { return "TaskbarWidget"; }
private:
virtual void paint_event(GPaintEvent&) override;
};

Binary file not shown.

View file

@ -0,0 +1,29 @@
#include "TaskbarWindow.h"
#include "TaskbarWidget.h"
#include <LibGUI/GWindow.h>
#include <LibGUI/GDesktop.h>
#include <stdio.h>
TaskbarWindow::TaskbarWindow()
{
set_window_type(GWindowType::Taskbar);
set_title("Taskbar");
set_should_exit_event_loop_on_close(true);
on_screen_rect_change(GDesktop::the().rect());
GDesktop::the().on_rect_change = [this] (const Rect& rect) { on_screen_rect_change(rect); };
auto* widget = new TaskbarWidget;
set_main_widget(widget);
}
TaskbarWindow::~TaskbarWindow()
{
}
void TaskbarWindow::on_screen_rect_change(const Rect& rect)
{
Rect new_rect { rect.x(), rect.bottom() - taskbar_height() + 1, rect.width(), taskbar_height() };
set_rect(new_rect);
}

View file

@ -0,0 +1,118 @@
TaskbarWindow.o: TaskbarWindow.cpp TaskbarWindow.h ../../LibGUI/GWindow.h \
../../LibGUI/GObject.h ../../AK/Vector.h ../../AK/Assertions.h \
../../LibC/assert.h ../../LibC/sys/cdefs.h ../../AK/OwnPtr.h \
../../AK/StdLibExtras.h ../../LibC/stdlib.h ../../LibC/sys/types.h \
../../LibC/stdint.h ../../LibC/stddef.h ../../LibC/string.h \
../../AK/Types.h ../../AK/Traits.h ../../AK/kstdio.h \
../../Kernel/kstdio.h ../../Kernel/kprintf.h ../../AK/HashFunctions.h \
../../AK/kmalloc.h ../../AK/Weakable.h ../../AK/Retainable.h \
../../AK/RetainPtr.h ../../AK/Retained.h ../../SharedGraphics/Rect.h \
../../SharedGraphics/Point.h ../../AK/AKString.h ../../AK/ByteBuffer.h \
../../AK/StringImpl.h ../../SharedGraphics/Size.h \
../../SharedGraphics/GraphicsBitmap.h ../../SharedGraphics/Color.h \
../../AK/MappedFile.h ../../LibC/SharedBuffer.h ../../AK/WeakPtr.h \
../../LibGUI/GWidget.h ../../LibGUI/GElapsedTimer.h ../../LibC/time.h \
../../LibGUI/GEvent.h ../../Kernel/KeyCode.h ../../SharedGraphics/Font.h \
../../AK/Badge.h TaskbarWidget.h ../../LibGUI/GFrame.h \
../../LibGUI/GDesktop.h ../../AK/Function.h ../../LibC/stdio.h \
../../LibC/stdarg.h ../../LibC/limits.h
TaskbarWindow.h:
../../LibGUI/GWindow.h:
../../LibGUI/GObject.h:
../../AK/Vector.h:
../../AK/Assertions.h:
../../LibC/assert.h:
../../LibC/sys/cdefs.h:
../../AK/OwnPtr.h:
../../AK/StdLibExtras.h:
../../LibC/stdlib.h:
../../LibC/sys/types.h:
../../LibC/stdint.h:
../../LibC/stddef.h:
../../LibC/string.h:
../../AK/Types.h:
../../AK/Traits.h:
../../AK/kstdio.h:
../../Kernel/kstdio.h:
../../Kernel/kprintf.h:
../../AK/HashFunctions.h:
../../AK/kmalloc.h:
../../AK/Weakable.h:
../../AK/Retainable.h:
../../AK/RetainPtr.h:
../../AK/Retained.h:
../../SharedGraphics/Rect.h:
../../SharedGraphics/Point.h:
../../AK/AKString.h:
../../AK/ByteBuffer.h:
../../AK/StringImpl.h:
../../SharedGraphics/Size.h:
../../SharedGraphics/GraphicsBitmap.h:
../../SharedGraphics/Color.h:
../../AK/MappedFile.h:
../../LibC/SharedBuffer.h:
../../AK/WeakPtr.h:
../../LibGUI/GWidget.h:
../../LibGUI/GElapsedTimer.h:
../../LibC/time.h:
../../LibGUI/GEvent.h:
../../Kernel/KeyCode.h:
../../SharedGraphics/Font.h:
../../AK/Badge.h:
TaskbarWidget.h:
../../LibGUI/GFrame.h:
../../LibGUI/GDesktop.h:
../../AK/Function.h:
../../LibC/stdio.h:
../../LibC/stdarg.h:
../../LibC/limits.h:

View file

@ -0,0 +1,16 @@
#include <LibGUI/GWindow.h>
#include <LibGUI/GWidget.h>
class TaskbarWindow final : public GWindow {
public:
TaskbarWindow();
virtual ~TaskbarWindow() override;
int taskbar_height() const { return 20; }
virtual const char* class_name() const override { return "TaskbarWindow"; }
private:
void on_screen_rect_change(const Rect&);
};

Binary file not shown.

View file

@ -0,0 +1,10 @@
#include <LibGUI/GApplication.h>
#include "TaskbarWindow.h"
int main(int argc, char** argv)
{
GApplication app(argc, argv);
TaskbarWindow window;
window.show();
return app.exec();
}

114
Applications/Taskbar/main.d Normal file
View file

@ -0,0 +1,114 @@
main.o: main.cpp ../../LibGUI/GApplication.h ../../AK/Badge.h \
../../AK/OwnPtr.h ../../AK/StdLibExtras.h ../../LibC/stdlib.h \
../../LibC/sys/cdefs.h ../../LibC/sys/types.h ../../LibC/stdint.h \
../../LibC/stddef.h ../../LibC/string.h ../../AK/Types.h \
../../AK/Traits.h ../../AK/kstdio.h ../../Kernel/kstdio.h \
../../Kernel/kprintf.h ../../AK/HashFunctions.h ../../AK/HashMap.h \
../../AK/HashTable.h ../../AK/Assertions.h ../../LibC/assert.h \
../../AK/DoublyLinkedList.h ../../LibGUI/GShortcut.h \
../../Kernel/KeyCode.h ../../AK/AKString.h ../../AK/ByteBuffer.h \
../../AK/Retainable.h ../../AK/RetainPtr.h ../../AK/Retained.h \
../../AK/kmalloc.h ../../AK/StringImpl.h ../../AK/Vector.h \
TaskbarWindow.h ../../LibGUI/GWindow.h ../../LibGUI/GObject.h \
../../AK/Weakable.h ../../SharedGraphics/Rect.h \
../../SharedGraphics/Point.h ../../SharedGraphics/Size.h \
../../SharedGraphics/GraphicsBitmap.h ../../SharedGraphics/Color.h \
../../AK/MappedFile.h ../../LibC/SharedBuffer.h ../../AK/WeakPtr.h \
../../LibGUI/GWidget.h ../../LibGUI/GElapsedTimer.h ../../LibC/time.h \
../../LibGUI/GEvent.h ../../SharedGraphics/Font.h
../../LibGUI/GApplication.h:
../../AK/Badge.h:
../../AK/OwnPtr.h:
../../AK/StdLibExtras.h:
../../LibC/stdlib.h:
../../LibC/sys/cdefs.h:
../../LibC/sys/types.h:
../../LibC/stdint.h:
../../LibC/stddef.h:
../../LibC/string.h:
../../AK/Types.h:
../../AK/Traits.h:
../../AK/kstdio.h:
../../Kernel/kstdio.h:
../../Kernel/kprintf.h:
../../AK/HashFunctions.h:
../../AK/HashMap.h:
../../AK/HashTable.h:
../../AK/Assertions.h:
../../LibC/assert.h:
../../AK/DoublyLinkedList.h:
../../LibGUI/GShortcut.h:
../../Kernel/KeyCode.h:
../../AK/AKString.h:
../../AK/ByteBuffer.h:
../../AK/Retainable.h:
../../AK/RetainPtr.h:
../../AK/Retained.h:
../../AK/kmalloc.h:
../../AK/StringImpl.h:
../../AK/Vector.h:
TaskbarWindow.h:
../../LibGUI/GWindow.h:
../../LibGUI/GObject.h:
../../AK/Weakable.h:
../../SharedGraphics/Rect.h:
../../SharedGraphics/Point.h:
../../SharedGraphics/Size.h:
../../SharedGraphics/GraphicsBitmap.h:
../../SharedGraphics/Color.h:
../../AK/MappedFile.h:
../../LibC/SharedBuffer.h:
../../AK/WeakPtr.h:
../../LibGUI/GWidget.h:
../../LibGUI/GElapsedTimer.h:
../../LibC/time.h:
../../LibGUI/GEvent.h:
../../SharedGraphics/Font.h:

BIN
Applications/Taskbar/main.o Normal file

Binary file not shown.

View file

@ -34,6 +34,8 @@ $make_cmd -C ../Applications/About clean && \
$make_cmd -C ../Applications/About && \ $make_cmd -C ../Applications/About && \
$make_cmd -C ../Applications/IRCClient clean && \ $make_cmd -C ../Applications/IRCClient clean && \
$make_cmd -C ../Applications/IRCClient && \ $make_cmd -C ../Applications/IRCClient && \
$make_cmd -C ../Applications/Taskbar clean && \
$make_cmd -C ../Applications/Taskbar && \
$make_cmd clean &&\ $make_cmd clean &&\
$make_cmd && \ $make_cmd && \
sudo ./sync.sh sudo ./sync.sh

View file

@ -92,6 +92,8 @@ ln -s IRCClient mnt/bin/irc
ln -s FileManager mnt/bin/fm ln -s FileManager mnt/bin/fm
cp -v ../Servers/LookupServer/LookupServer mnt/bin/LookupServer cp -v ../Servers/LookupServer/LookupServer mnt/bin/LookupServer
cp -v ../Servers/WindowServer/WindowServer mnt/bin/WindowServer cp -v ../Servers/WindowServer/WindowServer mnt/bin/WindowServer
cp -v ../Applications/Taskbar/Taskbar mnt/bin/Taskbar
ln -s Taskbar mnt/bin/tb
cp -v kernel.map mnt/ cp -v kernel.map mnt/
sh sync-local.sh sh sync-local.sh
sync sync

View file

@ -16,7 +16,11 @@ GDesktop::GDesktop()
void GDesktop::did_receive_screen_rect(Badge<GEventLoop>, const Rect& rect) void GDesktop::did_receive_screen_rect(Badge<GEventLoop>, const Rect& rect)
{ {
if (m_rect == rect)
return;
m_rect = rect; m_rect = rect;
if (on_rect_change)
on_rect_change(rect);
} }
bool GDesktop::set_wallpaper(const String& path) bool GDesktop::set_wallpaper(const String& path)

View file

@ -2,6 +2,7 @@
#include <AK/AKString.h> #include <AK/AKString.h>
#include <AK/Badge.h> #include <AK/Badge.h>
#include <AK/Function.h>
#include <SharedGraphics/Rect.h> #include <SharedGraphics/Rect.h>
class GEventLoop; class GEventLoop;
@ -17,6 +18,8 @@ public:
Rect rect() const { return m_rect; } Rect rect() const { return m_rect; }
void did_receive_screen_rect(Badge<GEventLoop>, const Rect&); void did_receive_screen_rect(Badge<GEventLoop>, const Rect&);
Function<void(const Rect&)> on_rect_change;
private: private:
Rect m_rect; Rect m_rect;
}; };

View file

@ -64,6 +64,7 @@ void GEventLoop::connect_to_server()
request.greeting.client_pid = getpid(); request.greeting.client_pid = getpid();
auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting); auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting);
s_server_pid = response.greeting.server_pid; s_server_pid = response.greeting.server_pid;
GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), response.greeting.screen_rect);
} }
GEventLoop::GEventLoop() GEventLoop::GEventLoop()

View file

@ -64,6 +64,7 @@ void GWindow::show()
request.window.opacity = m_opacity_when_windowless; request.window.opacity = m_opacity_when_windowless;
request.window.size_increment = m_size_increment; request.window.size_increment = m_size_increment;
request.window.base_size = m_base_size; request.window.base_size = m_base_size;
request.window.type = (WSAPI_WindowType)m_window_type;
ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text)); ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text));
strcpy(request.text, m_title_when_windowless.characters()); strcpy(request.text, m_title_when_windowless.characters());
request.text_length = m_title_when_windowless.length(); request.text_length = m_title_when_windowless.length();
@ -140,6 +141,11 @@ void GWindow::set_rect(const Rect& a_rect)
GEventLoop::current().post_message_to_server(request); GEventLoop::current().post_message_to_server(request);
} }
void GWindow::set_window_type(GWindowType window_type)
{
m_window_type = window_type;
}
void GWindow::set_override_cursor(GStandardCursor cursor) void GWindow::set_override_cursor(GStandardCursor cursor)
{ {
if (!m_window_id) if (!m_window_id)

View file

@ -16,6 +16,12 @@ enum class GStandardCursor {
ResizeVertical, ResizeVertical,
}; };
enum class GWindowType {
Invalid = 0,
Normal,
Taskbar,
};
class GWindow : public GObject { class GWindow : public GObject {
public: public:
GWindow(GObject* parent = nullptr); GWindow(GObject* parent = nullptr);
@ -29,6 +35,7 @@ public:
void set_double_buffering_enabled(bool); void set_double_buffering_enabled(bool);
void set_has_alpha_channel(bool); void set_has_alpha_channel(bool);
void set_opacity(float); void set_opacity(float);
void set_window_type(GWindowType);
int window_id() const { return m_window_id; } int window_id() const { return m_window_id; }
@ -117,6 +124,7 @@ private:
Vector<Rect> m_pending_paint_event_rects; Vector<Rect> m_pending_paint_event_rects;
Size m_size_increment; Size m_size_increment;
Size m_base_size; Size m_base_size;
GWindowType m_window_type { GWindowType::Normal };
bool m_is_active { false }; bool m_is_active { false };
bool m_should_exit_app_on_close { false }; bool m_should_exit_app_on_close { false };
bool m_has_alpha_channel { false }; bool m_has_alpha_channel { false };
@ -124,4 +132,3 @@ private:
bool m_modal { false }; bool m_modal { false };
bool m_resizable { true }; bool m_resizable { true };
}; };

View file

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

View file

@ -311,6 +311,7 @@ void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request
} }
auto& window = *(*it).value; auto& window = *(*it).value;
window.set_rect(request.rect()); window.set_rect(request.rect());
post_paint_request(window, request.rect());
} }
void WSClientConnection::handle_request(const WSAPIGetWindowRectRequest& request) void WSClientConnection::handle_request(const WSAPIGetWindowRectRequest& request)
@ -370,7 +371,7 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&)
void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request) void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request)
{ {
int window_id = m_next_window_id++; 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_has_alpha_channel(request.has_alpha_channel());
window->set_resizable(request.is_resizable()); window->set_resizable(request.is_resizable());
window->set_title(request.title()); window->set_title(request.title());
@ -399,6 +400,16 @@ void WSClientConnection::handle_request(const WSAPIDestroyWindowRequest& request
m_windows.remove(it); 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) void WSClientConnection::handle_request(const WSAPIInvalidateRectRequest& request)
{ {
int window_id = request.window_id(); int window_id = request.window_id();
@ -408,12 +419,7 @@ void WSClientConnection::handle_request(const WSAPIInvalidateRectRequest& reques
return; return;
} }
auto& window = *(*it).value; auto& window = *(*it).value;
WSAPI_ServerMessage response; post_paint_request(window, request.rect());
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);
} }
void WSClientConnection::handle_request(const WSAPIDidFinishPaintingNotification& request) void WSClientConnection::handle_request(const WSAPIDidFinishPaintingNotification& request)

View file

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

View file

@ -6,6 +6,7 @@
#include <AK/Types.h> #include <AK/Types.h>
#include <Kernel/KeyCode.h> #include <Kernel/KeyCode.h>
#include <WindowServer/WSCursor.h> #include <WindowServer/WSCursor.h>
#include <WindowServer/WSWindowType.h>
class WSMessage { class WSMessage {
public: public:
@ -408,7 +409,7 @@ private:
class WSAPICreateWindowRequest : public WSAPIClientRequest { class WSAPICreateWindowRequest : public WSAPIClientRequest {
public: 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) : WSAPIClientRequest(WSMessage::APICreateWindowRequest, client_id)
, m_rect(rect) , m_rect(rect)
, m_title(title) , m_title(title)
@ -418,6 +419,7 @@ public:
, m_resizable(resizable) , m_resizable(resizable)
, m_size_increment(size_increment) , m_size_increment(size_increment)
, m_base_size(base_size) , m_base_size(base_size)
, m_window_type(window_type)
{ {
} }
@ -429,6 +431,7 @@ public:
float opacity() const { return m_opacity; } float opacity() const { return m_opacity; }
Size size_increment() const { return m_size_increment; } Size size_increment() const { return m_size_increment; }
Size base_size() const { return m_base_size; } Size base_size() const { return m_base_size; }
WSWindowType window_type() const { return m_window_type; }
private: private:
Rect m_rect; Rect m_rect;
@ -439,6 +442,7 @@ private:
bool m_resizable { false }; bool m_resizable { false };
Size m_size_increment; Size m_size_increment;
Size m_base_size; Size m_base_size;
WSWindowType m_window_type;
}; };
class WSAPIDestroyWindowRequest : public WSAPIClientRequest { 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)); 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) void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessage& message)
{ {
WSClientConnection& client = *WSClientConnection::from_client_id(client_id); 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; break;
case WSAPI_ClientMessage::Type::CreateWindow: case WSAPI_ClientMessage::Type::CreateWindow:
ASSERT(message.text_length < (ssize_t)sizeof(message.text)); 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; break;
case WSAPI_ClientMessage::Type::DestroyWindow: case WSAPI_ClientMessage::Type::DestroyWindow:
post_message(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id)); 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); 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_client(&client)
, m_type(WSWindowType::Normal) , m_type(window_type)
, m_modal(modal) , m_modal(modal)
, m_window_id(window_id) , m_window_id(window_id)
, m_icon(default_window_icon()) , m_icon(default_window_icon())

View file

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

View file

@ -104,6 +104,8 @@ static inline Rect outer_window_rect(const WSWindow& window)
return menu_window_rect(window.rect()); return menu_window_rect(window.rect());
if (window.type() == WSWindowType::WindowSwitcher) if (window.type() == WSWindowType::WindowSwitcher)
return window.rect(); return window.rect();
if (window.type() == WSWindowType::Taskbar)
return window.rect();
ASSERT(window.type() == WSWindowType::Normal); ASSERT(window.type() == WSWindowType::Normal);
return outer_window_rect(window.rect()); return outer_window_rect(window.rect());
} }
@ -418,6 +420,9 @@ void WSWindowManager::paint_window_frame(const WSWindow& window)
if (window.type() == WSWindowType::WindowSwitcher) if (window.type() == WSWindowType::WindowSwitcher)
return; return;
if (window.type() == WSWindowType::Taskbar)
return;
auto titlebar_rect = title_bar_rect(window.rect()); auto titlebar_rect = title_bar_rect(window.rect());
auto titlebar_icon_rect = title_bar_icon_rect(window.rect()); auto titlebar_icon_rect = title_bar_icon_rect(window.rect());
auto titlebar_inner_rect = title_bar_text_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()); invalidate(window.rect());
return; return;
} }
if (window.type() == WSWindowType::Taskbar) {
invalidate(window.rect());
return;
}
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
} }

View file

@ -228,6 +228,8 @@ IterationDecision WSWindowManager::for_each_visible_window_from_back_to_front(Ca
return IterationDecision::Abort; return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Abort) if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Abort)
return 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); 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> template<typename Callback>
IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Callback 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) if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menu, callback) == IterationDecision::Abort)
return IterationDecision::Abort; return IterationDecision::Abort;
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, callback) == 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, Normal,
Menu, Menu,
WindowSwitcher, WindowSwitcher,
Taskbar,
}; };