LibGUI: Turn GUI::Application::the() into a pointer

During app teardown, the Application object may be destroyed before
something else, and so having Application::the() return a reference was
obscuring the truth about its lifetime.

This patch makes the API more honest by returning a pointer. While
this makes call sites look a bit more sketchy, do note that the global
Application pointer only becomes null during app teardown.
This commit is contained in:
Andreas Kling 2020-07-04 16:52:01 +02:00
parent f7577585a6
commit ca93c22ae2
26 changed files with 51 additions and 49 deletions

View file

@ -254,7 +254,7 @@ Tab::Tab()
app_menu.add_action(*m_reload_action); app_menu.add_action(*m_reload_action);
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(); GUI::Application::the()->quit();
})); }));
auto& view_menu = m_menubar->add_menu("View"); auto& view_menu = m_menubar->add_menu("View");
@ -429,7 +429,7 @@ void Tab::did_become_active()
m_toolbar_container->set_visible(!is_fullscreen); m_toolbar_container->set_visible(!is_fullscreen);
m_statusbar->set_visible(!is_fullscreen); m_statusbar->set_visible(!is_fullscreen);
GUI::Application::the().set_menubar(m_menubar); GUI::Application::the()->set_menubar(m_menubar);
} }
void Tab::context_menu_requested(const Gfx::IntPoint& screen_position) void Tab::context_menu_requested(const Gfx::IntPoint& screen_position)

View file

@ -69,7 +69,7 @@ int main(int argc, char** argv)
auto& app_menu = menubar->add_menu("Calculator"); auto& app_menu = menubar->add_menu("Calculator");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -74,7 +74,7 @@ int main(int argc, char** argv)
})); }));
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -247,7 +247,7 @@ void DisplaySettingsWidget::create_frame()
ok_button.set_preferred_size(60, 22); ok_button.set_preferred_size(60, 22);
ok_button.on_click = [this](auto) { ok_button.on_click = [this](auto) {
send_settings_to_window_server(); send_settings_to_window_server();
GUI::Application::the().quit(); GUI::Application::the()->quit();
}; };
auto& cancel_button = bottom_widget.add<GUI::Button>(); auto& cancel_button = bottom_widget.add<GUI::Button>();
@ -255,7 +255,7 @@ void DisplaySettingsWidget::create_frame()
cancel_button.set_size_policy(Orientation::Horizontal, GUI::SizePolicy::Fixed); cancel_button.set_size_policy(Orientation::Horizontal, GUI::SizePolicy::Fixed);
cancel_button.set_preferred_size(60, 22); cancel_button.set_preferred_size(60, 22);
cancel_button.on_click = [](auto) { cancel_button.on_click = [](auto) {
GUI::Application::the().quit(); GUI::Application::the()->quit();
}; };
auto& apply_button = bottom_widget.add<GUI::Button>(); auto& apply_button = bottom_widget.add<GUI::Button>();

View file

@ -225,7 +225,7 @@ int run_in_desktop_mode(RefPtr<Core::ConfigFile> config, String initial_location
}; };
window->show(); window->show();
return GUI::Application::the().exec(); return GUI::Application::the()->exec();
} }
int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_location) int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_location)
@ -627,7 +627,7 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
app_menu.add_action(properties_action); app_menu.add_action(properties_action);
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
auto& view_menu = menubar->add_menu("View"); auto& view_menu = menubar->add_menu("View");
@ -646,7 +646,7 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
GUI::AboutDialog::show("File Manager", Gfx::Bitmap::load_from_file("/res/icons/32x32/filetype-folder.png"), window); GUI::AboutDialog::show("File Manager", Gfx::Bitmap::load_from_file("/res/icons/32x32/filetype-folder.png"), window);
})); }));
GUI::Application::the().set_menubar(move(menubar)); GUI::Application::the()->set_menubar(move(menubar));
main_toolbar.add_action(go_back_action); main_toolbar.add_action(go_back_action);
main_toolbar.add_action(go_forward_action); main_toolbar.add_action(go_forward_action);
@ -856,5 +856,5 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
return GUI::Window::CloseRequestDecision::Close; return GUI::Window::CloseRequestDecision::Close;
}; };
return GUI::Application::the().exec(); return GUI::Application::the()->exec();
} }

View file

