WindowServer: Refactor more of the menu APIs to be message-based.

This is all pretty verbose but I can whittle it down later. :^)
This commit is contained in:
Andreas Kling 2019-02-13 18:48:22 +01:00
parent fbbf57b61c
commit cf432b4c3d
13 changed files with 229 additions and 171 deletions

View file

@ -70,6 +70,10 @@ struct GUI_ServerMessage {
MenuItemActivated, MenuItemActivated,
DidCreateMenubar, DidCreateMenubar,
DidDestroyMenubar, DidDestroyMenubar,
DidCreateMenu,
DidDestroyMenu,
DidAddMenuToMenubar,
DidSetApplicationMenubar,
}; };
Type type { Invalid }; Type type { Invalid };
int window_id { -1 }; int window_id { -1 };
@ -104,6 +108,10 @@ struct GUI_ClientMessage {
Invalid, Invalid,
CreateMenubar, CreateMenubar,
DestroyMenubar, DestroyMenubar,
CreateMenu,
DestroyMenu,
AddMenuToMenubar,
SetApplicationMenubar,
}; };
Type type { Invalid }; Type type { Invalid };
int window_id { -1 }; int window_id { -1 };
@ -112,6 +120,9 @@ struct GUI_ClientMessage {
struct { struct {
int menubar_id; int menubar_id;
int menu_id; int menu_id;
unsigned identifier;
unsigned text_length;
char text[256];
} menu; } menu;
}; };
}; };

View file

