summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibGUI/Window.cpp2
-rw-r--r--Userland/Libraries/LibGUI/WindowType.h3
-rw-r--r--Userland/Libraries/LibGfx/ClassicWindowTheme.cpp56
-rw-r--r--Userland/Libraries/LibGfx/ClassicWindowTheme.h3
-rw-r--r--Userland/Libraries/LibGfx/WindowTheme.h4
-rw-r--r--Userland/Services/WindowServer/ClientConnection.cpp2
-rw-r--r--Userland/Services/WindowServer/Window.h4
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp37
-rw-r--r--Userland/Services/WindowServer/WindowFrame.h2
-rw-r--r--Userland/Services/WindowServer/WindowManager.cpp22
-rw-r--r--Userland/Services/WindowServer/WindowManager.h4
-rw-r--r--Userland/Services/WindowServer/WindowType.h3
12 files changed, 105 insertions, 37 deletions
diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp
index 5ddc73b1a5..7ba7de901d 100644
--- a/Userland/Libraries/LibGUI/Window.cpp
+++ b/Userland/Libraries/LibGUI/Window.cpp
@@ -299,7 +299,7 @@ void Window::set_window_type(WindowType window_type)
if (!m_minimum_size_modified) {
// Apply minimum size defaults.
- if (m_window_type == WindowType::Normal)
+ if (m_window_type == WindowType::Normal || m_window_type == WindowType::ToolWindow)
m_minimum_size_when_windowless = { 50, 50 };
else
m_minimum_size_when_windowless = { 1, 1 };
diff --git a/Userland/Libraries/LibGUI/WindowType.h b/Userland/Libraries/LibGUI/WindowType.h
index b3b2638aba..a7fae0987b 100644
--- a/Userland/Libraries/LibGUI/WindowType.h
+++ b/Userland/Libraries/LibGUI/WindowType.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@ enum class WindowType {
MenuApplet,
Notification,
Desktop,
+ ToolWindow,
};
}
diff --git a/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp b/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
index 7b51828c68..2fd3cb3f72 100644
--- a/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
+++ b/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
@@ -26,7 +26,6 @@
#include <LibGfx/Bitmap.h>
#include <LibGfx/ClassicWindowTheme.h>
-#include <LibGfx/Font.h>
#include <LibGfx/FontDatabase.h>
#include <LibGfx/Painter.h>
#include <LibGfx/Palette.h>
@@ -44,6 +43,9 @@ ClassicWindowTheme::~ClassicWindowTheme()
Gfx::IntRect ClassicWindowTheme::title_bar_icon_rect(WindowType window_type, const IntRect& window_rect, const Palette& palette) const
{
+ if (window_type == WindowType::ToolWindow)
+ return {};
+
auto titlebar_rect = title_bar_rect(window_type, window_rect, palette);
Gfx::IntRect icon_rect {
titlebar_rect.x() + 2,
@@ -61,9 +63,9 @@ Gfx::IntRect ClassicWindowTheme::title_bar_text_rect(WindowType window_type, con
auto titlebar_rect = title_bar_rect(window_type, window_rect, palette);
auto titlebar_icon_rect = title_bar_icon_rect(window_type, window_rect, palette);
return {
- titlebar_rect.x() + 3 + titlebar_icon_rect.width() + 2,
+ titlebar_rect.x() + 3 + (titlebar_icon_rect.is_empty() ? 0 : titlebar_icon_rect.width() + 2),
titlebar_rect.y(),
- titlebar_rect.width() - 5 - titlebar_icon_rect.width() - 2,
+ titlebar_rect.width() - 5 - (titlebar_icon_rect.is_empty() ? 0 : titlebar_icon_rect.width() - 2),
titlebar_rect.height()
};
}
@@ -110,10 +112,41 @@ void ClassicWindowTheme::paint_normal_frame(Painter& painter, WindowState window
painter.blit(titlebar_icon_rect.location(), icon, icon.rect());
}
+void ClassicWindowTheme::paint_tool_window_frame(Painter& painter, WindowState window_state, const IntRect& window_rect, const StringView& title_text, const Palette& palette, const IntRect& leftmost_button_rect) const
+{
+ auto frame_rect = frame_rect_for_window(WindowType::ToolWindow, window_rect, palette);
+ frame_rect.set_location({ 0, 0 });
+ Gfx::StylePainter::paint_window_frame(painter, frame_rect, palette);
+
+ auto& title_font = FontDatabase::default_bold_font();
+
+ auto titlebar_rect = title_bar_rect(WindowType::ToolWindow, window_rect, palette);
+ auto titlebar_inner_rect = title_bar_text_rect(WindowType::ToolWindow, window_rect, palette);
+ auto titlebar_title_rect = titlebar_inner_rect;
+ titlebar_title_rect.set_width(FontDatabase::default_bold_font().width(title_text));
+
+ auto [title_color, border_color, border_color2, stripes_color, shadow_color] = compute_frame_colors(window_state, palette);
+
+ painter.draw_line(titlebar_rect.bottom_left().translated(0, 1), titlebar_rect.bottom_right().translated(0, 1), palette.button());
+ painter.draw_line(titlebar_rect.bottom_left().translated(0, 2), titlebar_rect.bottom_right().translated(0, 2), palette.button());
+
+ painter.fill_rect_with_gradient(titlebar_rect, border_color, border_color2);
+
+ int stripe_right = leftmost_button_rect.left() - 3;
+
+ auto clipped_title_rect = titlebar_title_rect;
+ clipped_title_rect.set_width(stripe_right - clipped_title_rect.x());
+ if (!clipped_title_rect.is_empty()) {
+ painter.draw_text(clipped_title_rect.translated(1, 2), title_text, title_font, Gfx::TextAlignment::CenterLeft, shadow_color, Gfx::TextElision::Right);
+ // FIXME: The translated(0, 1) wouldn't be necessary if we could center text based on its baseline.
+ painter.draw_text(clipped_title_rect.translated(0, 1), title_text, title_font, Gfx::TextAlignment::CenterLeft, title_color, Gfx::TextElision::Right);
+ }
+}
+
IntRect ClassicWindowTheme::title_bar_rect(WindowType window_type, const IntRect& window_rect, const Palette& palette) const
{
auto& title_font = FontDatabase::default_bold_font();
- auto window_titlebar_height = title_bar_height(palette);
+ auto window_titlebar_height = title_bar_height(window_type, palette);
// FIXME: The top of the titlebar doesn't get redrawn properly if this padding is different
int total_vertical_padding = title_font.glyph_height() - 1;
@@ -160,10 +193,11 @@ void ClassicWindowTheme::paint_notification_frame(Painter& painter, const IntRec
IntRect ClassicWindowTheme::frame_rect_for_window(WindowType window_type, const IntRect& window_rect, const Gfx::Palette& palette) const
{
- auto window_titlebar_height = title_bar_height(palette);
+ auto window_titlebar_height = title_bar_height(window_type, palette);
switch (window_type) {
case WindowType::Normal:
+ case WindowType::ToolWindow:
return {
window_rect.x() - 4,
window_rect.y() - window_titlebar_height - 6,
@@ -210,10 +244,18 @@ Vector<IntRect> ClassicWindowTheme::layout_buttons(WindowType window_type, const
return button_rects;
}
-int ClassicWindowTheme::title_bar_height(const Palette& palette) const
+int ClassicWindowTheme::title_bar_height(WindowType window_type, const Palette& palette) const
{
auto& title_font = FontDatabase::default_bold_font();
- return max(palette.window_title_height(), title_font.glyph_height() + 8);
+ switch (window_type) {
+ case WindowType::Normal:
+ case WindowType::Notification:
+ return max(palette.window_title_height(), title_font.glyph_height() + 8);
+ case WindowType::ToolWindow:
+ return max(palette.window_title_height() - 4, title_font.glyph_height() + 4);
+ default:
+ return 0;
+ }
}
}
diff --git a/Userland/Libraries/LibGfx/ClassicWindowTheme.h b/Userland/Libraries/LibGfx/ClassicWindowTheme.h
index b0f2c86136..ae5b633e1d 100644
--- a/Userland/Libraries/LibGfx/ClassicWindowTheme.h
+++ b/Userland/Libraries/LibGfx/ClassicWindowTheme.h
@@ -37,9 +37,10 @@ public:
virtual ~ClassicWindowTheme() override;
virtual void paint_normal_frame(Painter&, WindowState, const IntRect& window_rect, const StringView& title, const Bitmap& icon, const Palette&, const IntRect& leftmost_button_rect) const override;
+ virtual void paint_tool_window_frame(Painter&, WindowState, const IntRect& window_rect, const StringView& title, const Palette&, const IntRect& leftmost_button_rect) const override;
virtual void paint_notification_frame(Painter&, const IntRect& window_rect, const Palette&, const IntRect& close_button_rect) const override;
- virtual int title_bar_height(const Palette&) const override;
+ virtual int title_bar_height(WindowType, const Palette&) const override;
virtual IntRect title_bar_rect(WindowType, const IntRect& window_rect, const Palette&) const override;
virtual IntRect title_bar_icon_rect(WindowType, const IntRect& window_rect, const Palette&) const override;
virtual IntRect title_bar_text_rect(WindowType, const IntRect& window_rect, const Palette&) const override;
diff --git a/Userland/Libraries/LibGfx/WindowTheme.h b/Userland/Libraries/LibGfx/WindowTheme.h
index 7a18a0b422..2231187feb 100644
--- a/Userland/Libraries/LibGfx/WindowTheme.h
+++ b/Userland/Libraries/LibGfx/WindowTheme.h
@@ -35,6 +35,7 @@ class WindowTheme {
public:
enum class WindowType {
Normal,
+ ToolWindow,
Notification,
Other,
};
@@ -51,9 +52,10 @@ public:
static WindowTheme& current();
virtual void paint_normal_frame(Painter&, WindowState, const IntRect& window_rect, const StringView& title, const Bitmap& icon, const Palette&, const IntRect& leftmost_button_rect) const = 0;
+ virtual void paint_tool_window_frame(Painter&, WindowState, const IntRect& window_rect, const StringView& title, const Palette&, const IntRect& leftmost_button_rect) const = 0;
virtual void paint_notification_frame(Painter&, const IntRect& window_rect, const Palette&, const IntRect& close_button_rect) const = 0;
- virtual int title_bar_height(const Palette&) const = 0;
+ virtual int title_bar_height(WindowType, const Palette&) const = 0;
virtual IntRect title_bar_rect(WindowType, const IntRect& window_rect, const Palette&) const = 0;
virtual IntRect title_bar_icon_rect(WindowType, const IntRect& window_rect, const Palette&) const = 0;
virtual IntRect title_bar_text_rect(WindowType, const IntRect& window_rect, const Palette&) const = 0;
diff --git a/Userland/Services/WindowServer/ClientConnection.cpp b/Userland/Services/WindowServer/ClientConnection.cpp
index 3778213805..40f199b6a8 100644
--- a/Userland/Services/WindowServer/ClientConnection.cpp
+++ b/Userland/Services/WindowServer/ClientConnection.cpp
@@ -492,7 +492,7 @@ OwnPtr<Messages::WindowServer::CreateWindowResponse> ClientConnection::handle(co
window->set_title(message.title());
if (!message.fullscreen()) {
auto rect = message.rect();
- if (message.auto_position() && window->type() == WindowType::Normal) {
+ if (message.auto_position() && window->is_movable()) {
rect = { WindowManager::the().get_recommended_window_position({ 100, 100 }), message.rect().size() };
window->set_default_positioned(true);
}
diff --git a/Userland/Services/WindowServer/Window.h b/Userland/Services/WindowServer/Window.h
index cf36a38df0..5ed3aed27e 100644
--- a/Userland/Services/WindowServer/Window.h
+++ b/Userland/Services/WindowServer/Window.h
@@ -97,7 +97,7 @@ public:
bool is_minimized() const { return m_minimized; }
void set_minimized(bool);
- bool is_minimizable() const { return m_minimizable; }
+ bool is_minimizable() const { return m_type == WindowType::Normal && m_minimizable; }
void set_minimizable(bool);
bool is_resizable() const { return m_resizable && !m_fullscreen; }
@@ -120,7 +120,7 @@ public:
bool is_movable() const
{
- return m_type == WindowType::Normal;
+ return m_type == WindowType::Normal || m_type == WindowType::ToolWindow;
}
WindowFrame& frame() { return m_frame; }
diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp
index 85de106ee2..19231b52de 100644
--- a/Userland/Services/WindowServer/WindowFrame.cpp
+++ b/Userland/Services/WindowServer/WindowFrame.cpp
@@ -45,6 +45,8 @@ static Gfx::WindowTheme::WindowType to_theme_window_type(WindowType type)
switch (type) {
case WindowType::Normal:
return Gfx::WindowTheme::WindowType::Normal;
+ case WindowType::ToolWindow:
+ return Gfx::WindowTheme::WindowType::ToolWindow;
case WindowType::Notification:
return Gfx::WindowTheme::WindowType::Notification;
default:
@@ -271,22 +273,25 @@ void WindowFrame::paint_notification_frame(Gfx::Painter& painter)
Gfx::WindowTheme::current().paint_notification_frame(painter, m_window.rect(), palette, m_buttons.last().relative_rect());
}
-void WindowFrame::paint_normal_frame(Gfx::Painter& painter)
+String WindowFrame::compute_title_text() const
+{
+ if (m_window.client() && m_window.client()->is_unresponsive())
+ return String::formatted("{} (Not responding)", m_window.title());
+ return m_window.title();
+}
+
+void WindowFrame::paint_tool_window_frame(Gfx::Painter& painter)
{
auto palette = WindowManager::the().palette();
- auto& window = m_window;
- String title_text;
- if (window.client() && window.client()->is_unresponsive()) {
- StringBuilder builder;
- builder.append(window.title());
- builder.append(" (Not responding)");
- title_text = builder.to_string();
- } else {
- title_text = window.title();
- }
+ auto leftmost_button_rect = m_buttons.is_empty() ? Gfx::IntRect() : m_buttons.last().relative_rect();
+ Gfx::WindowTheme::current().paint_tool_window_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), palette, leftmost_button_rect);
+}
+void WindowFrame::paint_normal_frame(Gfx::Painter& painter)
+{
+ auto palette = WindowManager::the().palette();
auto leftmost_button_rect = m_buttons.is_empty() ? Gfx::IntRect() : m_buttons.last().relative_rect();
- Gfx::WindowTheme::current().paint_normal_frame(painter, window_state_for_theme(), m_window.rect(), title_text, m_window.icon(), palette, leftmost_button_rect);
+ Gfx::WindowTheme::current().paint_normal_frame(painter, window_state_for_theme(), m_window.rect(), compute_title_text(), m_window.icon(), palette, leftmost_button_rect);
}
void WindowFrame::paint(Gfx::Painter& painter, const Gfx::IntRect& rect)
@@ -341,6 +346,8 @@ void WindowFrame::render(Gfx::Painter& painter)
paint_notification_frame(painter);
else if (m_window.type() == WindowType::Normal)
paint_normal_frame(painter);
+ else if (m_window.type() == WindowType::ToolWindow)
+ paint_tool_window_frame(painter);
else
return;
@@ -574,10 +581,10 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
ASSERT(!m_window.is_fullscreen());
auto& wm = WindowManager::the();
- if (m_window.type() != WindowType::Normal && m_window.type() != WindowType::Notification)
+ if (m_window.type() != WindowType::Normal && m_window.type() != WindowType::ToolWindow && m_window.type() != WindowType::Notification)
return;
- if (m_window.type() == WindowType::Normal) {
+ if (m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) {
if (event.type() == Event::MouseDown)
wm.move_to_front_and_make_active(m_window);
@@ -632,7 +639,7 @@ void WindowFrame::on_mouse_event(const MouseEvent& event)
return button.on_mouse_event(event.translated(-button.relative_rect().location()));
}
if (event.type() == Event::MouseDown) {
- if (m_window.type() == WindowType::Normal && event.button() == MouseButton::Right) {
+ if ((m_window.type() == WindowType::Normal || m_window.type() == WindowType::ToolWindow) && event.button() == MouseButton::Right) {
auto default_action = m_window.is_maximized() ? WindowMenuDefaultAction::Restore : WindowMenuDefaultAction::Maximize;
m_window.popup_window_menu(event.position().translated(rect().location()), default_action);
return;
diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h
index b03b58d955..9ca67bf5ab 100644
--- a/Userland/Services/WindowServer/WindowFrame.h
+++ b/Userland/Services/WindowServer/WindowFrame.h
@@ -96,12 +96,14 @@ private:
void paint_simple_rect_shadow(Gfx::Painter&, const Gfx::IntRect&, const Gfx::Bitmap&) const;
void paint_notification_frame(Gfx::Painter&);
void paint_normal_frame(Gfx::Painter&);
+ void paint_tool_window_frame(Gfx::Painter&);
Gfx::Bitmap* window_shadow() const;
bool frame_has_alpha() const;
Gfx::IntRect inflated_for_shadow(const Gfx::IntRect&) const;
Gfx::Bitmap* inflate_for_shadow(Gfx::IntRect&, Gfx::IntPoint&) const;
Gfx::WindowTheme::WindowState window_state_for_theme() const;
+ String compute_title_text() const;
Window& m_window;
NonnullOwnPtrVector<Button> m_buttons;
diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp
index 19f2a7ef70..2551ebfcfb 100644
--- a/Userland/Services/WindowServer/WindowManager.cpp
+++ b/Userland/Services/WindowServer/WindowManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -340,9 +340,14 @@ void WindowManager::tell_wm_listeners_window_rect_changed(Window& window)
});
}
+static bool window_type_has_title(WindowType type)
+{
+ return type == WindowType::Normal || type == WindowType::ToolWindow;
+}
+
void WindowManager::notify_title_changed(Window& window)
{
- if (window.type() != WindowType::Normal)
+ if (!window_type_has_title(window.type()))
return;
dbgln_if(WINDOWMANAGER_DEBUG, "[WM] Window({}) title set to '{}'", &window, window.title());
@@ -412,7 +417,9 @@ bool WindowManager::pick_new_active_window(Window* previous_active)
{
bool new_window_picked = false;
Window* first_candidate = nullptr;
- for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, [&](Window& candidate) {
+ for_each_visible_window_from_front_to_back([&](Window& candidate) {
+ if (candidate.type() != WindowType::Normal && candidate.type() == WindowType::ToolWindow)
+ return IterationDecision::Continue;
if (candidate.is_destroyed())
return IterationDecision::Continue;
if (previous_active != first_candidate)
@@ -984,7 +991,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind
if (auto* blocking_modal_window = window.blocking_modal_window())
blocking_modal_window->frame().start_flash_animation();
- if (window.type() == WindowType::Normal)
+ if (window.type() == WindowType::Normal || window.type() == WindowType::ToolWindow)
move_to_front_and_make_active(window);
else if (window.type() == WindowType::Desktop)
set_active_window(&window);
@@ -1068,6 +1075,7 @@ Gfx::IntRect WindowManager::arena_rect_for_type(WindowType type) const
switch (type) {
case WindowType::Desktop:
case WindowType::Normal:
+ case WindowType::ToolWindow:
return desktop_rect();
case WindowType::Menu:
case WindowType::WindowSwitcher:
@@ -1218,7 +1226,7 @@ bool WindowManager::is_active_window_or_accessory(Window& window) const
static bool window_type_can_become_active(WindowType type)
{
- return type == WindowType::Normal || type == WindowType::Desktop;
+ return type == WindowType::Normal || type == WindowType::ToolWindow || type == WindowType::Desktop;
}
void WindowManager::restore_active_input_window(Window* window)
@@ -1507,7 +1515,7 @@ void WindowManager::maximize_windows(Window& window, bool maximized)
Gfx::IntPoint WindowManager::get_recommended_window_position(const Gfx::IntPoint& desired)
{
// FIXME: Find a better source for the width and height to shift by.
- Gfx::IntPoint shift(8, Gfx::WindowTheme::current().title_bar_height(palette()) + 10);
+ Gfx::IntPoint shift(8, Gfx::WindowTheme::current().title_bar_height(Gfx::WindowTheme::WindowType::Normal, palette()) + 10);
// FIXME: Find a better source for this.
int taskbar_height = 28;
@@ -1526,7 +1534,7 @@ Gfx::IntPoint WindowManager::get_recommended_window_position(const Gfx::IntPoint
point = overlap_window->position() + shift;
point = { point.x() % Screen::the().width(),
(point.y() >= (Screen::the().height() - taskbar_height))
- ? menubar_height + Gfx::WindowTheme::current().title_bar_height(palette())
+ ? menubar_height + Gfx::WindowTheme::current().title_bar_height(Gfx::WindowTheme::WindowType::Normal, palette())
: point.y() };
} else {
point = desired;
diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h
index 84673fd0f5..52f2e530c6 100644
--- a/Userland/Services/WindowServer/WindowManager.h
+++ b/Userland/Services/WindowServer/WindowManager.h
@@ -389,6 +389,8 @@ IterationDecision WindowManager::for_each_visible_window_from_back_to_front(Call
return IterationDecision::Break;
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Normal, callback) == IterationDecision::Break)
return IterationDecision::Break;
+ if (for_each_visible_window_of_type_from_back_to_front(WindowType::ToolWindow, callback) == IterationDecision::Break)
+ return IterationDecision::Break;
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Taskbar, callback) == IterationDecision::Break)
return IterationDecision::Break;
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Notification, callback) == IterationDecision::Break)
@@ -440,6 +442,8 @@ IterationDecision WindowManager::for_each_visible_window_from_front_to_back(Call
return IterationDecision::Break;
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Taskbar, callback) == IterationDecision::Break)
return IterationDecision::Break;
+ if (for_each_visible_window_of_type_from_front_to_back(WindowType::ToolWindow, callback) == IterationDecision::Break)
+ return IterationDecision::Break;
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, callback) == IterationDecision::Break)
return IterationDecision::Break;
return for_each_visible_window_of_type_from_front_to_back(WindowType::Desktop, callback);
diff --git a/Userland/Services/WindowServer/WindowType.h b/Userland/Services/WindowServer/WindowType.h
index a3c53007a1..214aad9338 100644
--- a/Userland/Services/WindowServer/WindowType.h
+++ b/Userland/Services/WindowServer/WindowType.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,4 +38,5 @@ enum class WindowType {
MenuApplet,
Notification,
Desktop,
+ ToolWindow,
};