all repos — openbox @ 7fb107cd37a09787c5cfa590688944b3bcb2bab8

openbox fork - make it a bit more like ryudo

Merge branch 'backport' into work

Conflicts:

	openbox/actions/execute.c
	openbox/event.c
	openbox/openbox.c
	openbox/openbox.h
Dana Jansens danakj@orodu.net
commit

7fb107cd37a09787c5cfa590688944b3bcb2bab8

parent

ac255432b46617fe01fd40fd02fdea878893ce3c

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

@@ -96,11 +96,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); }

@@ -124,7 +128,8 @@ { _("Yes"), 1 }

}; ocp = dup_options(options); - p = prompt_new(o->prompt, answers, 2, 0, 0, prompt_cb, ocp); + p = prompt_new(o->prompt, _("Execute"), answers, 2, 0, 0, + prompt_cb, prompt_cleanup, ocp); prompt_show(p, NULL, FALSE); return FALSE;

@@ -204,7 +209,7 @@ event_cancel_all_key_grabs();

e = NULL; if (!g_shell_parse_argv(cmd, NULL, &argv, &e)) { - g_message(_("Failed to execute \"%s\": %s"), o->cmd, e->message); + g_message(e->message, o->cmd); g_error_free(e); } else {

@@ -226,8 +231,7 @@ G_SPAWN_SEARCH_PATH |

G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, NULL, &e); if (!ok) { - g_message(_("Failed to execute \"%s\": %s"), - o->cmd, e->message); + g_message(e->message, o->cmd); g_error_free(e); }
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,8 @@ { _("Exit"), 1 }

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

