diff --git a/Libraries/LibGUI/GApplication.cpp b/Libraries/LibGUI/GApplication.cpp index 072021eb4a..d61a68b54d 100644 --- a/Libraries/LibGUI/GApplication.cpp +++ b/Libraries/LibGUI/GApplication.cpp @@ -111,3 +111,9 @@ void GApplication::hide_tooltip() if (m_tooltip_window) m_tooltip_window->hide(); } + +void GApplication::did_delete_last_window(Badge) +{ + if (m_quit_when_last_window_deleted) + m_event_loop->quit(0); +} diff --git a/Libraries/LibGUI/GApplication.h b/Libraries/LibGUI/GApplication.h index e68ad1f690..4b571cc6da 100644 --- a/Libraries/LibGUI/GApplication.h +++ b/Libraries/LibGUI/GApplication.h @@ -6,9 +6,10 @@ #include class GAction; -class GKeyEvent; class GEventLoop; +class GKeyEvent; class GMenuBar; +class GWindow; class Point; class GApplication { @@ -29,10 +30,16 @@ public: void show_tooltip(const StringView&, const Point& screen_location); void hide_tooltip(); + bool quit_when_last_window_deleted() const { return m_quit_when_last_window_deleted; } + void set_quit_when_last_window_deleted(bool b) { m_quit_when_last_window_deleted = b; } + + void did_delete_last_window(Badge); + private: OwnPtr m_event_loop; OwnPtr m_menubar; HashMap m_global_shortcut_actions; class TooltipWindow; TooltipWindow* m_tooltip_window { nullptr }; + bool m_quit_when_last_window_deleted { true }; }; diff --git a/Libraries/LibGUI/GWindow.cpp b/Libraries/LibGUI/GWindow.cpp index 1e20137269..eeff1bcb75 100644 --- a/Libraries/LibGUI/GWindow.cpp +++ b/Libraries/LibGUI/GWindow.cpp @@ -1,30 +1,25 @@ -#include "GWindow.h" -#include "GEvent.h" -#include "GEventLoop.h" -#include "GWidget.h" #include #include #include #include #include -#include #include +#include +#include +#include +#include +#include +#include //#define UPDATE_COALESCING_DEBUG -static HashMap* s_windows; - -static HashMap& windows() -{ - if (!s_windows) - s_windows = new HashMap; - return *s_windows; -} +static HashTable all_windows; +static HashMap reified_windows; GWindow* GWindow::from_window_id(int window_id) { - auto it = windows().find(window_id); - if (it != windows().end()) + auto it = reified_windows.find(window_id); + if (it != reified_windows.end()) return (*it).value; return nullptr; } @@ -32,15 +27,21 @@ GWindow* GWindow::from_window_id(int window_id) GWindow::GWindow(CObject* parent) : CObject(parent) { + all_windows.set(this); m_rect_when_windowless = { 100, 400, 140, 140 }; m_title_when_windowless = "GWindow"; } GWindow::~GWindow() { + all_windows.remove(this); if (m_main_widget) delete m_main_widget; hide(); + + if (all_windows.is_empty()) { + GApplication::the().did_delete_last_window({}); + } } void GWindow::close() @@ -87,7 +88,7 @@ void GWindow::show() auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateWindow); m_window_id = response.window_id; - windows().set(m_window_id, this); + reified_windows.set(m_window_id, this); update(); } @@ -95,7 +96,7 @@ void GWindow::hide() { if (!m_window_id) return; - windows().remove(m_window_id); + reified_windows.remove(m_window_id); WSAPI_ClientMessage request; request.type = WSAPI_ClientMessage::Type::DestroyWindow; request.window_id = m_window_id;