@ -292,23 +292,6 @@ DisplayInfo Process::set_video_resolution(int width, int height)
return info; return info;
} }
int Process::gui$menubar_add_menu(int menubar_id, int menu_id)
{
return WSWindowManager::the().api$menubar_add_menu(menubar_id, menu_id);
}
int Process::gui$menu_create(const char* name)
{
if (!validate_read_str(name))
return -EFAULT;
return WSWindowManager::the().api$menu_create(String(name));
}
int Process::gui$menu_destroy(int menu_id)
{
return WSWindowManager::the().api$menu_destroy(menu_id);
}
int Process::gui$menu_add_separator(int menu_id) int Process::gui$menu_add_separator(int menu_id)
{ {
return WSWindowManager::the().api$menu_add_separator(menu_id); return WSWindowManager::the().api$menu_add_separator(menu_id);
@ -320,8 +303,3 @@ int Process::gui$menu_add_item(int menu_id, unsigned identifier, const char* tex
return -EFAULT; return -EFAULT;
return WSWindowManager::the().api$menu_add_item(menu_id, identifier, String(text)); return WSWindowManager::the().api$menu_add_item(menu_id, identifier, String(text));
} }
int Process::gui$set_menubar(int menubar_id)
{
return WSWindowManager::the().api$app_set_menubar(menubar_id);
}

View file

@ -223,18 +223,10 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2,
return current->sys$rmdir((const char*)arg1); return current->sys$rmdir((const char*)arg1);
case Syscall::SC_chmod: case Syscall::SC_chmod:
return current->sys$chmod((const char*)arg1, (mode_t)arg2); return current->sys$chmod((const char*)arg1, (mode_t)arg2);
case Syscall::SC_gui_menubar_add_menu:
return current->gui$menubar_add_menu((int)arg1, (int)arg2);
case Syscall::SC_gui_menu_create:
return current->gui$menu_create((const char*)arg1);
case Syscall::SC_gui_menu_destroy:
return current->gui$menu_destroy((int)arg1);
case Syscall::SC_gui_menu_add_separator: case Syscall::SC_gui_menu_add_separator:
return current->gui$menu_add_separator((int)arg1); return current->gui$menu_add_separator((int)arg1);
case Syscall::SC_gui_menu_add_item: case Syscall::SC_gui_menu_add_item:
return current->gui$menu_add_item((int)arg1, (unsigned)arg2, (const char*)arg3); return current->gui$menu_add_item((int)arg1, (unsigned)arg2, (const char*)arg3);
case Syscall::SC_gui_app_set_menubar:
return current->gui$set_menubar((int)arg1);
default: default:
kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); kprintf("<%u> int0x80: Unknown function %u requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3);
break; break;

View file

@ -85,12 +85,8 @@
__ENUMERATE_SYSCALL(rmdir) \ __ENUMERATE_SYSCALL(rmdir) \
__ENUMERATE_SYSCALL(chmod) \ __ENUMERATE_SYSCALL(chmod) \
__ENUMERATE_SYSCALL(usleep) \ __ENUMERATE_SYSCALL(usleep) \
__ENUMERATE_SYSCALL(gui_menubar_add_menu) \
__ENUMERATE_SYSCALL(gui_menu_create) \
__ENUMERATE_SYSCALL(gui_menu_destroy) \
__ENUMERATE_SYSCALL(gui_menu_add_separator) \ __ENUMERATE_SYSCALL(gui_menu_add_separator) \
__ENUMERATE_SYSCALL(gui_menu_add_item) \ __ENUMERATE_SYSCALL(gui_menu_add_item) \
__ENUMERATE_SYSCALL(gui_app_set_menubar) \
#ifdef SERENITY #ifdef SERENITY

View file

@ -69,24 +69,6 @@ int gui_set_global_cursor_tracking_enabled(int window_id, bool enabled)
__RETURN_WITH_ERRNO(rc, rc, -1); __RETURN_WITH_ERRNO(rc, rc, -1);
} }
int gui_menubar_add_menu(int menubar_id, int menu_id)
{
int rc = syscall(SC_gui_menubar_add_menu, menubar_id, menu_id);
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int gui_menu_create(const char* name)
{
int rc = syscall(SC_gui_menu_create, name);
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int gui_menu_destroy(int menu_id)
{
int rc = syscall(SC_gui_menu_destroy, menu_id);
__RETURN_WITH_ERRNO(rc, rc, -1);
}
int gui_menu_add_separator(int menu_id) int gui_menu_add_separator(int menu_id)
{ {
int rc = syscall(SC_gui_menu_add_separator, menu_id); int rc = syscall(SC_gui_menu_add_separator, menu_id);
@ -98,9 +80,3 @@ int gui_menu_add_item(int menu_id, unsigned identifier, const char* text)
int rc = syscall(SC_gui_menu_add_item, menu_id, identifier, text); int rc = syscall(SC_gui_menu_add_item, menu_id, identifier, text);
__RETURN_WITH_ERRNO(rc, rc, -1); __RETURN_WITH_ERRNO(rc, rc, -1);
} }
int gui_app_set_menubar(int menubar_id)
{
int rc = syscall(SC_gui_app_set_menubar, menubar_id);
__RETURN_WITH_ERRNO(rc, rc, -1);
}

View file

@ -16,12 +16,8 @@ int gui_set_window_title(int window_id, const char*, size_t);
int gui_get_window_rect(int window_id, GUI_Rect*); int gui_get_window_rect(int window_id, GUI_Rect*);
int gui_set_window_rect(int window_id, const GUI_Rect*); int gui_set_window_rect(int window_id, const GUI_Rect*);
int gui_set_global_cursor_tracking_enabled(int window_id, bool); int gui_set_global_cursor_tracking_enabled(int window_id, bool);
int gui_menubar_add_menu(int menubar_id, int menu_id);
int gui_menu_create(const char* name);
int gui_menu_destroy(int menu_id);
int gui_menu_add_separator(int menu_id); int gui_menu_add_separator(int menu_id);
int gui_menu_add_item(int menu_id, unsigned identifier, const char* text); int gui_menu_add_item(int menu_id, unsigned identifier, const char* text);
int gui_app_set_menubar(int menubar_id);
__END_DECLS __END_DECLS

View file

@ -1,5 +1,6 @@
#include <LibGUI/GAction.h> #include <LibGUI/GAction.h>
#include <LibGUI/GMenu.h> #include <LibGUI/GMenu.h>
#include <LibGUI/GEventLoop.h>
#include <LibC/gui.h> #include <LibC/gui.h>
#include <AK/HashMap.h> #include <AK/HashMap.h>
@ -26,11 +27,7 @@ GMenu::GMenu(const String& name)
GMenu::~GMenu() GMenu::~GMenu()
{ {
if (m_menu_id) { unrealize_menu();
all_menus().remove(m_menu_id);
gui_menu_destroy(m_menu_id);
m_menu_id = 0;
}
} }
void GMenu::add_action(OwnPtr<GAction>&& action) void GMenu::add_action(OwnPtr<GAction>&& action)
@ -45,7 +42,15 @@ void GMenu::add_separator()
int GMenu::realize_menu() int GMenu::realize_menu()
{ {
m_menu_id = gui_menu_create(m_name.characters()); GUI_ClientMessage request;
request.type = GUI_ClientMessage::Type::CreateMenu;
ASSERT(m_name.length() < sizeof(request.menu.text));
strcpy(request.menu.text, m_name.characters());
request.menu.text_length = m_name.length();
auto response = GEventLoop::main().sync_request(request, GUI_ServerMessage::Type::DidCreateMenu);
m_menu_id = response.menu.menu_id;
ASSERT(m_menu_id > 0); ASSERT(m_menu_id > 0);
for (size_t i = 0; i < m_items.size(); ++i) { for (size_t i = 0; i < m_items.size(); ++i) {
auto& item = *m_items[i]; auto& item = *m_items[i];
@ -62,6 +67,18 @@ int GMenu::realize_menu()
return m_menu_id; return m_menu_id;
} }
void GMenu::unrealize_menu()
{
if (!m_menu_id)
return;
all_menus().remove(m_menu_id);
GUI_ClientMessage request;
request.type = GUI_ClientMessage::Type::DestroyMenu;
request.menu.menu_id = m_menu_id;
GEventLoop::main().sync_request(request, GUI_ServerMessage::Type::DidDestroyMenu);
m_menu_id = 0;
}
GAction* GMenu::action_at(size_t index) GAction* GMenu::action_at(size_t index)
{ {
if (index >= m_items.size()) if (index >= m_items.size())

View file

@ -24,6 +24,7 @@ private:
friend class GMenuBar; friend class GMenuBar;
int menu_id() const { return m_menu_id; } int menu_id() const { return m_menu_id; }
int realize_menu(); int realize_menu();
void unrealize_menu();
int m_menu_id { 0 }; int m_menu_id { 0 };
String m_name; String m_name;

View file

@ -44,10 +44,16 @@ void GMenuBar::notify_added_to_application(Badge<GApplication>)
ASSERT(menu); ASSERT(menu);
int menu_id = menu->realize_menu(); int menu_id = menu->realize_menu();
ASSERT(menu_id > 0); ASSERT(menu_id > 0);
int rc = gui_menubar_add_menu(m_menubar_id, menu_id); GUI_ClientMessage request;
ASSERT(rc == 0); request.type = GUI_ClientMessage::Type::AddMenuToMenubar;
request.menu.menubar_id = m_menubar_id;
request.menu.menu_id = menu_id;
GEventLoop::main().sync_request(request, GUI_ServerMessage::Type::DidAddMenuToMenubar);
} }
gui_app_set_menubar(m_menubar_id); GUI_ClientMessage request;
request.type = GUI_ClientMessage::Type::SetApplicationMenubar;
request.menu.menubar_id = m_menubar_id;
GEventLoop::main().sync_request(request, GUI_ServerMessage::Type::DidSetApplicationMenubar);
} }
void GMenuBar::notify_removed_from_application(Badge<GApplication>) void GMenuBar::notify_removed_from_application(Badge<GApplication>)

View file

@ -27,6 +27,10 @@ public:
__Begin_API_Client_Requests, __Begin_API_Client_Requests,
APICreateMenubarRequest, APICreateMenubarRequest,
APIDestroyMenubarRequest, APIDestroyMenubarRequest,
APIAddMenuToMenubarRequest,
APISetApplicationMenubarRequest,
APICreateMenuRequest,
APIDestroyMenuRequest,
__End_API_Client_Requests, __End_API_Client_Requests,
}; };
@ -80,6 +84,66 @@ private:
int m_menubar_id { 0 }; int m_menubar_id { 0 };
}; };
class WSAPISetApplicationMenubarRequest : public WSAPIClientRequest {
public:
WSAPISetApplicationMenubarRequest(int client_id, int menubar_id)
: WSAPIClientRequest(WSMessage::APISetApplicationMenubarRequest, client_id)
, m_menubar_id(menubar_id)
{
}
int menubar_id() const { return m_menubar_id; }
private:
int m_menubar_id { 0 };
};
class WSAPIAddMenuToMenubarRequest : public WSAPIClientRequest {
public:
WSAPIAddMenuToMenubarRequest(int client_id, int menubar_id, int menu_id)
: WSAPIClientRequest(WSMessage::APIAddMenuToMenubarRequest, client_id)
, m_menubar_id(menubar_id)
, m_menu_id(menu_id)
{
}
int menubar_id() const { return m_menubar_id; }
int menu_id() const { return m_menu_id; }
private:
int m_menubar_id { 0 };
int m_menu_id { 0 };
};
class WSAPICreateMenuRequest : public WSAPIClientRequest {
public:
WSAPICreateMenuRequest(int client_id, const String& text)
: WSAPIClientRequest(WSMessage::APICreateMenuRequest, client_id)
, m_text(text)
{
}
String text() const { return m_text; }
private:
String m_text;
};
class WSAPIDestroyMenuRequest : public WSAPIClientRequest {
public:
WSAPIDestroyMenuRequest(int client_id, int menu_id)
: WSAPIClientRequest(WSMessage::APIDestroyMenuRequest, client_id)
, m_menu_id(menu_id)
{
}
int menu_id() const { return m_menu_id; }
private:
int m_menu_id { 0 };
};
class WSClientFinishedPaintMessage final : public WSMessage { class WSClientFinishedPaintMessage final : public WSMessage {
public: public:
explicit WSClientFinishedPaintMessage(const Rect& rect = Rect()) explicit WSClientFinishedPaintMessage(const Rect& rect = Rect())

View file

@ -274,6 +274,19 @@ ssize_t WSMessageLoop::on_receive_from_client(int client_id, const byte* data, s
case GUI_ClientMessage::Type::DestroyMenubar: case GUI_ClientMessage::Type::DestroyMenubar:
post_message(&WSWindowManager::the(), make<WSAPIDestroyMenubarRequest>(client_id, message.menu.menubar_id)); post_message(&WSWindowManager::the(), make<WSAPIDestroyMenubarRequest>(client_id, message.menu.menubar_id));
break; break;
case GUI_ClientMessage::Type::SetApplicationMenubar:
post_message(&WSWindowManager::the(), make<WSAPISetApplicationMenubarRequest>(client_id, message.menu.menubar_id));
break;
case GUI_ClientMessage::Type::AddMenuToMenubar:
post_message(&WSWindowManager::the(), make<WSAPIAddMenuToMenubarRequest>(client_id, message.menu.menubar_id, message.menu.menu_id));
break;
case GUI_ClientMessage::Type::CreateMenu:
ASSERT(message.menu.text_length < sizeof(message.menu.text));
post_message(&WSWindowManager::the(), make<WSAPICreateMenuRequest>(client_id, String(message.menu.text, message.menu.text_length)));
break;
case GUI_ClientMessage::Type::DestroyMenu:
post_message(&WSWindowManager::the(), make<WSAPIDestroyMenuRequest>(client_id, message.menu.menu_id));
break;
} }
return size; return size;
} }