@@ -31,17 +31,22 @@

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) { -#ifndef USE_SM +#ifdef USE_SM session_request_logout(o->silent); #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,8 @@ };

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

@@ -3339,12 +3339,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;

@@ -3391,11 +3399,13 @@ /* set the dialog buttons' text */

answers[0].text = _("Cancel"); /* "no" */ answers[1].text = y; /* "yes" */ - self->kill_prompt = prompt_new(m, answers, + self->kill_prompt = prompt_new(m, NULL, 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/debug.copenbox/debug.c

@@ -135,7 +135,7 @@ static void prompt_handler(const gchar *log_domain, GLogLevelFlags log_level,

const gchar *message, gpointer data) { if (ob_state() == OB_STATE_RUNNING) - prompt_show_message(message, _("Close")); + prompt_show_message(message, _("Openbox"), _("Close")); } static inline void log_argv(ObDebugType type,
M openbox/event.copenbox/event.c

@@ -657,8 +657,10 @@ else if (e->type == MappingNotify) {

/* keyboard layout changes for modifier mapping changes. reload the modifier map, and rebind all the key bindings as appropriate */ ob_debug("Kepboard map changed. Reloading keyboard bindings."); + ob_set_state(OB_STATE_RECONFIGURING); obt_keyboard_reload(); keyboard_rebind(); + ob_set_state(OB_STATE_RUNNING); } else if (e->type == ClientMessage) { /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
M openbox/misc.hopenbox/misc.h

@@ -60,7 +60,8 @@ typedef enum

{ OB_STATE_STARTING, OB_STATE_RUNNING, - OB_STATE_EXITING + OB_STATE_EXITING, + OB_STATE_RECONFIGURING } ObState; typedef enum
M openbox/openbox.copenbox/openbox.c

@@ -118,7 +118,7 @@ gint main(gint argc, gchar **argv)

{ gchar *program_name; - state = OB_STATE_STARTING; + ob_set_state(OB_STATE_STARTING); ob_debug_startup();

@@ -212,6 +212,8 @@ XC_top_left_corner);

if (screen_annex()) { /* it will be ours! */ do { + ObPrompt *xmlprompt = NULL; + if (reconfigure) obt_keyboard_reload(); /* get the keycodes for keys we use */

@@ -308,7 +310,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);

@@ -316,6 +317,7 @@ keyboard_startup(reconfigure);

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

@@ -351,13 +353,35 @@ }

reconfigure = FALSE; - state = OB_STATE_RUNNING; + ob_set_state(OB_STATE_RUNNING); + + /* look for parsing errors */ + { + xmlErrorPtr e = xmlGetLastError(); + if (e) { + gchar *m; + + m = g_strdup_printf(_("One or more XML syntax errors were found while parsing the Openbox configuration files. See stdout for more information. The last error seen was in file \"%s\" line %d, with message: %s"), e->file, e->line, e->message); + xmlprompt = + prompt_show_message(m, _("Openbox Syntax Error"), _("Close")); + g_free(m); + xmlResetError(e); + } + } + obt_main_loop_run(ob_main_loop); - state = OB_STATE_EXITING; + ob_set_state(reconfigure ? + OB_STATE_RECONFIGURING : OB_STATE_EXITING); + + if (xmlprompt) { + prompt_unref(xmlprompt); + xmlprompt = NULL; + } if (!reconfigure) window_unmanage_all(); + prompt_shutdown(reconfigure); menu_shutdown(reconfigure); menu_frame_shutdown(reconfigure); mouse_shutdown(reconfigure);

@@ -365,7 +389,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);

@@ -695,3 +718,8 @@ ObState ob_state(void)

{ return state; } + +void ob_set_state(ObState s) +{ + state = s; +}
M openbox/openbox.hopenbox/openbox.h

@@ -49,6 +49,7 @@ extern gboolean ob_debug_xinerama;

/* The state of execution of the window manager */ ObState ob_state(void); +void ob_set_state(ObState state); void ob_restart_other(const gchar *path); void ob_restart(void);
M openbox/prompt.copenbox/prompt.c

@@ -28,7 +28,6 @@ #include "obt/prop.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);

@@ -132,10 +140,11 @@ RrAppearanceFree(prompt_a_pfocus);

RrAppearanceFree(prompt_a_msg); } -ObPrompt* prompt_new(const gchar *msg, +ObPrompt* prompt_new(const gchar *msg, const gchar *title, 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;

@@ -160,6 +170,10 @@

/* make it a dialog type window */ OBT_PROP_SET32(self->super.window, NET_WM_WINDOW_TYPE, ATOM, OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG)); + + /* set the window's title */ + if (title) + OBT_PROP_SETS(self->super.window, NET_WM_NAME, utf8, title); /* listen for key presses on the window */ self->event_mask = KeyPressMask;

@@ -523,8 +537,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) ||

@@ -582,10 +595,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;

@@ -603,24 +614,41 @@ }

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); } -void prompt_show_message(const gchar *msg, const gchar *answer) +ObPrompt* prompt_show_message(const gchar *msg, const gchar *title, + const gchar *answer) { ObPrompt *p; 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, title, ans, 1, 0, 0, + prompt_show_message_cb, prompt_show_message_cleanup, NULL); prompt_show(p, NULL, FALSE); + return p; +} + +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, +ObPrompt* prompt_new(const gchar *msg, const gchar *title, 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);

@@ -107,6 +116,7 @@ gboolean prompt_key_event(ObPrompt *self, XEvent *e);

gboolean prompt_mouse_event(ObPrompt *self, XEvent *e); void prompt_cancel(ObPrompt *self); -void prompt_show_message(const gchar *msg, const gchar *answer); +ObPrompt* prompt_show_message(const gchar *msg, const gchar *title, + const gchar *answer); #endif
M openbox/screen.copenbox/screen.c

@@ -481,7 +481,7 @@ screen_physical_size.height = geometry[1] = h;

OBT_PROP_SETA32(obt_root(ob_screen), NET_DESKTOP_GEOMETRY, CARDINAL, geometry, 2); - if (ob_state() == OB_STATE_STARTING) + if (ob_state() != OB_STATE_RUNNING) return; screen_update_areas();