1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:17:42 +00:00

WindowServer: Clean up any menu objects on process exit.

..and now that this works, implement the Quit menu action in Terminal. :^)
This commit is contained in:
Andreas Kling 2019-02-12 10:41:09 +01:00
parent f311d0f353
commit 4b8133e925
10 changed files with 76 additions and 16 deletions

View file

@ -76,22 +76,29 @@ int main(int argc, char** argv)
auto menubar = make<GMenuBar>(); auto menubar = make<GMenuBar>();
auto app_menu = make<GMenu>("Terminal"); auto app_menu = make<GMenu>("Terminal");
app_menu->add_item(1, "Quit"); app_menu->add_item(0, "Quit");
app_menu->on_item_activation = [] (unsigned identifier) {
if (identifier == 0) {
dbgprintf("Terminal: Quit menu activated!\n");
GApplication::the().exit(0);
return;
}
};
menubar->add_menu(move(app_menu)); menubar->add_menu(move(app_menu));
auto font_menu = make<GMenu>("Font"); auto font_menu = make<GMenu>("Font");
font_menu->add_item(30, "Liza Thin"); font_menu->add_item(0, "Liza Thin");
font_menu->add_item(31, "Liza Regular"); font_menu->add_item(1, "Liza Regular");
font_menu->add_item(32, "Liza Bold"); font_menu->add_item(2, "Liza Bold");
font_menu->on_item_activation = [&terminal] (unsigned identifier) { font_menu->on_item_activation = [&terminal] (unsigned identifier) {
switch (identifier) { switch (identifier) {
case 30: case 0:
terminal.set_font(Font::load_from_file("/res/fonts/Liza8x10.font")); terminal.set_font(Font::load_from_file("/res/fonts/Liza8x10.font"));
break; break;
case 31: case 1:
terminal.set_font(Font::load_from_file("/res/fonts/LizaRegular8x10.font")); terminal.set_font(Font::load_from_file("/res/fonts/LizaRegular8x10.font"));
break; break;
case 32: case 2:
terminal.set_font(Font::load_from_file("/res/fonts/LizaBold8x10.font")); terminal.set_font(Font::load_from_file("/res/fonts/LizaBold8x10.font"));
break; break;
} }
@ -100,7 +107,7 @@ int main(int argc, char** argv)
menubar->add_menu(move(font_menu)); menubar->add_menu(move(font_menu));
auto help_menu = make<GMenu>("Help"); auto help_menu = make<GMenu>("Help");
help_menu->add_item(2, "About"); help_menu->add_item(0, "About");
menubar->add_menu(move(help_menu)); menubar->add_menu(move(help_menu));
app.set_menubar(move(menubar)); app.set_menubar(move(menubar));

View file

@ -2133,6 +2133,7 @@ void Process::finalize()
{ {
ASSERT(current == g_finalizer); ASSERT(current == g_finalizer);
destroy_all_menus();
destroy_all_windows(); destroy_all_windows();
m_fds.clear(); m_fds.clear();
m_tty = nullptr; m_tty = nullptr;

View file

@ -244,6 +244,7 @@ public:
static void initialize(); static void initialize();
static void initialize_gui_statics(); static void initialize_gui_statics();
int make_window_id(); int make_window_id();
void destroy_all_menus();
void destroy_all_windows(); void destroy_all_windows();
void crash() NORETURN; void crash() NORETURN;
@ -419,6 +420,7 @@ private:
Vector<GUI_Event> m_gui_events; Vector<GUI_Event> m_gui_events;
Lock m_gui_events_lock; Lock m_gui_events_lock;
int m_next_window_id { 1 }; int m_next_window_id { 1 };
bool m_has_created_menus { false };
dword m_wakeup_requested { false }; dword m_wakeup_requested { false };
bool m_has_used_fpu { false }; bool m_has_used_fpu { false };

View file

@ -257,6 +257,13 @@ int Process::gui$set_global_cursor_tracking_enabled(int window_id, bool enabled)
return 0; return 0;
} }
void Process::destroy_all_menus()
{
if (!m_has_created_menus)
return;
WSWindowManager::the().destroy_all_menus(*this);
}
void Process::destroy_all_windows() void Process::destroy_all_windows()
{ {
for (auto& it : m_windows) { for (auto& it : m_windows) {
@ -267,7 +274,6 @@ void Process::destroy_all_windows()
m_windows.clear(); m_windows.clear();
} }
DisplayInfo Process::set_video_resolution(int width, int height) DisplayInfo Process::set_video_resolution(int width, int height)
{ {
DisplayInfo info; DisplayInfo info;
@ -288,6 +294,7 @@ DisplayInfo Process::set_video_resolution(int width, int height)
int Process::gui$menubar_create() int Process::gui$menubar_create()
{ {
m_has_created_menus = true;
return WSWindowManager::the().api$menubar_create(); return WSWindowManager::the().api$menubar_create();
} }
@ -305,6 +312,7 @@ int Process::gui$menu_create(const char* name)
{ {
if (!validate_read_str(name)) if (!validate_read_str(name))
return -EFAULT; return -EFAULT;
m_has_created_menus = true;
return WSWindowManager::the().api$menu_create(String(name)); return WSWindowManager::the().api$menu_create(String(name));
} }

View file

@ -7,6 +7,10 @@ GMenuBar::GMenuBar()
GMenuBar::~GMenuBar() GMenuBar::~GMenuBar()
{ {
if (m_menubar_id) {
gui_menubar_destroy(m_menubar_id);
m_menubar_id = 0;
}
} }
void GMenuBar::add_menu(OwnPtr<GMenu>&& menu) void GMenuBar::add_menu(OwnPtr<GMenu>&& menu)

View file

@ -18,6 +18,7 @@ public:
~WSMenu(); ~WSMenu();
int menu_id() const { return m_menu_id; } int menu_id() const { return m_menu_id; }
const Process* process() const { return m_process.ptr(); }
WSMenuBar* menu_bar() { return m_menubar; } WSMenuBar* menu_bar() { return m_menubar; }
const WSMenuBar* menu_bar() const { return m_menubar; } const WSMenuBar* menu_bar() const { return m_menubar; }

View file

@ -3,8 +3,9 @@
#include "WSMenuItem.h" #include "WSMenuItem.h"
#include <Kernel/Process.h> #include <Kernel/Process.h>
WSMenuBar::WSMenuBar(Process& process) WSMenuBar::WSMenuBar(int menubar_id, Process& process)
: m_process(process.make_weak_ptr()) : m_menubar_id(menubar_id)
, m_process(process.make_weak_ptr())
{ {
} }

View file

@ -8,9 +8,11 @@ class Process;
class WSMenuBar { class WSMenuBar {
public: public:
explicit WSMenuBar(Process&); WSMenuBar(int menubar_id, Process&);
~WSMenuBar(); ~WSMenuBar();
int menubar_id() const { return m_menubar_id; }
const Process* process() const { return m_process.ptr(); }
void add_menu(WSMenu* menu) { m_menus.append(menu); } void add_menu(WSMenu* menu) { m_menus.append(menu); }
template<typename Callback> template<typename Callback>
@ -23,6 +25,7 @@ public:
} }
private: private:
int m_menubar_id { 0 };
WeakPtr<Process> m_process; WeakPtr<Process> m_process;
Vector<WSMenu*> m_menus; Vector<WSMenu*> m_menus;
}; };

View file

@ -761,8 +761,8 @@ void WSWindowManager::flush(const Rect& a_rect)
void WSWindowManager::close_menu(WSMenu& menu) void WSWindowManager::close_menu(WSMenu& menu)
{ {
LOCKER(m_lock); LOCKER(m_lock);
ASSERT(m_current_menu == &menu); if (m_current_menu == &menu)
close_current_menu(); close_current_menu();
} }
WSMenu& WSWindowManager::create_menu(String&& name) WSMenu& WSWindowManager::create_menu(String&& name)
@ -779,8 +779,8 @@ WSMenu& WSWindowManager::create_menu(String&& name)
int WSWindowManager::api$menubar_create() int WSWindowManager::api$menubar_create()
{ {
LOCKER(m_lock); LOCKER(m_lock);
auto menubar = make<WSMenuBar>(*current);
int menubar_id = m_next_menubar_id++; int menubar_id = m_next_menubar_id++;
auto menubar = make<WSMenuBar>(menubar_id, *current);
m_menubars.set(menubar_id, move(menubar)); m_menubars.set(menubar_id, move(menubar));
return menubar_id; return menubar_id;
} }
@ -793,7 +793,7 @@ int WSWindowManager::api$menubar_destroy(int menubar_id)
return -EBADMENUBAR; return -EBADMENUBAR;
auto& menubar = *(*it).value; auto& menubar = *(*it).value;
if (&menubar == m_current_menubar) if (&menubar == m_current_menubar)
ASSERT_NOT_REACHED(); set_current_menubar(nullptr);
m_menubars.remove(it); m_menubars.remove(it);
return 0; return 0;
} }
@ -827,6 +827,8 @@ int WSWindowManager::api$menu_destroy(int menu_id)
auto it = m_menus.find(menu_id); auto it = m_menus.find(menu_id);
if (it == m_menus.end()) if (it == m_menus.end())
return -EBADMENU; return -EBADMENU;
auto& menu = *(*it).value;
close_menu(menu);
m_menus.remove(it); m_menus.remove(it);
return 0; return 0;
} }
@ -868,3 +870,33 @@ int WSWindowManager::api$app_set_menubar(int menubar_id)
invalidate(); invalidate();
return 0; return 0;
} }
void WSWindowManager::destroy_all_menus(Process& process)
{
LOCKER(m_lock);
Vector<int> menu_ids;
bool should_close_current_menu = false;
for (auto& it : m_menus) {
if (it.value->process() == &process)
menu_ids.append(it.value->menu_id());
if (m_current_menu == it.value.ptr())
should_close_current_menu = true;
}
if (should_close_current_menu)
close_current_menu();
for (int menu_id : menu_ids)
m_menus.remove(menu_id);
Vector<int> menubar_ids;
bool should_close_current_menubar = false;
for (auto& it : m_menubars) {
if (it.value->process() == &process)
menubar_ids.append(it.value->menubar_id());
if (m_current_menubar == it.value.ptr())
should_close_current_menubar = true;
}
if (should_close_current_menubar)
set_current_menubar(nullptr);
for (int menubar_id : menubar_ids)
m_menubars.remove(menubar_id);
}

View file

@ -62,6 +62,7 @@ public:
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); int api$app_set_menubar(int menubar_id);
void destroy_all_menus(Process&);
private: private:
WSWindowManager(); WSWindowManager();