mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
WindowServer: Move classes into WindowServer namespace
Also remove the leading WS from names and filenames.
This commit is contained in:
parent
5f4d81ff55
commit
73110e25a9
Notes:
sideshowbarker
2024-07-19 09:33:21 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/73110e25a9a
36 changed files with 1238 additions and 1119 deletions
|
@ -44,7 +44,7 @@
|
|||
#include <LibGUI/GWidget.h>
|
||||
#include <LibGUI/GWindow.h>
|
||||
#include <LibGUI/GWindowServerConnection.h>
|
||||
#include <Servers/WindowServer/WSWindowManager.h>
|
||||
#include <Servers/WindowServer/WindowManager.h>
|
||||
|
||||
DisplayPropertiesWidget::DisplayPropertiesWidget()
|
||||
: m_wm_config(Core::ConfigFile::get_for_app("WindowManager"))
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
namespace GUI {
|
||||
|
||||
// Keep this in sync with WSWindowType.
|
||||
// Keep this in sync with WindowType.
|
||||
enum class WindowType {
|
||||
Invalid = 0,
|
||||
Normal,
|
||||
|
|
|
@ -27,24 +27,26 @@
|
|||
#include <LibGfx/CharacterBitmap.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <WindowServer/WSButton.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/Button.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
WSButton::WSButton(WSWindowFrame& frame, NonnullRefPtr<Gfx::CharacterBitmap>&& bitmap, Function<void(WSButton&)>&& on_click_handler)
|
||||
namespace WindowServer {
|
||||
|
||||
Button::Button(WindowFrame& frame, NonnullRefPtr<Gfx::CharacterBitmap>&& bitmap, Function<void(Button&)>&& on_click_handler)
|
||||
: on_click(move(on_click_handler))
|
||||
, m_frame(frame)
|
||||
, m_bitmap(move(bitmap))
|
||||
{
|
||||
}
|
||||
|
||||
WSButton::~WSButton()
|
||||
Button::~Button()
|
||||
{
|
||||
}
|
||||
|
||||
void WSButton::paint(Gfx::Painter& painter)
|
||||
void Button::paint(Gfx::Painter& painter)
|
||||
{
|
||||
auto palette = WSWindowManager::the().palette();
|
||||
auto palette = WindowManager::the().palette();
|
||||
Gfx::PainterStateSaver saver(painter);
|
||||
painter.translate(relative_rect().location());
|
||||
Gfx::StylePainter::paint_button(painter, rect(), palette, Gfx::ButtonStyle::Normal, m_pressed, m_hovered);
|
||||
|
@ -55,18 +57,18 @@ void WSButton::paint(Gfx::Painter& painter)
|
|||
painter.draw_bitmap(x_location, *m_bitmap, palette.button_text());
|
||||
}
|
||||
|
||||
void WSButton::on_mouse_event(const WSMouseEvent& event)
|
||||
void Button::on_mouse_event(const MouseEvent& event)
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
|
||||
if (event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
|
||||
if (event.type() == Event::MouseDown && event.button() == MouseButton::Left) {
|
||||
m_pressed = true;
|
||||
wm.set_cursor_tracking_button(this);
|
||||
wm.invalidate(screen_rect());
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) {
|
||||
if (event.type() == Event::MouseUp && event.button() == MouseButton::Left) {
|
||||
if (wm.cursor_tracking_button() != this)
|
||||
return;
|
||||
wm.set_cursor_tracking_button(nullptr);
|
||||
|
@ -81,7 +83,7 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
|
|||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseMove) {
|
||||
if (event.type() == Event::MouseMove) {
|
||||
bool old_hovered = m_hovered;
|
||||
m_hovered = rect().contains(event.position());
|
||||
wm.set_hovered_button(m_hovered ? this : nullptr);
|
||||
|
@ -89,7 +91,7 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
|
|||
wm.invalidate(screen_rect());
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseMove && event.buttons() & (unsigned)MouseButton::Left) {
|
||||
if (event.type() == Event::MouseMove && event.buttons() & (unsigned)MouseButton::Left) {
|
||||
if (wm.cursor_tracking_button() != this)
|
||||
return;
|
||||
bool old_pressed = m_pressed;
|
||||
|
@ -99,7 +101,9 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
Gfx::Rect WSButton::screen_rect() const
|
||||
Gfx::Rect Button::screen_rect() const
|
||||
{
|
||||
return m_relative_rect.translated(m_frame.rect().location());
|
||||
}
|
||||
|
||||
}
|
|
@ -36,13 +36,15 @@ class CharacterBitmap;
|
|||
class Painter;
|
||||
}
|
||||
|
||||
class WSMouseEvent;
|
||||
class WSWindowFrame;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSButton : public Weakable<WSButton> {
|
||||
class MouseEvent;
|
||||
class WindowFrame;
|
||||
|
||||
class Button : public Weakable<Button> {
|
||||
public:
|
||||
WSButton(WSWindowFrame&, NonnullRefPtr<Gfx::CharacterBitmap>&&, Function<void(WSButton&)>&& on_click_handler);
|
||||
~WSButton();
|
||||
Button(WindowFrame&, NonnullRefPtr<Gfx::CharacterBitmap>&&, Function<void(Button&)>&& on_click_handler);
|
||||
~Button();
|
||||
|
||||
Gfx::Rect relative_rect() const { return m_relative_rect; }
|
||||
void set_relative_rect(const Gfx::Rect& rect) { m_relative_rect = rect; }
|
||||
|
@ -52,19 +54,21 @@ public:
|
|||
|
||||
void paint(Gfx::Painter&);
|
||||
|
||||
void on_mouse_event(const WSMouseEvent&);
|
||||
void on_mouse_event(const MouseEvent&);
|
||||
|
||||
Function<void(WSButton&)> on_click;
|
||||
Function<void(Button&)> on_click;
|
||||
|
||||
bool is_visible() const { return m_visible; }
|
||||
|
||||
void set_bitmap(const Gfx::CharacterBitmap& bitmap) { m_bitmap = bitmap; }
|
||||
|
||||
private:
|
||||
WSWindowFrame& m_frame;
|
||||
WindowFrame& m_frame;
|
||||
Gfx::Rect m_relative_rect;
|
||||
NonnullRefPtr<Gfx::CharacterBitmap> m_bitmap;
|
||||
bool m_pressed { false };
|
||||
bool m_visible { true };
|
||||
bool m_hovered { false };
|
||||
};
|
||||
|
||||
}
|
|
@ -27,26 +27,28 @@
|
|||
#include <AK/SharedBuffer.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/SystemTheme.h>
|
||||
#include <WindowServer/WSClientConnection.h>
|
||||
#include <WindowServer/WSClipboard.h>
|
||||
#include <WindowServer/WSCompositor.h>
|
||||
#include <WindowServer/WSEventLoop.h>
|
||||
#include <WindowServer/WSMenu.h>
|
||||
#include <WindowServer/WSMenuBar.h>
|
||||
#include <WindowServer/WSMenuItem.h>
|
||||
#include <WindowServer/WSScreen.h>
|
||||
#include <WindowServer/WSWindow.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/WSWindowSwitcher.h>
|
||||
#include <WindowServer/ClientConnection.h>
|
||||
#include <WindowServer/Clipboard.h>
|
||||
#include <WindowServer/Compositor.h>
|
||||
#include <WindowServer/EventLoop.h>
|
||||
#include <WindowServer/Menu.h>
|
||||
#include <WindowServer/MenuBar.h>
|
||||
#include <WindowServer/MenuItem.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/Window.h>
|
||||
#include <WindowServer/WindowClientEndpoint.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
#include <WindowServer/WindowSwitcher.h>
|
||||
#include <errno.h>
|
||||
#include <serenity.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
HashMap<int, NonnullRefPtr<WSClientConnection>>* s_connections;
|
||||
namespace WindowServer {
|
||||
|
||||
void WSClientConnection::for_each_client(Function<void(WSClientConnection&)> callback)
|
||||
HashMap<int, NonnullRefPtr<ClientConnection>>* s_connections;
|
||||
|
||||
void ClientConnection::for_each_client(Function<void(ClientConnection&)> callback)
|
||||
{
|
||||
if (!s_connections)
|
||||
return;
|
||||
|
@ -55,7 +57,7 @@ void WSClientConnection::for_each_client(Function<void(WSClientConnection&)> cal
|
|||
}
|
||||
}
|
||||
|
||||
WSClientConnection* WSClientConnection::from_client_id(int client_id)
|
||||
ClientConnection* ClientConnection::from_client_id(int client_id)
|
||||
{
|
||||
if (!s_connections)
|
||||
return nullptr;
|
||||
|
@ -65,48 +67,48 @@ WSClientConnection* WSClientConnection::from_client_id(int client_id)
|
|||
return (*it).value.ptr();
|
||||
}
|
||||
|
||||
WSClientConnection::WSClientConnection(Core::LocalSocket& client_socket, int client_id)
|
||||
ClientConnection::ClientConnection(Core::LocalSocket& client_socket, int client_id)
|
||||
: IPC::ClientConnection<WindowServerEndpoint>(*this, client_socket, client_id)
|
||||
{
|
||||
if (!s_connections)
|
||||
s_connections = new HashMap<int, NonnullRefPtr<WSClientConnection>>;
|
||||
s_connections = new HashMap<int, NonnullRefPtr<ClientConnection>>;
|
||||
s_connections->set(client_id, *this);
|
||||
}
|
||||
|
||||
WSClientConnection::~WSClientConnection()
|
||||
ClientConnection::~ClientConnection()
|
||||
{
|
||||
WSMenuManager::the().close_all_menus_from_client({}, *this);
|
||||
MenuManager::the().close_all_menus_from_client({}, *this);
|
||||
auto windows = move(m_windows);
|
||||
for (auto& window : windows)
|
||||
window.value->detach_client({});
|
||||
}
|
||||
|
||||
void WSClientConnection::die()
|
||||
void ClientConnection::die()
|
||||
{
|
||||
deferred_invoke([this](auto&) {
|
||||
s_connections->remove(client_id());
|
||||
});
|
||||
}
|
||||
|
||||
void WSClientConnection::notify_about_new_screen_rect(const Gfx::Rect& rect)
|
||||
void ClientConnection::notify_about_new_screen_rect(const Gfx::Rect& rect)
|
||||
{
|
||||
post_message(WindowClient::ScreenRectChanged(rect));
|
||||
}
|
||||
|
||||
void WSClientConnection::notify_about_clipboard_contents_changed()
|
||||
void ClientConnection::notify_about_clipboard_contents_changed()
|
||||
{
|
||||
post_message(WindowClient::ClipboardContentsChanged(WSClipboard::the().data_type()));
|
||||
post_message(WindowClient::ClipboardContentsChanged(Clipboard::the().data_type()));
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::CreateMenubarResponse> WSClientConnection::handle(const WindowServer::CreateMenubar&)
|
||||
OwnPtr<WindowServer::CreateMenubarResponse> ClientConnection::handle(const WindowServer::CreateMenubar&)
|
||||
{
|
||||
int menubar_id = m_next_menubar_id++;
|
||||
auto menubar = make<WSMenuBar>(*this, menubar_id);
|
||||
auto menubar = make<MenuBar>(*this, menubar_id);
|
||||
m_menubars.set(menubar_id, move(menubar));
|
||||
return make<WindowServer::CreateMenubarResponse>(menubar_id);
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::DestroyMenubarResponse> WSClientConnection::handle(const WindowServer::DestroyMenubar& message)
|
||||
OwnPtr<WindowServer::DestroyMenubarResponse> ClientConnection::handle(const WindowServer::DestroyMenubar& message)
|
||||
{
|
||||
int menubar_id = message.menubar_id();
|
||||
auto it = m_menubars.find(menubar_id);
|
||||
|
@ -115,20 +117,20 @@ OwnPtr<WindowServer::DestroyMenubarResponse> WSClientConnection::handle(const Wi
|
|||
return nullptr;
|
||||
}
|
||||
auto& menubar = *(*it).value;
|
||||
WSMenuManager::the().close_menubar(menubar);
|
||||
MenuManager::the().close_menubar(menubar);
|
||||
m_menubars.remove(it);
|
||||
return make<WindowServer::DestroyMenubarResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::CreateMenuResponse> WSClientConnection::handle(const WindowServer::CreateMenu& message)
|
||||
OwnPtr<WindowServer::CreateMenuResponse> ClientConnection::handle(const WindowServer::CreateMenu& message)
|
||||
{
|
||||
int menu_id = m_next_menu_id++;
|
||||
auto menu = WSMenu::construct(this, menu_id, message.menu_title());
|
||||
auto menu = Menu::construct(this, menu_id, message.menu_title());
|
||||
m_menus.set(menu_id, move(menu));
|
||||
return make<WindowServer::CreateMenuResponse>(menu_id);
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::DestroyMenuResponse> WSClientConnection::handle(const WindowServer::DestroyMenu& message)
|
||||
OwnPtr<WindowServer::DestroyMenuResponse> ClientConnection::handle(const WindowServer::DestroyMenu& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
auto it = m_menus.find(menu_id);
|
||||
|
@ -143,7 +145,7 @@ OwnPtr<WindowServer::DestroyMenuResponse> WSClientConnection::handle(const Windo
|
|||
return make<WindowServer::DestroyMenuResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetApplicationMenubarResponse> WSClientConnection::handle(const WindowServer::SetApplicationMenubar& message)
|
||||
OwnPtr<WindowServer::SetApplicationMenubarResponse> ClientConnection::handle(const WindowServer::SetApplicationMenubar& message)
|
||||
{
|
||||
int menubar_id = message.menubar_id();
|
||||
auto it = m_menubars.find(menubar_id);
|
||||
|
@ -153,11 +155,11 @@ OwnPtr<WindowServer::SetApplicationMenubarResponse> WSClientConnection::handle(c
|
|||
}
|
||||
auto& menubar = *(*it).value;
|
||||
m_app_menubar = menubar.make_weak_ptr();
|
||||
WSWindowManager::the().notify_client_changed_app_menubar(*this);
|
||||
WindowManager::the().notify_client_changed_app_menubar(*this);
|
||||
return make<WindowServer::SetApplicationMenubarResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::AddMenuToMenubarResponse> WSClientConnection::handle(const WindowServer::AddMenuToMenubar& message)
|
||||
OwnPtr<WindowServer::AddMenuToMenubarResponse> ClientConnection::handle(const WindowServer::AddMenuToMenubar& message)
|
||||
{
|
||||
int menubar_id = message.menubar_id();
|
||||
int menu_id = message.menu_id();
|
||||
|
@ -177,7 +179,7 @@ OwnPtr<WindowServer::AddMenuToMenubarResponse> WSClientConnection::handle(const
|
|||
return make<WindowServer::AddMenuToMenubarResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::AddMenuItemResponse> WSClientConnection::handle(const WindowServer::AddMenuItem& message)
|
||||
OwnPtr<WindowServer::AddMenuItemResponse> ClientConnection::handle(const WindowServer::AddMenuItem& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
unsigned identifier = message.identifier();
|
||||
|
@ -187,7 +189,7 @@ OwnPtr<WindowServer::AddMenuItemResponse> WSClientConnection::handle(const Windo
|
|||
return nullptr;
|
||||
}
|
||||
auto& menu = *(*it).value;
|
||||
auto menu_item = make<WSMenuItem>(menu, identifier, message.text(), message.shortcut(), message.enabled(), message.checkable(), message.checked());
|
||||
auto menu_item = make<MenuItem>(menu, identifier, message.text(), message.shortcut(), message.enabled(), message.checkable(), message.checked());
|
||||
if (message.icon_buffer_id() != -1) {
|
||||
auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(message.icon_buffer_id());
|
||||
if (!icon_buffer)
|
||||
|
@ -202,7 +204,7 @@ OwnPtr<WindowServer::AddMenuItemResponse> WSClientConnection::handle(const Windo
|
|||
return make<WindowServer::AddMenuItemResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::PopupMenuResponse> WSClientConnection::handle(const WindowServer::PopupMenu& message)
|
||||
OwnPtr<WindowServer::PopupMenuResponse> ClientConnection::handle(const WindowServer::PopupMenu& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
auto position = message.screen_position();
|
||||
|
@ -216,7 +218,7 @@ OwnPtr<WindowServer::PopupMenuResponse> WSClientConnection::handle(const WindowS
|
|||
return make<WindowServer::PopupMenuResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::DismissMenuResponse> WSClientConnection::handle(const WindowServer::DismissMenu& message)
|
||||
OwnPtr<WindowServer::DismissMenuResponse> ClientConnection::handle(const WindowServer::DismissMenu& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
auto it = m_menus.find(menu_id);
|
||||
|
@ -229,7 +231,7 @@ OwnPtr<WindowServer::DismissMenuResponse> WSClientConnection::handle(const Windo
|
|||
return make<WindowServer::DismissMenuResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::UpdateMenuItemResponse> WSClientConnection::handle(const WindowServer::UpdateMenuItem& message)
|
||||
OwnPtr<WindowServer::UpdateMenuItemResponse> ClientConnection::handle(const WindowServer::UpdateMenuItem& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
auto it = m_menus.find(menu_id);
|
||||
|
@ -252,7 +254,7 @@ OwnPtr<WindowServer::UpdateMenuItemResponse> WSClientConnection::handle(const Wi
|
|||
return make<WindowServer::UpdateMenuItemResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::AddMenuSeparatorResponse> WSClientConnection::handle(const WindowServer::AddMenuSeparator& message)
|
||||
OwnPtr<WindowServer::AddMenuSeparatorResponse> ClientConnection::handle(const WindowServer::AddMenuSeparator& message)
|
||||
{
|
||||
int menu_id = message.menu_id();
|
||||
auto it = m_menus.find(menu_id);
|
||||
|
@ -261,22 +263,22 @@ OwnPtr<WindowServer::AddMenuSeparatorResponse> WSClientConnection::handle(const
|
|||
return nullptr;
|
||||
}
|
||||
auto& menu = *(*it).value;
|
||||
menu.add_item(make<WSMenuItem>(menu, WSMenuItem::Separator));
|
||||
menu.add_item(make<MenuItem>(menu, MenuItem::Separator));
|
||||
return make<WindowServer::AddMenuSeparatorResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::MoveWindowToFrontResponse> WSClientConnection::handle(const WindowServer::MoveWindowToFront& message)
|
||||
OwnPtr<WindowServer::MoveWindowToFrontResponse> ClientConnection::handle(const WindowServer::MoveWindowToFront& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
did_misbehave("MoveWindowToFront: Bad window ID");
|
||||
return nullptr;
|
||||
}
|
||||
WSWindowManager::the().move_to_front_and_make_active(*(*it).value);
|
||||
WindowManager::the().move_to_front_and_make_active(*(*it).value);
|
||||
return make<WindowServer::MoveWindowToFrontResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetFullscreenResponse> WSClientConnection::handle(const WindowServer::SetFullscreen& message)
|
||||
OwnPtr<WindowServer::SetFullscreenResponse> ClientConnection::handle(const WindowServer::SetFullscreen& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -287,7 +289,7 @@ OwnPtr<WindowServer::SetFullscreenResponse> WSClientConnection::handle(const Win
|
|||
return make<WindowServer::SetFullscreenResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowOpacityResponse> WSClientConnection::handle(const WindowServer::SetWindowOpacity& message)
|
||||
OwnPtr<WindowServer::SetWindowOpacityResponse> ClientConnection::handle(const WindowServer::SetWindowOpacity& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -298,25 +300,25 @@ OwnPtr<WindowServer::SetWindowOpacityResponse> WSClientConnection::handle(const
|
|||
return make<WindowServer::SetWindowOpacityResponse>();
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::AsyncSetWallpaper& message)
|
||||
void ClientConnection::handle(const WindowServer::AsyncSetWallpaper& message)
|
||||
{
|
||||
WSCompositor::the().set_wallpaper(message.path(), [&](bool success) {
|
||||
Compositor::the().set_wallpaper(message.path(), [&](bool success) {
|
||||
post_message(WindowClient::AsyncSetWallpaperFinished(success));
|
||||
});
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::GetWallpaperResponse> WSClientConnection::handle(const WindowServer::GetWallpaper&)
|
||||
OwnPtr<WindowServer::GetWallpaperResponse> ClientConnection::handle(const WindowServer::GetWallpaper&)
|
||||
{
|
||||
return make<WindowServer::GetWallpaperResponse>(WSCompositor::the().wallpaper_path());
|
||||
return make<WindowServer::GetWallpaperResponse>(Compositor::the().wallpaper_path());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetResolutionResponse> WSClientConnection::handle(const WindowServer::SetResolution& message)
|
||||
OwnPtr<WindowServer::SetResolutionResponse> ClientConnection::handle(const WindowServer::SetResolution& message)
|
||||
{
|
||||
WSWindowManager::the().set_resolution(message.resolution().width(), message.resolution().height());
|
||||
WindowManager::the().set_resolution(message.resolution().width(), message.resolution().height());
|
||||
return make<WindowServer::SetResolutionResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowTitleResponse> WSClientConnection::handle(const WindowServer::SetWindowTitle& message)
|
||||
OwnPtr<WindowServer::SetWindowTitleResponse> ClientConnection::handle(const WindowServer::SetWindowTitle& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -327,7 +329,7 @@ OwnPtr<WindowServer::SetWindowTitleResponse> WSClientConnection::handle(const Wi
|
|||
return make<WindowServer::SetWindowTitleResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::GetWindowTitleResponse> WSClientConnection::handle(const WindowServer::GetWindowTitle& message)
|
||||
OwnPtr<WindowServer::GetWindowTitleResponse> ClientConnection::handle(const WindowServer::GetWindowTitle& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -337,7 +339,7 @@ OwnPtr<WindowServer::GetWindowTitleResponse> WSClientConnection::handle(const Wi
|
|||
return make<WindowServer::GetWindowTitleResponse>(it->value->title());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowIconBitmapResponse> WSClientConnection::handle(const WindowServer::SetWindowIconBitmap& message)
|
||||
OwnPtr<WindowServer::SetWindowIconBitmapResponse> ClientConnection::handle(const WindowServer::SetWindowIconBitmap& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -355,11 +357,11 @@ OwnPtr<WindowServer::SetWindowIconBitmapResponse> WSClientConnection::handle(con
|
|||
}
|
||||
|
||||
window.frame().invalidate_title_bar();
|
||||
WSWindowManager::the().tell_wm_listeners_window_icon_changed(window);
|
||||
WindowManager::the().tell_wm_listeners_window_icon_changed(window);
|
||||
return make<WindowServer::SetWindowIconBitmapResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowRectResponse> WSClientConnection::handle(const WindowServer::SetWindowRect& message)
|
||||
OwnPtr<WindowServer::SetWindowRectResponse> ClientConnection::handle(const WindowServer::SetWindowRect& message)
|
||||
{
|
||||
int window_id = message.window_id();
|
||||
auto it = m_windows.find(window_id);
|
||||
|
@ -369,7 +371,7 @@ OwnPtr<WindowServer::SetWindowRectResponse> WSClientConnection::handle(const Win
|
|||
}
|
||||
auto& window = *(*it).value;
|
||||
if (window.is_fullscreen()) {
|
||||
dbg() << "WSClientConnection: Ignoring SetWindowRect request for fullscreen window";
|
||||
dbg() << "ClientConnection: Ignoring SetWindowRect request for fullscreen window";
|
||||
return nullptr;
|
||||
}
|
||||
window.set_rect(message.rect());
|
||||
|
@ -377,7 +379,7 @@ OwnPtr<WindowServer::SetWindowRectResponse> WSClientConnection::handle(const Win
|
|||
return make<WindowServer::SetWindowRectResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::GetWindowRectResponse> WSClientConnection::handle(const WindowServer::GetWindowRect& message)
|
||||
OwnPtr<WindowServer::GetWindowRectResponse> ClientConnection::handle(const WindowServer::GetWindowRect& message)
|
||||
{
|
||||
int window_id = message.window_id();
|
||||
auto it = m_windows.find(window_id);
|
||||
|
@ -388,20 +390,20 @@ OwnPtr<WindowServer::GetWindowRectResponse> WSClientConnection::handle(const Win
|
|||
return make<WindowServer::GetWindowRectResponse>(it->value->rect());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetClipboardContentsResponse> WSClientConnection::handle(const WindowServer::SetClipboardContents& message)
|
||||
OwnPtr<WindowServer::SetClipboardContentsResponse> ClientConnection::handle(const WindowServer::SetClipboardContents& message)
|
||||
{
|
||||
auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(message.shared_buffer_id());
|
||||
if (!shared_buffer) {
|
||||
did_misbehave("SetClipboardContents: Bad shared buffer ID");
|
||||
return nullptr;
|
||||
}
|
||||
WSClipboard::the().set_data(*shared_buffer, message.content_size(), message.content_type());
|
||||
Clipboard::the().set_data(*shared_buffer, message.content_size(), message.content_type());
|
||||
return make<WindowServer::SetClipboardContentsResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::GetClipboardContentsResponse> WSClientConnection::handle(const WindowServer::GetClipboardContents&)
|
||||
OwnPtr<WindowServer::GetClipboardContentsResponse> ClientConnection::handle(const WindowServer::GetClipboardContents&)
|
||||
{
|
||||
auto& clipboard = WSClipboard::the();
|
||||
auto& clipboard = Clipboard::the();
|
||||
|
||||
i32 shared_buffer_id = -1;
|
||||
if (clipboard.size()) {
|
||||
|
@ -422,10 +424,10 @@ OwnPtr<WindowServer::GetClipboardContentsResponse> WSClientConnection::handle(co
|
|||
return make<WindowServer::GetClipboardContentsResponse>(shared_buffer_id, clipboard.size(), clipboard.data_type());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::CreateWindowResponse> WSClientConnection::handle(const WindowServer::CreateWindow& message)
|
||||
OwnPtr<WindowServer::CreateWindowResponse> ClientConnection::handle(const WindowServer::CreateWindow& message)
|
||||
{
|
||||
int window_id = m_next_window_id++;
|
||||
auto window = WSWindow::construct(*this, (WSWindowType)message.type(), window_id, message.modal(), message.minimizable(), message.resizable(), message.fullscreen());
|
||||
auto window = Window::construct(*this, (WindowType)message.type(), window_id, message.modal(), message.minimizable(), message.resizable(), message.fullscreen());
|
||||
window->set_has_alpha_channel(message.has_alpha_channel());
|
||||
window->set_title(message.title());
|
||||
if (!message.fullscreen())
|
||||
|
@ -435,13 +437,13 @@ OwnPtr<WindowServer::CreateWindowResponse> WSClientConnection::handle(const Wind
|
|||
window->set_size_increment(message.size_increment());
|
||||
window->set_base_size(message.base_size());
|
||||
window->invalidate();
|
||||
if (window->type() == WSWindowType::MenuApplet)
|
||||
WSMenuManager::the().add_applet(*window);
|
||||
if (window->type() == WindowType::MenuApplet)
|
||||
MenuManager::the().add_applet(*window);
|
||||
m_windows.set(window_id, move(window));
|
||||
return make<WindowServer::CreateWindowResponse>(window_id);
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::DestroyWindowResponse> WSClientConnection::handle(const WindowServer::DestroyWindow& message)
|
||||
OwnPtr<WindowServer::DestroyWindowResponse> ClientConnection::handle(const WindowServer::DestroyWindow& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -450,10 +452,10 @@ OwnPtr<WindowServer::DestroyWindowResponse> WSClientConnection::handle(const Win
|
|||
}
|
||||
auto& window = *(*it).value;
|
||||
|
||||
if (window.type() == WSWindowType::MenuApplet)
|
||||
WSMenuManager::the().remove_applet(window);
|
||||
if (window.type() == WindowType::MenuApplet)
|
||||
MenuManager::the().remove_applet(window);
|
||||
|
||||
WSWindowManager::the().invalidate(window);
|
||||
WindowManager::the().invalidate(window);
|
||||
remove_child(window);
|
||||
ASSERT(it->value.ptr() == &window);
|
||||
m_windows.remove(message.window_id());
|
||||
|
@ -461,7 +463,7 @@ OwnPtr<WindowServer::DestroyWindowResponse> WSClientConnection::handle(const Win
|
|||
return make<WindowServer::DestroyWindowResponse>();
|
||||
}
|
||||
|
||||
void WSClientConnection::post_paint_message(WSWindow& window)
|
||||
void ClientConnection::post_paint_message(Window& window)
|
||||
{
|
||||
auto rect_set = window.take_pending_paint_rects();
|
||||
if (window.is_minimized() || window.is_occluded())
|
||||
|
@ -470,7 +472,7 @@ void WSClientConnection::post_paint_message(WSWindow& window)
|
|||
post_message(WindowClient::Paint(window.window_id(), window.size(), rect_set.rects()));
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::InvalidateRect& message)
|
||||
void ClientConnection::handle(const WindowServer::InvalidateRect& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -482,7 +484,7 @@ void WSClientConnection::handle(const WindowServer::InvalidateRect& message)
|
|||
window.request_update(message.rects()[i].intersected({ {}, window.size() }));
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::DidFinishPainting& message)
|
||||
void ClientConnection::handle(const WindowServer::DidFinishPainting& message)
|
||||
{
|
||||
int window_id = message.window_id();
|
||||
auto it = m_windows.find(window_id);
|
||||
|
@ -492,12 +494,12 @@ void WSClientConnection::handle(const WindowServer::DidFinishPainting& message)
|
|||
}
|
||||
auto& window = *(*it).value;
|
||||
for (auto& rect : message.rects())
|
||||
WSWindowManager::the().invalidate(window, rect);
|
||||
WindowManager::the().invalidate(window, rect);
|
||||
|
||||
WSWindowSwitcher::the().refresh_if_needed();
|
||||
WindowSwitcher::the().refresh_if_needed();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowBackingStoreResponse> WSClientConnection::handle(const WindowServer::SetWindowBackingStore& message)
|
||||
OwnPtr<WindowServer::SetWindowBackingStoreResponse> ClientConnection::handle(const WindowServer::SetWindowBackingStore& message)
|
||||
{
|
||||
int window_id = message.window_id();
|
||||
auto it = m_windows.find(window_id);
|
||||
|
@ -525,7 +527,7 @@ OwnPtr<WindowServer::SetWindowBackingStoreResponse> WSClientConnection::handle(c
|
|||
return make<WindowServer::SetWindowBackingStoreResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetGlobalCursorTrackingResponse> WSClientConnection::handle(const WindowServer::SetGlobalCursorTracking& message)
|
||||
OwnPtr<WindowServer::SetGlobalCursorTrackingResponse> ClientConnection::handle(const WindowServer::SetGlobalCursorTracking& message)
|
||||
{
|
||||
int window_id = message.window_id();
|
||||
auto it = m_windows.find(window_id);
|
||||
|
@ -537,7 +539,7 @@ OwnPtr<WindowServer::SetGlobalCursorTrackingResponse> WSClientConnection::handle
|
|||
return make<WindowServer::SetGlobalCursorTrackingResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowOverrideCursorResponse> WSClientConnection::handle(const WindowServer::SetWindowOverrideCursor& message)
|
||||
OwnPtr<WindowServer::SetWindowOverrideCursorResponse> ClientConnection::handle(const WindowServer::SetWindowOverrideCursor& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -545,11 +547,11 @@ OwnPtr<WindowServer::SetWindowOverrideCursorResponse> WSClientConnection::handle
|
|||
return nullptr;
|
||||
}
|
||||
auto& window = *(*it).value;
|
||||
window.set_override_cursor(WSCursor::create((WSStandardCursor)message.cursor_type()));
|
||||
window.set_override_cursor(Cursor::create((StandardCursor)message.cursor_type()));
|
||||
return make<WindowServer::SetWindowOverrideCursorResponse>();
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::SetWindowHasAlphaChannelResponse> WSClientConnection::handle(const WindowServer::SetWindowHasAlphaChannel& message)
|
||||
OwnPtr<WindowServer::SetWindowHasAlphaChannelResponse> ClientConnection::handle(const WindowServer::SetWindowHasAlphaChannel& message)
|
||||
{
|
||||
auto it = m_windows.find(message.window_id());
|
||||
if (it == m_windows.end()) {
|
||||
|
@ -560,9 +562,9 @@ OwnPtr<WindowServer::SetWindowHasAlphaChannelResponse> WSClientConnection::handl
|
|||
return make<WindowServer::SetWindowHasAlphaChannelResponse>();
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::WM_SetActiveWindow& message)
|
||||
void ClientConnection::handle(const WindowServer::WM_SetActiveWindow& message)
|
||||
{
|
||||
auto* client = WSClientConnection::from_client_id(message.client_id());
|
||||
auto* client = ClientConnection::from_client_id(message.client_id());
|
||||
if (!client) {
|
||||
did_misbehave("WM_SetActiveWindow: Bad client ID");
|
||||
return;
|
||||
|
@ -574,12 +576,12 @@ void WSClientConnection::handle(const WindowServer::WM_SetActiveWindow& message)
|
|||
}
|
||||
auto& window = *(*it).value;
|
||||
window.set_minimized(false);
|
||||
WSWindowManager::the().move_to_front_and_make_active(window);
|
||||
WindowManager::the().move_to_front_and_make_active(window);
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::WM_PopupWindowMenu& message)
|
||||
void ClientConnection::handle(const WindowServer::WM_PopupWindowMenu& message)
|
||||
{
|
||||
auto* client = WSClientConnection::from_client_id(message.client_id());
|
||||
auto* client = ClientConnection::from_client_id(message.client_id());
|
||||
if (!client) {
|
||||
did_misbehave("WM_PopupWindowMenu: Bad client ID");
|
||||
return;
|
||||
|
@ -593,9 +595,9 @@ void WSClientConnection::handle(const WindowServer::WM_PopupWindowMenu& message)
|
|||
window.popup_window_menu(message.screen_position());
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::WM_StartWindowResize& request)
|
||||
void ClientConnection::handle(const WindowServer::WM_StartWindowResize& request)
|
||||
{
|
||||
auto* client = WSClientConnection::from_client_id(request.client_id());
|
||||
auto* client = ClientConnection::from_client_id(request.client_id());
|
||||
if (!client) {
|
||||
did_misbehave("WM_StartWindowResize: Bad client ID");
|
||||
return;
|
||||
|
@ -608,12 +610,12 @@ void WSClientConnection::handle(const WindowServer::WM_StartWindowResize& reques
|
|||
auto& window = *(*it).value;
|
||||
// FIXME: We are cheating a bit here by using the current cursor location and hard-coding the left button.
|
||||
// Maybe the client should be allowed to specify what initiated this request?
|
||||
WSWindowManager::the().start_window_resize(window, WSScreen::the().cursor_location(), MouseButton::Left);
|
||||
WindowManager::the().start_window_resize(window, Screen::the().cursor_location(), MouseButton::Left);
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::WM_SetWindowMinimized& message)
|
||||
void ClientConnection::handle(const WindowServer::WM_SetWindowMinimized& message)
|
||||
{
|
||||
auto* client = WSClientConnection::from_client_id(message.client_id());
|
||||
auto* client = ClientConnection::from_client_id(message.client_id());
|
||||
if (!client) {
|
||||
did_misbehave("WM_SetWindowMinimized: Bad client ID");
|
||||
return;
|
||||
|
@ -627,12 +629,12 @@ void WSClientConnection::handle(const WindowServer::WM_SetWindowMinimized& messa
|
|||
window.set_minimized(message.minimized());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::GreetResponse> WSClientConnection::handle(const WindowServer::Greet&)
|
||||
OwnPtr<WindowServer::GreetResponse> ClientConnection::handle(const WindowServer::Greet&)
|
||||
{
|
||||
return make<WindowServer::GreetResponse>(client_id(), WSScreen::the().rect(), Gfx::current_system_theme_buffer_id());
|
||||
return make<WindowServer::GreetResponse>(client_id(), Screen::the().rect(), Gfx::current_system_theme_buffer_id());
|
||||
}
|
||||
|
||||
bool WSClientConnection::is_showing_modal_window() const
|
||||
bool ClientConnection::is_showing_modal_window() const
|
||||
{
|
||||
for (auto& it : m_windows) {
|
||||
auto& window = *it.value;
|
||||
|
@ -642,9 +644,9 @@ bool WSClientConnection::is_showing_modal_window() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void WSClientConnection::handle(const WindowServer::WM_SetWindowTaskbarRect& message)
|
||||
void ClientConnection::handle(const WindowServer::WM_SetWindowTaskbarRect& message)
|
||||
{
|
||||
auto* client = WSClientConnection::from_client_id(message.client_id());
|
||||
auto* client = ClientConnection::from_client_id(message.client_id());
|
||||
if (!client) {
|
||||
did_misbehave("WM_SetWindowTaskbarRect: Bad client ID");
|
||||
return;
|
||||
|
@ -658,9 +660,9 @@ void WSClientConnection::handle(const WindowServer::WM_SetWindowTaskbarRect& mes
|
|||
window.set_taskbar_rect(message.rect());
|
||||
}
|
||||
|
||||
OwnPtr<WindowServer::StartDragResponse> WSClientConnection::handle(const WindowServer::StartDrag& message)
|
||||
OwnPtr<WindowServer::StartDragResponse> ClientConnection::handle(const WindowServer::StartDrag& message)
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
if (wm.dnd_client())
|
||||
return make<WindowServer::StartDragResponse>(false);
|
||||
|
||||
|
@ -679,14 +681,16 @@ OwnPtr<WindowServer::StartDragResponse> WSClientConnection::handle(const WindowS
|
|||
return make<WindowServer::StartDragResponse>(true);
|
||||
}
|
||||
|
||||
void WSClientConnection::boost()
|
||||
void ClientConnection::boost()
|
||||
{
|
||||
if (set_process_boost(client_pid(), 10) < 0)
|
||||
perror("boost: set_process_boost");
|
||||
}
|
||||
|
||||
void WSClientConnection::deboost()
|
||||
void ClientConnection::deboost()
|
||||
{
|
||||
if (set_process_boost(client_pid(), 0) < 0)
|
||||
perror("deboost: set_process_boost");
|
||||
}
|
||||
|
||||
}
|
|
@ -33,45 +33,47 @@
|
|||
#include <LibCore/Object.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibIPC/ClientConnection.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/WindowServerEndpoint.h>
|
||||
|
||||
class WSWindow;
|
||||
class WSMenu;
|
||||
class WSMenuBar;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSClientConnection final
|
||||
class Window;
|
||||
class Menu;
|
||||
class MenuBar;
|
||||
|
||||
class ClientConnection final
|
||||
: public IPC::ClientConnection<WindowServerEndpoint>
|
||||
, public WindowServerEndpoint {
|
||||
C_OBJECT(WSClientConnection)
|
||||
C_OBJECT(ClientConnection)
|
||||
public:
|
||||
~WSClientConnection() override;
|
||||
~ClientConnection() override;
|
||||
virtual void die() override;
|
||||
|
||||
void boost();
|
||||
void deboost();
|
||||
|
||||
static WSClientConnection* from_client_id(int client_id);
|
||||
static void for_each_client(Function<void(WSClientConnection&)>);
|
||||
static ClientConnection* from_client_id(int client_id);
|
||||
static void for_each_client(Function<void(ClientConnection&)>);
|
||||
|
||||
WSMenuBar* app_menubar() { return m_app_menubar.ptr(); }
|
||||
MenuBar* app_menubar() { return m_app_menubar.ptr(); }
|
||||
|
||||
bool is_showing_modal_window() const;
|
||||
|
||||
void notify_about_new_screen_rect(const Gfx::Rect&);
|
||||
void notify_about_clipboard_contents_changed();
|
||||
void post_paint_message(WSWindow&);
|
||||
void post_paint_message(Window&);
|
||||
|
||||
WSMenu* find_menu_by_id(int menu_id)
|
||||
Menu* find_menu_by_id(int menu_id)
|
||||
{
|
||||
auto menu = m_menus.get(menu_id);
|
||||
if (!menu.has_value())
|
||||
return nullptr;
|
||||
return const_cast<WSMenu*>(menu.value().ptr());
|
||||
return const_cast<Menu*>(menu.value().ptr());
|
||||
}
|
||||
|
||||
private:
|
||||
explicit WSClientConnection(Core::LocalSocket&, int client_id);
|
||||
explicit ClientConnection(Core::LocalSocket&, int client_id);
|
||||
|
||||
virtual OwnPtr<WindowServer::GreetResponse> handle(const WindowServer::Greet&) override;
|
||||
virtual OwnPtr<WindowServer::CreateMenubarResponse> handle(const WindowServer::CreateMenubar&) override;
|
||||
|
@ -113,10 +115,10 @@ private:
|
|||
virtual void handle(const WindowServer::WM_SetWindowTaskbarRect&) override;
|
||||
virtual OwnPtr<WindowServer::StartDragResponse> handle(const WindowServer::StartDrag&) override;
|
||||
|
||||
HashMap<int, NonnullRefPtr<WSWindow>> m_windows;
|
||||
HashMap<int, NonnullOwnPtr<WSMenuBar>> m_menubars;
|
||||
HashMap<int, NonnullRefPtr<WSMenu>> m_menus;
|
||||
WeakPtr<WSMenuBar> m_app_menubar;
|
||||
HashMap<int, NonnullRefPtr<Window>> m_windows;
|
||||
HashMap<int, NonnullOwnPtr<MenuBar>> m_menubars;
|
||||
HashMap<int, NonnullRefPtr<Menu>> m_menus;
|
||||
WeakPtr<MenuBar> m_app_menubar;
|
||||
|
||||
int m_next_menubar_id { 10000 };
|
||||
int m_next_menu_id { 20000 };
|
||||
|
@ -124,3 +126,5 @@ private:
|
|||
|
||||
RefPtr<SharedBuffer> m_last_sent_clipboard_content;
|
||||
};
|
||||
|
||||
}
|
|
@ -24,47 +24,49 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <WindowServer/WSClipboard.h>
|
||||
#include <WindowServer/Clipboard.h>
|
||||
|
||||
WSClipboard& WSClipboard::the()
|
||||
namespace WindowServer {
|
||||
|
||||
Clipboard& Clipboard::the()
|
||||
{
|
||||
static WSClipboard* s_the;
|
||||
static Clipboard* s_the;
|
||||
if (!s_the)
|
||||
s_the = new WSClipboard;
|
||||
s_the = new Clipboard;
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WSClipboard::WSClipboard()
|
||||
Clipboard::Clipboard()
|
||||
{
|
||||
}
|
||||
|
||||
WSClipboard::~WSClipboard()
|
||||
Clipboard::~Clipboard()
|
||||
{
|
||||
}
|
||||
|
||||
const u8* WSClipboard::data() const
|
||||
const u8* Clipboard::data() const
|
||||
{
|
||||
if (!m_shared_buffer)
|
||||
return nullptr;
|
||||
return (const u8*)m_shared_buffer->data();
|
||||
}
|
||||
|
||||
int WSClipboard::size() const
|
||||
int Clipboard::size() const
|
||||
{
|
||||
if (!m_shared_buffer)
|
||||
return 0;
|
||||
return m_contents_size;
|
||||
}
|
||||
|
||||
void WSClipboard::clear()
|
||||
void Clipboard::clear()
|
||||
{
|
||||
m_shared_buffer = nullptr;
|
||||
m_contents_size = 0;
|
||||
}
|
||||
|
||||
void WSClipboard::set_data(NonnullRefPtr<SharedBuffer>&& data, int contents_size, const String& data_type)
|
||||
void Clipboard::set_data(NonnullRefPtr<SharedBuffer>&& data, int contents_size, const String& data_type)
|
||||
{
|
||||
dbg() << "WSClipboard::set_data <- [" << data_type << "] " << data->data() << " (" << contents_size << " bytes)";
|
||||
dbg() << "Clipboard::set_data <- [" << data_type << "] " << data->data() << " (" << contents_size << " bytes)";
|
||||
m_shared_buffer = move(data);
|
||||
m_contents_size = contents_size;
|
||||
m_data_type = data_type;
|
||||
|
@ -72,3 +74,5 @@ void WSClipboard::set_data(NonnullRefPtr<SharedBuffer>&& data, int contents_size
|
|||
if (on_content_change)
|
||||
on_content_change();
|
||||
}
|
||||
|
||||
}
|
|
@ -30,10 +30,12 @@
|
|||
#include <AK/SharedBuffer.h>
|
||||
#include <AK/String.h>
|
||||
|
||||
class WSClipboard {
|
||||
namespace WindowServer {
|
||||
|
||||
class Clipboard {
|
||||
public:
|
||||
static WSClipboard& the();
|
||||
~WSClipboard();
|
||||
static Clipboard& the();
|
||||
~Clipboard();
|
||||
|
||||
bool has_data() const
|
||||
{
|
||||
|
@ -50,9 +52,11 @@ public:
|
|||
Function<void()> on_content_change;
|
||||
|
||||
private:
|
||||
WSClipboard();
|
||||
Clipboard();
|
||||
|
||||
String m_data_type;
|
||||
RefPtr<SharedBuffer> m_shared_buffer;
|
||||
int m_contents_size { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -24,21 +24,23 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSCompositor.h"
|
||||
#include "WSEvent.h"
|
||||
#include "WSEventLoop.h"
|
||||
#include "WSScreen.h"
|
||||
#include "WSWindow.h"
|
||||
#include "WSWindowManager.h"
|
||||
#include "Compositor.h"
|
||||
#include "Event.h"
|
||||
#include "EventLoop.h"
|
||||
#include "Screen.h"
|
||||
#include "Window.h"
|
||||
#include "WindowManager.h"
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <LibThread/BackgroundAction.h>
|
||||
|
||||
// #define COMPOSITOR_DEBUG
|
||||
|
||||
WSCompositor& WSCompositor::the()
|
||||
namespace WindowServer {
|
||||
|
||||
Compositor& Compositor::the()
|
||||
{
|
||||
static WSCompositor s_the;
|
||||
static Compositor s_the;
|
||||
return s_the;
|
||||
}
|
||||
|
||||
|
@ -55,18 +57,18 @@ WallpaperMode mode_to_enum(const String& name)
|
|||
return WallpaperMode::Simple;
|
||||
}
|
||||
|
||||
WSCompositor::WSCompositor()
|
||||
Compositor::Compositor()
|
||||
{
|
||||
m_compose_timer = Core::Timer::construct(this);
|
||||
m_immediate_compose_timer = Core::Timer::construct(this);
|
||||
|
||||
m_screen_can_set_buffer = WSScreen::the().can_set_buffer();
|
||||
m_screen_can_set_buffer = Screen::the().can_set_buffer();
|
||||
|
||||
init_bitmaps();
|
||||
|
||||
m_compose_timer->on_timeout = [&]() {
|
||||
#if defined(COMPOSITOR_DEBUG)
|
||||
dbgprintf("WSCompositor: delayed frame callback: %d rects\n", m_dirty_rects.size());
|
||||
dbgprintf("Compositor: delayed frame callback: %d rects\n", m_dirty_rects.size());
|
||||
#endif
|
||||
compose();
|
||||
};
|
||||
|
@ -74,7 +76,7 @@ WSCompositor::WSCompositor()
|
|||
m_compose_timer->set_interval(1000 / 60);
|
||||
m_immediate_compose_timer->on_timeout = [=]() {
|
||||
#if defined(COMPOSITOR_DEBUG)
|
||||
dbgprintf("WSCompositor: immediate frame callback: %d rects\n", m_dirty_rects.size());
|
||||
dbgprintf("Compositor: immediate frame callback: %d rects\n", m_dirty_rects.size());
|
||||
#endif
|
||||
compose();
|
||||
};
|
||||
|
@ -82,9 +84,9 @@ WSCompositor::WSCompositor()
|
|||
m_immediate_compose_timer->set_interval(0);
|
||||
}
|
||||
|
||||
void WSCompositor::init_bitmaps()
|
||||
void Compositor::init_bitmaps()
|
||||
{
|
||||
auto& screen = WSScreen::the();
|
||||
auto& screen = Screen::the();
|
||||
auto size = screen.size();
|
||||
|
||||
m_front_bitmap = Gfx::Bitmap::create_wrapper(Gfx::Bitmap::Format::RGB32, size, screen.pitch(), screen.scanline(0));
|
||||
|
@ -102,12 +104,12 @@ void WSCompositor::init_bitmaps()
|
|||
invalidate();
|
||||
}
|
||||
|
||||
void WSCompositor::compose()
|
||||
void Compositor::compose()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
if (m_wallpaper_mode == WallpaperMode::Unchecked)
|
||||
m_wallpaper_mode = mode_to_enum(wm.wm_config()->read_entry("Background", "Mode", "simple"));
|
||||
auto& ws = WSScreen::the();
|
||||
auto& ws = Screen::the();
|
||||
|
||||
auto dirty_rects = move(m_dirty_rects);
|
||||
|
||||
|
@ -116,15 +118,15 @@ void WSCompositor::compose()
|
|||
return;
|
||||
}
|
||||
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_geometry_label_rect, WSScreen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_cursor_rect, WSScreen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_dnd_rect, WSScreen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(current_cursor_rect(), WSScreen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_geometry_label_rect, Screen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_cursor_rect, Screen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(m_last_dnd_rect, Screen::the().rect()));
|
||||
dirty_rects.add(Gfx::Rect::intersection(current_cursor_rect(), Screen::the().rect()));
|
||||
#ifdef DEBUG_COUNTERS
|
||||
dbgprintf("[WM] compose #%u (%u rects)\n", ++m_compose_count, dirty_rects.rects().size());
|
||||
#endif
|
||||
|
||||
auto any_dirty_rect_intersects_window = [&dirty_rects](const WSWindow& window) {
|
||||
auto any_dirty_rect_intersects_window = [&dirty_rects](const Window& window) {
|
||||
auto window_frame_rect = window.frame().rect();
|
||||
for (auto& dirty_rect : dirty_rects.rects()) {
|
||||
if (dirty_rect.intersects(window_frame_rect))
|
||||
|
@ -160,7 +162,7 @@ void WSCompositor::compose()
|
|||
}
|
||||
}
|
||||
|
||||
auto compose_window = [&](WSWindow& window) -> IterationDecision {
|
||||
auto compose_window = [&](Window& window) -> IterationDecision {
|
||||
if (!any_dirty_rect_intersects_window(window))
|
||||
return IterationDecision::Continue;
|
||||
Gfx::PainterStateSaver saver(*m_back_painter);
|
||||
|
@ -188,7 +190,7 @@ void WSCompositor::compose()
|
|||
// background color.
|
||||
Gfx::Rect backing_rect;
|
||||
backing_rect.set_size(backing_store->size());
|
||||
switch (WSWindowManager::the().resize_direction_of_window(window)) {
|
||||
switch (WindowManager::the().resize_direction_of_window(window)) {
|
||||
case ResizeDirection::None:
|
||||
case ResizeDirection::Right:
|
||||
case ResizeDirection::Down:
|
||||
|
@ -212,9 +214,9 @@ void WSCompositor::compose()
|
|||
}
|
||||
|
||||
Gfx::Rect dirty_rect_in_backing_coordinates = dirty_rect
|
||||
.intersected(window.rect())
|
||||
.intersected(backing_rect)
|
||||
.translated(-backing_rect.location());
|
||||
.intersected(window.rect())
|
||||
.intersected(backing_rect)
|
||||
.translated(-backing_rect.location());
|
||||
|
||||
if (dirty_rect_in_backing_coordinates.is_empty())
|
||||
continue;
|
||||
|
@ -231,7 +233,7 @@ void WSCompositor::compose()
|
|||
if (auto* fullscreen_window = wm.active_fullscreen_window()) {
|
||||
compose_window(*fullscreen_window);
|
||||
} else {
|
||||
wm.for_each_visible_window_from_back_to_front([&](WSWindow& window) {
|
||||
wm.for_each_visible_window_from_back_to_front([&](Window& window) {
|
||||
return compose_window(window);
|
||||
});
|
||||
|
||||
|
@ -254,9 +256,9 @@ void WSCompositor::compose()
|
|||
flush(r);
|
||||
}
|
||||
|
||||
void WSCompositor::flush(const Gfx::Rect& a_rect)
|
||||
void Compositor::flush(const Gfx::Rect& a_rect)
|
||||
{
|
||||
auto rect = Gfx::Rect::intersection(a_rect, WSScreen::the().rect());
|
||||
auto rect = Gfx::Rect::intersection(a_rect, Screen::the().rect());
|
||||
|
||||
#ifdef DEBUG_COUNTERS
|
||||
dbgprintf("[WM] flush #%u (%d,%d %dx%d)\n", ++m_flush_count, rect.x(), rect.y(), rect.width(), rect.height());
|
||||
|
@ -293,15 +295,15 @@ void WSCompositor::flush(const Gfx::Rect& a_rect)
|
|||
}
|
||||
}
|
||||
|
||||
void WSCompositor::invalidate()
|
||||
void Compositor::invalidate()
|
||||
{
|
||||
m_dirty_rects.clear_with_capacity();
|
||||
invalidate(WSScreen::the().rect());
|
||||
invalidate(Screen::the().rect());
|
||||
}
|
||||
|
||||
void WSCompositor::invalidate(const Gfx::Rect& a_rect)
|
||||
void Compositor::invalidate(const Gfx::Rect& a_rect)
|
||||
{
|
||||
auto rect = Gfx::Rect::intersection(a_rect, WSScreen::the().rect());
|
||||
auto rect = Gfx::Rect::intersection(a_rect, Screen::the().rect());
|
||||
if (rect.is_empty())
|
||||
return;
|
||||
|
||||
|
@ -323,7 +325,7 @@ void WSCompositor::invalidate(const Gfx::Rect& a_rect)
|
|||
}
|
||||
}
|
||||
|
||||
bool WSCompositor::set_wallpaper(const String& path, Function<void(bool)>&& callback)
|
||||
bool Compositor::set_wallpaper(const String& path, Function<void(bool)>&& callback)
|
||||
{
|
||||
LibThread::BackgroundAction<RefPtr<Gfx::Bitmap>>::create(
|
||||
[path] {
|
||||
|
@ -343,20 +345,20 @@ bool WSCompositor::set_wallpaper(const String& path, Function<void(bool)>&& call
|
|||
return true;
|
||||
}
|
||||
|
||||
void WSCompositor::flip_buffers()
|
||||
void Compositor::flip_buffers()
|
||||
{
|
||||
ASSERT(m_screen_can_set_buffer);
|
||||
swap(m_front_bitmap, m_back_bitmap);
|
||||
swap(m_front_painter, m_back_painter);
|
||||
WSScreen::the().set_buffer(m_buffers_are_flipped ? 0 : 1);
|
||||
Screen::the().set_buffer(m_buffers_are_flipped ? 0 : 1);
|
||||
m_buffers_are_flipped = !m_buffers_are_flipped;
|
||||
}
|
||||
|
||||
void WSCompositor::run_animations()
|
||||
void Compositor::run_animations()
|
||||
{
|
||||
static const int minimize_animation_steps = 10;
|
||||
|
||||
WSWindowManager::the().for_each_window([&](WSWindow& window) {
|
||||
WindowManager::the().for_each_window([&](Window& window) {
|
||||
if (window.in_minimize_animation()) {
|
||||
int animation_index = window.minimize_animation_index();
|
||||
|
||||
|
@ -391,36 +393,36 @@ void WSCompositor::run_animations()
|
|||
});
|
||||
}
|
||||
|
||||
void WSCompositor::set_resolution(int desired_width, int desired_height)
|
||||
void Compositor::set_resolution(int desired_width, int desired_height)
|
||||
{
|
||||
auto screen_rect = WSScreen::the().rect();
|
||||
auto screen_rect = Screen::the().rect();
|
||||
if (screen_rect.width() == desired_width && screen_rect.height() == desired_height)
|
||||
return;
|
||||
|
||||
// Make sure it's impossible to set an invalid resolution
|
||||
ASSERT(desired_width >= 640 && desired_height >= 480);
|
||||
WSScreen::the().set_resolution(desired_width, desired_height);
|
||||
Screen::the().set_resolution(desired_width, desired_height);
|
||||
init_bitmaps();
|
||||
compose();
|
||||
}
|
||||
|
||||
Gfx::Rect WSCompositor::current_cursor_rect() const
|
||||
Gfx::Rect Compositor::current_cursor_rect() const
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
return { WSScreen::the().cursor_location().translated(-wm.active_cursor().hotspot()), wm.active_cursor().size() };
|
||||
auto& wm = WindowManager::the();
|
||||
return { Screen::the().cursor_location().translated(-wm.active_cursor().hotspot()), wm.active_cursor().size() };
|
||||
}
|
||||
|
||||
void WSCompositor::invalidate_cursor()
|
||||
void Compositor::invalidate_cursor()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
if (wm.dnd_client())
|
||||
invalidate(wm.dnd_rect());
|
||||
invalidate(current_cursor_rect());
|
||||
}
|
||||
|
||||
void WSCompositor::draw_geometry_label()
|
||||
void Compositor::draw_geometry_label()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
auto* window_being_moved_or_resized = wm.m_move_window ? wm.m_move_window.ptr() : (wm.m_resize_window ? wm.m_resize_window.ptr() : nullptr);
|
||||
if (!window_being_moved_or_resized) {
|
||||
m_last_geometry_label_rect = {};
|
||||
|
@ -440,9 +442,9 @@ void WSCompositor::draw_geometry_label()
|
|||
m_last_geometry_label_rect = geometry_label_rect;
|
||||
}
|
||||
|
||||
void WSCompositor::draw_cursor()
|
||||
void Compositor::draw_cursor()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
Gfx::Rect cursor_rect = current_cursor_rect();
|
||||
m_back_painter->blit(cursor_rect.location(), wm.active_cursor().bitmap(), wm.active_cursor().rect());
|
||||
|
||||
|
@ -464,3 +466,5 @@ void WSCompositor::draw_cursor()
|
|||
}
|
||||
m_last_cursor_rect = cursor_rect;
|
||||
}
|
||||
|
||||
}
|
|
@ -30,14 +30,16 @@
|
|||
#include <AK/RefPtr.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibGfx/DisjointRectSet.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/DisjointRectSet.h>
|
||||
|
||||
namespace Gfx {
|
||||
class Painter;
|
||||
}
|
||||
|
||||
class WSCursor;
|
||||
namespace WindowServer {
|
||||
|
||||
class Cursor;
|
||||
|
||||
enum class WallpaperMode {
|
||||
Simple,
|
||||
|
@ -47,10 +49,10 @@ enum class WallpaperMode {
|
|||
Unchecked
|
||||
};
|
||||
|
||||
class WSCompositor final : public Core::Object {
|
||||
C_OBJECT(WSCompositor)
|
||||
class Compositor final : public Core::Object {
|
||||
C_OBJECT(Compositor)
|
||||
public:
|
||||
static WSCompositor& the();
|
||||
static Compositor& the();
|
||||
|
||||
void compose();
|
||||
void invalidate();
|
||||
|
@ -65,7 +67,7 @@ public:
|
|||
Gfx::Rect current_cursor_rect() const;
|
||||
|
||||
private:
|
||||
WSCompositor();
|
||||
Compositor();
|
||||
void init_bitmaps();
|
||||
void flip_buffers();
|
||||
void flush(const Gfx::Rect&);
|
||||
|
@ -97,3 +99,5 @@ private:
|
|||
WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked };
|
||||
RefPtr<Gfx::Bitmap> m_wallpaper;
|
||||
};
|
||||
|
||||
}
|
|
@ -24,50 +24,54 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
WSCursor::WSCursor(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const Gfx::Point& hotspot)
|
||||
namespace WindowServer {
|
||||
|
||||
Cursor::Cursor(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const Gfx::Point& hotspot)
|
||||
: m_bitmap(move(bitmap))
|
||||
, m_hotspot(hotspot)
|
||||
{
|
||||
}
|
||||
|
||||
WSCursor::~WSCursor()
|
||||
Cursor::~Cursor()
|
||||
{
|
||||
}
|
||||
|
||||
NonnullRefPtr<WSCursor> WSCursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap)
|
||||
NonnullRefPtr<Cursor> Cursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap)
|
||||
{
|
||||
return adopt(*new WSCursor(move(bitmap), bitmap->rect().center()));
|
||||
return adopt(*new Cursor(move(bitmap), bitmap->rect().center()));
|
||||
}
|
||||
|
||||
NonnullRefPtr<WSCursor> WSCursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const Gfx::Point& hotspot)
|
||||
NonnullRefPtr<Cursor> Cursor::create(NonnullRefPtr<Gfx::Bitmap>&& bitmap, const Gfx::Point& hotspot)
|
||||
{
|
||||
return adopt(*new WSCursor(move(bitmap), hotspot));
|
||||
return adopt(*new Cursor(move(bitmap), hotspot));
|
||||
}
|
||||
|
||||
RefPtr<WSCursor> WSCursor::create(WSStandardCursor standard_cursor)
|
||||
RefPtr<Cursor> Cursor::create(StandardCursor standard_cursor)
|
||||
{
|
||||
switch (standard_cursor) {
|
||||
case WSStandardCursor::None:
|
||||
case StandardCursor::None:
|
||||
return nullptr;
|
||||
case WSStandardCursor::Arrow:
|
||||
return WSWindowManager::the().arrow_cursor();
|
||||
case WSStandardCursor::IBeam:
|
||||
return WSWindowManager::the().i_beam_cursor();
|
||||
case WSStandardCursor::ResizeHorizontal:
|
||||
return WSWindowManager::the().resize_horizontally_cursor();
|
||||
case WSStandardCursor::ResizeVertical:
|
||||
return WSWindowManager::the().resize_vertically_cursor();
|
||||
case WSStandardCursor::ResizeDiagonalTLBR:
|
||||
return WSWindowManager::the().resize_diagonally_tlbr_cursor();
|
||||
case WSStandardCursor::ResizeDiagonalBLTR:
|
||||
return WSWindowManager::the().resize_diagonally_bltr_cursor();
|
||||
case WSStandardCursor::Hand:
|
||||
return WSWindowManager::the().hand_cursor();
|
||||
case WSStandardCursor::Drag:
|
||||
return WSWindowManager::the().drag_cursor();
|
||||
case StandardCursor::Arrow:
|
||||
return WindowManager::the().arrow_cursor();
|
||||
case StandardCursor::IBeam:
|
||||
return WindowManager::the().i_beam_cursor();
|
||||
case StandardCursor::ResizeHorizontal:
|
||||
return WindowManager::the().resize_horizontally_cursor();
|
||||
case StandardCursor::ResizeVertical:
|
||||
return WindowManager::the().resize_vertically_cursor();
|
||||
case StandardCursor::ResizeDiagonalTLBR:
|
||||
return WindowManager::the().resize_diagonally_tlbr_cursor();
|
||||
case StandardCursor::ResizeDiagonalBLTR:
|
||||
return WindowManager::the().resize_diagonally_bltr_cursor();
|
||||
case StandardCursor::Hand:
|
||||
return WindowManager::the().hand_cursor();
|
||||
case StandardCursor::Drag:
|
||||
return WindowManager::the().drag_cursor();
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
|
@ -28,7 +28,9 @@
|
|||
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
enum class WSStandardCursor {
|
||||
namespace WindowServer {
|
||||
|
||||
enum class StandardCursor {
|
||||
None = 0,
|
||||
Arrow,
|
||||
IBeam,
|
||||
|
@ -40,12 +42,12 @@ enum class WSStandardCursor {
|
|||
Drag,
|
||||
};
|
||||
|
||||
class WSCursor : public RefCounted<WSCursor> {
|
||||
class Cursor : public RefCounted<Cursor> {
|
||||
public:
|
||||
static NonnullRefPtr<WSCursor> create(NonnullRefPtr<Gfx::Bitmap>&&, const Gfx::Point& hotspot);
|
||||
static NonnullRefPtr<WSCursor> create(NonnullRefPtr<Gfx::Bitmap>&&);
|
||||
static RefPtr<WSCursor> create(WSStandardCursor);
|
||||
~WSCursor();
|
||||
static NonnullRefPtr<Cursor> create(NonnullRefPtr<Gfx::Bitmap>&&, const Gfx::Point& hotspot);
|
||||
static NonnullRefPtr<Cursor> create(NonnullRefPtr<Gfx::Bitmap>&&);
|
||||
static RefPtr<Cursor> create(StandardCursor);
|
||||
~Cursor();
|
||||
|
||||
Gfx::Point hotspot() const { return m_hotspot; }
|
||||
const Gfx::Bitmap& bitmap() const { return *m_bitmap; }
|
||||
|
@ -54,8 +56,10 @@ public:
|
|||
Gfx::Size size() const { return m_bitmap->size(); }
|
||||
|
||||
private:
|
||||
WSCursor(NonnullRefPtr<Gfx::Bitmap>&&, const Gfx::Point&);
|
||||
Cursor(NonnullRefPtr<Gfx::Bitmap>&&, const Gfx::Point&);
|
||||
|
||||
RefPtr<Gfx::Bitmap> m_bitmap;
|
||||
Gfx::Point m_hotspot;
|
||||
};
|
||||
|
||||
}
|
|
@ -30,10 +30,12 @@
|
|||
#include <Kernel/KeyCode.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/WSWindowType.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/WindowType.h>
|
||||
|
||||
class WSEvent : public Core::Event {
|
||||
namespace WindowServer {
|
||||
|
||||
class Event : public Core::Event {
|
||||
public:
|
||||
enum Type {
|
||||
Invalid = 3000,
|
||||
|
@ -52,12 +54,12 @@ public:
|
|||
WindowResized,
|
||||
};
|
||||
|
||||
WSEvent() {}
|
||||
explicit WSEvent(Type type)
|
||||
Event() {}
|
||||
explicit Event(Type type)
|
||||
: Core::Event(type)
|
||||
{
|
||||
}
|
||||
virtual ~WSEvent() {}
|
||||
virtual ~Event() {}
|
||||
|
||||
bool is_mouse_event() const { return type() == MouseMove || type() == MouseDown || type() == MouseDoubleClick || type() == MouseUp || type() == MouseWheel; }
|
||||
bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
|
||||
|
@ -70,10 +72,10 @@ enum class MouseButton : u8 {
|
|||
Middle = 4,
|
||||
};
|
||||
|
||||
class WSKeyEvent final : public WSEvent {
|
||||
class KeyEvent final : public Event {
|
||||
public:
|
||||
WSKeyEvent(Type type, int key, char character, u8 modifiers)
|
||||
: WSEvent(type)
|
||||
KeyEvent(Type type, int key, char character, u8 modifiers)
|
||||
: Event(type)
|
||||
, m_key(key)
|
||||
, m_character(character)
|
||||
, m_modifiers(modifiers)
|
||||
|
@ -89,17 +91,17 @@ public:
|
|||
char character() const { return m_character; }
|
||||
|
||||
private:
|
||||
friend class WSEventLoop;
|
||||
friend class WSScreen;
|
||||
friend class EventLoop;
|
||||
friend class Screen;
|
||||
int m_key { 0 };
|
||||
char m_character { 0 };
|
||||
u8 m_modifiers { 0 };
|
||||
};
|
||||
|
||||
class WSMouseEvent final : public WSEvent {
|
||||
class MouseEvent final : public Event {
|
||||
public:
|
||||
WSMouseEvent(Type type, const Gfx::Point& position, unsigned buttons, MouseButton button, unsigned modifiers, int wheel_delta = 0)
|
||||
: WSEvent(type)
|
||||
MouseEvent(Type type, const Gfx::Point& position, unsigned buttons, MouseButton button, unsigned modifiers, int wheel_delta = 0)
|
||||
: Event(type)
|
||||
, m_position(position)
|
||||
, m_buttons(buttons)
|
||||
, m_button(button)
|
||||
|
@ -116,7 +118,7 @@ public:
|
|||
unsigned modifiers() const { return m_modifiers; }
|
||||
int wheel_delta() const { return m_wheel_delta; }
|
||||
|
||||
WSMouseEvent translated(const Gfx::Point& delta) const { return WSMouseEvent((Type)type(), m_position.translated(delta), m_buttons, m_button, m_modifiers, m_wheel_delta); }
|
||||
MouseEvent translated(const Gfx::Point& delta) const { return MouseEvent((Type)type(), m_position.translated(delta), m_buttons, m_button, m_modifiers, m_wheel_delta); }
|
||||
|
||||
private:
|
||||
Gfx::Point m_position;
|
||||
|
@ -126,10 +128,10 @@ private:
|
|||
int m_wheel_delta { 0 };
|
||||
};
|
||||
|
||||
class WSResizeEvent final : public WSEvent {
|
||||
class ResizeEvent final : public Event {
|
||||
public:
|
||||
WSResizeEvent(const Gfx::Rect& old_rect, const Gfx::Rect& rect)
|
||||
: WSEvent(WSEvent::WindowResized)
|
||||
ResizeEvent(const Gfx::Rect& old_rect, const Gfx::Rect& rect)
|
||||
: Event(Event::WindowResized)
|
||||
, m_old_rect(old_rect)
|
||||
, m_rect(rect)
|
||||
{
|
||||
|
@ -142,3 +144,5 @@ private:
|
|||
Gfx::Rect m_old_rect;
|
||||
Gfx::Rect m_rect;
|
||||
};
|
||||
|
||||
}
|
|
@ -24,17 +24,17 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSClipboard.h"
|
||||
#include "Clipboard.h"
|
||||
#include <Kernel/KeyCode.h>
|
||||
#include <Kernel/MousePacket.h>
|
||||
#include <LibCore/LocalSocket.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <WindowServer/WSClientConnection.h>
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/WSEventLoop.h>
|
||||
#include <WindowServer/WSScreen.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/ClientConnection.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/EventLoop.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
@ -46,7 +46,9 @@
|
|||
|
||||
//#define WSMESSAGELOOP_DEBUG
|
||||
|
||||
WSEventLoop::WSEventLoop()
|
||||
namespace WindowServer {
|
||||
|
||||
EventLoop::EventLoop()
|
||||
: m_server(Core::LocalServer::construct())
|
||||
{
|
||||
m_keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
||||
|
@ -63,7 +65,7 @@ WSEventLoop::WSEventLoop()
|
|||
}
|
||||
static int s_next_client_id = 0;
|
||||
int client_id = ++s_next_client_id;
|
||||
IPC::new_client_connection<WSClientConnection>(*client_socket, client_id);
|
||||
IPC::new_client_connection<ClientConnection>(*client_socket, client_id);
|
||||
};
|
||||
|
||||
ASSERT(m_keyboard_fd >= 0);
|
||||
|
@ -75,20 +77,20 @@ WSEventLoop::WSEventLoop()
|
|||
m_mouse_notifier = Core::Notifier::construct(m_mouse_fd, Core::Notifier::Read);
|
||||
m_mouse_notifier->on_ready_to_read = [this] { drain_mouse(); };
|
||||
|
||||
WSClipboard::the().on_content_change = [&] {
|
||||
WSClientConnection::for_each_client([&](auto& client) {
|
||||
Clipboard::the().on_content_change = [&] {
|
||||
ClientConnection::for_each_client([&](auto& client) {
|
||||
client.notify_about_clipboard_contents_changed();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
WSEventLoop::~WSEventLoop()
|
||||
EventLoop::~EventLoop()
|
||||
{
|
||||
}
|
||||
|
||||
void WSEventLoop::drain_mouse()
|
||||
void EventLoop::drain_mouse()
|
||||
{
|
||||
auto& screen = WSScreen::the();
|
||||
auto& screen = Screen::the();
|
||||
MousePacket state;
|
||||
state.buttons = screen.mouse_button_state();
|
||||
unsigned buttons = state.buttons;
|
||||
|
@ -99,7 +101,7 @@ void WSEventLoop::drain_mouse()
|
|||
break;
|
||||
ASSERT(nread == sizeof(packet));
|
||||
#ifdef WSMESSAGELOOP_DEBUG
|
||||
dbgprintf("WSEventLoop: Mouse X %d, Y %d, Z %d, relative %d\n", packet.x, packet.y, packet.z, packet.is_relative);
|
||||
dbgprintf("EventLoop: Mouse X %d, Y %d, Z %d, relative %d\n", packet.x, packet.y, packet.z, packet.is_relative);
|
||||
#endif
|
||||
buttons = packet.buttons;
|
||||
|
||||
|
@ -117,7 +119,7 @@ void WSEventLoop::drain_mouse()
|
|||
if (buttons != state.buttons) {
|
||||
state.buttons = buttons;
|
||||
#ifdef WSMESSAGELOOP_DEBUG
|
||||
dbgprintf("WSEventLoop: Mouse Button Event\n");
|
||||
dbgprintf("EventLoop: Mouse Button Event\n");
|
||||
#endif
|
||||
screen.on_receive_mouse_data(state);
|
||||
if (state.is_relative) {
|
||||
|
@ -133,11 +135,11 @@ void WSEventLoop::drain_mouse()
|
|||
screen.on_receive_mouse_data(state);
|
||||
}
|
||||
|
||||
void WSEventLoop::drain_keyboard()
|
||||
void EventLoop::drain_keyboard()
|
||||
{
|
||||
auto& screen = WSScreen::the();
|
||||
auto& screen = Screen::the();
|
||||
for (;;) {
|
||||
KeyEvent event;
|
||||
::KeyEvent event;
|
||||
ssize_t nread = read(m_keyboard_fd, (u8*)&event, sizeof(KeyEvent));
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
@ -145,3 +147,5 @@ void WSEventLoop::drain_keyboard()
|
|||
screen.on_receive_keyboard_data(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -31,12 +31,14 @@
|
|||
#include <LibCore/LocalServer.h>
|
||||
#include <LibCore/Notifier.h>
|
||||
|
||||
class WSClientConnection;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSEventLoop {
|
||||
class ClientConnection;
|
||||
|
||||
class EventLoop {
|
||||
public:
|
||||
WSEventLoop();
|
||||
virtual ~WSEventLoop();
|
||||
EventLoop();
|
||||
virtual ~EventLoop();
|
||||
|
||||
int exec() { return m_event_loop.exec(); }
|
||||
|
||||
|
@ -51,3 +53,5 @@ private:
|
|||
RefPtr<Core::Notifier> m_mouse_notifier;
|
||||
RefPtr<Core::LocalServer> m_server;
|
||||
};
|
||||
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
OBJS = \
|
||||
WSEventLoop.o \
|
||||
WSWindow.o \
|
||||
WSWindowManager.o \
|
||||
WSScreen.o \
|
||||
WSMenuBar.o \
|
||||
WSMenu.o \
|
||||
WSMenuItem.o \
|
||||
WSClientConnection.o \
|
||||
WSWindowSwitcher.o \
|
||||
WSClipboard.o \
|
||||
WSCursor.o \
|
||||
WSWindowFrame.o \
|
||||
WSButton.o \
|
||||
WSCompositor.o \
|
||||
WSMenuManager.o \
|
||||
Button.o \
|
||||
ClientConnection.o \
|
||||
Clipboard.o \
|
||||
Compositor.o \
|
||||
Cursor.o \
|
||||
EventLoop.o \
|
||||
Menu.o \
|
||||
MenuBar.o \
|
||||
MenuItem.o \
|
||||
MenuManager.o \
|
||||
Screen.o \
|
||||
Window.o \
|
||||
WindowFrame.o \
|
||||
WindowManager.o \
|
||||
WindowSwitcher.o \
|
||||
main.o
|
||||
|
||||
PROGRAM = WindowServer
|
||||
|
|
|
@ -25,24 +25,26 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSMenu.h"
|
||||
#include "WSEvent.h"
|
||||
#include "WSEventLoop.h"
|
||||
#include "WSMenuItem.h"
|
||||
#include "WSMenuManager.h"
|
||||
#include "WSScreen.h"
|
||||
#include "WSWindow.h"
|
||||
#include "WSWindowManager.h"
|
||||
#include "Menu.h"
|
||||
#include "Event.h"
|
||||
#include "EventLoop.h"
|
||||
#include "MenuItem.h"
|
||||
#include "MenuManager.h"
|
||||
#include "Screen.h"
|
||||
#include "Window.h"
|
||||
#include "WindowManager.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/CharacterBitmap.h>
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <LibGfx/Triangle.h>
|
||||
#include <WindowServer/WSClientConnection.h>
|
||||
#include <WindowServer/ClientConnection.h>
|
||||
#include <WindowServer/WindowClientEndpoint.h>
|
||||
|
||||
WSMenu::WSMenu(WSClientConnection* client, int menu_id, const String& name)
|
||||
namespace WindowServer {
|
||||
|
||||
Menu::Menu(ClientConnection* client, int menu_id, const String& name)
|
||||
: Core::Object(client)
|
||||
, m_client(client)
|
||||
, m_menu_id(menu_id)
|
||||
|
@ -50,11 +52,11 @@ WSMenu::WSMenu(WSClientConnection* client, int menu_id, const String& name)
|
|||
{
|
||||
}
|
||||
|
||||
WSMenu::~WSMenu()
|
||||
Menu::~Menu()
|
||||
{
|
||||
}
|
||||
|
||||
const Gfx::Font& WSMenu::font() const
|
||||
const Gfx::Font& Menu::font() const
|
||||
{
|
||||
return Gfx::Font::default_font();
|
||||
}
|
||||
|
@ -91,12 +93,12 @@ static const int s_submenu_arrow_bitmap_height = 9;
|
|||
static const int s_item_icon_width = 16;
|
||||
static const int s_stripe_width = 23;
|
||||
|
||||
int WSMenu::content_width() const
|
||||
int Menu::content_width() const
|
||||
{
|
||||
int widest_text = 0;
|
||||
int widest_shortcut = 0;
|
||||
for (auto& item : m_items) {
|
||||
if (item.type() != WSMenuItem::Text)
|
||||
if (item.type() != MenuItem::Text)
|
||||
continue;
|
||||
int text_width = font().width(item.text());
|
||||
if (!item.shortcut_text().is_empty()) {
|
||||
|
@ -113,7 +115,7 @@ int WSMenu::content_width() const
|
|||
return max(widest_item, rect_in_menubar().width()) + horizontal_padding() + frame_thickness() * 2;
|
||||
}
|
||||
|
||||
void WSMenu::redraw()
|
||||
void Menu::redraw()
|
||||
{
|
||||
if (!menu_window())
|
||||
return;
|
||||
|
@ -121,22 +123,22 @@ void WSMenu::redraw()
|
|||
menu_window()->invalidate();
|
||||
}
|
||||
|
||||
WSWindow& WSMenu::ensure_menu_window()
|
||||
Window& Menu::ensure_menu_window()
|
||||
{
|
||||
int width = this->content_width();
|
||||
if (!m_menu_window) {
|
||||
Gfx::Point next_item_location(frame_thickness(), frame_thickness());
|
||||
for (auto& item : m_items) {
|
||||
int height = 0;
|
||||
if (item.type() == WSMenuItem::Text)
|
||||
if (item.type() == MenuItem::Text)
|
||||
height = item_height();
|
||||
else if (item.type() == WSMenuItem::Separator)
|
||||
else if (item.type() == MenuItem::Separator)
|
||||
height = 8;
|
||||
item.set_rect({ next_item_location, { width - frame_thickness() * 2, height } });
|
||||
next_item_location.move_by(0, height);
|
||||
}
|
||||
|
||||
int window_height_available = WSScreen::the().height() - WSMenuManager::the().menubar_rect().height() - frame_thickness() * 2;
|
||||
int window_height_available = Screen::the().height() - MenuManager::the().menubar_rect().height() - frame_thickness() * 2;
|
||||
int max_window_height = (window_height_available / item_height()) * item_height() + frame_thickness() * 2;
|
||||
int content_height = m_items.is_empty() ? 0 : (m_items.last().rect().bottom() + 1) + frame_thickness();
|
||||
int window_height = min(max_window_height, content_height);
|
||||
|
@ -145,7 +147,7 @@ WSWindow& WSMenu::ensure_menu_window()
|
|||
m_max_scroll_offset = item_count() - window_height / item_height() + 2;
|
||||
}
|
||||
|
||||
auto window = WSWindow::construct(*this, WSWindowType::Menu);
|
||||
auto window = Window::construct(*this, WindowType::Menu);
|
||||
window->set_rect(0, 0, width, window_height);
|
||||
m_menu_window = move(window);
|
||||
draw();
|
||||
|
@ -153,7 +155,7 @@ WSWindow& WSMenu::ensure_menu_window()
|
|||
return *m_menu_window;
|
||||
}
|
||||
|
||||
int WSMenu::visible_item_count() const
|
||||
int Menu::visible_item_count() const
|
||||
{
|
||||
if (!is_scrollable())
|
||||
return m_items.size();
|
||||
|
@ -162,10 +164,10 @@ int WSMenu::visible_item_count() const
|
|||
return m_menu_window->height() / item_height() - 2;
|
||||
}
|
||||
|
||||
void WSMenu::draw()
|
||||
void Menu::draw()
|
||||
{
|
||||
auto palette = WSWindowManager::the().palette();
|
||||
m_theme_index_at_last_paint = WSMenuManager::the().theme_index();
|
||||
auto palette = WindowManager::the().palette();
|
||||
m_theme_index_at_last_paint = MenuManager::the().theme_index();
|
||||
|
||||
ASSERT(menu_window());
|
||||
ASSERT(menu_window()->backing_store());
|
||||
|
@ -203,7 +205,7 @@ void WSMenu::draw()
|
|||
|
||||
for (int i = 0; i < visible_item_count; ++i) {
|
||||
auto& item = m_items.at(m_scroll_offset + i);
|
||||
if (item.type() == WSMenuItem::Text) {
|
||||
if (item.type() == MenuItem::Text) {
|
||||
Color text_color = palette.menu_base_text();
|
||||
if (&item == hovered_item() && item.is_enabled()) {
|
||||
painter.fill_rect(item.rect(), palette.menu_selection());
|
||||
|
@ -248,7 +250,7 @@ void WSMenu::draw()
|
|||
submenu_arrow_rect.center_vertically_within(item.rect());
|
||||
painter.draw_bitmap(submenu_arrow_rect.location(), submenu_arrow_bitmap, text_color);
|
||||
}
|
||||
} else if (item.type() == WSMenuItem::Separator) {
|
||||
} else if (item.type() == MenuItem::Separator) {
|
||||
Gfx::Point p1(item.rect().translated(stripe_rect.width() + 4, 0).x(), item.rect().center().y() - 1);
|
||||
Gfx::Point p2(width - 7, item.rect().center().y() - 1);
|
||||
painter.draw_line(p1, p2, palette.threed_shadow1());
|
||||
|
@ -257,27 +259,27 @@ void WSMenu::draw()
|
|||
}
|
||||
}
|
||||
|
||||
WSMenuItem* WSMenu::hovered_item() const
|
||||
MenuItem* Menu::hovered_item() const
|
||||
{
|
||||
if (m_hovered_item_index == -1)
|
||||
return nullptr;
|
||||
return const_cast<WSMenuItem*>(&item(m_hovered_item_index));
|
||||
return const_cast<MenuItem*>(&item(m_hovered_item_index));
|
||||
}
|
||||
|
||||
void WSMenu::update_for_new_hovered_item()
|
||||
void Menu::update_for_new_hovered_item()
|
||||
{
|
||||
if (hovered_item() && hovered_item()->is_submenu()) {
|
||||
WSMenuManager::the().close_everyone_not_in_lineage(*hovered_item()->submenu());
|
||||
MenuManager::the().close_everyone_not_in_lineage(*hovered_item()->submenu());
|
||||
hovered_item()->submenu()->popup(hovered_item()->rect().top_right().translated(menu_window()->rect().location()), true);
|
||||
} else {
|
||||
WSMenuManager::the().close_everyone_not_in_lineage(*this);
|
||||
WSMenuManager::the().set_current_menu(this);
|
||||
MenuManager::the().close_everyone_not_in_lineage(*this);
|
||||
MenuManager::the().set_current_menu(this);
|
||||
menu_window()->set_visible(true);
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
void WSMenu::open_hovered_item()
|
||||
void Menu::open_hovered_item()
|
||||
{
|
||||
ASSERT(menu_window());
|
||||
ASSERT(menu_window()->is_visible());
|
||||
|
@ -288,18 +290,18 @@ void WSMenu::open_hovered_item()
|
|||
clear_hovered_item();
|
||||
}
|
||||
|
||||
void WSMenu::decend_into_submenu_at_hovered_item()
|
||||
void Menu::decend_into_submenu_at_hovered_item()
|
||||
{
|
||||
ASSERT(hovered_item());
|
||||
ASSERT(hovered_item()->is_submenu());
|
||||
auto submenu = hovered_item()->submenu();
|
||||
submenu->m_hovered_item_index = 0;
|
||||
ASSERT(submenu->hovered_item()->type() != WSMenuItem::Separator);
|
||||
ASSERT(submenu->hovered_item()->type() != MenuItem::Separator);
|
||||
submenu->update_for_new_hovered_item();
|
||||
m_in_submenu = true;
|
||||
}
|
||||
|
||||
void WSMenu::handle_mouse_move_event(const WSMouseEvent& mouse_event)
|
||||
void Menu::handle_mouse_move_event(const MouseEvent& mouse_event)
|
||||
{
|
||||
ASSERT(menu_window());
|
||||
if (hovered_item() && hovered_item()->is_submenu()) {
|
||||
|
@ -327,21 +329,21 @@ void WSMenu::handle_mouse_move_event(const WSMouseEvent& mouse_event)
|
|||
return;
|
||||
}
|
||||
|
||||
void WSMenu::event(Core::Event& event)
|
||||
void Menu::event(Core::Event& event)
|
||||
{
|
||||
if (event.type() == WSEvent::MouseMove) {
|
||||
handle_mouse_move_event(static_cast<const WSMouseEvent&>(event));
|
||||
if (event.type() == Event::MouseMove) {
|
||||
handle_mouse_move_event(static_cast<const MouseEvent&>(event));
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseUp) {
|
||||
if (event.type() == Event::MouseUp) {
|
||||
open_hovered_item();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseWheel && is_scrollable()) {
|
||||
if (event.type() == Event::MouseWheel && is_scrollable()) {
|
||||
ASSERT(menu_window());
|
||||
auto& mouse_event = static_cast<const WSMouseEvent&>(event);
|
||||
auto& mouse_event = static_cast<const MouseEvent&>(event);
|
||||
m_scroll_offset += mouse_event.wheel_delta();
|
||||
m_scroll_offset = clamp(m_scroll_offset, 0, m_max_scroll_offset);
|
||||
|
||||
|
@ -354,8 +356,8 @@ void WSMenu::event(Core::Event& event)
|
|||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::KeyDown) {
|
||||
auto key = static_cast<WSKeyEvent&>(event).key();
|
||||
if (event.type() == Event::KeyDown) {
|
||||
auto key = static_cast<KeyEvent&>(event).key();
|
||||
|
||||
if (!(key == Key_Up || key == Key_Down || key == Key_Left || key == Key_Right || key == Key_Return))
|
||||
return;
|
||||
|
@ -386,7 +388,7 @@ void WSMenu::event(Core::Event& event)
|
|||
}
|
||||
|
||||
if (key == Key_Up) {
|
||||
ASSERT(m_items.at(0).type() != WSMenuItem::Separator);
|
||||
ASSERT(m_items.at(0).type() != MenuItem::Separator);
|
||||
|
||||
if (is_scrollable() && m_hovered_item_index == 0)
|
||||
return;
|
||||
|
@ -398,7 +400,7 @@ void WSMenu::event(Core::Event& event)
|
|||
return;
|
||||
else
|
||||
--m_hovered_item_index;
|
||||
} while (hovered_item()->type() == WSMenuItem::Separator);
|
||||
} while (hovered_item()->type() == MenuItem::Separator);
|
||||
|
||||
if (is_scrollable() && m_hovered_item_index < m_scroll_offset)
|
||||
--m_scroll_offset;
|
||||
|
@ -408,7 +410,7 @@ void WSMenu::event(Core::Event& event)
|
|||
}
|
||||
|
||||
if (key == Key_Down) {
|
||||
ASSERT(m_items.at(0).type() != WSMenuItem::Separator);
|
||||
ASSERT(m_items.at(0).type() != MenuItem::Separator);
|
||||
|
||||
if (is_scrollable() && m_hovered_item_index == m_items.size() - 1)
|
||||
return;
|
||||
|
@ -420,7 +422,7 @@ void WSMenu::event(Core::Event& event)
|
|||
return;
|
||||
else
|
||||
++m_hovered_item_index;
|
||||
} while (hovered_item()->type() == WSMenuItem::Separator);
|
||||
} while (hovered_item()->type() == MenuItem::Separator);
|
||||
|
||||
if (is_scrollable() && m_hovered_item_index >= (m_scroll_offset + visible_item_count()))
|
||||
++m_scroll_offset;
|
||||
|
@ -448,7 +450,7 @@ void WSMenu::event(Core::Event& event)
|
|||
Core::Object::event(event);
|
||||
}
|
||||
|
||||
void WSMenu::clear_hovered_item()
|
||||
void Menu::clear_hovered_item()
|
||||
{
|
||||
if (!hovered_item())
|
||||
return;
|
||||
|
@ -457,21 +459,21 @@ void WSMenu::clear_hovered_item()
|
|||
redraw();
|
||||
}
|
||||
|
||||
void WSMenu::did_activate(WSMenuItem& item)
|
||||
void Menu::did_activate(MenuItem& item)
|
||||
{
|
||||
if (item.type() == WSMenuItem::Type::Separator)
|
||||
if (item.type() == MenuItem::Type::Separator)
|
||||
return;
|
||||
|
||||
if (on_item_activation)
|
||||
on_item_activation(item);
|
||||
|
||||
WSMenuManager::the().close_bar();
|
||||
MenuManager::the().close_bar();
|
||||
|
||||
if (m_client)
|
||||
m_client->post_message(WindowClient::MenuItemActivated(m_menu_id, item.identifier()));
|
||||
}
|
||||
|
||||
WSMenuItem* WSMenu::item_with_identifier(unsigned identifer)
|
||||
MenuItem* Menu::item_with_identifier(unsigned identifer)
|
||||
{
|
||||
for (auto& item : m_items) {
|
||||
if (item.identifier() == identifer)
|
||||
|
@ -480,7 +482,7 @@ WSMenuItem* WSMenu::item_with_identifier(unsigned identifer)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int WSMenu::item_index_at(const Gfx::Point& position)
|
||||
int Menu::item_index_at(const Gfx::Point& position)
|
||||
{
|
||||
int i = 0;
|
||||
for (auto& item : m_items) {
|
||||
|
@ -491,18 +493,18 @@ int WSMenu::item_index_at(const Gfx::Point& position)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void WSMenu::close()
|
||||
void Menu::close()
|
||||
{
|
||||
WSMenuManager::the().close_menu_and_descendants(*this);
|
||||
MenuManager::the().close_menu_and_descendants(*this);
|
||||
}
|
||||
|
||||
void WSMenu::redraw_if_theme_changed()
|
||||
void Menu::redraw_if_theme_changed()
|
||||
{
|
||||
if (m_theme_index_at_last_paint != WSMenuManager::the().theme_index())
|
||||
if (m_theme_index_at_last_paint != MenuManager::the().theme_index())
|
||||
redraw();
|
||||
}
|
||||
|
||||
void WSMenu::popup(const Gfx::Point& position, bool is_submenu)
|
||||
void Menu::popup(const Gfx::Point& position, bool is_submenu)
|
||||
{
|
||||
ASSERT(!is_empty());
|
||||
|
||||
|
@ -512,27 +514,27 @@ void WSMenu::popup(const Gfx::Point& position, bool is_submenu)
|
|||
const int margin = 30;
|
||||
Gfx::Point adjusted_pos = position;
|
||||
|
||||
if (adjusted_pos.x() + window.width() >= WSScreen::the().width() - margin) {
|
||||
if (adjusted_pos.x() + window.width() >= Screen::the().width() - margin) {
|
||||
adjusted_pos = adjusted_pos.translated(-window.width(), 0);
|
||||
}
|
||||
if (adjusted_pos.y() + window.height() >= WSScreen::the().height() - margin) {
|
||||
if (adjusted_pos.y() + window.height() >= Screen::the().height() - margin) {
|
||||
adjusted_pos = adjusted_pos.translated(0, -window.height());
|
||||
}
|
||||
|
||||
if (adjusted_pos.y() < WSMenuManager::the().menubar_rect().height())
|
||||
adjusted_pos.set_y(WSMenuManager::the().menubar_rect().height());
|
||||
if (adjusted_pos.y() < MenuManager::the().menubar_rect().height())
|
||||
adjusted_pos.set_y(MenuManager::the().menubar_rect().height());
|
||||
|
||||
window.move_to(adjusted_pos);
|
||||
window.set_visible(true);
|
||||
WSMenuManager::the().set_current_menu(this, is_submenu);
|
||||
MenuManager::the().set_current_menu(this, is_submenu);
|
||||
}
|
||||
|
||||
bool WSMenu::is_menu_ancestor_of(const WSMenu& other) const
|
||||
bool Menu::is_menu_ancestor_of(const Menu& other) const
|
||||
{
|
||||
for (auto& item : m_items) {
|
||||
if (!item.is_submenu())
|
||||
continue;
|
||||
auto& submenu = *const_cast<WSMenuItem&>(item).submenu();
|
||||
auto& submenu = *const_cast<MenuItem&>(item).submenu();
|
||||
if (&submenu == &other)
|
||||
return true;
|
||||
if (submenu.is_menu_ancestor_of(other))
|
||||
|
@ -540,3 +542,5 @@ bool WSMenu::is_menu_ancestor_of(const WSMenu& other) const
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,38 +31,40 @@
|
|||
#include <AK/WeakPtr.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/WSMenuItem.h>
|
||||
#include <WindowServer/WSWindow.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/MenuItem.h>
|
||||
#include <WindowServer/Window.h>
|
||||
|
||||
namespace Gfx {
|
||||
class Font;
|
||||
}
|
||||
|
||||
class WSClientConnection;
|
||||
class WSMenuBar;
|
||||
class WSEvent;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSMenu final : public Core::Object {
|
||||
C_OBJECT(WSMenu)
|
||||
class ClientConnection;
|
||||
class MenuBar;
|
||||
class Event;
|
||||
|
||||
class Menu final : public Core::Object {
|
||||
C_OBJECT(Menu)
|
||||
public:
|
||||
WSMenu(WSClientConnection*, int menu_id, const String& name);
|
||||
virtual ~WSMenu() override;
|
||||
Menu(ClientConnection*, int menu_id, const String& name);
|
||||
virtual ~Menu() override;
|
||||
|
||||
WSClientConnection* client() { return m_client; }
|
||||
const WSClientConnection* client() const { return m_client; }
|
||||
ClientConnection* client() { return m_client; }
|
||||
const ClientConnection* client() const { return m_client; }
|
||||
int menu_id() const { return m_menu_id; }
|
||||
|
||||
WSMenuBar* menubar() { return m_menubar; }
|
||||
const WSMenuBar* menubar() const { return m_menubar; }
|
||||
void set_menubar(WSMenuBar* menubar) { m_menubar = menubar; }
|
||||
MenuBar* menubar() { return m_menubar; }
|
||||
const MenuBar* menubar() const { return m_menubar; }
|
||||
void set_menubar(MenuBar* menubar) { m_menubar = menubar; }
|
||||
|
||||
bool is_empty() const { return m_items.is_empty(); }
|
||||
int item_count() const { return m_items.size(); }
|
||||
const WSMenuItem& item(int index) const { return m_items.at(index); }
|
||||
WSMenuItem& item(int index) { return m_items.at(index); }
|
||||
const MenuItem& item(int index) const { return m_items.at(index); }
|
||||
MenuItem& item(int index) { return m_items.at(index); }
|
||||
|
||||
void add_item(NonnullOwnPtr<WSMenuItem>&& item) { m_items.append(move(item)); }
|
||||
void add_item(NonnullOwnPtr<MenuItem>&& item) { m_items.append(move(item)); }
|
||||
|
||||
String name() const { return m_name; }
|
||||
|
||||
|
@ -79,11 +81,11 @@ public:
|
|||
Gfx::Rect rect_in_menubar() const { return m_rect_in_menubar; }
|
||||
void set_rect_in_menubar(const Gfx::Rect& rect) { m_rect_in_menubar = rect; }
|
||||
|
||||
WSWindow* menu_window() { return m_menu_window.ptr(); }
|
||||
WSWindow& ensure_menu_window();
|
||||
Window* menu_window() { return m_menu_window.ptr(); }
|
||||
Window& ensure_menu_window();
|
||||
|
||||
WSWindow* window_menu_of() { return m_window_menu_of; }
|
||||
void set_window_menu_of(WSWindow& window) { m_window_menu_of = window.make_weak_ptr(); }
|
||||
Window* window_menu_of() { return m_window_menu_of; }
|
||||
void set_window_menu_of(Window& window) { m_window_menu_of = window.make_weak_ptr(); }
|
||||
bool is_window_menu_open() { return m_is_window_menu_open; }
|
||||
void set_window_menu_open(bool is_open) { m_is_window_menu_open = is_open; }
|
||||
|
||||
|
@ -98,19 +100,19 @@ public:
|
|||
void draw();
|
||||
const Gfx::Font& font() const;
|
||||
|
||||
WSMenuItem* item_with_identifier(unsigned);
|
||||
MenuItem* item_with_identifier(unsigned);
|
||||
void redraw();
|
||||
|
||||
WSMenuItem* hovered_item() const;
|
||||
MenuItem* hovered_item() const;
|
||||
void clear_hovered_item();
|
||||
|
||||
Function<void(WSMenuItem&)> on_item_activation;
|
||||
Function<void(MenuItem&)> on_item_activation;
|
||||
|
||||
void close();
|
||||
|
||||
void popup(const Gfx::Point&, bool is_submenu = false);
|
||||
|
||||
bool is_menu_ancestor_of(const WSMenu&) const;
|
||||
bool is_menu_ancestor_of(const Menu&) const;
|
||||
|
||||
void redraw_if_theme_changed();
|
||||
|
||||
|
@ -120,26 +122,26 @@ public:
|
|||
private:
|
||||
virtual void event(Core::Event&) override;
|
||||
|
||||
void handle_mouse_move_event(const WSMouseEvent&);
|
||||
void handle_mouse_move_event(const MouseEvent&);
|
||||
int visible_item_count() const;
|
||||
|
||||
int item_index_at(const Gfx::Point&);
|
||||
int padding_between_text_and_shortcut() const { return 50; }
|
||||
void did_activate(WSMenuItem&);
|
||||
void did_activate(MenuItem&);
|
||||
void open_hovered_item();
|
||||
void update_for_new_hovered_item();
|
||||
void decend_into_submenu_at_hovered_item();
|
||||
|
||||
WSClientConnection* m_client { nullptr };
|
||||
ClientConnection* m_client { nullptr };
|
||||
int m_menu_id { 0 };
|
||||
String m_name;
|
||||
Gfx::Rect m_rect_in_menubar;
|
||||
Gfx::Rect m_text_rect_in_menubar;
|
||||
WSMenuBar* m_menubar { nullptr };
|
||||
NonnullOwnPtrVector<WSMenuItem> m_items;
|
||||
RefPtr<WSWindow> m_menu_window;
|
||||
MenuBar* m_menubar { nullptr };
|
||||
NonnullOwnPtrVector<MenuItem> m_items;
|
||||
RefPtr<Window> m_menu_window;
|
||||
|
||||
WeakPtr<WSWindow> m_window_menu_of;
|
||||
WeakPtr<Window> m_window_menu_of;
|
||||
bool m_is_window_menu_open = { false };
|
||||
Gfx::Point m_last_position_in_hover;
|
||||
int m_theme_index_at_last_paint { -1 };
|
||||
|
@ -150,3 +152,5 @@ private:
|
|||
int m_scroll_offset { 0 };
|
||||
int m_max_scroll_offset { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -24,17 +24,21 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSMenuBar.h"
|
||||
#include "WSMenu.h"
|
||||
#include "WSMenuItem.h"
|
||||
#include "MenuBar.h"
|
||||
#include "Menu.h"
|
||||
#include "MenuItem.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
WSMenuBar::WSMenuBar(WSClientConnection& client, int menubar_id)
|
||||
namespace WindowServer {
|
||||
|
||||
MenuBar::MenuBar(ClientConnection& client, int menubar_id)
|
||||
: m_client(client)
|
||||
, m_menubar_id(menubar_id)
|
||||
{
|
||||
}
|
||||
|
||||
WSMenuBar::~WSMenuBar()
|
||||
MenuBar::~MenuBar()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -26,20 +26,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "WSMenu.h"
|
||||
#include "Menu.h"
|
||||
#include <AK/Vector.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <AK/Weakable.h>
|
||||
|
||||
class WSMenuBar : public Weakable<WSMenuBar> {
|
||||
public:
|
||||
WSMenuBar(WSClientConnection& client, int menubar_id);
|
||||
~WSMenuBar();
|
||||
namespace WindowServer {
|
||||
|
||||
WSClientConnection& client() { return m_client; }
|
||||
const WSClientConnection& client() const { return m_client; }
|
||||
class MenuBar : public Weakable<MenuBar> {
|
||||
public:
|
||||
MenuBar(ClientConnection& client, int menubar_id);
|
||||
~MenuBar();
|
||||
|
||||
ClientConnection& client() { return m_client; }
|
||||
const ClientConnection& client() const { return m_client; }
|
||||
int menubar_id() const { return m_menubar_id; }
|
||||
void add_menu(WSMenu& menu)
|
||||
void add_menu(Menu& menu)
|
||||
{
|
||||
menu.set_menubar(this);
|
||||
m_menus.append(&menu);
|
||||
|
@ -55,7 +57,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
WSClientConnection& m_client;
|
||||
ClientConnection& m_client;
|
||||
int m_menubar_id { 0 };
|
||||
Vector<WSMenu*> m_menus;
|
||||
Vector<Menu*> m_menus;
|
||||
};
|
||||
|
||||
}
|
|
@ -24,13 +24,15 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSMenuItem.h"
|
||||
#include "WSClientConnection.h"
|
||||
#include "WSMenu.h"
|
||||
#include "WSWindowManager.h"
|
||||
#include "MenuItem.h"
|
||||
#include "ClientConnection.h"
|
||||
#include "Menu.h"
|
||||
#include "WindowManager.h"
|
||||
#include <LibGfx/Bitmap.h>
|
||||
|
||||
WSMenuItem::WSMenuItem(WSMenu& menu, unsigned identifier, const String& text, const String& shortcut_text, bool enabled, bool checkable, bool checked, const Gfx::Bitmap* icon)
|
||||
namespace WindowServer {
|
||||
|
||||
MenuItem::MenuItem(Menu& menu, unsigned identifier, const String& text, const String& shortcut_text, bool enabled, bool checkable, bool checked, const Gfx::Bitmap* icon)
|
||||
: m_menu(menu)
|
||||
, m_type(Text)
|
||||
, m_enabled(enabled)
|
||||
|
@ -43,17 +45,17 @@ WSMenuItem::WSMenuItem(WSMenu& menu, unsigned identifier, const String& text, co
|
|||
{
|
||||
}
|
||||
|
||||
WSMenuItem::WSMenuItem(WSMenu& menu, Type type)
|
||||
MenuItem::MenuItem(Menu& menu, Type type)
|
||||
: m_menu(menu)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
WSMenuItem::~WSMenuItem()
|
||||
MenuItem::~MenuItem()
|
||||
{
|
||||
}
|
||||
|
||||
void WSMenuItem::set_enabled(bool enabled)
|
||||
void MenuItem::set_enabled(bool enabled)
|
||||
{
|
||||
if (m_enabled == enabled)
|
||||
return;
|
||||
|
@ -61,7 +63,7 @@ void WSMenuItem::set_enabled(bool enabled)
|
|||
m_menu.redraw();
|
||||
}
|
||||
|
||||
void WSMenuItem::set_checked(bool checked)
|
||||
void MenuItem::set_checked(bool checked)
|
||||
{
|
||||
if (m_checked == checked)
|
||||
return;
|
||||
|
@ -69,17 +71,19 @@ void WSMenuItem::set_checked(bool checked)
|
|||
m_menu.redraw();
|
||||
}
|
||||
|
||||
WSMenu* WSMenuItem::submenu()
|
||||
Menu* MenuItem::submenu()
|
||||
{
|
||||
ASSERT(is_submenu());
|
||||
if (m_menu.client())
|
||||
return m_menu.client()->find_menu_by_id(m_submenu_id);
|
||||
return WSMenuManager::the().find_internal_menu_by_id(m_submenu_id);
|
||||
return MenuManager::the().find_internal_menu_by_id(m_submenu_id);
|
||||
}
|
||||
|
||||
Gfx::Rect WSMenuItem::rect() const
|
||||
Gfx::Rect MenuItem::rect() const
|
||||
{
|
||||
if (!m_menu.is_scrollable())
|
||||
return m_rect;
|
||||
return m_rect.translated(0, m_menu.item_height() - (m_menu.scroll_offset() * m_menu.item_height()));
|
||||
}
|
||||
|
||||
}
|
|
@ -34,9 +34,11 @@ namespace Gfx {
|
|||
class Bitmap;
|
||||
}
|
||||
|
||||
class WSMenu;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSMenuItem {
|
||||
class Menu;
|
||||
|
||||
class MenuItem {
|
||||
public:
|
||||
enum Type {
|
||||
None,
|
||||
|
@ -44,9 +46,9 @@ public:
|
|||
Separator,
|
||||
};
|
||||
|
||||
WSMenuItem(WSMenu&, unsigned identifier, const String& text, const String& shortcut_text = {}, bool enabled = true, bool checkable = false, bool checked = false, const Gfx::Bitmap* icon = nullptr);
|
||||
WSMenuItem(WSMenu&, Type);
|
||||
~WSMenuItem();
|
||||
MenuItem(Menu&, unsigned identifier, const String& text, const String& shortcut_text = {}, bool enabled = true, bool checkable = false, bool checked = false, const Gfx::Bitmap* icon = nullptr);
|
||||
MenuItem(Menu&, Type);
|
||||
~MenuItem();
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
||||
|
@ -77,13 +79,13 @@ public:
|
|||
int submenu_id() const { return m_submenu_id; }
|
||||
void set_submenu_id(int submenu_id) { m_submenu_id = submenu_id; }
|
||||
|
||||
WSMenu* submenu();
|
||||
Menu* submenu();
|
||||
|
||||
bool is_exclusive() const { return m_exclusive; }
|
||||
void set_exclusive(bool exclusive) { m_exclusive = exclusive; }
|
||||
|
||||
private:
|
||||
WSMenu& m_menu;
|
||||
Menu& m_menu;
|
||||
Type m_type { None };
|
||||
bool m_enabled { true };
|
||||
bool m_checkable { false };
|
||||
|
@ -96,3 +98,5 @@ private:
|
|||
int m_submenu_id { -1 };
|
||||
bool m_exclusive { false };
|
||||
};
|
||||
|
||||
}
|
|
@ -29,22 +29,24 @@
|
|||
#include <LibCore/DirIterator.h>
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <WindowServer/WSMenuManager.h>
|
||||
#include <WindowServer/WSScreen.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/MenuManager.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//#define DEBUG_MENUS
|
||||
|
||||
static WSMenuManager* s_the;
|
||||
namespace WindowServer {
|
||||
|
||||
WSMenuManager& WSMenuManager::the()
|
||||
static MenuManager* s_the;
|
||||
|
||||
MenuManager& MenuManager::the()
|
||||
{
|
||||
ASSERT(s_the);
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WSMenuManager::WSMenuManager()
|
||||
MenuManager::MenuManager()
|
||||
{
|
||||
s_the = this;
|
||||
m_username = getlogin();
|
||||
|
@ -74,14 +76,14 @@ WSMenuManager::WSMenuManager()
|
|||
quick_sort(sorted_app_categories.begin(), sorted_app_categories.end(), [](auto& a, auto& b) { return a < b; });
|
||||
|
||||
u8 system_menu_name[] = { 0xc3, 0xb8, 0 };
|
||||
m_system_menu = WSMenu::construct(nullptr, -1, String((const char*)system_menu_name));
|
||||
m_system_menu = Menu::construct(nullptr, -1, String((const char*)system_menu_name));
|
||||
|
||||
// First we construct all the necessary app category submenus.
|
||||
for (const auto& category : sorted_app_categories) {
|
||||
|
||||
if (m_app_category_menus.contains(category))
|
||||
continue;
|
||||
auto category_menu = WSMenu::construct(nullptr, 5000 + m_app_category_menus.size(), category);
|
||||
auto category_menu = Menu::construct(nullptr, 5000 + m_app_category_menus.size(), category);
|
||||
category_menu->on_item_activation = [this](auto& item) {
|
||||
if (item.identifier() >= 1 && item.identifier() <= 1u + m_apps.size() - 1) {
|
||||
if (fork() == 0) {
|
||||
|
@ -91,7 +93,7 @@ WSMenuManager::WSMenuManager()
|
|||
}
|
||||
}
|
||||
};
|
||||
auto item = make<WSMenuItem>(*m_system_menu, -1, category);
|
||||
auto item = make<MenuItem>(*m_system_menu, -1, category);
|
||||
item->set_submenu_id(category_menu->menu_id());
|
||||
m_system_menu->add_item(move(item));
|
||||
m_app_category_menus.set(category, move(category_menu));
|
||||
|
@ -101,14 +103,14 @@ WSMenuManager::WSMenuManager()
|
|||
int app_identifier = 1;
|
||||
for (const auto& app : m_apps) {
|
||||
auto parent_menu = m_app_category_menus.get(app.category).value_or(*m_system_menu);
|
||||
parent_menu->add_item(make<WSMenuItem>(*m_system_menu, app_identifier++, app.name, String(), true, false, false, Gfx::Bitmap::load_from_file(app.icon_path)));
|
||||
parent_menu->add_item(make<MenuItem>(*m_system_menu, app_identifier++, app.name, String(), true, false, false, Gfx::Bitmap::load_from_file(app.icon_path)));
|
||||
}
|
||||
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, WSMenuItem::Separator));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, MenuItem::Separator));
|
||||
|
||||
m_themes_menu = WSMenu::construct(nullptr, 9000, "Themes");
|
||||
m_themes_menu = Menu::construct(nullptr, 9000, "Themes");
|
||||
|
||||
auto themes_menu_item = make<WSMenuItem>(*m_system_menu, 100, "Themes");
|
||||
auto themes_menu_item = make<MenuItem>(*m_system_menu, 100, "Themes");
|
||||
themes_menu_item->set_submenu_id(m_themes_menu->menu_id());
|
||||
m_system_menu->add_item(move(themes_menu_item));
|
||||
|
||||
|
@ -125,24 +127,24 @@ WSMenuManager::WSMenuManager()
|
|||
{
|
||||
int theme_identifier = 9000;
|
||||
for (auto& theme : m_themes) {
|
||||
m_themes_menu->add_item(make<WSMenuItem>(*m_themes_menu, theme_identifier++, theme.name));
|
||||
m_themes_menu->add_item(make<MenuItem>(*m_themes_menu, theme_identifier++, theme.name));
|
||||
}
|
||||
}
|
||||
|
||||
m_themes_menu->on_item_activation = [this](WSMenuItem& item) {
|
||||
m_themes_menu->on_item_activation = [this](MenuItem& item) {
|
||||
auto& theme = m_themes[(int)item.identifier() - 9000];
|
||||
WSWindowManager::the().update_theme(theme.path, theme.name);
|
||||
WindowManager::the().update_theme(theme.path, theme.name);
|
||||
++m_theme_index;
|
||||
};
|
||||
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, WSMenuItem::Separator));
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, 100, "Reload WM Config File"));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, MenuItem::Separator));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, 100, "Reload WM Config File"));
|
||||
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, WSMenuItem::Separator));
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, 200, "About...", String(), true, false, false, Gfx::Bitmap::load_from_file("/res/icons/16x16/ladybug.png")));
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, WSMenuItem::Separator));
|
||||
m_system_menu->add_item(make<WSMenuItem>(*m_system_menu, 300, "Shutdown..."));
|
||||
m_system_menu->on_item_activation = [this](WSMenuItem& item) {
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, MenuItem::Separator));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, 200, "About...", String(), true, false, false, Gfx::Bitmap::load_from_file("/res/icons/16x16/ladybug.png")));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, MenuItem::Separator));
|
||||
m_system_menu->add_item(make<MenuItem>(*m_system_menu, 300, "Shutdown..."));
|
||||
m_system_menu->on_item_activation = [this](MenuItem& item) {
|
||||
if (item.identifier() >= 1 && item.identifier() <= 1u + m_apps.size() - 1) {
|
||||
if (fork() == 0) {
|
||||
const auto& bin = m_apps[item.identifier() - 1].executable;
|
||||
|
@ -152,7 +154,7 @@ WSMenuManager::WSMenuManager()
|
|||
}
|
||||
switch (item.identifier()) {
|
||||
case 100:
|
||||
WSWindowManager::the().reload_config(true);
|
||||
WindowManager::the().reload_config(true);
|
||||
break;
|
||||
case 200:
|
||||
if (fork() == 0) {
|
||||
|
@ -168,22 +170,22 @@ WSMenuManager::WSMenuManager()
|
|||
return;
|
||||
}
|
||||
#ifdef DEBUG_MENUS
|
||||
dbg() << "WSMenu 1 item activated: " << item.text();
|
||||
dbg() << "Menu 1 item activated: " << item.text();
|
||||
#endif
|
||||
};
|
||||
|
||||
// NOTE: This ensures that the system menu has the correct dimensions.
|
||||
set_current_menubar(nullptr);
|
||||
|
||||
m_window = WSWindow::construct(*this, WSWindowType::Menubar);
|
||||
m_window = Window::construct(*this, WindowType::Menubar);
|
||||
m_window->set_rect(menubar_rect());
|
||||
}
|
||||
|
||||
WSMenuManager::~WSMenuManager()
|
||||
MenuManager::~MenuManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool WSMenuManager::is_open(const WSMenu& menu) const
|
||||
bool MenuManager::is_open(const Menu& menu) const
|
||||
{
|
||||
for (int i = 0; i < m_open_menu_stack.size(); ++i) {
|
||||
if (&menu == m_open_menu_stack[i].ptr())
|
||||
|
@ -192,9 +194,9 @@ bool WSMenuManager::is_open(const WSMenu& menu) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void WSMenuManager::draw()
|
||||
void MenuManager::draw()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
auto palette = wm.palette();
|
||||
auto menubar_rect = this->menubar_rect();
|
||||
|
||||
|
@ -230,7 +232,7 @@ void WSMenuManager::draw()
|
|||
painter.fill_rect(menubar_rect, palette.window());
|
||||
painter.draw_line({ 0, menubar_rect.bottom() }, { menubar_rect.right(), menubar_rect.bottom() }, palette.threed_shadow1());
|
||||
int index = 0;
|
||||
for_each_active_menubar_menu([&](WSMenu& menu) {
|
||||
for_each_active_menubar_menu([&](Menu& menu) {
|
||||
Color text_color = palette.window_text();
|
||||
if (is_open(menu)) {
|
||||
painter.fill_rect(menu.rect_in_menubar(), palette.menu_selection());
|
||||
|
@ -256,12 +258,12 @@ void WSMenuManager::draw()
|
|||
}
|
||||
}
|
||||
|
||||
void WSMenuManager::tick_clock()
|
||||
void MenuManager::tick_clock()
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
void WSMenuManager::refresh()
|
||||
void MenuManager::refresh()
|
||||
{
|
||||
if (!m_window)
|
||||
return;
|
||||
|
@ -269,15 +271,15 @@ void WSMenuManager::refresh()
|
|||
window().invalidate();
|
||||
}
|
||||
|
||||
void WSMenuManager::event(Core::Event& event)
|
||||
void MenuManager::event(Core::Event& event)
|
||||
{
|
||||
if (WSWindowManager::the().active_window_is_modal())
|
||||
if (WindowManager::the().active_window_is_modal())
|
||||
return Core::Object::event(event);
|
||||
|
||||
if (event.type() == WSEvent::MouseMove || event.type() == WSEvent::MouseUp || event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseWheel) {
|
||||
if (event.type() == Event::MouseMove || event.type() == Event::MouseUp || event.type() == Event::MouseDown || event.type() == Event::MouseWheel) {
|
||||
|
||||
auto& mouse_event = static_cast<WSMouseEvent&>(event);
|
||||
for_each_active_menubar_menu([&](WSMenu& menu) {
|
||||
auto& mouse_event = static_cast<MouseEvent&>(event);
|
||||
for_each_active_menubar_menu([&](Menu& menu) {
|
||||
if (menu.rect_in_menubar().contains(mouse_event.position())) {
|
||||
handle_menu_mouse_event(menu, mouse_event);
|
||||
return IterationDecision::Break;
|
||||
|
@ -295,16 +297,16 @@ void WSMenuManager::event(Core::Event& event)
|
|||
}
|
||||
}
|
||||
|
||||
if (static_cast<WSEvent&>(event).is_key_event()) {
|
||||
auto& key_event = static_cast<const WSKeyEvent&>(event);
|
||||
if (static_cast<Event&>(event).is_key_event()) {
|
||||
auto& key_event = static_cast<const KeyEvent&>(event);
|
||||
|
||||
if (key_event.type() == WSEvent::KeyUp && key_event.key() == Key_Escape) {
|
||||
if (key_event.type() == Event::KeyUp && key_event.key() == Key_Escape) {
|
||||
close_everyone();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::KeyDown) {
|
||||
for_each_active_menubar_menu([&](WSMenu& menu) {
|
||||
if (event.type() == Event::KeyDown) {
|
||||
for_each_active_menubar_menu([&](Menu& menu) {
|
||||
if (is_open(menu))
|
||||
menu.dispatch_event(event);
|
||||
return IterationDecision::Continue;
|
||||
|
@ -315,12 +317,12 @@ void WSMenuManager::event(Core::Event& event)
|
|||
return Core::Object::event(event);
|
||||
}
|
||||
|
||||
void WSMenuManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
|
||||
void MenuManager::handle_menu_mouse_event(Menu& menu, const MouseEvent& event)
|
||||
{
|
||||
bool is_hover_with_any_menu_open = event.type() == WSMouseEvent::MouseMove
|
||||
bool is_hover_with_any_menu_open = event.type() == MouseEvent::MouseMove
|
||||
&& !m_open_menu_stack.is_empty()
|
||||
&& (m_open_menu_stack.first()->menubar() || m_open_menu_stack.first() == m_system_menu.ptr());
|
||||
bool is_mousedown_with_left_button = event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left;
|
||||
bool is_mousedown_with_left_button = event.type() == MouseEvent::MouseDown && event.button() == MouseButton::Left;
|
||||
bool should_open_menu = &menu != m_current_menu && (is_hover_with_any_menu_open || is_mousedown_with_left_button);
|
||||
|
||||
if (is_mousedown_with_left_button)
|
||||
|
@ -335,12 +337,12 @@ void WSMenuManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& ev
|
|||
close_everyone();
|
||||
}
|
||||
|
||||
void WSMenuManager::set_needs_window_resize()
|
||||
void MenuManager::set_needs_window_resize()
|
||||
{
|
||||
m_needs_window_resize = true;
|
||||
}
|
||||
|
||||
void WSMenuManager::close_all_menus_from_client(Badge<WSClientConnection>, WSClientConnection& client)
|
||||
void MenuManager::close_all_menus_from_client(Badge<ClientConnection>, ClientConnection& client)
|
||||
{
|
||||
if (m_open_menu_stack.is_empty())
|
||||
return;
|
||||
|
@ -349,7 +351,7 @@ void WSMenuManager::close_all_menus_from_client(Badge<WSClientConnection>, WSCli
|
|||
close_everyone();
|
||||
}
|
||||
|
||||
void WSMenuManager::close_everyone()
|
||||
void MenuManager::close_everyone()
|
||||
{
|
||||
for (auto& menu : m_open_menu_stack) {
|
||||
if (menu && menu->menu_window())
|
||||
|
@ -361,9 +363,9 @@ void WSMenuManager::close_everyone()
|
|||
refresh();
|
||||
}
|
||||
|
||||
void WSMenuManager::close_everyone_not_in_lineage(WSMenu& menu)
|
||||
void MenuManager::close_everyone_not_in_lineage(Menu& menu)
|
||||
{
|
||||
Vector<WSMenu*> menus_to_close;
|
||||
Vector<Menu*> menus_to_close;
|
||||
for (auto& open_menu : m_open_menu_stack) {
|
||||
if (!open_menu)
|
||||
continue;
|
||||
|
@ -374,7 +376,7 @@ void WSMenuManager::close_everyone_not_in_lineage(WSMenu& menu)
|
|||
close_menus(menus_to_close);
|
||||
}
|
||||
|
||||
void WSMenuManager::close_menus(const Vector<WSMenu*>& menus)
|
||||
void MenuManager::close_menus(const Vector<Menu*>& menus)
|
||||
{
|
||||
for (auto& menu : menus) {
|
||||
if (menu == m_current_menu)
|
||||
|
@ -389,25 +391,25 @@ void WSMenuManager::close_menus(const Vector<WSMenu*>& menus)
|
|||
refresh();
|
||||
}
|
||||
|
||||
static void collect_menu_subtree(WSMenu& menu, Vector<WSMenu*>& menus)
|
||||
static void collect_menu_subtree(Menu& menu, Vector<Menu*>& menus)
|
||||
{
|
||||
menus.append(&menu);
|
||||
for (int i = 0; i < menu.item_count(); ++i) {
|
||||
auto& item = menu.item(i);
|
||||
if (!item.is_submenu())
|
||||
continue;
|
||||
collect_menu_subtree(*const_cast<WSMenuItem&>(item).submenu(), menus);
|
||||
collect_menu_subtree(*const_cast<MenuItem&>(item).submenu(), menus);
|
||||
}
|
||||
}
|
||||
|
||||
void WSMenuManager::close_menu_and_descendants(WSMenu& menu)
|
||||
void MenuManager::close_menu_and_descendants(Menu& menu)
|
||||
{
|
||||
Vector<WSMenu*> menus_to_close;
|
||||
Vector<Menu*> menus_to_close;
|
||||
collect_menu_subtree(menu, menus_to_close);
|
||||
close_menus(menus_to_close);
|
||||
}
|
||||
|
||||
void WSMenuManager::toggle_menu(WSMenu& menu)
|
||||
void MenuManager::toggle_menu(Menu& menu)
|
||||
{
|
||||
if (is_open(menu)) {
|
||||
close_menu_and_descendants(menu);
|
||||
|
@ -416,7 +418,7 @@ void WSMenuManager::toggle_menu(WSMenu& menu)
|
|||
open_menu(menu);
|
||||
}
|
||||
|
||||
void WSMenuManager::open_menu(WSMenu& menu)
|
||||
void MenuManager::open_menu(Menu& menu)
|
||||
{
|
||||
if (is_open(menu))
|
||||
return;
|
||||
|
@ -430,7 +432,7 @@ void WSMenuManager::open_menu(WSMenu& menu)
|
|||
refresh();
|
||||
}
|
||||
|
||||
void WSMenuManager::set_current_menu(WSMenu* menu, bool is_submenu)
|
||||
void MenuManager::set_current_menu(Menu* menu, bool is_submenu)
|
||||
{
|
||||
if (!is_submenu) {
|
||||
if (menu)
|
||||
|
@ -448,13 +450,13 @@ void WSMenuManager::set_current_menu(WSMenu* menu, bool is_submenu)
|
|||
m_current_menu = menu->make_weak_ptr();
|
||||
}
|
||||
|
||||
void WSMenuManager::close_bar()
|
||||
void MenuManager::close_bar()
|
||||
{
|
||||
close_everyone();
|
||||
m_bar_open = false;
|
||||
}
|
||||
|
||||
void WSMenuManager::add_applet(WSWindow& applet)
|
||||
void MenuManager::add_applet(Window& applet)
|
||||
{
|
||||
int right_edge_x = m_username_rect.left() - 4;
|
||||
for (auto& existing_applet : m_applets) {
|
||||
|
@ -470,34 +472,34 @@ void WSMenuManager::add_applet(WSWindow& applet)
|
|||
m_applets.append(applet.make_weak_ptr());
|
||||
}
|
||||
|
||||
void WSMenuManager::remove_applet(WSWindow& applet)
|
||||
void MenuManager::remove_applet(Window& applet)
|
||||
{
|
||||
m_applets.remove_first_matching([&](auto& entry) {
|
||||
return &applet == entry.ptr();
|
||||
});
|
||||
}
|
||||
|
||||
void WSMenuManager::draw_applet(const WSWindow& applet)
|
||||
void MenuManager::draw_applet(const Window& applet)
|
||||
{
|
||||
if (!applet.backing_store())
|
||||
return;
|
||||
Gfx::Painter painter(*window().backing_store());
|
||||
painter.fill_rect(applet.rect_in_menubar(), WSWindowManager::the().palette().window());
|
||||
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());
|
||||
}
|
||||
|
||||
void WSMenuManager::invalidate_applet(const WSWindow& applet, const Gfx::Rect& rect)
|
||||
void MenuManager::invalidate_applet(const Window& applet, const Gfx::Rect& rect)
|
||||
{
|
||||
draw_applet(applet);
|
||||
window().invalidate(rect.translated(applet.rect_in_menubar().location()));
|
||||
}
|
||||
|
||||
Gfx::Rect WSMenuManager::menubar_rect() const
|
||||
Gfx::Rect MenuManager::menubar_rect() const
|
||||
{
|
||||
return { 0, 0, WSScreen::the().rect().width(), 18 };
|
||||
return { 0, 0, Screen::the().rect().width(), 18 };
|
||||
}
|
||||
|
||||
WSMenu* WSMenuManager::find_internal_menu_by_id(int menu_id)
|
||||
Menu* MenuManager::find_internal_menu_by_id(int menu_id)
|
||||
{
|
||||
if (m_themes_menu->menu_id() == menu_id)
|
||||
return m_themes_menu.ptr();
|
||||
|
@ -508,7 +510,7 @@ WSMenu* WSMenuManager::find_internal_menu_by_id(int menu_id)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void WSMenuManager::set_current_menubar(WSMenuBar* menubar)
|
||||
void MenuManager::set_current_menubar(MenuBar* menubar)
|
||||
{
|
||||
if (menubar)
|
||||
m_current_menubar = menubar->make_weak_ptr();
|
||||
|
@ -517,11 +519,11 @@ void WSMenuManager::set_current_menubar(WSMenuBar* menubar)
|
|||
#ifdef DEBUG_MENUS
|
||||
dbg() << "[WM] Current menubar is now " << menubar;
|
||||
#endif
|
||||
Gfx::Point next_menu_location { WSMenuManager::menubar_menu_margin() / 2, 0 };
|
||||
Gfx::Point next_menu_location { MenuManager::menubar_menu_margin() / 2, 0 };
|
||||
int index = 0;
|
||||
for_each_active_menubar_menu([&](WSMenu& menu) {
|
||||
for_each_active_menubar_menu([&](Menu& menu) {
|
||||
int text_width = index == 1 ? Gfx::Font::default_bold_font().width(menu.name()) : Gfx::Font::default_font().width(menu.name());
|
||||
menu.set_rect_in_menubar({ next_menu_location.x() - WSMenuManager::menubar_menu_margin() / 2, 0, text_width + WSMenuManager::menubar_menu_margin(), menubar_rect().height() - 1 });
|
||||
menu.set_rect_in_menubar({ next_menu_location.x() - MenuManager::menubar_menu_margin() / 2, 0, text_width + MenuManager::menubar_menu_margin(), menubar_rect().height() - 1 });
|
||||
menu.set_text_rect_in_menubar({ next_menu_location, { text_width, menubar_rect().height() } });
|
||||
next_menu_location.move_by(menu.rect_in_menubar().width(), 0);
|
||||
++index;
|
||||
|
@ -530,8 +532,10 @@ void WSMenuManager::set_current_menubar(WSMenuBar* menubar)
|
|||
refresh();
|
||||
}
|
||||
|
||||
void WSMenuManager::close_menubar(WSMenuBar& menubar)
|
||||
void MenuManager::close_menubar(MenuBar& menubar)
|
||||
{
|
||||
if (current_menubar() == &menubar)
|
||||
set_current_menubar(nullptr);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,58 +26,58 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "WSMenu.h"
|
||||
#include "WSMenuBar.h"
|
||||
#include "Menu.h"
|
||||
#include "MenuBar.h"
|
||||
#include "Window.h"
|
||||
#include <AK/HashMap.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <WindowServer/WSWindow.h>
|
||||
|
||||
class AClientConnection;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSMenuManager final : public Core::Object {
|
||||
C_OBJECT(WSMenuManager)
|
||||
class MenuManager final : public Core::Object {
|
||||
C_OBJECT(MenuManager)
|
||||
public:
|
||||
static WSMenuManager& the();
|
||||
static MenuManager& the();
|
||||
|
||||
WSMenuManager();
|
||||
virtual ~WSMenuManager() override;
|
||||
MenuManager();
|
||||
virtual ~MenuManager() override;
|
||||
|
||||
void refresh();
|
||||
|
||||
virtual void event(Core::Event&) override;
|
||||
|
||||
bool is_open(const WSMenu&) const;
|
||||
bool is_open(const Menu&) const;
|
||||
|
||||
Vector<WeakPtr<WSMenu>>& open_menu_stack() { return m_open_menu_stack; }
|
||||
Vector<WeakPtr<Menu>>& open_menu_stack() { return m_open_menu_stack; }
|
||||
|
||||
Gfx::Rect menubar_rect() const;
|
||||
static int menubar_menu_margin() { return 16; }
|
||||
|
||||
void set_needs_window_resize();
|
||||
|
||||
WSMenu* current_menu() { return m_current_menu.ptr(); }
|
||||
void set_current_menu(WSMenu*, bool is_submenu = false);
|
||||
void open_menu(WSMenu&);
|
||||
void toggle_menu(WSMenu&);
|
||||
Menu* current_menu() { return m_current_menu.ptr(); }
|
||||
void set_current_menu(Menu*, bool is_submenu = false);
|
||||
void open_menu(Menu&);
|
||||
void toggle_menu(Menu&);
|
||||
|
||||
WSMenuBar* current_menubar() { return m_current_menubar.ptr(); }
|
||||
void set_current_menubar(WSMenuBar*);
|
||||
void close_menubar(WSMenuBar&);
|
||||
MenuBar* current_menubar() { return m_current_menubar.ptr(); }
|
||||
void set_current_menubar(MenuBar*);
|
||||
void close_menubar(MenuBar&);
|
||||
|
||||
void close_bar();
|
||||
void close_everyone();
|
||||
void close_everyone_not_in_lineage(WSMenu&);
|
||||
void close_menu_and_descendants(WSMenu&);
|
||||
void close_everyone_not_in_lineage(Menu&);
|
||||
void close_menu_and_descendants(Menu&);
|
||||
|
||||
void close_all_menus_from_client(Badge<WSClientConnection>, WSClientConnection&);
|
||||
void close_all_menus_from_client(Badge<ClientConnection>, ClientConnection&);
|
||||
|
||||
void add_applet(WSWindow&);
|
||||
void remove_applet(WSWindow&);
|
||||
void invalidate_applet(const WSWindow&, const Gfx::Rect&);
|
||||
void add_applet(Window&);
|
||||
void remove_applet(Window&);
|
||||
void invalidate_applet(const Window&, const Gfx::Rect&);
|
||||
|
||||
Color menu_selection_color() const { return m_menu_selection_color; }
|
||||
WSMenu& system_menu() { return *m_system_menu; }
|
||||
WSMenu* find_internal_menu_by_id(int);
|
||||
Menu& system_menu() { return *m_system_menu; }
|
||||
Menu* find_internal_menu_by_id(int);
|
||||
int theme_index() const { return m_theme_index; }
|
||||
|
||||
template<typename Callback>
|
||||
|
@ -90,24 +90,24 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void close_menus(const Vector<WSMenu*>&);
|
||||
void close_menus(const Vector<Menu*>&);
|
||||
|
||||
WSWindow& window() { return *m_window; }
|
||||
const WSWindow& window() const { return *m_window; }
|
||||
Window& window() { return *m_window; }
|
||||
const Window& window() const { return *m_window; }
|
||||
|
||||
void handle_menu_mouse_event(WSMenu&, const WSMouseEvent&);
|
||||
void handle_menu_mouse_event(Menu&, const MouseEvent&);
|
||||
|
||||
void draw();
|
||||
void draw_applet(const WSWindow&);
|
||||
void draw_applet(const Window&);
|
||||
void tick_clock();
|
||||
|
||||
RefPtr<WSWindow> m_window;
|
||||
RefPtr<Window> m_window;
|
||||
String m_username;
|
||||
|
||||
WeakPtr<WSMenu> m_current_menu;
|
||||
Vector<WeakPtr<WSMenu>> m_open_menu_stack;
|
||||
WeakPtr<Menu> m_current_menu;
|
||||
Vector<WeakPtr<Menu>> m_open_menu_stack;
|
||||
|
||||
Vector<WeakPtr<WSWindow>> m_applets;
|
||||
Vector<WeakPtr<Window>> m_applets;
|
||||
|
||||
Gfx::Rect m_username_rect;
|
||||
|
||||
|
@ -122,19 +122,21 @@ private:
|
|||
};
|
||||
Vector<AppMetadata> m_apps;
|
||||
|
||||
HashMap<String, NonnullRefPtr<WSMenu>> m_app_category_menus;
|
||||
HashMap<String, NonnullRefPtr<Menu>> m_app_category_menus;
|
||||
|
||||
struct ThemeMetadata {
|
||||
String name;
|
||||
String path;
|
||||
};
|
||||
|
||||
RefPtr<WSMenu> m_system_menu;
|
||||
RefPtr<Menu> m_system_menu;
|
||||
Color m_menu_selection_color;
|
||||
|
||||
int m_theme_index { 0 };
|
||||
Vector<ThemeMetadata> m_themes;
|
||||
RefPtr<WSMenu> m_themes_menu;
|
||||
RefPtr<Menu> m_themes_menu;
|
||||
|
||||
WeakPtr<WSMenuBar> m_current_menubar;
|
||||
WeakPtr<MenuBar> m_current_menubar;
|
||||
};
|
||||
|
||||
}
|
|
@ -24,11 +24,11 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSScreen.h"
|
||||
#include "WSCompositor.h"
|
||||
#include "WSEvent.h"
|
||||
#include "WSEventLoop.h"
|
||||
#include "WSWindowManager.h"
|
||||
#include "Screen.h"
|
||||
#include "Compositor.h"
|
||||
#include "Event.h"
|
||||
#include "EventLoop.h"
|
||||
#include "WindowManager.h"
|
||||
#include <Kernel/FB.h>
|
||||
#include <Kernel/MousePacket.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -36,15 +36,17 @@
|
|||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static WSScreen* s_the;
|
||||
namespace WindowServer {
|
||||
|
||||
WSScreen& WSScreen::the()
|
||||
static Screen* s_the;
|
||||
|
||||
Screen& Screen::the()
|
||||
{
|
||||
ASSERT(s_the);
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WSScreen::WSScreen(unsigned desired_width, unsigned desired_height)
|
||||
Screen::Screen(unsigned desired_width, unsigned desired_height)
|
||||
{
|
||||
ASSERT(!s_the);
|
||||
s_the = this;
|
||||
|
@ -62,11 +64,11 @@ WSScreen::WSScreen(unsigned desired_width, unsigned desired_height)
|
|||
m_cursor_location = rect().center();
|
||||
}
|
||||
|
||||
WSScreen::~WSScreen()
|
||||
Screen::~Screen()
|
||||
{
|
||||
}
|
||||
|
||||
void WSScreen::set_resolution(int width, int height)
|
||||
void Screen::set_resolution(int width, int height)
|
||||
{
|
||||
FBResolution resolution { 0, (int)width, (int)height };
|
||||
int rc = fb_set_resolution(m_framebuffer_fd, &resolution);
|
||||
|
@ -74,7 +76,7 @@ void WSScreen::set_resolution(int width, int height)
|
|||
on_change_resolution(resolution.pitch, resolution.width, resolution.height);
|
||||
}
|
||||
|
||||
void WSScreen::on_change_resolution(int pitch, int width, int height)
|
||||
void Screen::on_change_resolution(int pitch, int width, int height)
|
||||
{
|
||||
if (m_framebuffer) {
|
||||
size_t previous_size_in_bytes = m_size_in_bytes;
|
||||
|
@ -95,25 +97,25 @@ void WSScreen::on_change_resolution(int pitch, int width, int height)
|
|||
m_cursor_location.constrain(rect());
|
||||
}
|
||||
|
||||
void WSScreen::set_buffer(int index)
|
||||
void Screen::set_buffer(int index)
|
||||
{
|
||||
ASSERT(m_can_set_buffer);
|
||||
int rc = fb_set_buffer(m_framebuffer_fd, index);
|
||||
ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
void WSScreen::on_receive_mouse_data(const MousePacket& packet)
|
||||
void Screen::on_receive_mouse_data(const MousePacket& packet)
|
||||
{
|
||||
auto prev_location = m_cursor_location;
|
||||
if (packet.is_relative) {
|
||||
m_cursor_location.move_by(packet.x, packet.y);
|
||||
#ifdef WSSCREEN_DEBUG
|
||||
dbgprintf("WSScreen: New Relative mouse point @ X %d, Y %d\n", m_cursor_location.x(), m_cursor_location.y());
|
||||
dbgprintf("Screen: New Relative mouse point @ X %d, Y %d\n", m_cursor_location.x(), m_cursor_location.y());
|
||||
#endif
|
||||
} else {
|
||||
m_cursor_location = { packet.x * m_width / 0xffff, packet.y * m_height / 0xffff };
|
||||
#ifdef WSSCREEN_DEBUG
|
||||
dbgprintf("WSScreen: New Absolute mouse point @ X %d, Y %d\n", m_cursor_location.x(), m_cursor_location.y());
|
||||
dbgprintf("Screen: New Absolute mouse point @ X %d, Y %d\n", m_cursor_location.x(), m_cursor_location.y());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -126,29 +128,31 @@ void WSScreen::on_receive_mouse_data(const MousePacket& packet)
|
|||
auto post_mousedown_or_mouseup_if_needed = [&](MouseButton button) {
|
||||
if (!(changed_buttons & (unsigned)button))
|
||||
return;
|
||||
auto message = make<WSMouseEvent>(buttons & (unsigned)button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, button, m_modifiers);
|
||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||
auto message = make<MouseEvent>(buttons & (unsigned)button ? Event::MouseDown : Event::MouseUp, m_cursor_location, buttons, button, m_modifiers);
|
||||
Core::EventLoop::current().post_event(WindowManager::the(), move(message));
|
||||
};
|
||||
post_mousedown_or_mouseup_if_needed(MouseButton::Left);
|
||||
post_mousedown_or_mouseup_if_needed(MouseButton::Right);
|
||||
post_mousedown_or_mouseup_if_needed(MouseButton::Middle);
|
||||
if (m_cursor_location != prev_location) {
|
||||
auto message = make<WSMouseEvent>(WSEvent::MouseMove, m_cursor_location, buttons, MouseButton::None, m_modifiers);
|
||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||
auto message = make<MouseEvent>(Event::MouseMove, m_cursor_location, buttons, MouseButton::None, m_modifiers);
|
||||
Core::EventLoop::current().post_event(WindowManager::the(), move(message));
|
||||
}
|
||||
|
||||
if (packet.z) {
|
||||
auto message = make<WSMouseEvent>(WSEvent::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, packet.z);
|
||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||
auto message = make<MouseEvent>(Event::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, packet.z);
|
||||
Core::EventLoop::current().post_event(WindowManager::the(), move(message));
|
||||
}
|
||||
|
||||
if (m_cursor_location != prev_location)
|
||||
WSCompositor::the().invalidate_cursor();
|
||||
Compositor::the().invalidate_cursor();
|
||||
}
|
||||
|
||||
void WSScreen::on_receive_keyboard_data(KeyEvent kernel_event)
|
||||
void Screen::on_receive_keyboard_data(::KeyEvent kernel_event)
|
||||
{
|
||||
m_modifiers = kernel_event.modifiers();
|
||||
auto message = make<WSKeyEvent>(kernel_event.is_press() ? WSEvent::KeyDown : WSEvent::KeyUp, kernel_event.key, kernel_event.character, kernel_event.modifiers());
|
||||
Core::EventLoop::current().post_event(WSWindowManager::the(), move(message));
|
||||
auto message = make<KeyEvent>(kernel_event.is_press() ? Event::KeyDown : Event::KeyUp, kernel_event.key, kernel_event.character, kernel_event.modifiers());
|
||||
Core::EventLoop::current().post_event(WindowManager::the(), move(message));
|
||||
}
|
||||
|
||||
}
|
|
@ -33,10 +33,12 @@
|
|||
|
||||
struct MousePacket;
|
||||
|
||||
class WSScreen {
|
||||
namespace WindowServer {
|
||||
|
||||
class Screen {
|
||||
public:
|
||||
WSScreen(unsigned width, unsigned height);
|
||||
~WSScreen();
|
||||
Screen(unsigned width, unsigned height);
|
||||
~Screen();
|
||||
|
||||
void set_resolution(int width, int height);
|
||||
bool can_set_buffer() { return m_can_set_buffer; }
|
||||
|
@ -47,7 +49,7 @@ public:
|
|||
size_t pitch() const { return m_pitch; }
|
||||
Gfx::RGBA32* scanline(int y);
|
||||
|
||||
static WSScreen& the();
|
||||
static Screen& the();
|
||||
|
||||
Gfx::Size size() const { return { width(), height() }; }
|
||||
Gfx::Rect rect() const { return { 0, 0, width(), height() }; }
|
||||
|
@ -56,7 +58,7 @@ public:
|
|||
unsigned mouse_button_state() const { return m_mouse_button_state; }
|
||||
|
||||
void on_receive_mouse_data(const MousePacket&);
|
||||
void on_receive_keyboard_data(KeyEvent);
|
||||
void on_receive_keyboard_data(::KeyEvent);
|
||||
|
||||
private:
|
||||
void on_change_resolution(int pitch, int width, int height);
|
||||
|
@ -76,7 +78,9 @@ private:
|
|||
unsigned m_modifiers { 0 };
|
||||
};
|
||||
|
||||
inline Gfx::RGBA32* WSScreen::scanline(int y)
|
||||
inline Gfx::RGBA32* Screen::scanline(int y)
|
||||
{
|
||||
return reinterpret_cast<Gfx::RGBA32*>(((u8*)m_framebuffer) + (y * m_pitch));
|
||||
}
|
||||
|
||||
}
|
|
@ -24,13 +24,15 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSWindow.h"
|
||||
#include "WSEvent.h"
|
||||
#include "WSEventLoop.h"
|
||||
#include "WSScreen.h"
|
||||
#include "WSWindowManager.h"
|
||||
#include <WindowServer/WSClientConnection.h>
|
||||
#include <WindowServer/WindowClientEndpoint.h>
|
||||
#include "Window.h"
|
||||
#include "ClientConnection.h"
|
||||
#include "Event.h"
|
||||
#include "EventLoop.h"
|
||||
#include "Screen.h"
|
||||
#include "WindowClientEndpoint.h"
|
||||
#include "WindowManager.h"
|
||||
|
||||
namespace WindowServer {
|
||||
|
||||
static String default_window_icon_path()
|
||||
{
|
||||
|
@ -45,16 +47,16 @@ static Gfx::Bitmap& default_window_icon()
|
|||
return *s_icon;
|
||||
}
|
||||
|
||||
WSWindow::WSWindow(Core::Object& parent, WSWindowType type)
|
||||
Window::Window(Core::Object& parent, WindowType type)
|
||||
: Core::Object(&parent)
|
||||
, m_type(type)
|
||||
, m_icon(default_window_icon())
|
||||
, m_frame(*this)
|
||||
{
|
||||
WSWindowManager::the().add_window(*this);
|
||||
WindowManager::the().add_window(*this);
|
||||
}
|
||||
|
||||
WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int window_id, bool modal, bool minimizable, bool resizable, bool fullscreen)
|
||||
Window::Window(ClientConnection& client, WindowType window_type, int window_id, bool modal, bool minimizable, bool resizable, bool fullscreen)
|
||||
: Core::Object(&client)
|
||||
, m_client(&client)
|
||||
, m_type(window_type)
|
||||
|
@ -68,31 +70,31 @@ WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int win
|
|||
, m_frame(*this)
|
||||
{
|
||||
// FIXME: This should not be hard-coded here.
|
||||
if (m_type == WSWindowType::Taskbar) {
|
||||
m_wm_event_mask = WSWMEventMask::WindowStateChanges | WSWMEventMask::WindowRemovals | WSWMEventMask::WindowIconChanges;
|
||||
if (m_type == WindowType::Taskbar) {
|
||||
m_wm_event_mask = WMEventMask::WindowStateChanges | WMEventMask::WindowRemovals | WMEventMask::WindowIconChanges;
|
||||
m_listens_to_wm_events = true;
|
||||
}
|
||||
WSWindowManager::the().add_window(*this);
|
||||
WindowManager::the().add_window(*this);
|
||||
}
|
||||
|
||||
WSWindow::~WSWindow()
|
||||
Window::~Window()
|
||||
{
|
||||
// Detach from client at the start of teardown since we don't want
|
||||
// to confuse things by trying to send messages to it.
|
||||
m_client = nullptr;
|
||||
|
||||
WSWindowManager::the().remove_window(*this);
|
||||
WindowManager::the().remove_window(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_title(const String& title)
|
||||
void Window::set_title(const String& title)
|
||||
{
|
||||
if (m_title == title)
|
||||
return;
|
||||
m_title = title;
|
||||
WSWindowManager::the().notify_title_changed(*this);
|
||||
WindowManager::the().notify_title_changed(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_rect(const Gfx::Rect& rect)
|
||||
void Window::set_rect(const Gfx::Rect& rect)
|
||||
{
|
||||
Gfx::Rect old_rect;
|
||||
if (m_rect == rect)
|
||||
|
@ -105,24 +107,24 @@ void WSWindow::set_rect(const Gfx::Rect& rect)
|
|||
m_frame.notify_window_rect_changed(old_rect, rect);
|
||||
}
|
||||
|
||||
void WSWindow::handle_mouse_event(const WSMouseEvent& event)
|
||||
void Window::handle_mouse_event(const MouseEvent& event)
|
||||
{
|
||||
set_automatic_cursor_tracking_enabled(event.buttons() != 0);
|
||||
|
||||
switch (event.type()) {
|
||||
case WSEvent::MouseMove:
|
||||
case Event::MouseMove:
|
||||
m_client->post_message(WindowClient::MouseMove(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta()));
|
||||
break;
|
||||
case WSEvent::MouseDown:
|
||||
case Event::MouseDown:
|
||||
m_client->post_message(WindowClient::MouseDown(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta()));
|
||||
break;
|
||||
case WSEvent::MouseDoubleClick:
|
||||
case Event::MouseDoubleClick:
|
||||
m_client->post_message(WindowClient::MouseDoubleClick(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta()));
|
||||
break;
|
||||
case WSEvent::MouseUp:
|
||||
case Event::MouseUp:
|
||||
m_client->post_message(WindowClient::MouseUp(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta()));
|
||||
break;
|
||||
case WSEvent::MouseWheel:
|
||||
case Event::MouseWheel:
|
||||
m_client->post_message(WindowClient::MouseWheel(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta()));
|
||||
break;
|
||||
default:
|
||||
|
@ -130,16 +132,15 @@ void WSWindow::handle_mouse_event(const WSMouseEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindow::update_menu_item_text(PopupMenuItem item)
|
||||
void Window::update_menu_item_text(PopupMenuItem item)
|
||||
{
|
||||
if (m_window_menu) {
|
||||
m_window_menu->item((int)item).set_text(item == PopupMenuItem::Minimize ?
|
||||
(m_minimized ? "Unminimize" : "Minimize") : (m_maximized ? "Restore" : "Maximize"));
|
||||
m_window_menu->item((int)item).set_text(item == PopupMenuItem::Minimize ? (m_minimized ? "Unminimize" : "Minimize") : (m_maximized ? "Restore" : "Maximize"));
|
||||
m_window_menu->redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void WSWindow::update_menu_item_enabled(PopupMenuItem item)
|
||||
void Window::update_menu_item_enabled(PopupMenuItem item)
|
||||
{
|
||||
if (m_window_menu) {
|
||||
m_window_menu->item((int)item).set_enabled(item == PopupMenuItem::Minimize ? m_minimizable : m_resizable);
|
||||
|
@ -147,7 +148,7 @@ void WSWindow::update_menu_item_enabled(PopupMenuItem item)
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindow::set_minimized(bool minimized)
|
||||
void Window::set_minimized(bool minimized)
|
||||
{
|
||||
if (m_minimized == minimized)
|
||||
return;
|
||||
|
@ -161,10 +162,10 @@ void WSWindow::set_minimized(bool minimized)
|
|||
if (!minimized)
|
||||
request_update({ {}, size() });
|
||||
invalidate();
|
||||
WSWindowManager::the().notify_minimization_state_changed(*this);
|
||||
WindowManager::the().notify_minimization_state_changed(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_minimizable(bool minimizable)
|
||||
void Window::set_minimizable(bool minimizable)
|
||||
{
|
||||
if (m_minimizable == minimizable)
|
||||
return;
|
||||
|
@ -173,23 +174,23 @@ void WSWindow::set_minimizable(bool minimizable)
|
|||
// TODO: Hide/show (or alternatively change enabled state of) window minimize button dynamically depending on value of m_minimizable
|
||||
}
|
||||
|
||||
void WSWindow::set_opacity(float opacity)
|
||||
void Window::set_opacity(float opacity)
|
||||
{
|
||||
if (m_opacity == opacity)
|
||||
return;
|
||||
m_opacity = opacity;
|
||||
WSWindowManager::the().notify_opacity_changed(*this);
|
||||
if (m_opacity == opacity)
|
||||
return;
|
||||
m_opacity = opacity;
|
||||
WindowManager::the().notify_opacity_changed(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_occluded(bool occluded)
|
||||
void Window::set_occluded(bool occluded)
|
||||
{
|
||||
if (m_occluded == occluded)
|
||||
return;
|
||||
m_occluded = occluded;
|
||||
WSWindowManager::the().notify_occlusion_state_changed(*this);
|
||||
WindowManager::the().notify_occlusion_state_changed(*this);
|
||||
}
|
||||
|
||||
void WSWindow::set_maximized(bool maximized)
|
||||
void Window::set_maximized(bool maximized)
|
||||
{
|
||||
if (m_maximized == maximized)
|
||||
return;
|
||||
|
@ -203,15 +204,15 @@ void WSWindow::set_maximized(bool maximized)
|
|||
auto old_rect = m_rect;
|
||||
if (maximized) {
|
||||
m_unmaximized_rect = m_rect;
|
||||
set_rect(WSWindowManager::the().maximized_window_rect(*this));
|
||||
set_rect(WindowManager::the().maximized_window_rect(*this));
|
||||
} else {
|
||||
set_rect(m_unmaximized_rect);
|
||||
}
|
||||
m_frame.did_set_maximized({}, maximized);
|
||||
Core::EventLoop::current().post_event(*this, make<WSResizeEvent>(old_rect, m_rect));
|
||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(old_rect, m_rect));
|
||||
}
|
||||
|
||||
void WSWindow::set_resizable(bool resizable)
|
||||
void Window::set_resizable(bool resizable)
|
||||
{
|
||||
if (m_resizable == resizable)
|
||||
return;
|
||||
|
@ -220,7 +221,7 @@ void WSWindow::set_resizable(bool resizable)
|
|||
// TODO: Hide/show (or alternatively change enabled state of) window maximize button dynamically depending on value of is_resizable()
|
||||
}
|
||||
|
||||
void WSWindow::event(Core::Event& event)
|
||||
void Window::event(Core::Event& event)
|
||||
{
|
||||
if (!m_client) {
|
||||
ASSERT(parent());
|
||||
|
@ -231,57 +232,57 @@ void WSWindow::event(Core::Event& event)
|
|||
if (is_blocked_by_modal_window())
|
||||
return;
|
||||
|
||||
if (static_cast<WSEvent&>(event).is_mouse_event())
|
||||
return handle_mouse_event(static_cast<const WSMouseEvent&>(event));
|
||||
if (static_cast<Event&>(event).is_mouse_event())
|
||||
return handle_mouse_event(static_cast<const MouseEvent&>(event));
|
||||
|
||||
switch (event.type()) {
|
||||
case WSEvent::WindowEntered:
|
||||
case Event::WindowEntered:
|
||||
m_client->post_message(WindowClient::WindowEntered(m_window_id));
|
||||
break;
|
||||
case WSEvent::WindowLeft:
|
||||
case Event::WindowLeft:
|
||||
m_client->post_message(WindowClient::WindowLeft(m_window_id));
|
||||
break;
|
||||
case WSEvent::KeyDown:
|
||||
case Event::KeyDown:
|
||||
m_client->post_message(
|
||||
WindowClient::KeyDown(m_window_id,
|
||||
(u8) static_cast<const WSKeyEvent&>(event).character(),
|
||||
(u32) static_cast<const WSKeyEvent&>(event).key(),
|
||||
static_cast<const WSKeyEvent&>(event).modifiers()));
|
||||
(u8) static_cast<const KeyEvent&>(event).character(),
|
||||
(u32) static_cast<const KeyEvent&>(event).key(),
|
||||
static_cast<const KeyEvent&>(event).modifiers()));
|
||||
break;
|
||||
case WSEvent::KeyUp:
|
||||
case Event::KeyUp:
|
||||
m_client->post_message(
|
||||
WindowClient::KeyUp(m_window_id,
|
||||
(u8) static_cast<const WSKeyEvent&>(event).character(),
|
||||
(u32) static_cast<const WSKeyEvent&>(event).key(),
|
||||
static_cast<const WSKeyEvent&>(event).modifiers()));
|
||||
(u8) static_cast<const KeyEvent&>(event).character(),
|
||||
(u32) static_cast<const KeyEvent&>(event).key(),
|
||||
static_cast<const KeyEvent&>(event).modifiers()));
|
||||
break;
|
||||
case WSEvent::WindowActivated:
|
||||
case Event::WindowActivated:
|
||||
m_client->post_message(WindowClient::WindowActivated(m_window_id));
|
||||
break;
|
||||
case WSEvent::WindowDeactivated:
|
||||
case Event::WindowDeactivated:
|
||||
m_client->post_message(WindowClient::WindowDeactivated(m_window_id));
|
||||
break;
|
||||
case WSEvent::WindowCloseRequest:
|
||||
case Event::WindowCloseRequest:
|
||||
m_client->post_message(WindowClient::WindowCloseRequest(m_window_id));
|
||||
break;
|
||||
case WSEvent::WindowResized:
|
||||
case Event::WindowResized:
|
||||
m_client->post_message(
|
||||
WindowClient::WindowResized(
|
||||
m_window_id,
|
||||
static_cast<const WSResizeEvent&>(event).old_rect(),
|
||||
static_cast<const WSResizeEvent&>(event).rect()));
|
||||
static_cast<const ResizeEvent&>(event).old_rect(),
|
||||
static_cast<const ResizeEvent&>(event).rect()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WSWindow::set_global_cursor_tracking_enabled(bool enabled)
|
||||
void Window::set_global_cursor_tracking_enabled(bool enabled)
|
||||
{
|
||||
m_global_cursor_tracking_enabled = enabled;
|
||||
}
|
||||
|
||||
void WSWindow::set_visible(bool b)
|
||||
void Window::set_visible(bool b)
|
||||
{
|
||||
if (m_visible == b)
|
||||
return;
|
||||
|
@ -289,32 +290,32 @@ void WSWindow::set_visible(bool b)
|
|||
invalidate();
|
||||
}
|
||||
|
||||
void WSWindow::invalidate()
|
||||
void Window::invalidate()
|
||||
{
|
||||
WSWindowManager::the().invalidate(*this);
|
||||
WindowManager::the().invalidate(*this);
|
||||
}
|
||||
|
||||
void WSWindow::invalidate(const Gfx::Rect& rect)
|
||||
void Window::invalidate(const Gfx::Rect& rect)
|
||||
{
|
||||
WSWindowManager::the().invalidate(*this, rect);
|
||||
WindowManager::the().invalidate(*this, rect);
|
||||
}
|
||||
|
||||
bool WSWindow::is_active() const
|
||||
bool Window::is_active() const
|
||||
{
|
||||
return WSWindowManager::the().active_window() == this;
|
||||
return WindowManager::the().active_window() == this;
|
||||
}
|
||||
|
||||
bool WSWindow::is_blocked_by_modal_window() const
|
||||
bool Window::is_blocked_by_modal_window() const
|
||||
{
|
||||
return !is_modal() && client() && client()->is_showing_modal_window();
|
||||
}
|
||||
|
||||
void WSWindow::set_default_icon()
|
||||
void Window::set_default_icon()
|
||||
{
|
||||
m_icon = default_window_icon();
|
||||
}
|
||||
|
||||
void WSWindow::request_update(const Gfx::Rect& rect)
|
||||
void Window::request_update(const Gfx::Rect& rect)
|
||||
{
|
||||
if (m_pending_paint_rects.is_empty()) {
|
||||
deferred_invoke([this](auto&) {
|
||||
|
@ -324,16 +325,16 @@ void WSWindow::request_update(const Gfx::Rect& rect)
|
|||
m_pending_paint_rects.add(rect);
|
||||
}
|
||||
|
||||
void WSWindow::popup_window_menu(const Gfx::Point& position)
|
||||
void Window::popup_window_menu(const Gfx::Point& position)
|
||||
{
|
||||
if (!m_window_menu) {
|
||||
m_window_menu = WSMenu::construct(nullptr, -1, "(Window Menu)");
|
||||
m_window_menu = Menu::construct(nullptr, -1, "(Window Menu)");
|
||||
m_window_menu->set_window_menu_of(*this);
|
||||
|
||||
m_window_menu->add_item(make<WSMenuItem>(*m_window_menu, 1, m_minimized ? "Unminimize" : "Minimize"));
|
||||
m_window_menu->add_item(make<WSMenuItem>(*m_window_menu, 2, m_maximized ? "Restore" : "Maximize"));
|
||||
m_window_menu->add_item(make<WSMenuItem>(*m_window_menu, WSMenuItem::Type::Separator));
|
||||
m_window_menu->add_item(make<WSMenuItem>(*m_window_menu, 3, "Close"));
|
||||
m_window_menu->add_item(make<MenuItem>(*m_window_menu, 1, m_minimized ? "Unminimize" : "Minimize"));
|
||||
m_window_menu->add_item(make<MenuItem>(*m_window_menu, 2, m_maximized ? "Restore" : "Maximize"));
|
||||
m_window_menu->add_item(make<MenuItem>(*m_window_menu, MenuItem::Type::Separator));
|
||||
m_window_menu->add_item(make<MenuItem>(*m_window_menu, 3, "Close"));
|
||||
|
||||
m_window_menu->item((int)PopupMenuItem::Minimize).set_enabled(m_minimizable);
|
||||
m_window_menu->item((int)PopupMenuItem::Maximize).set_enabled(m_resizable);
|
||||
|
@ -343,13 +344,13 @@ void WSWindow::popup_window_menu(const Gfx::Point& position)
|
|||
case 1:
|
||||
set_minimized(!m_minimized);
|
||||
if (!m_minimized)
|
||||
WSWindowManager::the().move_to_front_and_make_active(*this);
|
||||
WindowManager::the().move_to_front_and_make_active(*this);
|
||||
break;
|
||||
case 2:
|
||||
set_maximized(!m_maximized);
|
||||
if (m_minimized)
|
||||
set_minimized(false);
|
||||
WSWindowManager::the().move_to_front_and_make_active(*this);
|
||||
WindowManager::the().move_to_front_and_make_active(*this);
|
||||
break;
|
||||
case 3:
|
||||
request_close();
|
||||
|
@ -360,13 +361,13 @@ void WSWindow::popup_window_menu(const Gfx::Point& position)
|
|||
m_window_menu->popup(position);
|
||||
}
|
||||
|
||||
void WSWindow::request_close()
|
||||
void Window::request_close()
|
||||
{
|
||||
WSEvent close_request(WSEvent::WindowCloseRequest);
|
||||
Event close_request(Event::WindowCloseRequest);
|
||||
event(close_request);
|
||||
}
|
||||
|
||||
void WSWindow::set_fullscreen(bool fullscreen)
|
||||
void Window::set_fullscreen(bool fullscreen)
|
||||
{
|
||||
if (m_fullscreen == fullscreen)
|
||||
return;
|
||||
|
@ -374,15 +375,15 @@ void WSWindow::set_fullscreen(bool fullscreen)
|
|||
Gfx::Rect new_window_rect = m_rect;
|
||||
if (m_fullscreen) {
|
||||
m_saved_nonfullscreen_rect = m_rect;
|
||||
new_window_rect = WSScreen::the().rect();
|
||||
new_window_rect = Screen::the().rect();
|
||||
} else if (!m_saved_nonfullscreen_rect.is_empty()) {
|
||||
new_window_rect = m_saved_nonfullscreen_rect;
|
||||
}
|
||||
Core::EventLoop::current().post_event(*this, make<WSResizeEvent>(m_rect, new_window_rect));
|
||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(m_rect, new_window_rect));
|
||||
set_rect(new_window_rect);
|
||||
}
|
||||
|
||||
void WSWindow::set_tiled(WindowTileType tiled)
|
||||
void Window::set_tiled(WindowTileType tiled)
|
||||
{
|
||||
if (m_tiled == tiled)
|
||||
return;
|
||||
|
@ -391,23 +392,25 @@ void WSWindow::set_tiled(WindowTileType tiled)
|
|||
|
||||
int frame_width = (m_frame.rect().width() - m_rect.width()) / 2;
|
||||
switch (tiled) {
|
||||
case WindowTileType::None :
|
||||
case WindowTileType::None:
|
||||
set_rect(m_untiled_rect);
|
||||
break;
|
||||
case WindowTileType::Left :
|
||||
case WindowTileType::Left:
|
||||
m_untiled_rect = m_rect;
|
||||
set_rect(0,
|
||||
WSWindowManager::the().maximized_window_rect(*this).y(),
|
||||
WSScreen::the().width() / 2 - frame_width,
|
||||
WSWindowManager::the().maximized_window_rect(*this).height());
|
||||
WindowManager::the().maximized_window_rect(*this).y(),
|
||||
Screen::the().width() / 2 - frame_width,
|
||||
WindowManager::the().maximized_window_rect(*this).height());
|
||||
break;
|
||||
case WindowTileType::Right :
|
||||
case WindowTileType::Right:
|
||||
m_untiled_rect = m_rect;
|
||||
set_rect(WSScreen::the().width() / 2 + frame_width,
|
||||
WSWindowManager::the().maximized_window_rect(*this).y(),
|
||||
WSScreen::the().width() / 2 - frame_width,
|
||||
WSWindowManager::the().maximized_window_rect(*this).height());
|
||||
set_rect(Screen::the().width() / 2 + frame_width,
|
||||
WindowManager::the().maximized_window_rect(*this).y(),
|
||||
Screen::the().width() / 2 - frame_width,
|
||||
WindowManager::the().maximized_window_rect(*this).height());
|
||||
break;
|
||||
}
|
||||
Core::EventLoop::current().post_event(*this, make<WSResizeEvent>(old_rect, m_rect));
|
||||
Core::EventLoop::current().post_event(*this, make<ResizeEvent>(old_rect, m_rect));
|
||||
}
|
||||
|
||||
}
|
|
@ -29,18 +29,20 @@
|
|||
#include <AK/InlineLinkedList.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibGfx/DisjointRectSet.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/DisjointRectSet.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <WindowServer/WSWindowFrame.h>
|
||||
#include <WindowServer/WSWindowType.h>
|
||||
#include <WindowServer/WindowFrame.h>
|
||||
#include <WindowServer/WindowType.h>
|
||||
|
||||
class WSClientConnection;
|
||||
class WSCursor;
|
||||
class WSMenu;
|
||||
class WSMouseEvent;
|
||||
namespace WindowServer {
|
||||
|
||||
enum WSWMEventMask {
|
||||
class ClientConnection;
|
||||
class Cursor;
|
||||
class Menu;
|
||||
class MouseEvent;
|
||||
|
||||
enum WMEventMask {
|
||||
WindowRectChanges = 1 << 0,
|
||||
WindowStateChanges = 1 << 1,
|
||||
WindowIconChanges = 1 << 2,
|
||||
|
@ -58,13 +60,13 @@ enum class PopupMenuItem {
|
|||
Maximize,
|
||||
};
|
||||
|
||||
class WSWindow final : public Core::Object
|
||||
, public InlineLinkedListNode<WSWindow> {
|
||||
C_OBJECT(WSWindow)
|
||||
class Window final : public Core::Object
|
||||
, public InlineLinkedListNode<Window> {
|
||||
C_OBJECT(Window)
|
||||
public:
|
||||
WSWindow(WSClientConnection&, WSWindowType, int window_id, bool modal, bool minimizable, bool resizable, bool fullscreen);
|
||||
WSWindow(Core::Object&, WSWindowType);
|
||||
virtual ~WSWindow() override;
|
||||
Window(ClientConnection&, WindowType, int window_id, bool modal, bool minimizable, bool resizable, bool fullscreen);
|
||||
Window(Core::Object&, WindowType);
|
||||
virtual ~Window() override;
|
||||
|
||||
void popup_window_menu(const Gfx::Point&);
|
||||
void request_close();
|
||||
|
@ -98,20 +100,20 @@ public:
|
|||
|
||||
bool is_movable() const
|
||||
{
|
||||
return m_type == WSWindowType::Normal;
|
||||
return m_type == WindowType::Normal;
|
||||
}
|
||||
|
||||
WSWindowFrame& frame() { return m_frame; }
|
||||
const WSWindowFrame& frame() const { return m_frame; }
|
||||
WindowFrame& frame() { return m_frame; }
|
||||
const WindowFrame& frame() const { return m_frame; }
|
||||
|
||||
bool is_blocked_by_modal_window() const;
|
||||
|
||||
bool listens_to_wm_events() const { return m_listens_to_wm_events; }
|
||||
|
||||
WSClientConnection* client() { return m_client; }
|
||||
const WSClientConnection* client() const { return m_client; }
|
||||
ClientConnection* client() { return m_client; }
|
||||
const ClientConnection* client() const { return m_client; }
|
||||
|
||||
WSWindowType type() const { return m_type; }
|
||||
WindowType type() const { return m_type; }
|
||||
int window_id() const { return m_window_id; }
|
||||
|
||||
bool is_internal() const { return m_client_id == -1; }
|
||||
|
@ -166,7 +168,7 @@ public:
|
|||
|
||||
virtual void event(Core::Event&) override;
|
||||
|
||||
// Only used by WSWindowType::MenuApplet. Perhaps it could be a WSWindow 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::Rect& rect) { m_rect_in_menubar = rect; }
|
||||
const Gfx::Rect& rect_in_menubar() const { return m_rect_in_menubar; }
|
||||
|
||||
|
@ -204,8 +206,8 @@ public:
|
|||
|
||||
void set_default_icon();
|
||||
|
||||
const WSCursor* override_cursor() const { return m_override_cursor.ptr(); }
|
||||
void set_override_cursor(RefPtr<WSCursor>&& cursor) { m_override_cursor = move(cursor); }
|
||||
const Cursor* override_cursor() const { return m_override_cursor.ptr(); }
|
||||
void set_override_cursor(RefPtr<Cursor>&& cursor) { m_override_cursor = move(cursor); }
|
||||
|
||||
void request_update(const Gfx::Rect&);
|
||||
Gfx::DisjointRectSet take_pending_paint_rects() { return move(m_pending_paint_rects); }
|
||||
|
@ -218,23 +220,23 @@ public:
|
|||
void end_minimize_animation() { m_minimize_animation_step = -1; }
|
||||
|
||||
// For InlineLinkedList.
|
||||
// FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that.
|
||||
WSWindow* m_next { nullptr };
|
||||
WSWindow* m_prev { nullptr };
|
||||
// FIXME: Maybe make a ListHashSet and then WindowManager can just use that.
|
||||
Window* m_next { nullptr };
|
||||
Window* m_prev { nullptr };
|
||||
|
||||
void detach_client(Badge<WSClientConnection>) { m_client = nullptr; }
|
||||
void detach_client(Badge<ClientConnection>) { m_client = nullptr; }
|
||||
|
||||
private:
|
||||
void handle_mouse_event(const WSMouseEvent&);
|
||||
void handle_mouse_event(const MouseEvent&);
|
||||
void update_menu_item_text(PopupMenuItem item);
|
||||
void update_menu_item_enabled(PopupMenuItem item);
|
||||
|
||||
WSClientConnection* m_client { nullptr };
|
||||
ClientConnection* m_client { nullptr };
|
||||
String m_title;
|
||||
Gfx::Rect m_rect;
|
||||
Gfx::Rect m_saved_nonfullscreen_rect;
|
||||
Gfx::Rect m_taskbar_rect;
|
||||
WSWindowType m_type { WSWindowType::Normal };
|
||||
WindowType m_type { WindowType::Normal };
|
||||
bool m_global_cursor_tracking_enabled { false };
|
||||
bool m_automatic_cursor_tracking_enabled { false };
|
||||
bool m_visible { true };
|
||||
|
@ -258,12 +260,14 @@ private:
|
|||
Gfx::Size m_size_increment;
|
||||
Gfx::Size m_base_size;
|
||||
NonnullRefPtr<Gfx::Bitmap> m_icon;
|
||||
RefPtr<WSCursor> m_override_cursor;
|
||||
WSWindowFrame m_frame;
|
||||
RefPtr<Cursor> m_override_cursor;
|
||||
WindowFrame m_frame;
|
||||
unsigned m_wm_event_mask { 0 };
|
||||
Gfx::DisjointRectSet m_pending_paint_rects;
|
||||
Gfx::Rect m_unmaximized_rect;
|
||||
Gfx::Rect m_rect_in_menubar;
|
||||
RefPtr<WSMenu> m_window_menu;
|
||||
RefPtr<Menu> m_window_menu;
|
||||
int m_minimize_animation_step { -1 };
|
||||
};
|
||||
|
||||
}
|
|
@ -28,12 +28,14 @@
|
|||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <WindowServer/WSButton.h>
|
||||
#include <WindowServer/WSCompositor.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/WSWindow.h>
|
||||
#include <WindowServer/WSWindowFrame.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/Button.h>
|
||||
#include <WindowServer/Compositor.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/Window.h>
|
||||
#include <WindowServer/WindowFrame.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
|
||||
namespace WindowServer {
|
||||
|
||||
static const int window_titlebar_height = 19;
|
||||
|
||||
|
@ -101,7 +103,7 @@ static Gfx::CharacterBitmap* s_unmaximize_button_bitmap;
|
|||
static const int s_unmaximize_button_bitmap_width = 8;
|
||||
static const int s_unmaximize_button_bitmap_height = 9;
|
||||
|
||||
WSWindowFrame::WSWindowFrame(WSWindow& window)
|
||||
WindowFrame::WindowFrame(Window& window)
|
||||
: m_window(window)
|
||||
{
|
||||
if (!s_close_button_bitmap)
|
||||
|
@ -116,12 +118,12 @@ WSWindowFrame::WSWindowFrame(WSWindow& window)
|
|||
if (!s_unmaximize_button_bitmap)
|
||||
s_unmaximize_button_bitmap = &Gfx::CharacterBitmap::create_from_ascii(s_unmaximize_button_bitmap_data, s_unmaximize_button_bitmap_width, s_unmaximize_button_bitmap_height).leak_ref();
|
||||
|
||||
m_buttons.append(make<WSButton>(*this, *s_close_button_bitmap, [this](auto&) {
|
||||
m_buttons.append(make<Button>(*this, *s_close_button_bitmap, [this](auto&) {
|
||||
m_window.request_close();
|
||||
}));
|
||||
|
||||
if (window.is_resizable()) {
|
||||
auto button = make<WSButton>(*this, *s_maximize_button_bitmap, [this](auto&) {
|
||||
auto button = make<Button>(*this, *s_maximize_button_bitmap, [this](auto&) {
|
||||
m_window.set_maximized(!m_window.is_maximized());
|
||||
});
|
||||
m_maximize_button = button.ptr();
|
||||
|
@ -129,7 +131,7 @@ WSWindowFrame::WSWindowFrame(WSWindow& window)
|
|||
}
|
||||
|
||||
if (window.is_minimizable()) {
|
||||
auto button = make<WSButton>(*this, *s_minimize_button_bitmap, [this](auto&) {
|
||||
auto button = make<Button>(*this, *s_minimize_button_bitmap, [this](auto&) {
|
||||
m_window.set_minimized(true);
|
||||
});
|
||||
m_minimize_button = button.ptr();
|
||||
|
@ -137,22 +139,22 @@ WSWindowFrame::WSWindowFrame(WSWindow& window)
|
|||
}
|
||||
}
|
||||
|
||||
WSWindowFrame::~WSWindowFrame()
|
||||
WindowFrame::~WindowFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void WSWindowFrame::did_set_maximized(Badge<WSWindow>, bool maximized)
|
||||
void WindowFrame::did_set_maximized(Badge<Window>, bool maximized)
|
||||
{
|
||||
ASSERT(m_maximize_button);
|
||||
m_maximize_button->set_bitmap(maximized ? *s_unmaximize_button_bitmap : *s_maximize_button_bitmap);
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowFrame::title_bar_rect() const
|
||||
Gfx::Rect WindowFrame::title_bar_rect() const
|
||||
{
|
||||
return { 3, 3, m_window.width(), window_titlebar_height };
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowFrame::title_bar_icon_rect() const
|
||||
Gfx::Rect WindowFrame::title_bar_icon_rect() const
|
||||
{
|
||||
auto titlebar_rect = title_bar_rect();
|
||||
return {
|
||||
|
@ -163,7 +165,7 @@ Gfx::Rect WSWindowFrame::title_bar_icon_rect() const
|
|||
};
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowFrame::title_bar_text_rect() const
|
||||
Gfx::Rect WindowFrame::title_bar_text_rect() const
|
||||
{
|
||||
auto titlebar_rect = title_bar_rect();
|
||||
auto titlebar_icon_rect = title_bar_icon_rect();
|
||||
|
@ -175,15 +177,15 @@ Gfx::Rect WSWindowFrame::title_bar_text_rect() const
|
|||
};
|
||||
}
|
||||
|
||||
void WSWindowFrame::paint(Gfx::Painter& painter)
|
||||
void WindowFrame::paint(Gfx::Painter& painter)
|
||||
{
|
||||
Gfx::PainterStateSaver saver(painter);
|
||||
painter.translate(rect().location());
|
||||
|
||||
if (m_window.type() != WSWindowType::Normal)
|
||||
if (m_window.type() != WindowType::Normal)
|
||||
return;
|
||||
|
||||
auto palette = WSWindowManager::the().palette();
|
||||
auto palette = WindowManager::the().palette();
|
||||
auto& window = m_window;
|
||||
|
||||
auto titlebar_rect = title_bar_rect();
|
||||
|
@ -198,7 +200,7 @@ void WSWindowFrame::paint(Gfx::Painter& painter)
|
|||
Color border_color;
|
||||
Color border_color2;
|
||||
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
|
||||
if (&window == wm.m_highlight_window) {
|
||||
border_color = palette.highlight_window_border1();
|
||||
|
@ -252,13 +254,13 @@ void WSWindowFrame::paint(Gfx::Painter& painter)
|
|||
}
|
||||
}
|
||||
|
||||
static Gfx::Rect frame_rect_for_window(WSWindow& window, const Gfx::Rect& rect)
|
||||
static Gfx::Rect frame_rect_for_window(Window& window, const Gfx::Rect& rect)
|
||||
{
|
||||
auto type = window.type();
|
||||
auto offset = !window.show_titlebar() ? (window_titlebar_height + 1) : 0;
|
||||
|
||||
switch (type) {
|
||||
case WSWindowType::Normal:
|
||||
case WindowType::Normal:
|
||||
return { rect.x() - 3,
|
||||
rect.y() - window_titlebar_height - 4 + offset,
|
||||
rect.width() + 6,
|
||||
|
@ -268,22 +270,22 @@ static Gfx::Rect frame_rect_for_window(WSWindow& window, const Gfx::Rect& rect)
|
|||
}
|
||||
}
|
||||
|
||||
static Gfx::Rect frame_rect_for_window(WSWindow& window)
|
||||
static Gfx::Rect frame_rect_for_window(Window& window)
|
||||
{
|
||||
return frame_rect_for_window(window, window.rect());
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowFrame::rect() const
|
||||
Gfx::Rect WindowFrame::rect() const
|
||||
{
|
||||
return frame_rect_for_window(m_window);
|
||||
}
|
||||
|
||||
void WSWindowFrame::invalidate_title_bar()
|
||||
void WindowFrame::invalidate_title_bar()
|
||||
{
|
||||
WSWindowManager::the().invalidate(title_bar_rect().translated(rect().location()));
|
||||
WindowManager::the().invalidate(title_bar_rect().translated(rect().location()));
|
||||
}
|
||||
|
||||
void WSWindowFrame::notify_window_rect_changed(const Gfx::Rect& old_rect, const Gfx::Rect& new_rect)
|
||||
void WindowFrame::notify_window_rect_changed(const Gfx::Rect& old_rect, const Gfx::Rect& new_rect)
|
||||
{
|
||||
int window_button_width = 15;
|
||||
int window_button_height = 15;
|
||||
|
@ -296,25 +298,24 @@ void WSWindowFrame::notify_window_rect_changed(const Gfx::Rect& old_rect, const
|
|||
button.set_relative_rect(rect);
|
||||
}
|
||||
|
||||
auto& wm = WSWindowManager::the();
|
||||
auto& wm = WindowManager::the();
|
||||
wm.invalidate(frame_rect_for_window(m_window, old_rect));
|
||||
wm.invalidate(frame_rect_for_window(m_window, new_rect));
|
||||
wm.notify_rect_changed(m_window, old_rect, new_rect);
|
||||
}
|
||||
|
||||
void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
|
||||
void WindowFrame::on_mouse_event(const MouseEvent& event)
|
||||
{
|
||||
ASSERT(!m_window.is_fullscreen());
|
||||
|
||||
if (m_window.is_blocked_by_modal_window())
|
||||
return;
|
||||
|
||||
auto& wm = WSWindowManager::the();
|
||||
if (m_window.type() != WSWindowType::Normal)
|
||||
auto& wm = WindowManager::the();
|
||||
if (m_window.type() != WindowType::Normal)
|
||||
return;
|
||||
|
||||
if (event.type() == WSEvent::MouseDown && (event.button() == MouseButton::Left || event.button() == MouseButton::Right) &&
|
||||
title_bar_icon_rect().contains(event.position())) {
|
||||
if (event.type() == Event::MouseDown && (event.button() == MouseButton::Left || event.button() == MouseButton::Right) && title_bar_icon_rect().contains(event.position())) {
|
||||
wm.move_to_front_and_make_active(m_window);
|
||||
m_window.popup_window_menu(event.position().translated(rect().location()));
|
||||
return;
|
||||
|
@ -329,14 +330,14 @@ void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
|
|||
if (adjusted_title_bar_rect.contains(event.position())) {
|
||||
wm.clear_resize_candidate();
|
||||
|
||||
if (event.type() == WSEvent::MouseDown)
|
||||
if (event.type() == Event::MouseDown)
|
||||
wm.move_to_front_and_make_active(m_window);
|
||||
|
||||
for (auto& button : m_buttons) {
|
||||
if (button.relative_rect().contains(event.position()))
|
||||
return button.on_mouse_event(event.translated(-button.relative_rect().location()));
|
||||
}
|
||||
if (event.type() == WSEvent::MouseDown) {
|
||||
if (event.type() == Event::MouseDown) {
|
||||
if (event.button() == MouseButton::Right) {
|
||||
m_window.popup_window_menu(event.position().translated(rect().location()));
|
||||
return;
|
||||
|
@ -347,7 +348,7 @@ void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_window.is_resizable() && event.type() == WSEvent::MouseMove && event.buttons() == 0) {
|
||||
if (m_window.is_resizable() && event.type() == Event::MouseMove && event.buttons() == 0) {
|
||||
constexpr ResizeDirection direction_for_hot_area[3][3] = {
|
||||
{ ResizeDirection::UpLeft, ResizeDirection::Up, ResizeDirection::UpRight },
|
||||
{ ResizeDirection::Left, ResizeDirection::None, ResizeDirection::Right },
|
||||
|
@ -360,10 +361,12 @@ void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
|
|||
int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3));
|
||||
int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3));
|
||||
wm.set_resize_candidate(m_window, direction_for_hot_area[hot_area_row][hot_area_column]);
|
||||
WSCompositor::the().invalidate_cursor();
|
||||
Compositor::the().invalidate_cursor();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_window.is_resizable() && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left)
|
||||
if (m_window.is_resizable() && event.type() == Event::MouseDown && event.button() == MouseButton::Left)
|
||||
wm.start_window_resize(m_window, event.translated(rect().location()));
|
||||
}
|
||||
|
||||
}
|
|
@ -34,18 +34,20 @@ class Painter;
|
|||
class Rect;
|
||||
}
|
||||
|
||||
class WSButton;
|
||||
class WSMouseEvent;
|
||||
class WSWindow;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSWindowFrame {
|
||||
class Button;
|
||||
class MouseEvent;
|
||||
class Window;
|
||||
|
||||
class WindowFrame {
|
||||
public:
|
||||
WSWindowFrame(WSWindow&);
|
||||
~WSWindowFrame();
|
||||
WindowFrame(Window&);
|
||||
~WindowFrame();
|
||||
|
||||
Gfx::Rect rect() const;
|
||||
void paint(Gfx::Painter&);
|
||||
void on_mouse_event(const WSMouseEvent&);
|
||||
void on_mouse_event(const MouseEvent&);
|
||||
void notify_window_rect_changed(const Gfx::Rect& old_rect, const Gfx::Rect& new_rect);
|
||||
void invalidate_title_bar();
|
||||
|
||||
|
@ -53,11 +55,13 @@ public:
|
|||
Gfx::Rect title_bar_icon_rect() const;
|
||||
Gfx::Rect title_bar_text_rect() const;
|
||||
|
||||
void did_set_maximized(Badge<WSWindow>, bool);
|
||||
void did_set_maximized(Badge<Window>, bool);
|
||||
|
||||
private:
|
||||
WSWindow& m_window;
|
||||
NonnullOwnPtrVector<WSButton> m_buttons;
|
||||
WSButton* m_maximize_button { nullptr };
|
||||
WSButton* m_minimize_button { nullptr };
|
||||
Window& m_window;
|
||||
NonnullOwnPtrVector<Button> m_buttons;
|
||||
Button* m_maximize_button { nullptr };
|
||||
Button* m_minimize_button { nullptr };
|
||||
};
|
||||
|
||||
}
|
|
@ -24,14 +24,14 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "WSWindowManager.h"
|
||||
#include "WSCompositor.h"
|
||||
#include "WSEventLoop.h"
|
||||
#include "WSMenu.h"
|
||||
#include "WSMenuBar.h"
|
||||
#include "WSMenuItem.h"
|
||||
#include "WSScreen.h"
|
||||
#include "WSWindow.h"
|
||||
#include "WindowManager.h"
|
||||
#include "Compositor.h"
|
||||
#include "EventLoop.h"
|
||||
#include "Menu.h"
|
||||
#include "MenuBar.h"
|
||||
#include "MenuItem.h"
|
||||
#include "Screen.h"
|
||||
#include "Window.h"
|
||||
#include <AK/LogStream.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Vector.h>
|
||||
|
@ -40,9 +40,9 @@
|
|||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <LibGfx/SystemTheme.h>
|
||||
#include <WindowServer/WSButton.h>
|
||||
#include <WindowServer/WSClientConnection.h>
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/Button.h>
|
||||
#include <WindowServer/ClientConnection.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/WindowClientEndpoint.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@ -54,15 +54,17 @@
|
|||
//#define MOVE_DEBUG
|
||||
//#define DOUBLECLICK_DEBUG
|
||||
|
||||
static WSWindowManager* s_the;
|
||||
namespace WindowServer {
|
||||
|
||||
WSWindowManager& WSWindowManager::the()
|
||||
static WindowManager* s_the;
|
||||
|
||||
WindowManager& WindowManager::the()
|
||||
{
|
||||
ASSERT(s_the);
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WSWindowManager::WSWindowManager(const Gfx::PaletteImpl& palette)
|
||||
WindowManager::WindowManager(const Gfx::PaletteImpl& palette)
|
||||
: m_palette(palette)
|
||||
{
|
||||
s_the = this;
|
||||
|
@ -70,33 +72,33 @@ WSWindowManager::WSWindowManager(const Gfx::PaletteImpl& palette)
|
|||
reload_config(false);
|
||||
|
||||
invalidate();
|
||||
WSCompositor::the().compose();
|
||||
Compositor::the().compose();
|
||||
}
|
||||
|
||||
WSWindowManager::~WSWindowManager()
|
||||
WindowManager::~WindowManager()
|
||||
{
|
||||
}
|
||||
|
||||
NonnullRefPtr<WSCursor> WSWindowManager::get_cursor(const String& name, const Gfx::Point& hotspot)
|
||||
NonnullRefPtr<Cursor> WindowManager::get_cursor(const String& name, const Gfx::Point& hotspot)
|
||||
{
|
||||
auto path = m_wm_config->read_entry("Cursor", name, "/res/cursors/arrow.png");
|
||||
auto gb = Gfx::Bitmap::load_from_file(path);
|
||||
if (gb)
|
||||
return WSCursor::create(*gb, hotspot);
|
||||
return WSCursor::create(*Gfx::Bitmap::load_from_file("/res/cursors/arrow.png"));
|
||||
return Cursor::create(*gb, hotspot);
|
||||
return Cursor::create(*Gfx::Bitmap::load_from_file("/res/cursors/arrow.png"));
|
||||
}
|
||||
|
||||
NonnullRefPtr<WSCursor> WSWindowManager::get_cursor(const String& name)
|
||||
NonnullRefPtr<Cursor> WindowManager::get_cursor(const String& name)
|
||||
{
|
||||
auto path = m_wm_config->read_entry("Cursor", name, "/res/cursors/arrow.png");
|
||||
auto gb = Gfx::Bitmap::load_from_file(path);
|
||||
|
||||
if (gb)
|
||||
return WSCursor::create(*gb);
|
||||
return WSCursor::create(*Gfx::Bitmap::load_from_file("/res/cursors/arrow.png"));
|
||||
return Cursor::create(*gb);
|
||||
return Cursor::create(*Gfx::Bitmap::load_from_file("/res/cursors/arrow.png"));
|
||||
}
|
||||
|
||||
void WSWindowManager::reload_config(bool set_screen)
|
||||
void WindowManager::reload_config(bool set_screen)
|
||||
{
|
||||
m_wm_config = Core::ConfigFile::get_for_app("WindowManager");
|
||||
|
||||
|
@ -118,32 +120,32 @@ void WSWindowManager::reload_config(bool set_screen)
|
|||
m_drag_cursor = get_cursor("Drag");
|
||||
}
|
||||
|
||||
const Gfx::Font& WSWindowManager::font() const
|
||||
const Gfx::Font& WindowManager::font() const
|
||||
{
|
||||
return Gfx::Font::default_font();
|
||||
}
|
||||
|
||||
const Gfx::Font& WSWindowManager::window_title_font() const
|
||||
const Gfx::Font& WindowManager::window_title_font() const
|
||||
{
|
||||
return Gfx::Font::default_bold_font();
|
||||
}
|
||||
|
||||
const Gfx::Font& WSWindowManager::menu_font() const
|
||||
const Gfx::Font& WindowManager::menu_font() const
|
||||
{
|
||||
return Gfx::Font::default_font();
|
||||
}
|
||||
|
||||
const Gfx::Font& WSWindowManager::app_menu_font() const
|
||||
const Gfx::Font& WindowManager::app_menu_font() const
|
||||
{
|
||||
return Gfx::Font::default_bold_font();
|
||||
}
|
||||
|
||||
void WSWindowManager::set_resolution(int width, int height)
|
||||
void WindowManager::set_resolution(int width, int height)
|
||||
{
|
||||
WSCompositor::the().set_resolution(width, height);
|
||||
WSMenuManager::the().set_needs_window_resize();
|
||||
WSClientConnection::for_each_client([&](WSClientConnection& client) {
|
||||
client.notify_about_new_screen_rect(WSScreen::the().rect());
|
||||
Compositor::the().set_resolution(width, height);
|
||||
MenuManager::the().set_needs_window_resize();
|
||||
ClientConnection::for_each_client([&](ClientConnection& client) {
|
||||
client.notify_about_new_screen_rect(Screen::the().rect());
|
||||
});
|
||||
if (m_wm_config) {
|
||||
dbg() << "Saving resolution: " << Gfx::Size(width, height) << " to config file at " << m_wm_config->file_name();
|
||||
|
@ -153,23 +155,23 @@ void WSWindowManager::set_resolution(int width, int height)
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindowManager::add_window(WSWindow& window)
|
||||
void WindowManager::add_window(Window& window)
|
||||
{
|
||||
m_windows_in_order.append(&window);
|
||||
|
||||
if (window.is_fullscreen()) {
|
||||
Core::EventLoop::current().post_event(window, make<WSResizeEvent>(window.rect(), WSScreen::the().rect()));
|
||||
window.set_rect(WSScreen::the().rect());
|
||||
Core::EventLoop::current().post_event(window, make<ResizeEvent>(window.rect(), Screen::the().rect()));
|
||||
window.set_rect(Screen::the().rect());
|
||||
}
|
||||
|
||||
set_active_window(&window);
|
||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||
if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher)
|
||||
m_switcher.refresh();
|
||||
|
||||
recompute_occlusions();
|
||||
|
||||
if (window.listens_to_wm_events()) {
|
||||
for_each_window([&](WSWindow& other_window) {
|
||||
for_each_window([&](Window& other_window) {
|
||||
if (&window != &other_window) {
|
||||
tell_wm_listener_about_window(window, other_window);
|
||||
tell_wm_listener_about_window_icon(window, other_window);
|
||||
|
@ -181,7 +183,7 @@ void WSWindowManager::add_window(WSWindow& window)
|
|||
tell_wm_listeners_window_state_changed(window);
|
||||
}
|
||||
|
||||
void WSWindowManager::move_to_front_and_make_active(WSWindow& window)
|
||||
void WindowManager::move_to_front_and_make_active(Window& window)
|
||||
{
|
||||
if (window.is_blocked_by_modal_window())
|
||||
return;
|
||||
|
@ -196,20 +198,19 @@ void WSWindowManager::move_to_front_and_make_active(WSWindow& window)
|
|||
set_active_window(&window);
|
||||
}
|
||||
|
||||
void WSWindowManager::remove_window(WSWindow& window)
|
||||
void WindowManager::remove_window(Window& window)
|
||||
{
|
||||
invalidate(window);
|
||||
m_windows_in_order.remove(&window);
|
||||
if (window.is_active())
|
||||
pick_new_active_window();
|
||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||
if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher)
|
||||
m_switcher.refresh();
|
||||
|
||||
|
||||
recompute_occlusions();
|
||||
|
||||
for_each_window_listening_to_wm_events([&window](WSWindow& listener) {
|
||||
if (!(listener.wm_event_mask() & WSWMEventMask::WindowRemovals))
|
||||
for_each_window_listening_to_wm_events([&window](Window& listener) {
|
||||
if (!(listener.wm_event_mask() & WMEventMask::WindowRemovals))
|
||||
return IterationDecision::Continue;
|
||||
if (!window.is_internal())
|
||||
listener.client()->post_message(WindowClient::WM_WindowRemoved(listener.window_id(), window.client_id(), window.window_id()));
|
||||
|
@ -217,27 +218,27 @@ void WSWindowManager::remove_window(WSWindow& window)
|
|||
});
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow& window)
|
||||
void WindowManager::tell_wm_listener_about_window(Window& listener, Window& window)
|
||||
{
|
||||
if (!(listener.wm_event_mask() & WSWMEventMask::WindowStateChanges))
|
||||
if (!(listener.wm_event_mask() & WMEventMask::WindowStateChanges))
|
||||
return;
|
||||
if (window.is_internal())
|
||||
return;
|
||||
listener.client()->post_message(WindowClient::WM_WindowStateChanged(listener.window_id(), window.client_id(), window.window_id(), window.is_active(), window.is_minimized(), (i32)window.type(), window.title(), window.rect()));
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow& window)
|
||||
void WindowManager::tell_wm_listener_about_window_rect(Window& listener, Window& window)
|
||||
{
|
||||
if (!(listener.wm_event_mask() & WSWMEventMask::WindowRectChanges))
|
||||
if (!(listener.wm_event_mask() & WMEventMask::WindowRectChanges))
|
||||
return;
|
||||
if (window.is_internal())
|
||||
return;
|
||||
listener.client()->post_message(WindowClient::WM_WindowRectChanged(listener.window_id(), window.client_id(), window.window_id(), window.rect()));
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow& window)
|
||||
void WindowManager::tell_wm_listener_about_window_icon(Window& listener, Window& window)
|
||||
{
|
||||
if (!(listener.wm_event_mask() & WSWMEventMask::WindowIconChanges))
|
||||
if (!(listener.wm_event_mask() & WMEventMask::WindowIconChanges))
|
||||
return;
|
||||
if (window.is_internal())
|
||||
return;
|
||||
|
@ -250,35 +251,35 @@ void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSW
|
|||
listener.client()->post_message(WindowClient::WM_WindowIconBitmapChanged(listener.window_id(), window.client_id(), window.window_id(), window.icon().shared_buffer_id(), window.icon().size()));
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window)
|
||||
void WindowManager::tell_wm_listeners_window_state_changed(Window& window)
|
||||
{
|
||||
for_each_window_listening_to_wm_events([&](WSWindow& listener) {
|
||||
for_each_window_listening_to_wm_events([&](Window& listener) {
|
||||
tell_wm_listener_about_window(listener, window);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listeners_window_icon_changed(WSWindow& window)
|
||||
void WindowManager::tell_wm_listeners_window_icon_changed(Window& window)
|
||||
{
|
||||
for_each_window_listening_to_wm_events([&](WSWindow& listener) {
|
||||
for_each_window_listening_to_wm_events([&](Window& listener) {
|
||||
tell_wm_listener_about_window_icon(listener, window);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
void WSWindowManager::tell_wm_listeners_window_rect_changed(WSWindow& window)
|
||||
void WindowManager::tell_wm_listeners_window_rect_changed(Window& window)
|
||||
{
|
||||
for_each_window_listening_to_wm_events([&](WSWindow& listener) {
|
||||
for_each_window_listening_to_wm_events([&](Window& listener) {
|
||||
tell_wm_listener_about_window_rect(listener, window);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_title_changed(WSWindow& window)
|
||||
void WindowManager::notify_title_changed(Window& window)
|
||||
{
|
||||
if (window.type() != WSWindowType::Normal)
|
||||
if (window.type() != WindowType::Normal)
|
||||
return;
|
||||
dbg() << "[WM] WSWindow{" << &window << "} title set to \"" << window.title() << '"';
|
||||
dbg() << "[WM] Window{" << &window << "} title set to \"" << window.title() << '"';
|
||||
invalidate(window.frame().rect());
|
||||
if (m_switcher.is_visible())
|
||||
m_switcher.refresh();
|
||||
|
@ -286,26 +287,26 @@ void WSWindowManager::notify_title_changed(WSWindow& window)
|
|||
tell_wm_listeners_window_state_changed(window);
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_rect_changed(WSWindow& window, const Gfx::Rect& old_rect, const Gfx::Rect& new_rect)
|
||||
void WindowManager::notify_rect_changed(Window& window, const Gfx::Rect& old_rect, const Gfx::Rect& new_rect)
|
||||
{
|
||||
UNUSED_PARAM(old_rect);
|
||||
UNUSED_PARAM(new_rect);
|
||||
#ifdef RESIZE_DEBUG
|
||||
dbg() << "[WM] WSWindow " << &window << " rect changed " << old_rect << " -> " << new_rect;
|
||||
dbg() << "[WM] Window " << &window << " rect changed " << old_rect << " -> " << new_rect;
|
||||
#endif
|
||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||
if (m_switcher.is_visible() && window.type() != WindowType::WindowSwitcher)
|
||||
m_switcher.refresh();
|
||||
|
||||
recompute_occlusions();
|
||||
|
||||
tell_wm_listeners_window_rect_changed(window);
|
||||
|
||||
WSMenuManager::the().refresh();
|
||||
MenuManager::the().refresh();
|
||||
}
|
||||
|
||||
void WSWindowManager::recompute_occlusions()
|
||||
void WindowManager::recompute_occlusions()
|
||||
{
|
||||
for_each_visible_window_from_back_to_front([&](WSWindow& window) {
|
||||
for_each_visible_window_from_back_to_front([&](Window& window) {
|
||||
if (m_switcher.is_visible()) {
|
||||
window.set_occluded(false);
|
||||
} else {
|
||||
|
@ -318,12 +319,12 @@ void WSWindowManager::recompute_occlusions()
|
|||
});
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_opacity_changed(WSWindow&)
|
||||
void WindowManager::notify_opacity_changed(Window&)
|
||||
{
|
||||
recompute_occlusions();
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_minimization_state_changed(WSWindow& window)
|
||||
void WindowManager::notify_minimization_state_changed(Window& window)
|
||||
{
|
||||
tell_wm_listeners_window_state_changed(window);
|
||||
|
||||
|
@ -334,16 +335,16 @@ void WSWindowManager::notify_minimization_state_changed(WSWindow& window)
|
|||
pick_new_active_window();
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_occlusion_state_changed(WSWindow& window)
|
||||
void WindowManager::notify_occlusion_state_changed(Window& window)
|
||||
{
|
||||
if (window.client())
|
||||
window.client()->post_message(WindowClient::WindowStateChanged(window.window_id(), window.is_minimized(), window.is_occluded()));
|
||||
}
|
||||
|
||||
void WSWindowManager::pick_new_active_window()
|
||||
void WindowManager::pick_new_active_window()
|
||||
{
|
||||
bool new_window_picked = false;
|
||||
for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, [&](WSWindow& candidate) {
|
||||
for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, [&](Window& candidate) {
|
||||
set_active_window(&candidate);
|
||||
new_window_picked = true;
|
||||
return IterationDecision::Break;
|
||||
|
@ -352,10 +353,10 @@ void WSWindowManager::pick_new_active_window()
|
|||
set_active_window(nullptr);
|
||||
}
|
||||
|
||||
void WSWindowManager::start_window_move(WSWindow& window, const WSMouseEvent& event)
|
||||
void WindowManager::start_window_move(Window& window, const MouseEvent& event)
|
||||
{
|
||||
#ifdef MOVE_DEBUG
|
||||
dbg() << "[WM] Begin moving WSWindow{" << &window << "}";
|
||||
dbg() << "[WM] Begin moving Window{" << &window << "}";
|
||||
#endif
|
||||
move_to_front_and_make_active(window);
|
||||
m_move_window = window.make_weak_ptr();
|
||||
|
@ -364,7 +365,7 @@ void WSWindowManager::start_window_move(WSWindow& window, const WSMouseEvent& ev
|
|||
invalidate(window);
|
||||
}
|
||||
|
||||
void WSWindowManager::start_window_resize(WSWindow& window, const Gfx::Point& position, MouseButton button)
|
||||
void WindowManager::start_window_resize(Window& window, const Gfx::Point& position, MouseButton button)
|
||||
{
|
||||
move_to_front_and_make_active(window);
|
||||
constexpr ResizeDirection direction_for_hot_area[3][3] = {
|
||||
|
@ -385,7 +386,7 @@ void WSWindowManager::start_window_resize(WSWindow& window, const Gfx::Point& po
|
|||
}
|
||||
|
||||
#ifdef RESIZE_DEBUG
|
||||
dbg() << "[WM] Begin resizing WSWindow{" << &window << "}";
|
||||
dbg() << "[WM] Begin resizing Window{" << &window << "}";
|
||||
#endif
|
||||
m_resizing_mouse_button = button;
|
||||
m_resize_window = window.make_weak_ptr();
|
||||
|
@ -396,18 +397,18 @@ void WSWindowManager::start_window_resize(WSWindow& window, const Gfx::Point& po
|
|||
invalidate(window);
|
||||
}
|
||||
|
||||
void WSWindowManager::start_window_resize(WSWindow& window, const WSMouseEvent& event)
|
||||
void WindowManager::start_window_resize(Window& window, const MouseEvent& event)
|
||||
{
|
||||
start_window_resize(window, event.position(), event.button());
|
||||
}
|
||||
|
||||
bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow*& hovered_window)
|
||||
bool WindowManager::process_ongoing_window_move(MouseEvent& event, Window*& hovered_window)
|
||||
{
|
||||
if (!m_move_window)
|
||||
return false;
|
||||
if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) {
|
||||
if (event.type() == Event::MouseUp && event.button() == MouseButton::Left) {
|
||||
#ifdef MOVE_DEBUG
|
||||
dbg() << "[WM] Finish moving WSWindow{" << m_move_window << "}";
|
||||
dbg() << "[WM] Finish moving Window{" << m_move_window << "}";
|
||||
#endif
|
||||
|
||||
invalidate(*m_move_window);
|
||||
|
@ -415,7 +416,7 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow*
|
|||
hovered_window = m_move_window;
|
||||
if (m_move_window->is_resizable()) {
|
||||
process_event_for_doubleclick(*m_move_window, event);
|
||||
if (event.type() == WSEvent::MouseDoubleClick) {
|
||||
if (event.type() == Event::MouseDoubleClick) {
|
||||
#if defined(DOUBLECLICK_DEBUG)
|
||||
dbg() << "[WM] Click up became doubleclick!";
|
||||
#endif
|
||||
|
@ -425,7 +426,7 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow*
|
|||
m_move_window = nullptr;
|
||||
return true;
|
||||
}
|
||||
if (event.type() == WSEvent::MouseMove) {
|
||||
if (event.type() == Event::MouseMove) {
|
||||
|
||||
#ifdef MOVE_DEBUG
|
||||
dbg() << "[WM] Moving, origin: " << m_move_origin << ", now: " << event.position();
|
||||
|
@ -462,7 +463,7 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow*
|
|||
}
|
||||
if (is_resizable && event.x() <= tiling_deadzone) {
|
||||
m_move_window->set_tiled(WindowTileType::Left);
|
||||
} else if (is_resizable && event.x() >= WSScreen::the().width() - tiling_deadzone) {
|
||||
} else if (is_resizable && event.x() >= Screen::the().width() - tiling_deadzone) {
|
||||
m_move_window->set_tiled(WindowTileType::Right);
|
||||
} else if (pixels_moved_from_start > 5 || m_move_window->tiled() == WindowTileType::None) {
|
||||
m_move_window->set_tiled(WindowTileType::None);
|
||||
|
@ -477,16 +478,16 @@ bool WSWindowManager::process_ongoing_window_move(WSMouseEvent& event, WSWindow*
|
|||
return false;
|
||||
}
|
||||
|
||||
bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, WSWindow*& hovered_window)
|
||||
bool WindowManager::process_ongoing_window_resize(const MouseEvent& event, Window*& hovered_window)
|
||||
{
|
||||
if (!m_resize_window)
|
||||
return false;
|
||||
|
||||
if (event.type() == WSEvent::MouseUp && event.button() == m_resizing_mouse_button) {
|
||||
if (event.type() == Event::MouseUp && event.button() == m_resizing_mouse_button) {
|
||||
#ifdef RESIZE_DEBUG
|
||||
dbg() << "[WM] Finish resizing WSWindow{" << m_resize_window << "}";
|
||||
dbg() << "[WM] Finish resizing Window{" << m_resize_window << "}";
|
||||
#endif
|
||||
Core::EventLoop::current().post_event(*m_resize_window, make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect()));
|
||||
Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(m_resize_window->rect(), m_resize_window->rect()));
|
||||
invalidate(*m_resize_window);
|
||||
if (m_resize_window->rect().contains(event.position()))
|
||||
hovered_window = m_resize_window;
|
||||
|
@ -495,7 +496,7 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W
|
|||
return true;
|
||||
}
|
||||
|
||||
if (event.type() != WSEvent::MouseMove)
|
||||
if (event.type() != Event::MouseMove)
|
||||
return false;
|
||||
|
||||
auto old_rect = m_resize_window->rect();
|
||||
|
@ -588,15 +589,15 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W
|
|||
dbg() << "[WM] Resizing, original: " << m_resize_window_original_rect << ", now: " << new_rect;
|
||||
#endif
|
||||
m_resize_window->set_rect(new_rect);
|
||||
Core::EventLoop::current().post_event(*m_resize_window, make<WSResizeEvent>(old_rect, new_rect));
|
||||
Core::EventLoop::current().post_event(*m_resize_window, make<ResizeEvent>(old_rect, new_rect));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WSWindowManager::process_ongoing_drag(WSMouseEvent& event, WSWindow*& hovered_window)
|
||||
bool WindowManager::process_ongoing_drag(MouseEvent& event, Window*& hovered_window)
|
||||
{
|
||||
if (!m_dnd_client)
|
||||
return false;
|
||||
if (!(event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left))
|
||||
if (!(event.type() == Event::MouseUp && event.button() == MouseButton::Left))
|
||||
return true;
|
||||
|
||||
hovered_window = nullptr;
|
||||
|
@ -622,12 +623,12 @@ bool WSWindowManager::process_ongoing_drag(WSMouseEvent& event, WSWindow*& hover
|
|||
return true;
|
||||
}
|
||||
|
||||
void WSWindowManager::set_cursor_tracking_button(WSButton* button)
|
||||
void WindowManager::set_cursor_tracking_button(Button* button)
|
||||
{
|
||||
m_cursor_tracking_button = button ? button->make_weak_ptr() : nullptr;
|
||||
}
|
||||
|
||||
auto WSWindowManager::DoubleClickInfo::metadata_for_button(MouseButton button) -> ClickMetadata&
|
||||
auto WindowManager::DoubleClickInfo::metadata_for_button(MouseButton button) -> ClickMetadata&
|
||||
{
|
||||
switch (button) {
|
||||
case MouseButton::Left:
|
||||
|
@ -643,10 +644,10 @@ auto WSWindowManager::DoubleClickInfo::metadata_for_button(MouseButton button) -
|
|||
|
||||
// #define DOUBLECLICK_DEBUG
|
||||
|
||||
void WSWindowManager::process_event_for_doubleclick(WSWindow& window, WSMouseEvent& event)
|
||||
void WindowManager::process_event_for_doubleclick(Window& window, MouseEvent& event)
|
||||
{
|
||||
// We only care about button presses (because otherwise it's not a doubleclick, duh!)
|
||||
ASSERT(event.type() == WSEvent::MouseUp);
|
||||
ASSERT(event.type() == Event::MouseUp);
|
||||
|
||||
if (&window != m_double_click_info.m_clicked_window) {
|
||||
// we either haven't clicked anywhere, or we haven't clicked on this
|
||||
|
@ -677,7 +678,7 @@ void WSWindowManager::process_event_for_doubleclick(WSWindow& window, WSMouseEve
|
|||
#if defined(DOUBLECLICK_DEBUG)
|
||||
dbg() << "Transforming MouseUp to MouseDoubleClick (" << elapsed_since_last_click << " < " << m_double_click_speed << ")!";
|
||||
#endif
|
||||
event = WSMouseEvent(WSEvent::MouseDoubleClick, event.position(), event.buttons(), event.button(), event.modifiers(), event.wheel_delta());
|
||||
event = MouseEvent(Event::MouseDoubleClick, event.position(), event.buttons(), event.button(), event.modifiers(), event.wheel_delta());
|
||||
// invalidate this now we've delivered a doubleclick, otherwise
|
||||
// tripleclick will deliver two doubleclick events (incorrectly).
|
||||
metadata.clock = {};
|
||||
|
@ -691,17 +692,17 @@ void WSWindowManager::process_event_for_doubleclick(WSWindow& window, WSMouseEve
|
|||
metadata.last_position = event.position();
|
||||
}
|
||||
|
||||
void WSWindowManager::deliver_mouse_event(WSWindow& window, WSMouseEvent& event)
|
||||
void WindowManager::deliver_mouse_event(Window& window, MouseEvent& event)
|
||||
{
|
||||
window.dispatch_event(event);
|
||||
if (event.type() == WSEvent::MouseUp) {
|
||||
if (event.type() == Event::MouseUp) {
|
||||
process_event_for_doubleclick(window, event);
|
||||
if (event.type() == WSEvent::MouseDoubleClick)
|
||||
if (event.type() == Event::MouseDoubleClick)
|
||||
window.dispatch_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovered_window)
|
||||
void WindowManager::process_mouse_event(MouseEvent& event, Window*& hovered_window)
|
||||
{
|
||||
hovered_window = nullptr;
|
||||
|
||||
|
@ -717,11 +718,11 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
if (m_cursor_tracking_button)
|
||||
return m_cursor_tracking_button->on_mouse_event(event.translated(-m_cursor_tracking_button->screen_rect().location()));
|
||||
|
||||
// This is quite hackish, but it's how the WSButton hover effect is implemented.
|
||||
if (m_hovered_button && event.type() == WSEvent::MouseMove)
|
||||
// This is quite hackish, but it's how the Button hover effect is implemented.
|
||||
if (m_hovered_button && event.type() == Event::MouseMove)
|
||||
m_hovered_button->on_mouse_event(event.translated(-m_hovered_button->screen_rect().location()));
|
||||
|
||||
HashTable<WSWindow*> windows_who_received_mouse_event_due_to_cursor_tracking;
|
||||
HashTable<Window*> windows_who_received_mouse_event_due_to_cursor_tracking;
|
||||
|
||||
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
||||
if (!window->global_cursor_tracking())
|
||||
|
@ -735,12 +736,12 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
|
||||
// FIXME: Now that the menubar has a dedicated window, is this special-casing really necessary?
|
||||
if (!active_window_is_modal() && menubar_rect().contains(event.position())) {
|
||||
WSMenuManager::the().dispatch_event(event);
|
||||
MenuManager::the().dispatch_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WSMenuManager::the().open_menu_stack().is_empty()) {
|
||||
auto* topmost_menu = WSMenuManager::the().open_menu_stack().last().ptr();
|
||||
if (!MenuManager::the().open_menu_stack().is_empty()) {
|
||||
auto* topmost_menu = MenuManager::the().open_menu_stack().last().ptr();
|
||||
ASSERT(topmost_menu);
|
||||
auto* window = topmost_menu->menu_window();
|
||||
ASSERT(window);
|
||||
|
@ -755,7 +756,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
|
||||
if (topmost_menu->hovered_item())
|
||||
topmost_menu->clear_hovered_item();
|
||||
if (event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseUp) {
|
||||
if (event.type() == Event::MouseDown || event.type() == Event::MouseUp) {
|
||||
auto* window_menu_of = topmost_menu->window_menu_of();
|
||||
if (window_menu_of) {
|
||||
bool event_is_inside_taskbar_button = window_menu_of->taskbar_rect().contains(event.position());
|
||||
|
@ -765,14 +766,14 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
}
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseDown) {
|
||||
WSMenuManager::the().close_bar();
|
||||
if (event.type() == Event::MouseDown) {
|
||||
MenuManager::the().close_bar();
|
||||
topmost_menu->set_window_menu_open(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type() == WSEvent::MouseMove) {
|
||||
for (auto& menu : WSMenuManager::the().open_menu_stack()) {
|
||||
if (event.type() == Event::MouseMove) {
|
||||
for (auto& menu : MenuManager::the().open_menu_stack()) {
|
||||
if (!menu)
|
||||
continue;
|
||||
if (!menu->menu_window()->rect().contains(event.position()))
|
||||
|
@ -786,7 +787,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
return;
|
||||
}
|
||||
|
||||
WSWindow* event_window_with_frame = nullptr;
|
||||
Window* event_window_with_frame = nullptr;
|
||||
|
||||
if (m_active_input_window) {
|
||||
// At this point, we have delivered the start of an input sequence to a
|
||||
|
@ -800,7 +801,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
deliver_mouse_event(*m_active_input_window, translated_event);
|
||||
windows_who_received_mouse_event_due_to_cursor_tracking.set(m_active_input_window.ptr());
|
||||
}
|
||||
if (event.type() == WSEvent::MouseUp && event.buttons() == 0) {
|
||||
if (event.type() == Event::MouseUp && event.buttons() == 0) {
|
||||
m_active_input_window = nullptr;
|
||||
}
|
||||
|
||||
|
@ -812,7 +813,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
return IterationDecision::Continue;
|
||||
});
|
||||
} else {
|
||||
for_each_visible_window_from_front_to_back([&](WSWindow& window) {
|
||||
for_each_visible_window_from_front_to_back([&](Window& window) {
|
||||
auto window_frame_rect = window.frame().rect();
|
||||
if (!window_frame_rect.contains(event.position()))
|
||||
return IterationDecision::Continue;
|
||||
|
@ -823,13 +824,13 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
// First check if we should initiate a move or resize (Logo+LMB or Logo+RMB).
|
||||
// In those cases, the event is swallowed by the window manager.
|
||||
if (window.is_movable()) {
|
||||
if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
|
||||
if (!window.is_fullscreen() && m_keyboard_modifiers == Mod_Logo && event.type() == Event::MouseDown && event.button() == MouseButton::Left) {
|
||||
hovered_window = &window;
|
||||
start_window_move(window, event);
|
||||
m_moved_or_resized_since_logo_keydown = true;
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
if (window.is_resizable() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Right && !window.is_blocked_by_modal_window()) {
|
||||
if (window.is_resizable() && m_keyboard_modifiers == Mod_Logo && event.type() == Event::MouseDown && event.button() == MouseButton::Right && !window.is_blocked_by_modal_window()) {
|
||||
hovered_window = &window;
|
||||
start_window_resize(window, event);
|
||||
m_moved_or_resized_since_logo_keydown = true;
|
||||
|
@ -837,7 +838,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
}
|
||||
}
|
||||
|
||||
if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseWheel) {
|
||||
if (m_keyboard_modifiers == Mod_Logo && event.type() == Event::MouseWheel) {
|
||||
float opacity_change = -event.wheel_delta() * 0.05f;
|
||||
float new_opacity = window.opacity() + opacity_change;
|
||||
if (new_opacity < 0.05f)
|
||||
|
@ -851,28 +852,28 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
|
||||
// Well okay, let's see if we're hitting the frame or the window inside the frame.
|
||||
if (window.rect().contains(event.position())) {
|
||||
if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown)
|
||||
if (window.type() == WindowType::Normal && event.type() == Event::MouseDown)
|
||||
move_to_front_and_make_active(window);
|
||||
|
||||
hovered_window = &window;
|
||||
if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window)) {
|
||||
auto translated_event = event.translated(-window.position());
|
||||
deliver_mouse_event(window, translated_event);
|
||||
if (event.type() == WSEvent::MouseDown) {
|
||||
if (event.type() == Event::MouseDown) {
|
||||
m_active_input_window = window.make_weak_ptr();
|
||||
}
|
||||
}
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
|
||||
// We are hitting the frame, pass the event along to WSWindowFrame.
|
||||
// We are hitting the frame, pass the event along to WindowFrame.
|
||||
window.frame().on_mouse_event(event.translated(-window_frame_rect.location()));
|
||||
event_window_with_frame = &window;
|
||||
return IterationDecision::Break;
|
||||
});
|
||||
|
||||
// Clicked outside of any window
|
||||
if (!hovered_window && !event_window_with_frame && event.type() == WSEvent::MouseDown)
|
||||
if (!hovered_window && !event_window_with_frame && event.type() == Event::MouseDown)
|
||||
set_active_window(nullptr);
|
||||
}
|
||||
|
||||
|
@ -880,17 +881,17 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
|
|||
clear_resize_candidate();
|
||||
}
|
||||
|
||||
void WSWindowManager::clear_resize_candidate()
|
||||
void WindowManager::clear_resize_candidate()
|
||||
{
|
||||
if (m_resize_candidate)
|
||||
WSCompositor::the().invalidate_cursor();
|
||||
Compositor::the().invalidate_cursor();
|
||||
m_resize_candidate = nullptr;
|
||||
}
|
||||
|
||||
bool WSWindowManager::any_opaque_window_contains_rect(const Gfx::Rect& rect)
|
||||
bool WindowManager::any_opaque_window_contains_rect(const Gfx::Rect& rect)
|
||||
{
|
||||
bool found_containing_window = false;
|
||||
for_each_visible_window_from_back_to_front([&](WSWindow& window) {
|
||||
for_each_visible_window_from_back_to_front([&](Window& window) {
|
||||
if (window.is_minimized())
|
||||
return IterationDecision::Continue;
|
||||
if (window.opacity() < 1.0f)
|
||||
|
@ -909,11 +910,11 @@ bool WSWindowManager::any_opaque_window_contains_rect(const Gfx::Rect& rect)
|
|||
return found_containing_window;
|
||||
};
|
||||
|
||||
bool WSWindowManager::any_opaque_window_above_this_one_contains_rect(const WSWindow& a_window, const Gfx::Rect& rect)
|
||||
bool WindowManager::any_opaque_window_above_this_one_contains_rect(const Window& a_window, const Gfx::Rect& rect)
|
||||
{
|
||||
bool found_containing_window = false;
|
||||
bool checking = false;
|
||||
for_each_visible_window_from_back_to_front([&](WSWindow& window) {
|
||||
for_each_visible_window_from_back_to_front([&](Window& window) {
|
||||
if (&window == &a_window) {
|
||||
checking = true;
|
||||
return IterationDecision::Continue;
|
||||
|
@ -937,56 +938,56 @@ bool WSWindowManager::any_opaque_window_above_this_one_contains_rect(const WSWin
|
|||
return found_containing_window;
|
||||
};
|
||||
|
||||
Gfx::Rect WSWindowManager::menubar_rect() const
|
||||
Gfx::Rect WindowManager::menubar_rect() const
|
||||
{
|
||||
if (active_fullscreen_window())
|
||||
return {};
|
||||
return WSMenuManager::the().menubar_rect();
|
||||
return MenuManager::the().menubar_rect();
|
||||
}
|
||||
|
||||
void WSWindowManager::draw_window_switcher()
|
||||
void WindowManager::draw_window_switcher()
|
||||
{
|
||||
if (m_switcher.is_visible())
|
||||
m_switcher.draw();
|
||||
}
|
||||
|
||||
void WSWindowManager::event(Core::Event& event)
|
||||
void WindowManager::event(Core::Event& event)
|
||||
{
|
||||
if (static_cast<WSEvent&>(event).is_mouse_event()) {
|
||||
WSWindow* hovered_window = nullptr;
|
||||
process_mouse_event(static_cast<WSMouseEvent&>(event), hovered_window);
|
||||
if (static_cast<Event&>(event).is_mouse_event()) {
|
||||
Window* hovered_window = nullptr;
|
||||
process_mouse_event(static_cast<MouseEvent&>(event), hovered_window);
|
||||
set_hovered_window(hovered_window);
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<WSEvent&>(event).is_key_event()) {
|
||||
auto& key_event = static_cast<const WSKeyEvent&>(event);
|
||||
if (static_cast<Event&>(event).is_key_event()) {
|
||||
auto& key_event = static_cast<const KeyEvent&>(event);
|
||||
m_keyboard_modifiers = key_event.modifiers();
|
||||
|
||||
if (key_event.type() == WSEvent::KeyDown && key_event.key() == Key_Escape && m_dnd_client) {
|
||||
if (key_event.type() == Event::KeyDown && key_event.key() == Key_Escape && m_dnd_client) {
|
||||
m_dnd_client->post_message(WindowClient::DragCancelled());
|
||||
end_dnd_drag();
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_event.key() == Key_Logo) {
|
||||
if (key_event.type() == WSEvent::KeyUp) {
|
||||
if (key_event.type() == Event::KeyUp) {
|
||||
if (!m_moved_or_resized_since_logo_keydown && !m_switcher.is_visible() && !m_move_window && !m_resize_window) {
|
||||
WSMenuManager::the().toggle_menu(WSMenuManager::the().system_menu());
|
||||
MenuManager::the().toggle_menu(MenuManager::the().system_menu());
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (key_event.type() == WSEvent::KeyDown) {
|
||||
} else if (key_event.type() == Event::KeyDown) {
|
||||
m_moved_or_resized_since_logo_keydown = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (WSMenuManager::the().current_menu()) {
|
||||
WSMenuManager::the().dispatch_event(event);
|
||||
if (MenuManager::the().current_menu()) {
|
||||
MenuManager::the().dispatch_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key_event.type() == WSEvent::KeyDown && ((key_event.modifiers() == Mod_Logo && key_event.key() == Key_Tab) || (key_event.modifiers() == (Mod_Logo | Mod_Shift) && key_event.key() == Key_Tab)))
|
||||
if (key_event.type() == Event::KeyDown && ((key_event.modifiers() == Mod_Logo && key_event.key() == Key_Tab) || (key_event.modifiers() == (Mod_Logo | Mod_Shift) && key_event.key() == Key_Tab)))
|
||||
m_switcher.show();
|
||||
if (m_switcher.is_visible()) {
|
||||
m_switcher.on_key_event(key_event);
|
||||
|
@ -994,7 +995,7 @@ void WSWindowManager::event(Core::Event& event)
|
|||
}
|
||||
|
||||
if (m_active_window) {
|
||||
if (key_event.type() == WSEvent::KeyDown && key_event.modifiers() == Mod_Logo) {
|
||||
if (key_event.type() == Event::KeyDown && key_event.modifiers() == Mod_Logo) {
|
||||
if (key_event.key() == Key_Down) {
|
||||
m_moved_or_resized_since_logo_keydown = true;
|
||||
if (m_active_window->is_resizable() && m_active_window->is_maximized()) {
|
||||
|
@ -1043,7 +1044,7 @@ void WSWindowManager::event(Core::Event& event)
|
|||
Core::Object::event(event);
|
||||
}
|
||||
|
||||
void WSWindowManager::set_highlight_window(WSWindow* window)
|
||||
void WindowManager::set_highlight_window(Window* window)
|
||||
{
|
||||
if (window == m_highlight_window)
|
||||
return;
|
||||
|
@ -1054,12 +1055,12 @@ void WSWindowManager::set_highlight_window(WSWindow* window)
|
|||
invalidate(*m_highlight_window);
|
||||
}
|
||||
|
||||
void WSWindowManager::set_active_window(WSWindow* window)
|
||||
void WindowManager::set_active_window(Window* window)
|
||||
{
|
||||
if (window && window->is_blocked_by_modal_window())
|
||||
return;
|
||||
|
||||
if (window && window->type() != WSWindowType::Normal)
|
||||
if (window && window->type() != WindowType::Normal)
|
||||
return;
|
||||
|
||||
if (window == m_active_window)
|
||||
|
@ -1067,12 +1068,12 @@ void WSWindowManager::set_active_window(WSWindow* window)
|
|||
|
||||
auto* previously_active_window = m_active_window.ptr();
|
||||
|
||||
WSClientConnection* previously_active_client = nullptr;
|
||||
WSClientConnection* active_client = nullptr;
|
||||
ClientConnection* previously_active_client = nullptr;
|
||||
ClientConnection* active_client = nullptr;
|
||||
|
||||
if (previously_active_window) {
|
||||
previously_active_client = previously_active_window->client();
|
||||
Core::EventLoop::current().post_event(*previously_active_window, make<WSEvent>(WSEvent::WindowDeactivated));
|
||||
Core::EventLoop::current().post_event(*previously_active_window, make<Event>(Event::WindowDeactivated));
|
||||
invalidate(*previously_active_window);
|
||||
m_active_window = nullptr;
|
||||
tell_wm_listeners_window_state_changed(*previously_active_window);
|
||||
|
@ -1081,15 +1082,15 @@ void WSWindowManager::set_active_window(WSWindow* window)
|
|||
if (window) {
|
||||
m_active_window = window->make_weak_ptr();
|
||||
active_client = m_active_window->client();
|
||||
Core::EventLoop::current().post_event(*m_active_window, make<WSEvent>(WSEvent::WindowActivated));
|
||||
Core::EventLoop::current().post_event(*m_active_window, make<Event>(Event::WindowActivated));
|
||||
invalidate(*m_active_window);
|
||||
|
||||
auto* client = window->client();
|
||||
ASSERT(client);
|
||||
WSMenuManager::the().set_current_menubar(client->app_menubar());
|
||||
MenuManager::the().set_current_menubar(client->app_menubar());
|
||||
tell_wm_listeners_window_state_changed(*m_active_window);
|
||||
} else {
|
||||
WSMenuManager::the().set_current_menubar(nullptr);
|
||||
MenuManager::the().set_current_menubar(nullptr);
|
||||
}
|
||||
|
||||
if (active_client != previously_active_client) {
|
||||
|
@ -1100,39 +1101,39 @@ void WSWindowManager::set_active_window(WSWindow* window)
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindowManager::set_hovered_window(WSWindow* window)
|
||||
void WindowManager::set_hovered_window(Window* window)
|
||||
{
|
||||
if (m_hovered_window == window)
|
||||
return;
|
||||
|
||||
if (m_hovered_window)
|
||||
Core::EventLoop::current().post_event(*m_hovered_window, make<WSEvent>(WSEvent::WindowLeft));
|
||||
Core::EventLoop::current().post_event(*m_hovered_window, make<Event>(Event::WindowLeft));
|
||||
|
||||
m_hovered_window = window ? window->make_weak_ptr() : nullptr;
|
||||
|
||||
if (m_hovered_window)
|
||||
Core::EventLoop::current().post_event(*m_hovered_window, make<WSEvent>(WSEvent::WindowEntered));
|
||||
Core::EventLoop::current().post_event(*m_hovered_window, make<Event>(Event::WindowEntered));
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate()
|
||||
void WindowManager::invalidate()
|
||||
{
|
||||
WSCompositor::the().invalidate();
|
||||
Compositor::the().invalidate();
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate(const Gfx::Rect& rect)
|
||||
void WindowManager::invalidate(const Gfx::Rect& rect)
|
||||
{
|
||||
WSCompositor::the().invalidate(rect);
|
||||
Compositor::the().invalidate(rect);
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate(const WSWindow& window)
|
||||
void WindowManager::invalidate(const Window& window)
|
||||
{
|
||||
invalidate(window.frame().rect());
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate(const WSWindow& window, const Gfx::Rect& rect)
|
||||
void WindowManager::invalidate(const Window& window, const Gfx::Rect& rect)
|
||||
{
|
||||
if (window.type() == WSWindowType::MenuApplet) {
|
||||
WSMenuManager::the().invalidate_applet(window, rect);
|
||||
if (window.type() == WindowType::MenuApplet) {
|
||||
MenuManager::the().invalidate_applet(window, rect);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1148,20 +1149,20 @@ void WSWindowManager::invalidate(const WSWindow& window, const Gfx::Rect& rect)
|
|||
invalidate(inner_rect);
|
||||
}
|
||||
|
||||
const WSClientConnection* WSWindowManager::active_client() const
|
||||
const ClientConnection* WindowManager::active_client() const
|
||||
{
|
||||
if (m_active_window)
|
||||
return m_active_window->client();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WSWindowManager::notify_client_changed_app_menubar(WSClientConnection& client)
|
||||
void WindowManager::notify_client_changed_app_menubar(ClientConnection& client)
|
||||
{
|
||||
if (active_client() == &client)
|
||||
WSMenuManager::the().set_current_menubar(client.app_menubar());
|
||||
MenuManager::the().set_current_menubar(client.app_menubar());
|
||||
}
|
||||
|
||||
const WSCursor& WSWindowManager::active_cursor() const
|
||||
const Cursor& WindowManager::active_cursor() const
|
||||
{
|
||||
if (m_dnd_client)
|
||||
return *m_drag_cursor;
|
||||
|
@ -1194,27 +1195,27 @@ const WSCursor& WSWindowManager::active_cursor() const
|
|||
return *m_arrow_cursor;
|
||||
}
|
||||
|
||||
void WSWindowManager::set_hovered_button(WSButton* button)
|
||||
void WindowManager::set_hovered_button(Button* button)
|
||||
{
|
||||
m_hovered_button = button ? button->make_weak_ptr() : nullptr;
|
||||
}
|
||||
|
||||
void WSWindowManager::set_resize_candidate(WSWindow& window, ResizeDirection direction)
|
||||
void WindowManager::set_resize_candidate(Window& window, ResizeDirection direction)
|
||||
{
|
||||
m_resize_candidate = window.make_weak_ptr();
|
||||
m_resize_direction = direction;
|
||||
}
|
||||
|
||||
ResizeDirection WSWindowManager::resize_direction_of_window(const WSWindow& window)
|
||||
ResizeDirection WindowManager::resize_direction_of_window(const Window& window)
|
||||
{
|
||||
if (&window != m_resize_window)
|
||||
return ResizeDirection::None;
|
||||
return m_resize_direction;
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowManager::maximized_window_rect(const WSWindow& window) const
|
||||
Gfx::Rect WindowManager::maximized_window_rect(const Window& window) const
|
||||
{
|
||||
Gfx::Rect rect = WSScreen::the().rect();
|
||||
Gfx::Rect rect = Screen::the().rect();
|
||||
|
||||
// Subtract window title bar (leaving the border)
|
||||
rect.set_y(rect.y() + window.frame().title_bar_rect().height());
|
||||
|
@ -1225,7 +1226,7 @@ Gfx::Rect WSWindowManager::maximized_window_rect(const WSWindow& window) const
|
|||
rect.set_height(rect.height() - menubar_rect().height());
|
||||
|
||||
// Subtract taskbar window height if present
|
||||
const_cast<WSWindowManager*>(this)->for_each_visible_window_of_type_from_back_to_front(WSWindowType::Taskbar, [&rect](WSWindow& taskbar_window) {
|
||||
const_cast<WindowManager*>(this)->for_each_visible_window_of_type_from_back_to_front(WindowType::Taskbar, [&rect](Window& taskbar_window) {
|
||||
rect.set_height(rect.height() - taskbar_window.height());
|
||||
return IterationDecision::Break;
|
||||
});
|
||||
|
@ -1233,7 +1234,7 @@ Gfx::Rect WSWindowManager::maximized_window_rect(const WSWindow& window) const
|
|||
return rect;
|
||||
}
|
||||
|
||||
void WSWindowManager::start_dnd_drag(WSClientConnection& client, const String& text, Gfx::Bitmap* bitmap, const String& data_type, const String& data)
|
||||
void WindowManager::start_dnd_drag(ClientConnection& client, const String& text, Gfx::Bitmap* bitmap, const String& data_type, const String& data)
|
||||
{
|
||||
ASSERT(!m_dnd_client);
|
||||
m_dnd_client = client.make_weak_ptr();
|
||||
|
@ -1241,37 +1242,37 @@ void WSWindowManager::start_dnd_drag(WSClientConnection& client, const String& t
|
|||
m_dnd_bitmap = bitmap;
|
||||
m_dnd_data_type = data_type;
|
||||
m_dnd_data = data;
|
||||
WSCompositor::the().invalidate_cursor();
|
||||
Compositor::the().invalidate_cursor();
|
||||
m_active_input_window = nullptr;
|
||||
}
|
||||
|
||||
void WSWindowManager::end_dnd_drag()
|
||||
void WindowManager::end_dnd_drag()
|
||||
{
|
||||
ASSERT(m_dnd_client);
|
||||
WSCompositor::the().invalidate_cursor();
|
||||
Compositor::the().invalidate_cursor();
|
||||
m_dnd_client = nullptr;
|
||||
m_dnd_text = {};
|
||||
m_dnd_bitmap = nullptr;
|
||||
}
|
||||
|
||||
Gfx::Rect WSWindowManager::dnd_rect() const
|
||||
Gfx::Rect WindowManager::dnd_rect() const
|
||||
{
|
||||
int bitmap_width = m_dnd_bitmap ? m_dnd_bitmap->width() : 0;
|
||||
int bitmap_height = m_dnd_bitmap ? m_dnd_bitmap->height() : 0;
|
||||
int width = font().width(m_dnd_text) + bitmap_width;
|
||||
int height = max((int)font().glyph_height(), bitmap_height);
|
||||
auto location = WSCompositor::the().current_cursor_rect().center().translated(8, 8);
|
||||
auto location = Compositor::the().current_cursor_rect().center().translated(8, 8);
|
||||
return Gfx::Rect(location, { width, height }).inflated(4, 4);
|
||||
}
|
||||
|
||||
void WSWindowManager::update_theme(String theme_path, String theme_name)
|
||||
void WindowManager::update_theme(String theme_path, String theme_name)
|
||||
{
|
||||
auto new_theme = Gfx::load_system_theme(theme_path);
|
||||
ASSERT(new_theme);
|
||||
Gfx::set_system_theme(*new_theme);
|
||||
m_palette = Gfx::PaletteImpl::create_with_shared_buffer(*new_theme);
|
||||
HashTable<WSClientConnection*> notified_clients;
|
||||
for_each_window([&](WSWindow& window) {
|
||||
HashTable<ClientConnection*> notified_clients;
|
||||
for_each_window([&](Window& window) {
|
||||
if (window.client()) {
|
||||
if (!notified_clients.contains(window.client())) {
|
||||
window.client()->post_message(WindowClient::UpdateSystemTheme(Gfx::current_system_theme_buffer_id()));
|
||||
|
@ -1285,3 +1286,5 @@ void WSWindowManager::update_theme(String theme_path, String theme_name)
|
|||
wm_config->sync();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
}
|
|
@ -37,21 +37,22 @@
|
|||
#include <LibGfx/Painter.h>
|
||||
#include <LibGfx/Palette.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <WindowServer/WSCursor.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/WSMenuBar.h>
|
||||
#include <WindowServer/WSMenuManager.h>
|
||||
#include <WindowServer/WSWindow.h>
|
||||
#include <WindowServer/WSWindowSwitcher.h>
|
||||
#include <WindowServer/WSWindowType.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/MenuBar.h>
|
||||
#include <WindowServer/MenuManager.h>
|
||||
#include <WindowServer/Window.h>
|
||||
#include <WindowServer/WindowSwitcher.h>
|
||||
#include <WindowServer/WindowType.h>
|
||||
|
||||
class WSScreen;
|
||||
class WSMouseEvent;
|
||||
class WSClientWantsToPaintMessage;
|
||||
class WSWindow;
|
||||
class WSClientConnection;
|
||||
class WSWindowSwitcher;
|
||||
class WSButton;
|
||||
namespace WindowServer {
|
||||
|
||||
class Screen;
|
||||
class MouseEvent;
|
||||
class Window;
|
||||
class ClientConnection;
|
||||
class WindowSwitcher;
|
||||
class Button;
|
||||
|
||||
enum class ResizeDirection {
|
||||
None,
|
||||
|
@ -65,18 +66,18 @@ enum class ResizeDirection {
|
|||
DownLeft
|
||||
};
|
||||
|
||||
class WSWindowManager : public Core::Object {
|
||||
C_OBJECT(WSWindowManager)
|
||||
class WindowManager : public Core::Object {
|
||||
C_OBJECT(WindowManager)
|
||||
|
||||
friend class WSCompositor;
|
||||
friend class WSWindowFrame;
|
||||
friend class WSWindowSwitcher;
|
||||
friend class Compositor;
|
||||
friend class WindowFrame;
|
||||
friend class WindowSwitcher;
|
||||
|
||||
public:
|
||||
static WSWindowManager& the();
|
||||
static WindowManager& the();
|
||||
|
||||
explicit WSWindowManager(const Gfx::PaletteImpl&);
|
||||
virtual ~WSWindowManager() override;
|
||||
explicit WindowManager(const Gfx::PaletteImpl&);
|
||||
virtual ~WindowManager() override;
|
||||
|
||||
Palette palette() const { return Palette(*m_palette); }
|
||||
|
||||
|
@ -86,55 +87,55 @@ public:
|
|||
}
|
||||
void reload_config(bool);
|
||||
|
||||
void add_window(WSWindow&);
|
||||
void remove_window(WSWindow&);
|
||||
void add_window(Window&);
|
||||
void remove_window(Window&);
|
||||
|
||||
void notify_title_changed(WSWindow&);
|
||||
void notify_rect_changed(WSWindow&, const Gfx::Rect& oldRect, const Gfx::Rect& newRect);
|
||||
void notify_minimization_state_changed(WSWindow&);
|
||||
void notify_opacity_changed(WSWindow&);
|
||||
void notify_occlusion_state_changed(WSWindow&);
|
||||
void notify_client_changed_app_menubar(WSClientConnection&);
|
||||
void notify_title_changed(Window&);
|
||||
void notify_rect_changed(Window&, const Gfx::Rect& oldRect, const Gfx::Rect& newRect);
|
||||
void notify_minimization_state_changed(Window&);
|
||||
void notify_opacity_changed(Window&);
|
||||
void notify_occlusion_state_changed(Window&);
|
||||
void notify_client_changed_app_menubar(ClientConnection&);
|
||||
|
||||
Gfx::Rect maximized_window_rect(const WSWindow&) const;
|
||||
Gfx::Rect maximized_window_rect(const Window&) const;
|
||||
|
||||
WSClientConnection* dnd_client() { return m_dnd_client.ptr(); }
|
||||
ClientConnection* dnd_client() { return m_dnd_client.ptr(); }
|
||||
const String& dnd_text() const { return m_dnd_text; }
|
||||
const String& dnd_data_type() const { return m_dnd_data_type; }
|
||||
const String& dnd_data() const { return m_dnd_data; }
|
||||
const Gfx::Bitmap* dnd_bitmap() const { return m_dnd_bitmap; }
|
||||
Gfx::Rect dnd_rect() const;
|
||||
|
||||
void start_dnd_drag(WSClientConnection&, const String& text, Gfx::Bitmap*, const String& data_type, const String& data);
|
||||
void start_dnd_drag(ClientConnection&, const String& text, Gfx::Bitmap*, const String& data_type, const String& data);
|
||||
void end_dnd_drag();
|
||||
|
||||
WSWindow* active_window() { return m_active_window.ptr(); }
|
||||
const WSClientConnection* active_client() const;
|
||||
Window* active_window() { return m_active_window.ptr(); }
|
||||
const ClientConnection* active_client() const;
|
||||
bool active_window_is_modal() const { return m_active_window && m_active_window->is_modal(); }
|
||||
|
||||
WSWindow* highlight_window() { return m_highlight_window.ptr(); }
|
||||
void set_highlight_window(WSWindow*);
|
||||
Window* highlight_window() { return m_highlight_window.ptr(); }
|
||||
void set_highlight_window(Window*);
|
||||
|
||||
void move_to_front_and_make_active(WSWindow&);
|
||||
void move_to_front_and_make_active(Window&);
|
||||
|
||||
void draw_window_switcher();
|
||||
|
||||
Gfx::Rect menubar_rect() const;
|
||||
|
||||
const WSCursor& active_cursor() const;
|
||||
const WSCursor& arrow_cursor() const { return *m_arrow_cursor; }
|
||||
const WSCursor& hand_cursor() const { return *m_hand_cursor; }
|
||||
const WSCursor& resize_horizontally_cursor() const { return *m_resize_horizontally_cursor; }
|
||||
const WSCursor& resize_vertically_cursor() const { return *m_resize_vertically_cursor; }
|
||||
const WSCursor& resize_diagonally_tlbr_cursor() const { return *m_resize_diagonally_tlbr_cursor; }
|
||||
const WSCursor& resize_diagonally_bltr_cursor() const { return *m_resize_diagonally_bltr_cursor; }
|
||||
const WSCursor& i_beam_cursor() const { return *m_i_beam_cursor; }
|
||||
const WSCursor& disallowed_cursor() const { return *m_disallowed_cursor; }
|
||||
const WSCursor& move_cursor() const { return *m_move_cursor; }
|
||||
const WSCursor& drag_cursor() const { return *m_drag_cursor; }
|
||||
const Cursor& active_cursor() const;
|
||||
const Cursor& arrow_cursor() const { return *m_arrow_cursor; }
|
||||
const Cursor& hand_cursor() const { return *m_hand_cursor; }
|
||||
const Cursor& resize_horizontally_cursor() const { return *m_resize_horizontally_cursor; }
|
||||
const Cursor& resize_vertically_cursor() const { return *m_resize_vertically_cursor; }
|
||||
const Cursor& resize_diagonally_tlbr_cursor() const { return *m_resize_diagonally_tlbr_cursor; }
|
||||
const Cursor& resize_diagonally_bltr_cursor() const { return *m_resize_diagonally_bltr_cursor; }
|
||||
const Cursor& i_beam_cursor() const { return *m_i_beam_cursor; }
|
||||
const Cursor& disallowed_cursor() const { return *m_disallowed_cursor; }
|
||||
const Cursor& move_cursor() const { return *m_move_cursor; }
|
||||
const Cursor& drag_cursor() const { return *m_drag_cursor; }
|
||||
|
||||
void invalidate(const WSWindow&);
|
||||
void invalidate(const WSWindow&, const Gfx::Rect&);
|
||||
void invalidate(const Window&);
|
||||
void invalidate(const Window&, const Gfx::Rect&);
|
||||
void invalidate(const Gfx::Rect&);
|
||||
void invalidate();
|
||||
void flush(const Gfx::Rect&);
|
||||
|
@ -148,47 +149,47 @@ public:
|
|||
|
||||
void set_resolution(int width, int height);
|
||||
|
||||
void set_active_window(WSWindow*);
|
||||
void set_hovered_button(WSButton*);
|
||||
void set_active_window(Window*);
|
||||
void set_hovered_button(Button*);
|
||||
|
||||
WSButton* cursor_tracking_button() { return m_cursor_tracking_button.ptr(); }
|
||||
void set_cursor_tracking_button(WSButton*);
|
||||
Button* cursor_tracking_button() { return m_cursor_tracking_button.ptr(); }
|
||||
void set_cursor_tracking_button(Button*);
|
||||
|
||||
void set_resize_candidate(WSWindow&, ResizeDirection);
|
||||
void set_resize_candidate(Window&, ResizeDirection);
|
||||
void clear_resize_candidate();
|
||||
ResizeDirection resize_direction_of_window(const WSWindow&);
|
||||
ResizeDirection resize_direction_of_window(const Window&);
|
||||
|
||||
bool any_opaque_window_contains_rect(const Gfx::Rect&);
|
||||
bool any_opaque_window_above_this_one_contains_rect(const WSWindow&, const Gfx::Rect&);
|
||||
bool any_opaque_window_above_this_one_contains_rect(const Window&, const Gfx::Rect&);
|
||||
|
||||
void tell_wm_listeners_window_state_changed(WSWindow&);
|
||||
void tell_wm_listeners_window_icon_changed(WSWindow&);
|
||||
void tell_wm_listeners_window_rect_changed(WSWindow&);
|
||||
void tell_wm_listeners_window_state_changed(Window&);
|
||||
void tell_wm_listeners_window_icon_changed(Window&);
|
||||
void tell_wm_listeners_window_rect_changed(Window&);
|
||||
|
||||
void start_window_resize(WSWindow&, const Gfx::Point&, MouseButton);
|
||||
void start_window_resize(WSWindow&, const WSMouseEvent&);
|
||||
void start_window_resize(Window&, const Gfx::Point&, MouseButton);
|
||||
void start_window_resize(Window&, const MouseEvent&);
|
||||
|
||||
const WSWindow* active_fullscreen_window() const { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
|
||||
WSWindow* active_fullscreen_window() { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
|
||||
const Window* active_fullscreen_window() const { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
|
||||
Window* active_fullscreen_window() { return (m_active_window && m_active_window->is_fullscreen()) ? m_active_window : nullptr; }
|
||||
|
||||
void update_theme(String theme_path, String theme_name);
|
||||
|
||||
private:
|
||||
NonnullRefPtr<WSCursor> get_cursor(const String& name);
|
||||
NonnullRefPtr<WSCursor> get_cursor(const String& name, const Gfx::Point& hotspot);
|
||||
NonnullRefPtr<Cursor> get_cursor(const String& name);
|
||||
NonnullRefPtr<Cursor> get_cursor(const String& name, const Gfx::Point& hotspot);
|
||||
|
||||
void process_mouse_event(WSMouseEvent&, WSWindow*& hovered_window);
|
||||
void process_event_for_doubleclick(WSWindow& window, WSMouseEvent& event);
|
||||
void deliver_mouse_event(WSWindow& window, WSMouseEvent& event);
|
||||
bool process_ongoing_window_resize(const WSMouseEvent&, WSWindow*& hovered_window);
|
||||
bool process_ongoing_window_move(WSMouseEvent&, WSWindow*& hovered_window);
|
||||
bool process_ongoing_drag(WSMouseEvent&, WSWindow*& hovered_window);
|
||||
void start_window_move(WSWindow&, const WSMouseEvent&);
|
||||
void set_hovered_window(WSWindow*);
|
||||
void process_mouse_event(MouseEvent&, Window*& hovered_window);
|
||||
void process_event_for_doubleclick(Window& window, MouseEvent& event);
|
||||
void deliver_mouse_event(Window& window, MouseEvent& event);
|
||||
bool process_ongoing_window_resize(const MouseEvent&, Window*& hovered_window);
|
||||
bool process_ongoing_window_move(MouseEvent&, Window*& hovered_window);
|
||||
bool process_ongoing_drag(MouseEvent&, Window*& hovered_window);
|
||||
void start_window_move(Window&, const MouseEvent&);
|
||||
void set_hovered_window(Window*);
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_visible_window_of_type_from_back_to_front(WSWindowType, Callback, bool ignore_highlight = false);
|
||||
IterationDecision for_each_visible_window_of_type_from_back_to_front(WindowType, Callback, bool ignore_highlight = false);
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_visible_window_of_type_from_front_to_back(WSWindowType, Callback, bool ignore_highlight = false);
|
||||
IterationDecision for_each_visible_window_of_type_from_front_to_back(WindowType, Callback, bool ignore_highlight = false);
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_visible_window_from_front_to_back(Callback);
|
||||
template<typename Callback>
|
||||
|
@ -198,27 +199,27 @@ private:
|
|||
template<typename Callback>
|
||||
void for_each_window(Callback);
|
||||
template<typename Callback>
|
||||
IterationDecision for_each_window_of_type_from_front_to_back(WSWindowType, Callback, bool ignore_highlight = false);
|
||||
IterationDecision for_each_window_of_type_from_front_to_back(WindowType, Callback, bool ignore_highlight = false);
|
||||
|
||||
virtual void event(Core::Event&) override;
|
||||
void paint_window_frame(const WSWindow&);
|
||||
void tell_wm_listener_about_window(WSWindow& listener, WSWindow&);
|
||||
void tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow&);
|
||||
void tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow&);
|
||||
void paint_window_frame(const Window&);
|
||||
void tell_wm_listener_about_window(Window& listener, Window&);
|
||||
void tell_wm_listener_about_window_icon(Window& listener, Window&);
|
||||
void tell_wm_listener_about_window_rect(Window& listener, Window&);
|
||||
void pick_new_active_window();
|
||||
|
||||
void recompute_occlusions();
|
||||
|
||||
RefPtr<WSCursor> m_arrow_cursor;
|
||||
RefPtr<WSCursor> m_hand_cursor;
|
||||
RefPtr<WSCursor> m_resize_horizontally_cursor;
|
||||
RefPtr<WSCursor> m_resize_vertically_cursor;
|
||||
RefPtr<WSCursor> m_resize_diagonally_tlbr_cursor;
|
||||
RefPtr<WSCursor> m_resize_diagonally_bltr_cursor;
|
||||
RefPtr<WSCursor> m_i_beam_cursor;
|
||||
RefPtr<WSCursor> m_disallowed_cursor;
|
||||
RefPtr<WSCursor> m_move_cursor;
|
||||
RefPtr<WSCursor> m_drag_cursor;
|
||||
RefPtr<Cursor> m_arrow_cursor;
|
||||
RefPtr<Cursor> m_hand_cursor;
|
||||
RefPtr<Cursor> m_resize_horizontally_cursor;
|
||||
RefPtr<Cursor> m_resize_vertically_cursor;
|
||||
RefPtr<Cursor> m_resize_diagonally_tlbr_cursor;
|
||||
RefPtr<Cursor> m_resize_diagonally_bltr_cursor;
|
||||
RefPtr<Cursor> m_i_beam_cursor;
|
||||
RefPtr<Cursor> m_disallowed_cursor;
|
||||
RefPtr<Cursor> m_move_cursor;
|
||||
RefPtr<Cursor> m_drag_cursor;
|
||||
|
||||
Color m_background_color;
|
||||
Color m_active_window_border_color;
|
||||
|
@ -234,7 +235,7 @@ private:
|
|||
Color m_highlight_window_border_color2;
|
||||
Color m_highlight_window_title_color;
|
||||
|
||||
InlineLinkedList<WSWindow> m_windows_in_order;
|
||||
InlineLinkedList<Window> m_windows_in_order;
|
||||
|
||||
struct DoubleClickInfo {
|
||||
struct ClickMetadata {
|
||||
|
@ -251,7 +252,7 @@ private:
|
|||
m_middle = {};
|
||||
}
|
||||
|
||||
WeakPtr<WSWindow> m_clicked_window;
|
||||
WeakPtr<Window> m_clicked_window;
|
||||
|
||||
private:
|
||||
ClickMetadata m_left;
|
||||
|
@ -262,17 +263,17 @@ private:
|
|||
int m_double_click_speed { 0 };
|
||||
int m_max_distance_for_double_click { 4 };
|
||||
|
||||
WeakPtr<WSWindow> m_active_window;
|
||||
WeakPtr<WSWindow> m_hovered_window;
|
||||
WeakPtr<WSWindow> m_highlight_window;
|
||||
WeakPtr<WSWindow> m_active_input_window;
|
||||
WeakPtr<Window> m_active_window;
|
||||
WeakPtr<Window> m_hovered_window;
|
||||
WeakPtr<Window> m_highlight_window;
|
||||
WeakPtr<Window> m_active_input_window;
|
||||
|
||||
WeakPtr<WSWindow> m_move_window;
|
||||
WeakPtr<Window> m_move_window;
|
||||
Gfx::Point m_move_origin;
|
||||
Gfx::Point m_move_window_origin;
|
||||
|
||||
WeakPtr<WSWindow> m_resize_window;
|
||||
WeakPtr<WSWindow> m_resize_candidate;
|
||||
WeakPtr<Window> m_resize_window;
|
||||
WeakPtr<Window> m_resize_candidate;
|
||||
MouseButton m_resizing_mouse_button { MouseButton::None };
|
||||
Gfx::Rect m_resize_window_original_rect;
|
||||
Gfx::Point m_resize_origin;
|
||||
|
@ -282,16 +283,16 @@ private:
|
|||
|
||||
u8 m_keyboard_modifiers { 0 };
|
||||
|
||||
WSWindowSwitcher m_switcher;
|
||||
WindowSwitcher m_switcher;
|
||||
|
||||
WeakPtr<WSButton> m_cursor_tracking_button;
|
||||
WeakPtr<WSButton> m_hovered_button;
|
||||
WeakPtr<Button> m_cursor_tracking_button;
|
||||
WeakPtr<Button> m_hovered_button;
|
||||
|
||||
NonnullRefPtr<Gfx::PaletteImpl> m_palette;
|
||||
|
||||
RefPtr<Core::ConfigFile> m_wm_config;
|
||||
|
||||
WeakPtr<WSClientConnection> m_dnd_client;
|
||||
WeakPtr<ClientConnection> m_dnd_client;
|
||||
String m_dnd_text;
|
||||
String m_dnd_data_type;
|
||||
String m_dnd_data;
|
||||
|
@ -299,7 +300,7 @@ private:
|
|||
};
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision WSWindowManager::for_each_visible_window_of_type_from_back_to_front(WSWindowType type, Callback callback, bool ignore_highlight)
|
||||
IterationDecision WindowManager::for_each_visible_window_of_type_from_back_to_front(WindowType type, Callback callback, bool ignore_highlight)
|
||||
{
|
||||
bool do_highlight_window_at_end = false;
|
||||
for (auto& window : m_windows_in_order) {
|
||||
|
@ -324,23 +325,23 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_back_to_
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision WSWindowManager::for_each_visible_window_from_back_to_front(Callback callback)
|
||||
IterationDecision WindowManager::for_each_visible_window_from_back_to_front(Callback callback)
|
||||
{
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Normal, callback) == 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(WSWindowType::Taskbar, callback) == 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(WSWindowType::Tooltip, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Tooltip, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menubar, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Menubar, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WSWindowType::Menu, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_back_to_front(WindowType::Menu, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
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(WindowType::WindowSwitcher, callback);
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision WSWindowManager::for_each_visible_window_of_type_from_front_to_back(WSWindowType type, Callback callback, bool ignore_highlight)
|
||||
IterationDecision WindowManager::for_each_visible_window_of_type_from_front_to_back(WindowType type, Callback callback, bool ignore_highlight)
|
||||
{
|
||||
if (!ignore_highlight && m_highlight_window && m_highlight_window->type() == type && m_highlight_window->is_visible()) {
|
||||
if (callback(*m_highlight_window) == IterationDecision::Break)
|
||||
|
@ -363,23 +364,23 @@ IterationDecision WSWindowManager::for_each_visible_window_of_type_from_front_to
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Callback callback)
|
||||
IterationDecision WindowManager::for_each_visible_window_from_front_to_back(Callback callback)
|
||||
{
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::WindowSwitcher, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menu, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Menu, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Menubar, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Menubar, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WSWindowType::Taskbar, callback) == 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(WSWindowType::Tooltip, callback) == IterationDecision::Break)
|
||||
if (for_each_visible_window_of_type_from_front_to_back(WindowType::Tooltip, callback) == IterationDecision::Break)
|
||||
return IterationDecision::Break;
|
||||
return for_each_visible_window_of_type_from_front_to_back(WSWindowType::Normal, callback);
|
||||
return for_each_visible_window_of_type_from_front_to_back(WindowType::Normal, callback);
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void WSWindowManager::for_each_window_listening_to_wm_events(Callback callback)
|
||||
void WindowManager::for_each_window_listening_to_wm_events(Callback callback)
|
||||
{
|
||||
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
||||
if (!window->listens_to_wm_events())
|
||||
|
@ -390,7 +391,7 @@ void WSWindowManager::for_each_window_listening_to_wm_events(Callback callback)
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
void WSWindowManager::for_each_window(Callback callback)
|
||||
void WindowManager::for_each_window(Callback callback)
|
||||
{
|
||||
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
||||
if (callback(*window) == IterationDecision::Break)
|
||||
|
@ -399,7 +400,7 @@ void WSWindowManager::for_each_window(Callback callback)
|
|||
}
|
||||
|
||||
template<typename Callback>
|
||||
IterationDecision WSWindowManager::for_each_window_of_type_from_front_to_back(WSWindowType type, Callback callback, bool ignore_highlight)
|
||||
IterationDecision WindowManager::for_each_window_of_type_from_front_to_back(WindowType type, Callback callback, bool ignore_highlight)
|
||||
{
|
||||
if (!ignore_highlight && m_highlight_window && m_highlight_window->type() == type && m_highlight_window->is_visible()) {
|
||||
if (callback(*m_highlight_window) == IterationDecision::Break)
|
||||
|
@ -416,3 +417,5 @@ IterationDecision WSWindowManager::for_each_window_of_type_from_front_to_back(WS
|
|||
}
|
||||
return IterationDecision::Continue;
|
||||
}
|
||||
|
||||
}
|
|
@ -24,37 +24,39 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <WindowServer/WSEvent.h>
|
||||
#include <WindowServer/WSScreen.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <WindowServer/WSWindowSwitcher.h>
|
||||
#include <WindowServer/Event.h>
|
||||
#include <WindowServer/Screen.h>
|
||||
#include <WindowServer/WindowManager.h>
|
||||
#include <WindowServer/WindowSwitcher.h>
|
||||
|
||||
static WSWindowSwitcher* s_the;
|
||||
namespace WindowServer {
|
||||
|
||||
WSWindowSwitcher& WSWindowSwitcher::the()
|
||||
static WindowSwitcher* s_the;
|
||||
|
||||
WindowSwitcher& WindowSwitcher::the()
|
||||
{
|
||||
ASSERT(s_the);
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WSWindowSwitcher::WSWindowSwitcher()
|
||||
WindowSwitcher::WindowSwitcher()
|
||||
{
|
||||
s_the = this;
|
||||
}
|
||||
|
||||
WSWindowSwitcher::~WSWindowSwitcher()
|
||||
WindowSwitcher::~WindowSwitcher()
|
||||
{
|
||||
}
|
||||
|
||||
void WSWindowSwitcher::set_visible(bool visible)
|
||||
void WindowSwitcher::set_visible(bool visible)
|
||||
{
|
||||
if (m_visible == visible)
|
||||
return;
|
||||
m_visible = visible;
|
||||
WSWindowManager::the().recompute_occlusions();
|
||||
WindowManager::the().recompute_occlusions();
|
||||
if (m_switcher_window)
|
||||
m_switcher_window->set_visible(visible);
|
||||
if (!m_visible)
|
||||
|
@ -62,22 +64,22 @@ void WSWindowSwitcher::set_visible(bool visible)
|
|||
refresh();
|
||||
}
|
||||
|
||||
WSWindow* WSWindowSwitcher::selected_window()
|
||||
Window* WindowSwitcher::selected_window()
|
||||
{
|
||||
if (m_selected_index < 0 || m_selected_index >= m_windows.size())
|
||||
return nullptr;
|
||||
return m_windows[m_selected_index].ptr();
|
||||
}
|
||||
|
||||
void WSWindowSwitcher::on_key_event(const WSKeyEvent& event)
|
||||
void WindowSwitcher::on_key_event(const KeyEvent& event)
|
||||
{
|
||||
if (event.type() == WSEvent::KeyUp) {
|
||||
if (event.type() == Event::KeyUp) {
|
||||
if (event.key() == Key_Logo) {
|
||||
if (auto* window = selected_window()) {
|
||||
window->set_minimized(false);
|
||||
WSWindowManager::the().move_to_front_and_make_active(*window);
|
||||
WindowManager::the().move_to_front_and_make_active(*window);
|
||||
}
|
||||
WSWindowManager::the().set_highlight_window(nullptr);
|
||||
WindowManager::the().set_highlight_window(nullptr);
|
||||
hide();
|
||||
}
|
||||
return;
|
||||
|
@ -86,7 +88,7 @@ void WSWindowSwitcher::on_key_event(const WSKeyEvent& event)
|
|||
if (event.key() == Key_LeftShift || event.key() == Key_RightShift)
|
||||
return;
|
||||
if (event.key() != Key_Tab) {
|
||||
WSWindowManager::the().set_highlight_window(nullptr);
|
||||
WindowManager::the().set_highlight_window(nullptr);
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
|
@ -102,14 +104,14 @@ void WSWindowSwitcher::on_key_event(const WSKeyEvent& event)
|
|||
ASSERT(m_selected_index < m_windows.size());
|
||||
auto* highlight_window = m_windows.at(m_selected_index).ptr();
|
||||
ASSERT(highlight_window);
|
||||
WSWindowManager::the().set_highlight_window(highlight_window);
|
||||
WindowManager::the().set_highlight_window(highlight_window);
|
||||
draw();
|
||||
WSWindowManager::the().invalidate(m_rect);
|
||||
WindowManager::the().invalidate(m_rect);
|
||||
}
|
||||
|
||||
void WSWindowSwitcher::draw()
|
||||
void WindowSwitcher::draw()
|
||||
{
|
||||
auto palette = WSWindowManager::the().palette();
|
||||
auto palette = WindowManager::the().palette();
|
||||
Gfx::Painter painter(*m_switcher_window->backing_store());
|
||||
painter.fill_rect({ {}, m_rect.size() }, palette.window());
|
||||
painter.draw_rect({ {}, m_rect.size() }, palette.threed_shadow2());
|
||||
|
@ -140,15 +142,15 @@ void WSWindowSwitcher::draw()
|
|||
Gfx::Rect icon_rect = { thumbnail_rect.bottom_right().translated(-window.icon().width(), -window.icon().height()), { window.icon().width(), window.icon().height() } };
|
||||
painter.fill_rect(icon_rect, palette.window());
|
||||
painter.blit(icon_rect.location(), window.icon(), window.icon().rect());
|
||||
painter.draw_text(item_rect.translated(thumbnail_width() + 12, 0), window.title(), WSWindowManager::the().window_title_font(), Gfx::TextAlignment::CenterLeft, text_color);
|
||||
painter.draw_text(item_rect.translated(thumbnail_width() + 12, 0), window.title(), WindowManager::the().window_title_font(), Gfx::TextAlignment::CenterLeft, text_color);
|
||||
painter.draw_text(item_rect, window.rect().to_string(), Gfx::TextAlignment::CenterRight, rect_text_color);
|
||||
}
|
||||
}
|
||||
|
||||
void WSWindowSwitcher::refresh()
|
||||
void WindowSwitcher::refresh()
|
||||
{
|
||||
auto& wm = WSWindowManager::the();
|
||||
WSWindow* selected_window = nullptr;
|
||||
auto& wm = WindowManager::the();
|
||||
Window* selected_window = nullptr;
|
||||
if (m_selected_index > 0 && m_windows[m_selected_index])
|
||||
selected_window = m_windows[m_selected_index].ptr();
|
||||
if (!selected_window)
|
||||
|
@ -157,14 +159,15 @@ void WSWindowSwitcher::refresh()
|
|||
m_selected_index = 0;
|
||||
int window_count = 0;
|
||||
int longest_title_width = 0;
|
||||
wm.for_each_window_of_type_from_front_to_back(WSWindowType::Normal, [&](WSWindow& window) {
|
||||
++window_count;
|
||||
longest_title_width = max(longest_title_width, wm.font().width(window.title()));
|
||||
if (selected_window == &window)
|
||||
m_selected_index = m_windows.size();
|
||||
m_windows.append(window.make_weak_ptr());
|
||||
return IterationDecision::Continue;
|
||||
},
|
||||
wm.for_each_window_of_type_from_front_to_back(
|
||||
WindowType::Normal, [&](Window& window) {
|
||||
++window_count;
|
||||
longest_title_width = max(longest_title_width, wm.font().width(window.title()));
|
||||
if (selected_window == &window)
|
||||
m_selected_index = m_windows.size();
|
||||
m_windows.append(window.make_weak_ptr());
|
||||
return IterationDecision::Continue;
|
||||
},
|
||||
true);
|
||||
if (m_windows.is_empty()) {
|
||||
hide();
|
||||
|
@ -173,17 +176,19 @@ void WSWindowSwitcher::refresh()
|
|||
int space_for_window_rect = 180;
|
||||
m_rect.set_width(thumbnail_width() + longest_title_width + space_for_window_rect + padding() * 2 + item_padding() * 2);
|
||||
m_rect.set_height(window_count * item_height() + padding() * 2);
|
||||
m_rect.center_within(WSScreen::the().rect());
|
||||
m_rect.center_within(Screen::the().rect());
|
||||
if (!m_switcher_window)
|
||||
m_switcher_window = WSWindow::construct(*this, WSWindowType::WindowSwitcher);
|
||||
m_switcher_window = Window::construct(*this, WindowType::WindowSwitcher);
|
||||
m_switcher_window->set_rect(m_rect);
|
||||
draw();
|
||||
}
|
||||
|
||||
void WSWindowSwitcher::refresh_if_needed()
|
||||
void WindowSwitcher::refresh_if_needed()
|
||||
{
|
||||
if (m_visible) {
|
||||
refresh();
|
||||
WSWindowManager::the().invalidate(m_rect);
|
||||
WindowManager::the().invalidate(m_rect);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -35,16 +35,18 @@ namespace Gfx {
|
|||
class Painter;
|
||||
}
|
||||
|
||||
class WSKeyEvent;
|
||||
class WSWindow;
|
||||
namespace WindowServer {
|
||||
|
||||
class WSWindowSwitcher : public Core::Object {
|
||||
C_OBJECT(WSWindowSwitcher)
|
||||
class KeyEvent;
|
||||
class Window;
|
||||
|
||||
class WindowSwitcher : public Core::Object {
|
||||
C_OBJECT(WindowSwitcher)
|
||||
public:
|
||||
static WSWindowSwitcher& the();
|
||||
static WindowSwitcher& the();
|
||||
|
||||
WSWindowSwitcher();
|
||||
virtual ~WSWindowSwitcher() override;
|
||||
WindowSwitcher();
|
||||
virtual ~WindowSwitcher() override;
|
||||
|
||||
bool is_visible() const { return m_visible; }
|
||||
void set_visible(bool);
|
||||
|
@ -52,7 +54,7 @@ public:
|
|||
void show() { set_visible(true); }
|
||||
void hide() { set_visible(false); }
|
||||
|
||||
void on_key_event(const WSKeyEvent&);
|
||||
void on_key_event(const KeyEvent&);
|
||||
void refresh();
|
||||
void refresh_if_needed();
|
||||
|
||||
|
@ -65,14 +67,16 @@ public:
|
|||
int padding() { return 8; }
|
||||
int item_padding() { return 8; }
|
||||
|
||||
WSWindow* selected_window();
|
||||
Window* selected_window();
|
||||
|
||||
WSWindow* switcher_window() { return m_switcher_window.ptr(); }
|
||||
Window* switcher_window() { return m_switcher_window.ptr(); }
|
||||
|
||||
private:
|
||||
RefPtr<WSWindow> m_switcher_window;
|
||||
RefPtr<Window> m_switcher_window;
|
||||
Gfx::Rect m_rect;
|
||||
bool m_visible { false };
|
||||
Vector<WeakPtr<WSWindow>> m_windows;
|
||||
Vector<WeakPtr<Window>> m_windows;
|
||||
int m_selected_index { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@
|
|||
#pragma once
|
||||
|
||||
// Keep this in sync with GWindowType.
|
||||
enum class WSWindowType {
|
||||
enum class WindowType {
|
||||
Invalid = 0,
|
||||
Normal,
|
||||
Menu,
|
|
@ -24,13 +24,13 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "Compositor.h"
|
||||
#include "EventLoop.h"
|
||||
#include "Screen.h"
|
||||
#include "WindowManager.h"
|
||||
#include <LibCore/ConfigFile.h>
|
||||
#include <LibGfx/Palette.h>
|
||||
#include <LibGfx/SystemTheme.h>
|
||||
#include <WindowServer/WSCompositor.h>
|
||||
#include <WindowServer/WSEventLoop.h>
|
||||
#include <WindowServer/WSScreen.h>
|
||||
#include <WindowServer/WSWindowManager.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -87,18 +87,18 @@ int main(int, char**)
|
|||
Gfx::set_system_theme(*theme);
|
||||
auto palette = Gfx::PaletteImpl::create_with_shared_buffer(*theme);
|
||||
|
||||
WSEventLoop loop;
|
||||
WindowServer::EventLoop loop;
|
||||
|
||||
if (pledge("stdio video thread shared_buffer accept rpath wpath cpath proc exec", nullptr) < 0) {
|
||||
perror("pledge");
|
||||
return 1;
|
||||
}
|
||||
|
||||
WSScreen screen(wm_config->read_num_entry("Screen", "Width", 1024),
|
||||
WindowServer::Screen screen(wm_config->read_num_entry("Screen", "Width", 1024),
|
||||
wm_config->read_num_entry("Screen", "Height", 768));
|
||||
WSCompositor::the();
|
||||
auto wm = WSWindowManager::construct(*palette);
|
||||
auto mm = WSMenuManager::construct();
|
||||
WindowServer::Compositor::the();
|
||||
auto wm = WindowServer::WindowManager::construct(*palette);
|
||||
auto mm = WindowServer::MenuManager::construct();
|
||||
|
||||
if (unveil("/tmp", "") < 0) {
|
||||
perror("unveil");
|
||||
|
|
Loading…
Reference in a new issue