View file

@ -734,39 +734,109 @@ void WSWindowManager::on_message(WSMessage& message)
return; return;
} }
if (message.is_client_request()) { if (message.is_client_request())
auto& request = static_cast<WSAPIClientRequest&>(message); handle_client_request(static_cast<WSAPIClientRequest&>(message));
switch (request.type()) { }
case WSMessage::APICreateMenubarRequest: {
int menubar_id = m_next_menubar_id++; void WSWindowManager::handle_client_request(WSAPIClientRequest& request)
auto menubar = make<WSMenuBar>(menubar_id, *WSMessageLoop::process_from_client_id(request.client_id())); {
m_menubars.set(menubar_id, move(menubar)); switch (request.type()) {
GUI_ServerMessage response; case WSMessage::APICreateMenubarRequest: {
response.type = GUI_ServerMessage::Type::DidCreateMenubar; int menubar_id = m_next_menubar_id++;
response.menu.menubar_id = menubar_id; auto menubar = make<WSMenuBar>(menubar_id, *WSMessageLoop::process_from_client_id(request.client_id()));
WSMessageLoop::the().post_message_to_client(request.client_id(), response); m_menubars.set(menubar_id, move(menubar));
break; GUI_ServerMessage response;
response.type = GUI_ServerMessage::Type::DidCreateMenubar;
response.menu.menubar_id = menubar_id;
WSMessageLoop::the().post_message_to_client(request.client_id(), response);
break;
}
case WSMessage::APIDestroyMenubarRequest: {
int menubar_id = static_cast<WSAPIDestroyMenubarRequest&>(request).menubar_id();
auto it = m_menubars.find(menubar_id);
if (it == m_menubars.end()) {
ASSERT_NOT_REACHED();
// FIXME: Send an error.
return;
} }
case WSMessage::APIDestroyMenubarRequest: { auto& menubar = *(*it).value;
int menubar_id = static_cast<WSAPIDestroyMenubarRequest&>(request).menubar_id(); if (&menubar == m_current_menubar)
auto it = m_menubars.find(menubar_id); set_current_menubar(nullptr);
if (it == m_menubars.end()) { m_menubars.remove(it);
ASSERT_NOT_REACHED(); GUI_ServerMessage response;
// FIXME: Send an error. response.type = GUI_ServerMessage::Type::DidDestroyMenubar;
return; response.menu.menubar_id = menubar_id;
} WSMessageLoop::the().post_message_to_client(request.client_id(), response);
auto& menubar = *(*it).value; break;
if (&menubar == m_current_menubar) }
set_current_menubar(nullptr); case WSMessage::APICreateMenuRequest: {
m_menubars.remove(it); int menu_id = m_next_menu_id++;
GUI_ServerMessage response; auto menu = make<WSMenu>(*WSMessageLoop::process_from_client_id(request.client_id()), menu_id, static_cast<WSAPICreateMenuRequest&>(request).text());
response.type = GUI_ServerMessage::Type::DidDestroyMenubar; m_menus.set(menu_id, move(menu));
response.menu.menubar_id = menubar_id; GUI_ServerMessage response;
WSMessageLoop::the().post_message_to_client(request.client_id(), response); response.type = GUI_ServerMessage::Type::DidCreateMenu;
response.menu.menu_id = menu_id;
WSMessageLoop::the().post_message_to_client(request.client_id(), response);
break;
}
case WSMessage::APIDestroyMenuRequest: {
int menu_id = static_cast<WSAPIDestroyMenuRequest&>(request).menu_id();
auto it = m_menus.find(menu_id);
if (it == m_menus.end()) {
ASSERT_NOT_REACHED();
// FIXME: Send an error.
return;
} }
default: auto& menu = *(*it).value;
break; close_menu(menu);
m_menus.remove(it);
GUI_ServerMessage response;
response.type = GUI_ServerMessage::Type::DidDestroyMenu;
response.menu.menu_id = menu_id;
WSMessageLoop::the().post_message_to_client(request.client_id(), response);
break;
}
case WSMessage::APISetApplicationMenubarRequest: {
int menubar_id = static_cast<WSAPISetApplicationMenubarRequest&>(request).menubar_id();
auto it = m_menubars.find(menubar_id);
if (it == m_menubars.end()) {
ASSERT_NOT_REACHED();
// FIXME: Send an error.
return;
} }
auto& menubar = *(*it).value;
m_app_menubars.set(request.client_id(), &menubar);
if (active_client_id() == request.client_id())
set_current_menubar(&menubar);
invalidate();
GUI_ServerMessage response;
response.type = GUI_ServerMessage::Type::DidSetApplicationMenubar;
response.menu.menubar_id = menubar_id;
WSMessageLoop::the().post_message_to_client(request.client_id(), response);
break;
}
case WSMessage::APIAddMenuToMenubarRequest: {
int menubar_id = static_cast<WSAPIAddMenuToMenubarRequest&>(request).menubar_id();
int menu_id = static_cast<WSAPIAddMenuToMenubarRequest&>(request).menu_id();
auto it = m_menubars.find(menubar_id);
auto jt = m_menus.find(menu_id);
if (it == m_menubars.end() || jt == m_menus.end()) {
ASSERT_NOT_REACHED();
// FIXME: Send an error.
return;
}
auto& menubar = *(*it).value;
auto& menu = *(*jt).value;
menubar.add_menu(&menu);
GUI_ServerMessage response;
response.type = GUI_ServerMessage::Type::DidAddMenuToMenubar;
response.menu.menubar_id = menubar_id;
response.menu.menu_id = menu_id;
WSMessageLoop::the().post_message_to_client(request.client_id(), response);
break;
}
default:
break;
} }
} }
@ -786,7 +856,7 @@ void WSWindowManager::set_active_window(WSWindow* window)
invalidate(*m_active_window); invalidate(*m_active_window);
ASSERT(window->process()); ASSERT(window->process());
auto it = m_app_menubars.find(window->process()); auto it = m_app_menubars.find(window->process()->gui_client_id());
if (it != m_app_menubars.end()) { if (it != m_app_menubars.end()) {
auto* menubar = (*it).value; auto* menubar = (*it).value;
if (menubar != m_current_menubar) if (menubar != m_current_menubar)
@ -880,51 +950,6 @@ void WSWindowManager::close_menu(WSMenu& menu)
close_current_menu(); close_current_menu();
} }
WSMenu& WSWindowManager::create_menu(String&& name)
{
LOCKER(m_lock);
int menu_id = m_next_menu_id++;
auto menu = make<WSMenu>(*current, menu_id, move(name));
auto* menu_ptr = menu.ptr();
m_menus.set(menu_id, move(menu));
return *menu_ptr;
}
int WSWindowManager::api$menubar_add_menu(int menubar_id, int menu_id)
{
LOCKER(m_lock);
auto it = m_menubars.find(menubar_id);
if (it == m_menubars.end())
return -EBADMENUBAR;
auto& menubar = *(*it).value;
auto jt = m_menus.find(menu_id);
if (jt == m_menus.end())
return -EBADMENU;
auto& menu = *(*jt).value;
menubar.add_menu(&menu);
return 0;
}
int WSWindowManager::api$menu_create(String&& name)
{
LOCKER(m_lock);
return create_menu(move(name)).menu_id();
}
int WSWindowManager::api$menu_destroy(int menu_id)
{
LOCKER(m_lock);
auto it = m_menus.find(menu_id);
if (it == m_menus.end())
return -EBADMENU;
auto& menu = *(*it).value;
close_menu(menu);
m_menus.remove(it);
return 0;
}
int WSWindowManager::api$menu_add_separator(int menu_id) int WSWindowManager::api$menu_add_separator(int menu_id)
{ {
LOCKER(m_lock); LOCKER(m_lock);
@ -947,24 +972,10 @@ int WSWindowManager::api$menu_add_item(int menu_id, unsigned identifier, String&
return 0; return 0;
} }
const Process* WSWindowManager::active_process() const int WSWindowManager::active_client_id() const
{ {
if (m_active_window) if (m_active_window)
return m_active_window->process(); return m_active_window->process()->gui_client_id();
return nullptr;
}
int WSWindowManager::api$app_set_menubar(int menubar_id)
{
LOCKER(m_lock);
auto it = m_menubars.find(menubar_id);
if (it == m_menubars.end())
return -EBADMENUBAR;
auto& menubar = *(*it).value;
m_app_menubars.set(current, &menubar);
if (active_process() == current)
set_current_menubar(&menubar);
invalidate();
return 0; return 0;
} }
@ -996,5 +1007,5 @@ void WSWindowManager::destroy_all_menus(Process& process)
set_current_menubar(nullptr); set_current_menubar(nullptr);
for (int menubar_id : menubar_ids) for (int menubar_id : menubar_ids)
m_menubars.remove(menubar_id); m_menubars.remove(menubar_id);
m_app_menubars.remove(&process); m_app_menubars.remove(process.gui_client_id());
} }