@ -86,8 +86,8 @@ int main(int argc, char** argv)
auto menubar = GUI::MenuBar::construct(); auto menubar = GUI::MenuBar::construct();
auto& app_menu = menubar->add_menu("Font Editor"); auto& app_menu = menubar->add_menu("Font Editor");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) {
GUI::Application::the().quit(0); app->quit();
return; return;
})); }));

View file

@ -194,7 +194,7 @@ int main(int argc, char* argv[])
})); }));
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
auto& go_menu = menubar->add_menu("Go"); auto& go_menu = menubar->add_menu("Go");

View file

@ -142,7 +142,7 @@ HexEditorWidget::HexEditorWidget()
app_menu.add_action(GUI::CommonActions::make_quit_action([this](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([this](auto&) {
if (!request_close()) if (!request_close())
return; return;
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
m_goto_decimal_offset_action = GUI::Action::create("Go To Offset (Decimal)...", { Mod_Ctrl | Mod_Shift, Key_G }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [this](const GUI::Action&) { m_goto_decimal_offset_action = GUI::Action::create("Go To Offset (Decimal)...", { Mod_Ctrl | Mod_Shift, Key_G }, Gfx::Bitmap::load_from_file("/res/icons/16x16/go-forward.png"), [this](const GUI::Action&) {
@ -199,7 +199,7 @@ HexEditorWidget::HexEditorWidget()
GUI::AboutDialog::show("Hex Editor", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-hexeditor.png"), window()); GUI::AboutDialog::show("Hex Editor", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-hexeditor.png"), window());
})); }));
GUI::Application::the().set_menubar(move(menubar)); GUI::Application::the()->set_menubar(move(menubar));
m_editor->set_focus(true); m_editor->set_focus(true);
} }

View file

@ -263,7 +263,7 @@ void IRCAppWindow::setup_menus()
auto& app_menu = menubar->add_menu("IRC Client"); auto& app_menu = menubar->add_menu("IRC Client");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
dbgprintf("Terminal: Quit menu activated!\n"); dbgprintf("Terminal: Quit menu activated!\n");
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));
@ -301,7 +301,7 @@ void IRCAppWindow::setup_menus()
GUI::AboutDialog::show("IRC Client", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-irc-client.png"), this); GUI::AboutDialog::show("IRC Client", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-irc-client.png"), this);
})); }));
GUI::Application::the().set_menubar(move(menubar)); GUI::Application::the()->set_menubar(move(menubar));
} }
void IRCAppWindow::setup_widgets() void IRCAppWindow::setup_widgets()

View file

@ -96,7 +96,7 @@ int main(int argc, char** argv)
auto& app_menu = menubar->add_menu("Piano"); auto& app_menu = menubar->add_menu("Piano");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));
app_menu.add_action(GUI::Action::create("Export", { Mod_Ctrl, Key_E }, [&](const GUI::Action&) { app_menu.add_action(GUI::Action::create("Export", { Mod_Ctrl, Key_E }, [&](const GUI::Action&) {

View file

@ -113,7 +113,7 @@ int main(int argc, char** argv)
})); }));
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -223,7 +223,7 @@ int main(int argc, char** argv)
auto menubar = GUI::MenuBar::construct(); auto menubar = GUI::MenuBar::construct();
auto& app_menu = menubar->add_menu("System Monitor"); auto& app_menu = menubar->add_menu("System Monitor");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -291,7 +291,7 @@ int main(int argc, char** argv)
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
dbgprintf("Terminal: Quit menu activated!\n"); dbgprintf("Terminal: Quit menu activated!\n");
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
auto& edit_menu = menubar->add_menu("Edit"); auto& edit_menu = menubar->add_menu("Edit");

View file

@ -368,7 +368,7 @@ TextEditorWidget::TextEditorWidget()
app_menu.add_action(GUI::CommonActions::make_quit_action([this](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([this](auto&) {
if (!request_close()) if (!request_close())
return; return;
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
auto& edit_menu = menubar->add_menu("Edit"); auto& edit_menu = menubar->add_menu("Edit");
@ -455,7 +455,7 @@ TextEditorWidget::TextEditorWidget()
GUI::AboutDialog::show("Text Editor", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-texteditor.png"), window()); GUI::AboutDialog::show("Text Editor", Gfx::Bitmap::load_from_file("/res/icons/32x32/app-texteditor.png"), window());
})); }));
GUI::Application::the().set_menubar(move(menubar)); GUI::Application::the()->set_menubar(move(menubar));
toolbar.add_action(*m_new_action); toolbar.add_action(*m_new_action);
toolbar.add_action(*m_open_action); toolbar.add_action(*m_open_action);

View file

@ -144,11 +144,11 @@ bool prompt_to_stop_profiling()
auto& stop_button = widget.add<GUI::Button>("Stop"); auto& stop_button = widget.add<GUI::Button>("Stop");
stop_button.on_click = [&](auto) { stop_button.on_click = [&](auto) {
GUI::Application::the().quit(); GUI::Application::the()->quit();
}; };
window->show(); window->show();
return GUI::Application::the().exec() == 0; return GUI::Application::the()->exec() == 0;
} }
bool generate_profile(pid_t pid) bool generate_profile(pid_t pid)

View file

@ -59,7 +59,7 @@ int main(int argc, char** argv)
auto menubar = GUI::MenuBar::construct(); auto menubar = GUI::MenuBar::construct();
auto& app_menu = menubar->add_menu("Visual Builder"); auto& app_menu = menubar->add_menu("Visual Builder");
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -104,7 +104,7 @@ int main(int argc, char** argv)
app_menu.add_separator(); app_menu.add_separator();
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
return; return;
})); }));

View file

@ -65,7 +65,7 @@ int main(int argc, char** argv)
game.reset(); game.reset();
})); }));
app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) { app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
GUI::Application::the().quit(0); GUI::Application::the()->quit();
})); }));
auto& help_menu = menubar->add_menu("Help"); auto& help_menu = menubar->add_menu("Help");

View file

@ -157,14 +157,17 @@ Action::Action(const StringView& text, const Shortcut& shortcut, RefPtr<Gfx::Bit
m_scope = ShortcutScope::WindowLocal; m_scope = ShortcutScope::WindowLocal;
} else { } else {
m_scope = ShortcutScope::ApplicationGlobal; m_scope = ShortcutScope::ApplicationGlobal;
Application::the().register_global_shortcut_action({}, *this); if (auto* app = Application::the())
app->register_global_shortcut_action({}, *this);
} }
} }
Action::~Action() Action::~Action()
{ {
if (m_shortcut.is_valid() && m_scope == ShortcutScope::ApplicationGlobal) if (m_shortcut.is_valid() && m_scope == ShortcutScope::ApplicationGlobal) {
Application::the().unregister_global_shortcut_action({}, *this); if (auto* app = Application::the())
app->unregister_global_shortcut_action({}, *this);
}
} }
void Action::activate(Core::Object* activator) void Action::activate(Core::Object* activator)

View file

@ -39,18 +39,17 @@
namespace GUI { namespace GUI {
static Application* s_the; static WeakPtr<Application> s_the;
Application& Application::the() Application* Application::the()
{ {
ASSERT(s_the); return s_the;
return *s_the;
} }
Application::Application(int argc, char** argv) Application::Application(int argc, char** argv)
{ {
ASSERT(!s_the); ASSERT(!s_the);
s_the = this; s_the = make_weak_ptr();
m_event_loop = make<Core::EventLoop>(); m_event_loop = make<Core::EventLoop>();
WindowServerConnection::the(); WindowServerConnection::the();
Clipboard::initialize({}); Clipboard::initialize({});
@ -68,7 +67,7 @@ Application::Application(int argc, char** argv)
Application::~Application() Application::~Application()
{ {
s_the = nullptr; revoke_weak_ptrs();
} }
int Application::exec() int Application::exec()

View file

@ -40,7 +40,7 @@ class Application : public Core::Object {
C_OBJECT(Application); C_OBJECT(Application);
public: public:
static Application& the(); static Application* the();
~Application(); ~Application();

View file

@ -98,7 +98,7 @@ Widget::Widget()
, m_background_role(Gfx::ColorRole::Window) , m_background_role(Gfx::ColorRole::Window)
, m_foreground_role(Gfx::ColorRole::WindowText) , m_foreground_role(Gfx::ColorRole::WindowText)
, m_font(Gfx::Font::default_font()) , m_font(Gfx::Font::default_font())
, m_palette(Application::the().palette().impl()) , m_palette(Application::the()->palette().impl())
{ {
} }
@ -245,7 +245,7 @@ void Widget::handle_paint_event(PaintEvent& event)
painter.draw_rect(rect(), Color::Magenta); painter.draw_rect(rect(), Color::Magenta);
} }
if (Application::the().focus_debugging_enabled()) { if (Application::the()->focus_debugging_enabled()) {
if (is_focused()) { if (is_focused()) {
Painter painter(*this); Painter painter(*this);
painter.draw_rect(rect(), Color::Cyan); painter.draw_rect(rect(), Color::Cyan);
@ -318,13 +318,13 @@ void Widget::handle_mousedoubleclick_event(MouseEvent& event)
void Widget::handle_enter_event(Core::Event& event) void Widget::handle_enter_event(Core::Event& event)
{ {
if (has_tooltip()) if (has_tooltip())
Application::the().show_tooltip(m_tooltip, screen_relative_rect().center().translated(0, height() / 2)); Application::the()->show_tooltip(m_tooltip, screen_relative_rect().center().translated(0, height() / 2));
enter_event(event); enter_event(event);
} }
void Widget::handle_leave_event(Core::Event& event) void Widget::handle_leave_event(Core::Event& event)
{ {
Application::the().hide_tooltip(); Application::the()->hide_tooltip();
leave_event(event); leave_event(event);
} }

View file

@ -113,7 +113,7 @@ void Window::show()
apply_icon(); apply_icon();
reified_windows->set(m_window_id, this); reified_windows->set(m_window_id, this);
Application::the().did_create_window({}); Application::the()->did_create_window({});
update(); update();
} }
@ -158,7 +158,7 @@ void Window::hide()
} }
} }
if (!app_has_visible_windows) if (!app_has_visible_windows)
Application::the().did_delete_last_window({}); Application::the()->did_delete_last_window({});
} }
void Window::set_title(const StringView& title) void Window::set_title(const StringView& title)

View file

@ -61,7 +61,7 @@ static void set_system_theme_from_shbuf_id(int id)
auto system_theme = SharedBuffer::create_from_shbuf_id(id); auto system_theme = SharedBuffer::create_from_shbuf_id(id);
ASSERT(system_theme); ASSERT(system_theme);
Gfx::set_system_theme(*system_theme); Gfx::set_system_theme(*system_theme);
Application::the().set_system_palette(*system_theme); Application::the()->set_system_palette(*system_theme);
} }
void WindowServerConnection::handshake() void WindowServerConnection::handshake()
@ -154,7 +154,7 @@ void WindowServerConnection::handle(const Messages::WindowClient::KeyDown& messa
} }
if (!action) { if (!action) {
action = Application::the().action_for_key_event(*key_event); action = Application::the()->action_for_key_event(*key_event);
#ifdef KEYBOARD_SHORTCUTS_DEBUG #ifdef KEYBOARD_SHORTCUTS_DEBUG
dbg() << " > Asked application, got action: " << action; dbg() << " > Asked application, got action: " << action;
#endif #endif

View file

@ -70,7 +70,7 @@ void TerminalWidget::set_pty_master_fd(int fd)
if (nread < 0) { if (nread < 0) {
dbgprintf("Terminal read error: %s\n", strerror(errno)); dbgprintf("Terminal read error: %s\n", strerror(errno));
perror("read(ptm)"); perror("read(ptm)");
GUI::Application::the().quit(1); GUI::Application::the()->quit(1);
return; return;
} }
if (nread == 0) { if (nread == 0) {

View file

@ -221,12 +221,12 @@ void PageView::page_did_middle_click_link(const String& href, [[maybe_unused]] c
void PageView::page_did_enter_tooltip_area(const Gfx::IntPoint& content_position, const String& title) void PageView::page_did_enter_tooltip_area(const Gfx::IntPoint& content_position, const String& title)
{ {
GUI::Application::the().show_tooltip(title, screen_relative_rect().location().translated(to_widget_position(content_position))); GUI::Application::the()->show_tooltip(title, screen_relative_rect().location().translated(to_widget_position(content_position)));
} }
void PageView::page_did_leave_tooltip_area() void PageView::page_did_leave_tooltip_area()
{ {
GUI::Application::the().hide_tooltip(); GUI::Application::the()->hide_tooltip();
} }
void PageView::page_did_hover_link(const URL& url) void PageView::page_did_hover_link(const URL& url)