mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:47:34 +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
|
@ -77,6 +77,7 @@ public:
|
||||||
WM_WindowStateChanged,
|
WM_WindowStateChanged,
|
||||||
WM_WindowRectChanged,
|
WM_WindowRectChanged,
|
||||||
WM_WindowIconBitmapChanged,
|
WM_WindowIconBitmapChanged,
|
||||||
|
WM_AppletAreaSizeChanged,
|
||||||
__End_WM_Events,
|
__End_WM_Events,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,6 +109,20 @@ private:
|
||||||
int m_window_id { -1 };
|
int m_window_id { -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WMAppletAreaSizeChangedEvent : public WMEvent {
|
||||||
|
public:
|
||||||
|
explicit WMAppletAreaSizeChangedEvent(const Gfx::IntSize& size)
|
||||||
|
: WMEvent(Event::Type::WM_AppletAreaSizeChanged, 0, 0)
|
||||||
|
, m_size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const Gfx::IntSize& size() const { return m_size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gfx::IntSize m_size;
|
||||||
|
};
|
||||||
|
|
||||||
class WMWindowRemovedEvent : public WMEvent {
|
class WMWindowRemovedEvent : public WMEvent {
|
||||||
public:
|
public:
|
||||||
WMWindowRemovedEvent(int client_id, int window_id)
|
WMWindowRemovedEvent(int client_id, int window_id)
|
||||||
|
|
|
@ -269,6 +269,12 @@ void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowState
|
||||||
Core::EventLoop::current().post_event(*window, make<WMWindowStateChangedEvent>(message.client_id(), message.window_id(), message.parent_client_id(), message.parent_window_id(), message.title(), message.rect(), message.is_active(), message.is_modal(), static_cast<WindowType>(message.window_type()), message.is_minimized(), message.is_frameless(), message.progress()));
|
Core::EventLoop::current().post_event(*window, make<WMWindowStateChangedEvent>(message.client_id(), message.window_id(), message.parent_client_id(), message.parent_window_id(), message.title(), message.rect(), message.is_active(), message.is_modal(), static_cast<WindowType>(message.window_type()), message.is_minimized(), message.is_frameless(), message.progress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowServerConnection::handle(const Messages::WindowClient::WM_AppletAreaSizeChanged& message)
|
||||||
|
{
|
||||||
|
if (auto* window = Window::from_window_id(message.wm_id()))
|
||||||
|
Core::EventLoop::current().post_event(*window, make<WMAppletAreaSizeChangedEvent>(message.size()));
|
||||||
|
}
|
||||||
|
|
||||||
void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowRectChanged& message)
|
void WindowServerConnection::handle(const Messages::WindowClient::WM_WindowRectChanged& message)
|
||||||
{
|
{
|
||||||
if (auto* window = Window::from_window_id(message.wm_id()))
|
if (auto* window = Window::from_window_id(message.wm_id()))
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
virtual void handle(const Messages::WindowClient::WM_WindowStateChanged&) override;
|
virtual void handle(const Messages::WindowClient::WM_WindowStateChanged&) override;
|
||||||
virtual void handle(const Messages::WindowClient::WM_WindowIconBitmapChanged&) override;
|
virtual void handle(const Messages::WindowClient::WM_WindowIconBitmapChanged&) override;
|
||||||
virtual void handle(const Messages::WindowClient::WM_WindowRectChanged&) override;
|
virtual void handle(const Messages::WindowClient::WM_WindowRectChanged&) override;
|
||||||
|
virtual void handle(const Messages::WindowClient::WM_AppletAreaSizeChanged&) override;
|
||||||
virtual void handle(const Messages::WindowClient::AsyncSetWallpaperFinished&) override;
|
virtual void handle(const Messages::WindowClient::AsyncSetWallpaperFinished&) override;
|
||||||
virtual void handle(const Messages::WindowClient::DragDropped&) override;
|
virtual void handle(const Messages::WindowClient::DragDropped&) override;
|
||||||
virtual void handle(const Messages::WindowClient::DragAccepted&) override;
|
virtual void handle(const Messages::WindowClient::DragAccepted&) override;
|
||||||
|
|
|
@ -88,7 +88,7 @@ TaskbarWindow::TaskbarWindow(NonnullRefPtr<GUI::Menu> start_menu)
|
||||||
auto& start_button = main_widget.add<GUI::Button>("Serenity");
|
auto& start_button = main_widget.add<GUI::Button>("Serenity");
|
||||||
start_button.set_font(Gfx::FontDatabase::default_bold_font());
|
start_button.set_font(Gfx::FontDatabase::default_bold_font());
|
||||||
start_button.set_icon_spacing(0);
|
start_button.set_icon_spacing(0);
|
||||||
start_button.set_fixed_width(80);
|
start_button.set_fixed_size(80, 22);
|
||||||
auto app_icon = GUI::Icon::default_icon("ladybug");
|
auto app_icon = GUI::Icon::default_icon("ladybug");
|
||||||
start_button.set_icon(app_icon.bitmap_for_size(16));
|
start_button.set_icon(app_icon.bitmap_for_size(16));
|
||||||
|
|
||||||
|
@ -104,6 +104,11 @@ TaskbarWindow::TaskbarWindow(NonnullRefPtr<GUI::Menu> start_menu)
|
||||||
|
|
||||||
m_default_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/window.png");
|
m_default_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/window.png");
|
||||||
|
|
||||||
|
m_applet_area_container = main_widget.add<GUI::Frame>();
|
||||||
|
m_applet_area_container->set_frame_thickness(1);
|
||||||
|
m_applet_area_container->set_frame_shape(Gfx::FrameShape::Box);
|
||||||
|
m_applet_area_container->set_frame_shadow(Gfx::FrameShadow::Sunken);
|
||||||
|
|
||||||
main_widget.add<Taskbar::ClockWidget>();
|
main_widget.add<Taskbar::ClockWidget>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +180,8 @@ void TaskbarWindow::on_screen_rect_change(const Gfx::IntRect& rect)
|
||||||
NonnullRefPtr<GUI::Button> TaskbarWindow::create_button(const WindowIdentifier& identifier)
|
NonnullRefPtr<GUI::Button> TaskbarWindow::create_button(const WindowIdentifier& identifier)
|
||||||
{
|
{
|
||||||
auto& button = m_task_button_container->add<TaskbarButton>(identifier);
|
auto& button = m_task_button_container->add<TaskbarButton>(identifier);
|
||||||
button.set_min_size(20, 23);
|
button.set_min_size(20, 22);
|
||||||
button.set_max_size(140, 23);
|
button.set_max_size(140, 22);
|
||||||
button.set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
button.set_text_alignment(Gfx::TextAlignment::CenterLeft);
|
||||||
button.set_icon(*m_default_icon);
|
button.set_icon(*m_default_icon);
|
||||||
return button;
|
return button;
|
||||||
|
@ -317,6 +322,17 @@ void TaskbarWindow::wm_event(GUI::WMEvent& event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GUI::Event::WM_AppletAreaSizeChanged: {
|
||||||
|
auto& changed_event = static_cast<GUI::WMAppletAreaSizeChangedEvent&>(event);
|
||||||
|
m_applet_area_container->set_fixed_size(changed_event.size().width() + 8, 22);
|
||||||
|
// NOTE: Widget layout is normally lazy, but here we have to force it right away so we can tell
|
||||||
|
// WindowServer where to place the applet area window.
|
||||||
|
main_widget()->do_layout();
|
||||||
|
Gfx::IntRect new_rect { {}, changed_event.size() };
|
||||||
|
new_rect.center_within(m_applet_area_container->screen_relative_rect());
|
||||||
|
GUI::WindowServerConnection::the().send_sync<Messages::WindowServer::WM_SetAppletAreaPosition>(new_rect.location());
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,4 +53,5 @@ private:
|
||||||
NonnullRefPtr<GUI::Menu> m_start_menu;
|
NonnullRefPtr<GUI::Menu> m_start_menu;
|
||||||
RefPtr<GUI::Widget> m_task_button_container;
|
RefPtr<GUI::Widget> m_task_button_container;
|
||||||
RefPtr<Gfx::Bitmap> m_default_icon;
|
RefPtr<Gfx::Bitmap> m_default_icon;
|
||||||
|
RefPtr<GUI::Frame> m_applet_area_container;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Hüseyin Aslıtürk <asliturk@hotmail.com>
|
* Copyright (c) 2020, Hüseyin Aslıtürk <asliturk@hotmail.com>
|
||||||
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -53,16 +54,26 @@ AppletManager& AppletManager::the()
|
||||||
return *s_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)
|
void AppletManager::event(Core::Event& event)
|
||||||
{
|
{
|
||||||
|
if (!is<MouseEvent>(event))
|
||||||
|
return;
|
||||||
auto& mouse_event = static_cast<MouseEvent&>(event);
|
auto& mouse_event = static_cast<MouseEvent&>(event);
|
||||||
|
|
||||||
|
dbgln("mouse_event: {}", mouse_event.position());
|
||||||
|
|
||||||
for (auto& applet : m_applets) {
|
for (auto& applet : m_applets) {
|
||||||
if (!applet)
|
if (!applet)
|
||||||
continue;
|
continue;
|
||||||
if (!applet->rect_in_menubar().contains(mouse_event.position()))
|
if (!applet->rect_in_applet_area().contains(mouse_event.position()))
|
||||||
continue;
|
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);
|
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);
|
return index_a.value_or(0) > index_b.value_or(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
calculate_applet_rects(MenuManager::the().window());
|
relayout();
|
||||||
|
|
||||||
MenuManager::the().refresh();
|
MenuManager::the().refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::calculate_applet_rects(Window& window)
|
void AppletManager::relayout()
|
||||||
{
|
{
|
||||||
auto menubar_rect = window.rect();
|
constexpr int applet_spacing = 4;
|
||||||
int right_edge_x = menubar_rect.width() - 4;
|
constexpr int applet_window_height = 20;
|
||||||
|
int total_width = 0;
|
||||||
for (auto& existing_applet : m_applets) {
|
for (auto& existing_applet : m_applets) {
|
||||||
|
total_width += max(0, existing_applet->size().width()) + applet_spacing;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
void AppletManager::remove_applet(Window& applet)
|
||||||
|
@ -108,7 +145,7 @@ void AppletManager::remove_applet(Window& applet)
|
||||||
return &applet == entry.ptr();
|
return &applet == entry.ptr();
|
||||||
});
|
});
|
||||||
|
|
||||||
MenuManager::the().refresh();
|
relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::draw()
|
void AppletManager::draw()
|
||||||
|
@ -125,17 +162,20 @@ void AppletManager::draw_applet(const Window& applet)
|
||||||
if (!applet.backing_store())
|
if (!applet.backing_store())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Gfx::Painter painter(*MenuManager::the().window().backing_store());
|
Gfx::Painter painter(*m_window->backing_store());
|
||||||
Gfx::PainterStateSaver saver(painter);
|
Gfx::PainterStateSaver saver(painter);
|
||||||
painter.add_clip_rect(applet.rect_in_menubar());
|
painter.add_clip_rect(applet.rect_in_applet_area());
|
||||||
painter.fill_rect(applet.rect_in_menubar(), WindowManager::the().palette().window());
|
painter.fill_rect(applet.rect_in_applet_area(), WindowManager::the().palette().window());
|
||||||
painter.blit(applet.rect_in_menubar().location(), *applet.backing_store(), applet.backing_store()->rect());
|
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);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,12 +45,18 @@ public:
|
||||||
void remove_applet(Window& applet);
|
void remove_applet(Window& applet);
|
||||||
void draw();
|
void draw();
|
||||||
void invalidate_applet(const Window& applet, const Gfx::IntRect& rect);
|
void invalidate_applet(const Window& applet, const Gfx::IntRect& rect);
|
||||||
void calculate_applet_rects(Window& window);
|
void relayout();
|
||||||
|
|
||||||
|
void set_position(const Gfx::IntPoint&);
|
||||||
|
|
||||||
|
Window* window() { return m_window; }
|
||||||
|
const Window* window() const { return m_window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void draw_applet(const Window& applet);
|
void draw_applet(const Window& applet);
|
||||||
|
|
||||||
Vector<WeakPtr<Window>> m_applets;
|
Vector<WeakPtr<Window>> m_applets;
|
||||||
|
RefPtr<Window> m_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@ OwnPtr<Messages::WindowServer::GetWindowRectInMenubarResponse> ClientConnection:
|
||||||
did_misbehave("GetWindowRectInMenubar: Bad window ID");
|
did_misbehave("GetWindowRectInMenubar: Bad window ID");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return make<Messages::WindowServer::GetWindowRectInMenubarResponse>(it->value->rect_in_menubar());
|
return make<Messages::WindowServer::GetWindowRectInMenubarResponse>(it->value->rect_in_applet_area());
|
||||||
}
|
}
|
||||||
|
|
||||||
Window* ClientConnection::window_from_id(i32 window_id)
|
Window* ClientConnection::window_from_id(i32 window_id)
|
||||||
|
@ -717,6 +717,12 @@ OwnPtr<Messages::WindowServer::SetWindowAlphaHitThresholdResponse> ClientConnect
|
||||||
return make<Messages::WindowServer::SetWindowAlphaHitThresholdResponse>();
|
return make<Messages::WindowServer::SetWindowAlphaHitThresholdResponse>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OwnPtr<Messages::WindowServer::WM_SetAppletAreaPositionResponse> ClientConnection::handle(const Messages::WindowServer::WM_SetAppletAreaPosition& message)
|
||||||
|
{
|
||||||
|
AppletManager::the().set_position(message.position());
|
||||||
|
return make<Messages::WindowServer::WM_SetAppletAreaPositionResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
void ClientConnection::handle(const Messages::WindowServer::WM_SetActiveWindow& message)
|
void ClientConnection::handle(const Messages::WindowServer::WM_SetActiveWindow& message)
|
||||||
{
|
{
|
||||||
auto* client = ClientConnection::from_client_id(message.client_id());
|
auto* client = ClientConnection::from_client_id(message.client_id());
|
||||||
|
|
|
@ -136,6 +136,7 @@ private:
|
||||||
virtual void handle(const Messages::WindowServer::WM_SetWindowMinimized&) override;
|
virtual void handle(const Messages::WindowServer::WM_SetWindowMinimized&) override;
|
||||||
virtual void handle(const Messages::WindowServer::WM_StartWindowResize&) override;
|
virtual void handle(const Messages::WindowServer::WM_StartWindowResize&) override;
|
||||||
virtual void handle(const Messages::WindowServer::WM_PopupWindowMenu&) override;
|
virtual void handle(const Messages::WindowServer::WM_PopupWindowMenu&) override;
|
||||||
|
virtual OwnPtr<Messages::WindowServer::WM_SetAppletAreaPositionResponse> handle(const Messages::WindowServer::WM_SetAppletAreaPosition&) override;
|
||||||
virtual OwnPtr<Messages::WindowServer::SetWindowHasAlphaChannelResponse> handle(const Messages::WindowServer::SetWindowHasAlphaChannel&) override;
|
virtual OwnPtr<Messages::WindowServer::SetWindowHasAlphaChannelResponse> handle(const Messages::WindowServer::SetWindowHasAlphaChannel&) override;
|
||||||
virtual OwnPtr<Messages::WindowServer::SetWindowAlphaHitThresholdResponse> handle(const Messages::WindowServer::SetWindowAlphaHitThreshold&) override;
|
virtual OwnPtr<Messages::WindowServer::SetWindowAlphaHitThresholdResponse> handle(const Messages::WindowServer::SetWindowAlphaHitThreshold&) override;
|
||||||
virtual OwnPtr<Messages::WindowServer::MoveWindowToFrontResponse> handle(const Messages::WindowServer::MoveWindowToFront&) override;
|
virtual OwnPtr<Messages::WindowServer::MoveWindowToFrontResponse> handle(const Messages::WindowServer::MoveWindowToFront&) override;
|
||||||
|
|
|
@ -28,10 +28,7 @@
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
#include <LibCore/DirIterator.h>
|
|
||||||
#include <LibGfx/Font.h>
|
|
||||||
#include <LibGfx/Painter.h>
|
#include <LibGfx/Painter.h>
|
||||||
#include <WindowServer/AppletManager.h>
|
|
||||||
#include <WindowServer/ClientConnection.h>
|
#include <WindowServer/ClientConnection.h>
|
||||||
#include <WindowServer/MenuManager.h>
|
#include <WindowServer/MenuManager.h>
|
||||||
#include <WindowServer/Screen.h>
|
#include <WindowServer/Screen.h>
|
||||||
|
@ -84,7 +81,6 @@ void MenuManager::draw()
|
||||||
|
|
||||||
if (m_needs_window_resize) {
|
if (m_needs_window_resize) {
|
||||||
m_window->set_rect(menubar_rect);
|
m_window->set_rect(menubar_rect);
|
||||||
AppletManager::the().calculate_applet_rects(window());
|
|
||||||
m_needs_window_resize = false;
|
m_needs_window_resize = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +89,6 @@ void MenuManager::draw()
|
||||||
painter.fill_rect(menubar_rect, palette.window());
|
painter.fill_rect(menubar_rect, palette.window());
|
||||||
painter.draw_line({ 0, menubar_rect.bottom() - 1 }, { menubar_rect.right(), menubar_rect.bottom() - 1 }, palette.threed_shadow1());
|
painter.draw_line({ 0, menubar_rect.bottom() - 1 }, { menubar_rect.right(), menubar_rect.bottom() - 1 }, palette.threed_shadow1());
|
||||||
painter.draw_line({ 0, menubar_rect.bottom() }, { menubar_rect.right(), menubar_rect.bottom() }, palette.threed_shadow2());
|
painter.draw_line({ 0, menubar_rect.bottom() }, { menubar_rect.right(), menubar_rect.bottom() }, palette.threed_shadow2());
|
||||||
|
|
||||||
AppletManager::the().draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::refresh()
|
void MenuManager::refresh()
|
||||||
|
@ -266,8 +260,6 @@ void MenuManager::handle_mouse_event(MouseEvent& mouse_event)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppletManager::the().dispatch_event(static_cast<Event&>(mouse_event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::set_needs_window_resize()
|
void MenuManager::set_needs_window_resize()
|
||||||
|
|
|
@ -153,12 +153,13 @@ void Window::set_title(const String& title)
|
||||||
|
|
||||||
void Window::set_rect(const Gfx::IntRect& rect)
|
void Window::set_rect(const Gfx::IntRect& rect)
|
||||||
{
|
{
|
||||||
VERIFY(!rect.is_empty());
|
|
||||||
if (m_rect == rect)
|
if (m_rect == rect)
|
||||||
return;
|
return;
|
||||||
auto old_rect = m_rect;
|
auto old_rect = m_rect;
|
||||||
m_rect = rect;
|
m_rect = rect;
|
||||||
if (!m_client && (!m_backing_store || old_rect.size() != rect.size())) {
|
if (rect.is_empty()) {
|
||||||
|
m_backing_store = nullptr;
|
||||||
|
} else if (!m_client && (!m_backing_store || old_rect.size() != rect.size())) {
|
||||||
m_backing_store = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, m_rect.size());
|
m_backing_store = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, m_rect.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,8 +207,8 @@ public:
|
||||||
Gfx::DisjointRectSet& dirty_rects() { return m_dirty_rects; }
|
Gfx::DisjointRectSet& dirty_rects() { return m_dirty_rects; }
|
||||||
|
|
||||||
// Only used by WindowType::MenuApplet. Perhaps it could be a Window subclass? I don't know.
|
// Only used by WindowType::MenuApplet. Perhaps it could be a Window subclass? I don't know.
|
||||||
void set_rect_in_menubar(const Gfx::IntRect& rect) { m_rect_in_menubar = rect; }
|
void set_rect_in_applet_area(const Gfx::IntRect& rect) { m_rect_in_applet_area = rect; }
|
||||||
const Gfx::IntRect& rect_in_menubar() const { return m_rect_in_menubar; }
|
const Gfx::IntRect& rect_in_applet_area() const { return m_rect_in_applet_area; }
|
||||||
|
|
||||||
const Gfx::Bitmap* backing_store() const { return m_backing_store.ptr(); }
|
const Gfx::Bitmap* backing_store() const { return m_backing_store.ptr(); }
|
||||||
Gfx::Bitmap* backing_store() { return m_backing_store.ptr(); }
|
Gfx::Bitmap* backing_store() { return m_backing_store.ptr(); }
|
||||||
|
@ -405,7 +405,7 @@ private:
|
||||||
unsigned m_wm_event_mask { 0 };
|
unsigned m_wm_event_mask { 0 };
|
||||||
Gfx::DisjointRectSet m_pending_paint_rects;
|
Gfx::DisjointRectSet m_pending_paint_rects;
|
||||||
Gfx::IntRect m_unmaximized_rect;
|
Gfx::IntRect m_unmaximized_rect;
|
||||||
Gfx::IntRect m_rect_in_menubar;
|
Gfx::IntRect m_rect_in_applet_area;
|
||||||
RefPtr<Menu> m_window_menu;
|
RefPtr<Menu> m_window_menu;
|
||||||
MenuItem* m_window_menu_minimize_item { nullptr };
|
MenuItem* m_window_menu_minimize_item { nullptr };
|
||||||
MenuItem* m_window_menu_maximize_item { nullptr };
|
MenuItem* m_window_menu_maximize_item { nullptr };
|
||||||
|
|
|
@ -26,6 +26,7 @@ endpoint WindowClient = 4
|
||||||
WM_WindowStateChanged(i32 wm_id, i32 client_id, i32 window_id, i32 parent_client_id, i32 parent_window_id, bool is_active, bool is_minimized, bool is_modal, bool is_frameless, i32 window_type, [UTF8] String title, Gfx::IntRect rect, i32 progress) =|
|
WM_WindowStateChanged(i32 wm_id, i32 client_id, i32 window_id, i32 parent_client_id, i32 parent_window_id, bool is_active, bool is_minimized, bool is_modal, bool is_frameless, i32 window_type, [UTF8] String title, Gfx::IntRect rect, i32 progress) =|
|
||||||
WM_WindowIconBitmapChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::ShareableBitmap bitmap) =|
|
WM_WindowIconBitmapChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::ShareableBitmap bitmap) =|
|
||||||
WM_WindowRectChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::IntRect rect) =|
|
WM_WindowRectChanged(i32 wm_id, i32 client_id, i32 window_id, Gfx::IntRect rect) =|
|
||||||
|
WM_AppletAreaSizeChanged(i32 wm_id, Gfx::IntSize size) =|
|
||||||
|
|
||||||
AsyncSetWallpaperFinished(bool success) =|
|
AsyncSetWallpaperFinished(bool success) =|
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,8 @@ Gfx::Bitmap* WindowFrame::window_shadow() const
|
||||||
return s_menu_bar_shadow;
|
return s_menu_bar_shadow;
|
||||||
case WindowType::Taskbar:
|
case WindowType::Taskbar:
|
||||||
return s_task_bar_shadow;
|
return s_task_bar_shadow;
|
||||||
|
case WindowType::AppletArea:
|
||||||
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
if (auto* highlight_window = WindowManager::the().highlight_window())
|
if (auto* highlight_window = WindowManager::the().highlight_window())
|
||||||
return highlight_window == &m_window ? s_active_window_shadow : s_inactive_window_shadow;
|
return highlight_window == &m_window ? s_active_window_shadow : s_inactive_window_shadow;
|
||||||
|
|
|
@ -204,6 +204,8 @@ void WindowManager::add_window(Window& window)
|
||||||
}
|
}
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
if (auto* applet_area_window = AppletManager::the().window())
|
||||||
|
tell_wm_listeners_applet_area_size_changed(applet_area_window->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
window.invalidate(true, true);
|
window.invalidate(true, true);
|
||||||
|
@ -341,6 +343,14 @@ void WindowManager::tell_wm_listeners_window_rect_changed(Window& window)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::tell_wm_listeners_applet_area_size_changed(const Gfx::IntSize& size)
|
||||||
|
{
|
||||||
|
for_each_window_listening_to_wm_events([&](Window& listener) {
|
||||||
|
listener.client()->post_message(Messages::WindowClient::WM_AppletAreaSizeChanged(listener.window_id(), size));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static bool window_type_has_title(WindowType type)
|
static bool window_type_has_title(WindowType type)
|
||||||
{
|
{
|
||||||
return type == WindowType::Normal || type == WindowType::ToolWindow;
|
return type == WindowType::Normal || type == WindowType::ToolWindow;
|
||||||
|
@ -382,7 +392,7 @@ void WindowManager::notify_rect_changed(Window& window, const Gfx::IntRect& old_
|
||||||
tell_wm_listeners_window_rect_changed(window);
|
tell_wm_listeners_window_rect_changed(window);
|
||||||
|
|
||||||
if (window.type() == WindowType::MenuApplet)
|
if (window.type() == WindowType::MenuApplet)
|
||||||
AppletManager::the().calculate_applet_rects(MenuManager::the().window());
|
AppletManager::the().relayout();
|
||||||
|
|
||||||
MenuManager::the().refresh();
|
MenuManager::the().refresh();
|
||||||
}
|
}
|
||||||
|
@ -931,7 +941,7 @@ void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_wind
|
||||||
if (MenuManager::the().has_open_menu()
|
if (MenuManager::the().has_open_menu()
|
||||||
|| hitting_menu_in_window_with_active_menu) {
|
|| hitting_menu_in_window_with_active_menu) {
|
||||||
for_each_visible_window_of_type_from_front_to_back(WindowType::MenuApplet, [&](auto& window) {
|
for_each_visible_window_of_type_from_front_to_back(WindowType::MenuApplet, [&](auto& window) {
|
||||||
if (!window.rect_in_menubar().contains(event.position()))
|
if (!window.rect_in_applet_area().contains(event.position()))
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
hovered_window = &window;
|
hovered_window = &window;
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
|
|
|
@ -167,6 +167,7 @@ public:
|
||||||
void tell_wm_listeners_window_state_changed(Window&);
|
void tell_wm_listeners_window_state_changed(Window&);
|
||||||
void tell_wm_listeners_window_icon_changed(Window&);
|
void tell_wm_listeners_window_icon_changed(Window&);
|
||||||
void tell_wm_listeners_window_rect_changed(Window&);
|
void tell_wm_listeners_window_rect_changed(Window&);
|
||||||
|
void tell_wm_listeners_applet_area_size_changed(const Gfx::IntSize&);
|
||||||
|
|
||||||
bool is_active_window_or_accessory(Window&) const;
|
bool is_active_window_or_accessory(Window&) const;
|
||||||
|
|
||||||
|
@ -397,6 +398,8 @@ IterationDecision WindowManager::for_each_visible_window_from_back_to_front(Call
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Taskbar, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Taskbar, callback) == IterationDecision::Break)
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
|
if (for_each_visible_window_of_type_from_back_to_front(WindowType::AppletArea, callback) == IterationDecision::Break)
|
||||||
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Notification, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Notification, callback) == IterationDecision::Break)
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Tooltip, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Tooltip, callback) == IterationDecision::Break)
|
||||||
|
@ -444,6 +447,8 @@ IterationDecision WindowManager::for_each_visible_window_from_front_to_back(Call
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Notification, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Notification, callback) == IterationDecision::Break)
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
|
if (for_each_visible_window_of_type_from_front_to_back(WindowType::AppletArea, callback) == IterationDecision::Break)
|
||||||
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Taskbar, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Taskbar, callback) == IterationDecision::Break)
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::ToolWindow, callback) == IterationDecision::Break)
|
if (for_each_visible_window_of_type_from_front_to_back(WindowType::ToolWindow, callback) == IterationDecision::Break)
|
||||||
|
|
|
@ -83,6 +83,7 @@ endpoint WindowServer = 2
|
||||||
WM_StartWindowResize(i32 client_id, i32 window_id) =|
|
WM_StartWindowResize(i32 client_id, i32 window_id) =|
|
||||||
WM_PopupWindowMenu(i32 client_id, i32 window_id, Gfx::IntPoint screen_position) =|
|
WM_PopupWindowMenu(i32 client_id, i32 window_id, Gfx::IntPoint screen_position) =|
|
||||||
WM_SetWindowTaskbarRect(i32 client_id, i32 window_id, Gfx::IntRect rect) =|
|
WM_SetWindowTaskbarRect(i32 client_id, i32 window_id, Gfx::IntRect rect) =|
|
||||||
|
WM_SetAppletAreaPosition(Gfx::IntPoint position) => ()
|
||||||
|
|
||||||
SetWindowHasAlphaChannel(i32 window_id, bool has_alpha_channel) => ()
|
SetWindowHasAlphaChannel(i32 window_id, bool has_alpha_channel) => ()
|
||||||
MoveWindowToFront(i32 window_id) => ()
|
MoveWindowToFront(i32 window_id) => ()
|
||||||
|
|
|
@ -40,6 +40,7 @@ enum class WindowType {
|
||||||
Notification,
|
Notification,
|
||||||
Desktop,
|
Desktop,
|
||||||
ToolWindow,
|
ToolWindow,
|
||||||
|
AppletArea,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue