all repos — openbox @ bb557f06a6828a95ee94c7579919dec1ee014484

openbox fork - make it a bit more like ryudo

add a cleanup callback to the prompt interface.  when the prompt's callback returns TRUE, then the cleanup function is called. likewise when the prompt system is shutdown (openbox is exiting), then the cleanup function is also called.  it should unref/destroy the prompt and any memory associated with it
Dana Jansens danakj@orodu.net
commit

bb557f06a6828a95ee94c7579919dec1ee014484

parent

527ecafab95e66a6f0cedd6967fe2c61dfe85101

M openbox/actions/execute.copenbox/actions/execute.c

@@ -98,11 +98,15 @@ }

static gboolean run_func(ObActionsData *data, gpointer options); -static void prompt_cb(ObPrompt *p, gint result, gpointer options) +static gboolean prompt_cb(ObPrompt *p, gint result, gpointer options) { if (result) run_func(NULL, options); + return TRUE; /* call the cleanup func */ +} +static void prompt_cleanup(ObPrompt *p, gpointer options) +{ prompt_unref(p); free_func(options); }

@@ -126,7 +130,8 @@ { _("Yes"), 1 }

}; ocp = dup_options(options); - p = prompt_new(o->prompt, answers, 2, 0, 0, prompt_cb, ocp); + p = prompt_new(o->prompt, answers, 2, 0, 0, + prompt_cb, prompt_cleanup, ocp); prompt_show(p, NULL, FALSE); return FALSE;
M openbox/actions/exit.copenbox/actions/exit.c

@@ -29,10 +29,15 @@

return o; } -static void prompt_cb(ObPrompt *p, gint result, gpointer data) +static gboolean prompt_cb(ObPrompt *p, gint result, gpointer data) { if (result) ob_exit(0); + return TRUE; /* call the cleanup func */ +} + +static void prompt_cleanup(ObPrompt *p, gpointer data) +{ prompt_unref(p); }

@@ -49,7 +54,7 @@ { _("Exit"), 1 }

}; p = prompt_new(_("Are you sure you want to exit Openbox?"), - answers, 2, 0, 0, prompt_cb, NULL); + answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL); prompt_show(p, NULL, FALSE); } else
M openbox/actions/session.copenbox/actions/session.c

@@ -31,7 +31,7 @@

return o; } -static void prompt_cb(ObPrompt *p, gint result, gpointer data) +static gboolean prompt_cb(ObPrompt *p, gint result, gpointer data) { Options *o = data; if (result) {

@@ -41,7 +41,12 @@ #else

g_message(_("The SessionLogout actions is not available since Openbox was built without session management support")); #endif } - g_free(o); + return TRUE; /* call cleanup func */ +} + +static void prompt_cleanup(ObPrompt *p, gpointer data) +{ + g_free(data); prompt_unref(p); }

@@ -60,7 +65,7 @@ };

o2 = g_memdup(o, sizeof(Options)); p = prompt_new(_("Are you sure you want to log out?"), - answers, 2, 0, 0, prompt_cb, o2); + answers, 2, 0, 0, prompt_cb, prompt_cleanup, o2); prompt_show(p, NULL, FALSE); } else
M openbox/client.copenbox/client.c

@@ -3400,12 +3400,20 @@

#define OB_KILL_RESULT_NO 0 #define OB_KILL_RESULT_YES 1 -static void client_kill_requested(ObPrompt *p, gint result, gpointer data) +static gboolean client_kill_requested(ObPrompt *p, gint result, gpointer data) { ObClient *self = data; if (result == OB_KILL_RESULT_YES) client_kill(self); + return TRUE; /* call the cleanup func */ +} + +static void client_kill_cleanup(ObPrompt *p, gpointer data) +{ + ObClient *self = data; + + g_assert(p == self->kill_prompt); prompt_unref(self->kill_prompt); self->kill_prompt = NULL;

@@ -3456,7 +3464,9 @@ self->kill_prompt = prompt_new(m, answers,

sizeof(answers)/sizeof(answers[0]), OB_KILL_RESULT_NO, /* default = no */ OB_KILL_RESULT_NO, /* cancel = no */ - client_kill_requested, self); + client_kill_requested, + client_kill_cleanup, + self); g_free(m); }
M openbox/openbox.copenbox/openbox.c

@@ -323,7 +323,6 @@ screen_startup(reconfigure);

grab_startup(reconfigure); group_startup(reconfigure); ping_startup(reconfigure); - prompt_startup(reconfigure); client_startup(reconfigure); dock_startup(reconfigure); moveresize_startup(reconfigure);

@@ -331,6 +330,7 @@ keyboard_startup(reconfigure);

mouse_startup(reconfigure); menu_frame_startup(reconfigure); menu_startup(reconfigure); + prompt_startup(reconfigure); if (!reconfigure) { guint32 xid;

@@ -377,6 +377,7 @@ dock_remove_all();

client_unmanage_all(); } + prompt_shutdown(reconfigure); menu_shutdown(reconfigure); menu_frame_shutdown(reconfigure); mouse_shutdown(reconfigure);

@@ -384,7 +385,6 @@ keyboard_shutdown(reconfigure);

moveresize_shutdown(reconfigure); dock_shutdown(reconfigure); client_shutdown(reconfigure); - prompt_shutdown(reconfigure); ping_shutdown(reconfigure); group_shutdown(reconfigure); grab_shutdown(reconfigure);
M openbox/prompt.copenbox/prompt.c

@@ -28,7 +28,6 @@ #include "event.h"

#include "gettext.h" static GList *prompt_list = NULL; -static GList *prompt_msg_list = NULL; /* we construct these */ static RrAppearance *prompt_a_bg;

@@ -51,6 +50,7 @@ static void prompt_layout(ObPrompt *self);

static void render_all(ObPrompt *self); static void render_button(ObPrompt *self, ObPromptElement *e); static void prompt_resize(ObPrompt *self, gint w, gint h); +static void prompt_run_callback(ObPrompt *self, gint result); void prompt_startup(gboolean reconfig) {

@@ -122,8 +122,16 @@ }

void prompt_shutdown(gboolean reconfig) { - while (prompt_msg_list) - prompt_cancel(prompt_msg_list->data); + GList *it; + + if (!reconfig) { + for (it = prompt_list; it; it = g_list_next(it)) { + ObPrompt *p = it->data; + if (p->cleanup) p->cleanup(p, p->data); + } + + g_assert(prompt_list == NULL); + } RrAppearanceFree(prompt_a_button); RrAppearanceFree(prompt_a_focus);

@@ -135,7 +143,8 @@

ObPrompt* prompt_new(const gchar *msg, const ObPromptAnswer *answers, gint n_answers, gint default_result, gint cancel_result, - ObPromptCallback func, gpointer data) + ObPromptCallback func, ObPromptCleanup cleanup, + gpointer data) { ObPrompt *self; XSetWindowAttributes attrib;

@@ -146,6 +155,7 @@

self = g_new0(ObPrompt, 1); self->ref = 1; self->func = func; + self->cleanup = cleanup; self->data = data; self->default_result = default_result; self->cancel_result = cancel_result;

@@ -524,8 +534,7 @@ prompt_cancel(self);

else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) || e->xkey.keycode == ob_keycode(OB_KEY_SPACE)) { - if (self->func) self->func(self, self->focus->result, self->data); - prompt_hide(self); + prompt_run_callback(self, self->focus->result); } else if (e->xkey.keycode == ob_keycode(OB_KEY_TAB) || e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||

@@ -583,10 +592,8 @@ if (oldfocus != but) render_button(self, oldfocus);

render_button(self, but); } else if (e->type == ButtonRelease) { - if (but->pressed) { - if (self->func) self->func(self, but->result, self->data); - prompt_hide(self); - } + if (but->pressed) + prompt_run_callback(self, but->result); } else if (e->type == MotionNotify) { gboolean press;

@@ -604,13 +611,16 @@ }

void prompt_cancel(ObPrompt *self) { - if (self->func) self->func(self, self->cancel_result, self->data); - prompt_hide(self); + prompt_run_callback(self, self->cancel_result); +} + +static gboolean prompt_show_message_cb(ObPrompt *p, int res, gpointer data) +{ + return TRUE; /* call the cleanup func */ } -static void prompt_show_message_cb(ObPrompt *p, int res, gpointer data) +static void prompt_show_message_cleanup(ObPrompt *p, gpointer data) { - prompt_msg_list = g_list_remove(prompt_msg_list, p); prompt_unref(p); }

@@ -621,7 +631,19 @@ ObPromptAnswer ans[] = {

{ answer, 0 } }; - p = prompt_new(msg, ans, 1, 0, 0, prompt_show_message_cb, NULL); - prompt_msg_list = g_list_prepend(prompt_msg_list, p); + p = prompt_new(msg, ans, 1, 0, 0, + prompt_show_message_cb, prompt_show_message_cleanup, NULL); prompt_show(p, NULL, FALSE); } + +static void prompt_run_callback(ObPrompt *self, gint result) +{ + prompt_ref(self); + if (self->func) { + gboolean clean = self->func(self, self->focus->result, self->data); + if (clean && self->cleanup) + self->cleanup(self, self->data); + } + prompt_hide(self); + prompt_unref(self); +}
M openbox/prompt.hopenbox/prompt.h

@@ -29,7 +29,8 @@ typedef struct _ObPrompt ObPrompt;

typedef struct _ObPromptElement ObPromptElement; typedef struct _ObPromptAnswer ObPromptAnswer; -typedef void (*ObPromptCallback)(ObPrompt *p, gint result, gpointer data); +typedef gboolean (*ObPromptCallback)(ObPrompt *p, gint result, gpointer data); +typedef void (*ObPromptCleanup)(ObPrompt *p, gpointer data); struct _ObPromptElement { gchar *text;

@@ -69,6 +70,7 @@ /* the cancel result if the dialog is closed */

gint cancel_result; ObPromptCallback func; + ObPromptCleanup cleanup; gpointer data; };

@@ -90,12 +92,19 @@ @param cancel_result The result that is given if the dialog is closed instead

of having a button presssed @param func The callback function which is called when the dialog is closed or a button is pressed + @param cleanup The cleanup function which is called if the prompt system + is shutting down, and someone is still holding a reference to the + prompt. This callback should cause the prompt's refcount to go to + zero so it can be freed, and free any other memory associated with + the prompt. The cleanup function is also called if the prompt's + callback function returns TRUE. @param data User defined data which will be passed to the callback */ ObPrompt* prompt_new(const gchar *msg, const ObPromptAnswer *answers, gint n_answers, gint default_result, gint cancel_result, - ObPromptCallback func, gpointer data); + ObPromptCallback func, ObPromptCleanup cleanup, + gpointer data); void prompt_ref(ObPrompt *self); void prompt_unref(ObPrompt *self);