View file

@ -12,6 +12,7 @@
#include "WSMenuBar.h" #include "WSMenuBar.h"
#include <WindowServer/WSWindowType.h> #include <WindowServer/WSWindowType.h>
class WSAPIClientRequest;
class WSScreen; class WSScreen;
class WSMenuBar; class WSMenuBar;
class WSMouseEvent; class WSMouseEvent;
@ -32,7 +33,7 @@ public:
void notify_rect_changed(WSWindow&, const Rect& oldRect, const Rect& newRect); void notify_rect_changed(WSWindow&, const Rect& oldRect, const Rect& newRect);
WSWindow* active_window() { return m_active_window.ptr(); } WSWindow* active_window() { return m_active_window.ptr(); }
const Process* active_process() const; int active_client_id() const;
void move_to_front(WSWindow&); void move_to_front(WSWindow&);
@ -59,12 +60,8 @@ public:
Color menu_selection_color() const { return m_menu_selection_color; } Color menu_selection_color() const { return m_menu_selection_color; }
int menubar_menu_margin() const; int menubar_menu_margin() const;
int api$menubar_add_menu(int menubar_id, int menu_id);
int api$menu_create(String&&);
int api$menu_destroy(int menu_id);
int api$menu_add_separator(int menu_id); int api$menu_add_separator(int menu_id);
int api$menu_add_item(int menu_id, unsigned identifier, String&& text); int api$menu_add_item(int menu_id, unsigned identifier, String&& text);
int api$app_set_menubar(int menubar_id);
void destroy_all_menus(Process&); void destroy_all_menus(Process&);
private: private:
@ -76,6 +73,7 @@ private:
void handle_menubar_mouse_event(WSMenuBar&, WSMouseEvent&); void handle_menubar_mouse_event(WSMenuBar&, WSMouseEvent&);
void handle_titlebar_mouse_event(WSWindow&, WSMouseEvent&); void handle_titlebar_mouse_event(WSWindow&, WSMouseEvent&);
void handle_close_button_mouse_event(WSWindow&, WSMouseEvent&); void handle_close_button_mouse_event(WSWindow&, WSMouseEvent&);
void handle_client_request(WSAPIClientRequest&);
void set_active_window(WSWindow*); void set_active_window(WSWindow*);
template<typename Callback> IterationDecision for_each_visible_window_of_type_from_back_to_front(WSWindowType, Callback); template<typename Callback> IterationDecision for_each_visible_window_of_type_from_back_to_front(WSWindowType, Callback);
@ -84,7 +82,6 @@ private:
template<typename Callback> IterationDecision for_each_visible_window_from_back_to_front(Callback); template<typename Callback> IterationDecision for_each_visible_window_from_back_to_front(Callback);
template<typename Callback> void for_each_active_menubar_menu(Callback); template<typename Callback> void for_each_active_menubar_menu(Callback);
void close_current_menu(); void close_current_menu();
WSMenu& create_menu(String&& name);
virtual void on_message(WSMessage&) override; virtual void on_message(WSMessage&) override;
@ -156,5 +153,5 @@ private:
WSMenu* m_current_menu { nullptr }; WSMenu* m_current_menu { nullptr };
HashMap<int, OwnPtr<WSMenuBar>> m_menubars; HashMap<int, OwnPtr<WSMenuBar>> m_menubars;
HashMap<int, OwnPtr<WSMenu>> m_menus; HashMap<int, OwnPtr<WSMenu>> m_menus;
HashMap<const Process*, WSMenuBar*> m_app_menubars; HashMap<int, WSMenuBar*> m_app_menubars;
}; };