diff --git a/src/app.cpp b/src/app.cpp index 45f02523e..f1ab41731 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -218,7 +218,7 @@ int App::run() // Create the list of tabs app_rebuild_documents_tabs(); - app_realloc_recent_list(); + app_rebuild_recent_list(); /* set current editor */ set_current_editor(editor); @@ -393,19 +393,12 @@ void app_update_document_tab(const Document* document) tabsbar->setTabText(str.c_str(), const_cast(document)); } -/** - * Updates the recent list menu. - * - * @warning This routine can't be used when a menu callback was - * called, because, it destroy the menus, you should use - * schedule_rebuild_recent_list() instead (src/modules/gui.c). - */ -bool app_realloc_recent_list() +bool app_rebuild_recent_list() { MenuItem* list_menuitem = get_recent_list_menuitem(); MenuItem* menuitem; - /* update the recent file list menu item */ + // Update the recent file list menu item if (list_menuitem) { if (list_menuitem->hasSubmenuOpened()) return false; @@ -415,7 +408,7 @@ bool app_realloc_recent_list() Menu* submenu = list_menuitem->getSubmenu(); if (submenu) { list_menuitem->setSubmenu(NULL); - jwidget_free(submenu); + submenu->deferDelete(); } // Build the menu of recent files diff --git a/src/app.h b/src/app.h index 2e0bc05ff..eae3ffbcf 100644 --- a/src/app.h +++ b/src/app.h @@ -92,7 +92,9 @@ void app_refresh_screen(const Document* document); void app_rebuild_documents_tabs(); void app_update_document_tab(const Document* document); -bool app_realloc_recent_list(); + +// Updates the list of recent files. +bool app_rebuild_recent_list(); int app_get_current_image_type(); diff --git a/src/gui/component.cpp b/src/gui/component.cpp index 561e608c4..b91a0b3cc 100644 --- a/src/gui/component.cpp +++ b/src/gui/component.cpp @@ -4,6 +4,8 @@ // This source file is ditributed under a BSD-like license, please // read LICENSE.txt for more information. +#include "config.h" + #include "base/shared_ptr.h" #include "gui/component.h" #include "gui/property.h" diff --git a/src/gui/manager.cpp b/src/gui/manager.cpp index 9da6ce2de..3e2ab2010 100644 --- a/src/gui/manager.cpp +++ b/src/gui/manager.cpp @@ -93,6 +93,7 @@ static std::vector timers; // Registered timers static JList new_windows; // Windows that we should show static WidgetsList mouse_widgets_list; // List of widgets to send mouse events +static WidgetsList garbage; static JList msg_queue; // Messages queue static JList msg_filters[NFILTERS]; // Filters for every enqueued message @@ -138,6 +139,16 @@ static void allegro_window_close_hook() want_close_stage = STAGE_WANT_CLOSE; } +static void collect_garbage() +{ + for (WidgetsList::iterator + it = garbage.begin(), + end = garbage.end(); it != end; ++it) { + delete *it; + } + garbage.clear(); +} + JWidget ji_get_default_manager() { return default_manager; @@ -204,6 +215,8 @@ void jmanager_free(JWidget widget) /* there are some messages in queue? */ jmanager_dispatch_messages(widget); + collect_garbage(); + /* finish with main manager */ if (default_manager == widget) { /* no more cursor */ @@ -243,8 +256,12 @@ void jmanager_free(JWidget widget) void jmanager_run(JWidget widget) { while (!jlist_empty(widget->children)) { - if (jmanager_generate_messages(widget)) + if (jmanager_generate_messages(widget)) { jmanager_dispatch_messages(widget); + } + else if (!garbage.empty()) { + collect_garbage(); + } } } @@ -571,6 +588,11 @@ void jmanager_dispatch_messages(JWidget manager) manager_pump_queue(manager); } +void jmanager_add_to_garbage(Widget* widget) +{ + garbage.push_back(widget); +} + /** * Adds a timer event for the specified widget. * @@ -1078,13 +1100,6 @@ static bool manager_msg_proc(JWidget widget, Message* msg) { switch (msg->type) { - case JM_DEFERREDFREE: - ASSERT_VALID_WIDGET(msg->deffree.widget_to_free); - ASSERT(msg->deffree.widget_to_free != widget); - - jwidget_free(msg->deffree.widget_to_free); - return true; - case JM_REQSIZE: manager_request_size(widget, &msg->reqsize.w, &msg->reqsize.h); return true; diff --git a/src/gui/manager.h b/src/gui/manager.h index de54a544c..157ac58f2 100644 --- a/src/gui/manager.h +++ b/src/gui/manager.h @@ -18,6 +18,8 @@ void jmanager_run(JWidget manager); bool jmanager_generate_messages(JWidget manager); void jmanager_dispatch_messages(JWidget manager); +void jmanager_add_to_garbage(Widget* widget); + /* timers */ int jmanager_add_timer(JWidget widget, int interval); diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index ad9249632..e675147fe 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -1220,7 +1220,7 @@ static bool window_msg_proc(Widget* widget, Message* msg) switch (msg->type) { case JM_CLOSE: - jwidget_free_deferred(widget); + widget->deferDelete(); break; } diff --git a/src/gui/message.h b/src/gui/message.h index e102406ae..aad17105e 100644 --- a/src/gui/message.h +++ b/src/gui/message.h @@ -28,12 +28,6 @@ struct MessageAny int shifts; /* key shifts pressed when message was created */ }; -struct MessageDefFree /* deferred jwidget_free call */ -{ - MessageAny any; - JWidget widget_to_free; -}; - struct MessageKey { MessageAny any; @@ -104,7 +98,6 @@ union Message { int type; MessageAny any; - MessageDefFree deffree; MessageKey key; MessageDraw draw; MessageMouse mouse; diff --git a/src/gui/widget.cpp b/src/gui/widget.cpp index 80d6dba80..bff86b920 100644 --- a/src/gui/widget.cpp +++ b/src/gui/widget.cpp @@ -34,7 +34,6 @@ static inline void mark_dirty_flag(Widget* widget) widget = widget->parent; } } - int ji_register_widget_type() { @@ -140,17 +139,9 @@ Widget::~Widget() _ji_remove_widget(this); } -void jwidget_free_deferred(JWidget widget) +void Widget::deferDelete() { - Message* msg; - - ASSERT_VALID_WIDGET(widget); - - msg = jmessage_new(JM_DEFERREDFREE); - msg->deffree.widget_to_free = widget; - /* TODO use the manager of 'widget' */ - jmessage_add_dest(msg, ji_get_default_manager()); - jmanager_enqueue_message(msg); + jmanager_add_to_garbage(this); } void Widget::initTheme() diff --git a/src/gui/widget.h b/src/gui/widget.h index abad9335a..4c98c0205 100644 --- a/src/gui/widget.h +++ b/src/gui/widget.h @@ -35,7 +35,6 @@ typedef std::vector WidgetsList; int ji_register_widget_type(); void jwidget_free(JWidget widget); -void jwidget_free_deferred(JWidget widget); /* hooks */ @@ -150,6 +149,10 @@ public: Widget(int type); virtual ~Widget(); + // Safe way to delete a widget when it is not in the manager message + // queue anymore. + void deferDelete(); + // main properties int getType(); diff --git a/src/modules/gui.cpp b/src/modules/gui.cpp index 139e94b9c..45ea25f9a 100644 --- a/src/modules/gui.cpp +++ b/src/modules/gui.cpp @@ -57,9 +57,8 @@ #include "widgets/toolbar.h" #include "xml_widgets.h" -#define REBUILD_RECENT_LIST 2 -#define REFRESH_FULL_SCREEN 4 -#define SYSTEM_WINDOW_RESIZE 8 +#define REFRESH_FULL_SCREEN 1 +#define SYSTEM_WINDOW_RESIZE 2 #define MONITOR_TIMER_MSECS 100 @@ -466,12 +465,6 @@ void gui_feedback() jmanager_refresh_screen(); } - // Menu stuff - if (next_idle_flags & REBUILD_RECENT_LIST) { - if (app_realloc_recent_list()) - next_idle_flags ^= REBUILD_RECENT_LIST; - } - if (next_idle_flags & REFRESH_FULL_SCREEN) { next_idle_flags ^= REFRESH_FULL_SCREEN; @@ -659,11 +652,6 @@ JWidget find_widget(JWidget widget, const char *name) return child; } -void schedule_rebuild_recent_list() -{ - next_idle_flags |= REBUILD_RECENT_LIST; -} - ////////////////////////////////////////////////////////////////////// // Hook signals diff --git a/src/modules/gui.h b/src/modules/gui.h index dfe7d2e2e..ac8a4bcc4 100644 --- a/src/modules/gui.h +++ b/src/modules/gui.h @@ -85,8 +85,6 @@ void save_window_pos(Widget* window, const char *section); Widget* load_widget(const char *filename, const char *name); Widget* find_widget(Widget* widget, const char *name); -void schedule_rebuild_recent_list(); - void hook_signal(Widget* widget, int signal_num, bool (*signal_handler)(Widget* widget, void *data), diff --git a/src/recent_files.cpp b/src/recent_files.cpp index 61077550a..a8caa0819 100644 --- a/src/recent_files.cpp +++ b/src/recent_files.cpp @@ -24,7 +24,6 @@ #include "app.h" #include "core/cfg.h" -#include "modules/gui.h" #include "recent_files.h" RecentFiles::RecentFiles() @@ -77,7 +76,8 @@ void RecentFiles::addRecentFile(const char* filename) // Move it to the first position m_files.erase(it); m_files.insert(m_files.begin(), filename); - schedule_rebuild_recent_list(); + + app_rebuild_recent_list(); return; } @@ -90,7 +90,7 @@ void RecentFiles::addRecentFile(const char* filename) } m_files.insert(m_files.begin(), filename); - schedule_rebuild_recent_list(); + app_rebuild_recent_list(); } void RecentFiles::removeRecentFile(const char* filename) @@ -99,7 +99,6 @@ void RecentFiles::removeRecentFile(const char* filename) if (it != m_files.end()) { m_files.erase(it); - - schedule_rebuild_recent_list(); + app_rebuild_recent_list(); } }