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:
parent
44602ae141
commit
9bbc1c9c93
18 changed files with 145 additions and 40 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue