Fix problem regenerating the recent file menu.

+ Added Widget::deferDelete().
+ Removed schedule_rebuild_recent_list().
+ Renamed app_realloc_recent_list() to app_rebuild_recent_list().
+ Removed JM_DEFERREDFREE message, MessageDefFree struct, and
  jwidget_free_deferred() function.
This commit is contained in:
David Capello 2011-06-25 19:10:31 -03:00
parent 7471229840
commit 12de365e6f
12 changed files with 47 additions and 61 deletions

View File

@ -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*>(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

View File

@ -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();

View File

@ -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"

View File

@ -93,6 +93,7 @@ static std::vector<Timer*> 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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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()

View File

@ -35,7 +35,6 @@ typedef std::vector<Widget*> 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();

View File

@ -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

View File

@ -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),

View File

@ -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();
}
}