1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:57:43 +00:00

WindowServer+Taskbar: Show applets in taskbar :^)

WindowServer now collects applet windows into an "applet area" which is
really just a window that a WM (window management) client can position
via IPC.

This is rather hackish, and I think we should come up with a better
architecture eventually, but this brings back the missing applets since
the global menu where they used to live is gone.
This commit is contained in:
Andreas Kling 2021-03-30 22:41:14 +02:00
parent 44602ae141
commit 9bbc1c9c93
18 changed files with 145 additions and 40 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Hüseyin Aslıtürk <asliturk@hotmail.com>
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -53,16 +54,26 @@ AppletManager& AppletManager::the()
return *s_the;
}
void AppletManager::set_position(const Gfx::IntPoint& position)
{
m_window->move_to(position);
m_window->set_visible(true);
}
void AppletManager::event(Core::Event& event)
{
if (!is<MouseEvent>(event))
return;
auto& mouse_event = static_cast<MouseEvent&>(event);
dbgln("mouse_event: {}", mouse_event.position());
for (auto& applet : m_applets) {
if (!applet)
continue;
if (!applet->rect_in_menubar().contains(mouse_event.position()))
if (!applet->rect_in_applet_area().contains(mouse_event.position()))
continue;
auto local_event = mouse_event.translated(-applet->rect_in_menubar().location());
auto local_event = mouse_event.translated(-applet->rect_in_applet_area().location());
applet->dispatch_event(local_event);
}
}
@ -82,24 +93,50 @@ void AppletManager::add_applet(Window& applet)
return index_a.value_or(0) > index_b.value_or(0);
});
calculate_applet_rects(MenuManager::the().window());
relayout();
MenuManager::the().refresh();
}
void AppletManager::calculate_applet_rects(Window& window)
void AppletManager::relayout()
{
auto menubar_rect = window.rect();
int right_edge_x = menubar_rect.width() - 4;
constexpr int applet_spacing = 4;
constexpr int applet_window_height = 20;
int total_width = 0;
for (auto& existing_applet : m_applets) {
Gfx::IntRect new_applet_rect(right_edge_x - existing_applet->size().width(), 0, existing_applet->size().width(), existing_applet->size().height());
Gfx::IntRect dummy_menubar_rect(0, 0, 0, 18);
new_applet_rect.center_vertically_within(dummy_menubar_rect);
existing_applet->set_rect_in_menubar(new_applet_rect);
right_edge_x = existing_applet->rect_in_menubar().x() - 4;
total_width += max(0, existing_applet->size().width()) + applet_spacing;
}
if (total_width > 0)
total_width -= applet_spacing;
auto right_edge_x = total_width;
for (auto& existing_applet : m_applets) {
auto applet_size = existing_applet->size();
Gfx::IntRect new_applet_rect(right_edge_x - applet_size.width(), 0, applet_size.width(), applet_size.height());
Gfx::IntRect dummy_container_rect(0, 0, 0, applet_window_height);
new_applet_rect.center_vertically_within(dummy_container_rect);
existing_applet->set_rect_in_applet_area(new_applet_rect);
right_edge_x = existing_applet->rect_in_applet_area().x() - applet_spacing;
}
if (!m_window) {
m_window = Window::construct(*this, WindowType::AppletArea);
m_window->set_visible(false);
}
Gfx::IntRect rect { m_window->position(), Gfx::IntSize { total_width, applet_window_height } };
if (m_window->rect() == rect)
return;
m_window->set_rect(rect);
if (!rect.is_empty()) {
Gfx::Painter painter(*m_window->backing_store());
painter.fill_rect(m_window->rect(), WindowManager::the().palette().window());
}
WindowManager::the().tell_wm_listeners_applet_area_size_changed(rect.size());
}
void AppletManager::remove_applet(Window& applet)
@ -108,7 +145,7 @@ void AppletManager::remove_applet(Window& applet)
return &applet == entry.ptr();
});
MenuManager::the().refresh();
relayout();
}
void AppletManager::draw()
@ -125,17 +162,20 @@ void AppletManager::draw_applet(const Window& applet)
if (!applet.backing_store())
return;
Gfx::Painter painter(*MenuManager::the().window().backing_store());
Gfx::Painter painter(*m_window->backing_store());
Gfx::PainterStateSaver saver(painter);
painter.add_clip_rect(applet.rect_in_menubar());
painter.fill_rect(applet.rect_in_menubar(), WindowManager::the().palette().window());
painter.blit(applet.rect_in_menubar().location(), *applet.backing_store(), applet.backing_store()->rect());
painter.add_clip_rect(applet.rect_in_applet_area());
painter.fill_rect(applet.rect_in_applet_area(), WindowManager::the().palette().window());
painter.blit(applet.rect_in_applet_area().location(), *applet.backing_store(), applet.backing_store()->rect());
}
void AppletManager::invalidate_applet(const Window& applet, const Gfx::IntRect& rect)
void AppletManager::invalidate_applet(const Window& applet, const Gfx::IntRect&)
{
draw_applet(applet);
MenuManager::the().window().invalidate(rect.translated(applet.rect_in_menubar().location()));
draw();
// FIXME: Invalidate only the exact rect we've been given.
if (m_window)
m_window->invalidate();
}
}