support reconfiguring throughout the entire codebase.
action_desktop_last,
NULL
},
+ {
+ "reconfigure",
+ action_reconfigure,
+ NULL
+ },
{
"restart",
action_restart,
data->moveresize.button, data->moveresize.corner);
}
+void action_reconfigure(union ActionData *data)
+{
+ ob_reconfigure();
+}
+
void action_restart(union ActionData *data)
{
ob_restart_other(data->execute.path);
void action_toggle_decorations(union ActionData *data);
/* MoveResize */
void action_moveresize(union ActionData *data);
+/* Any */
+void action_reconfigure(union ActionData *data);
/* Execute */
void action_restart(union ActionData *data);
/* Any */
static void client_restore_session_stacking(ObClient *self);
static void client_urgent_notify(ObClient *self);
-void client_startup()
+void client_startup(gboolean reconfig)
{
+ if (reconfig) return;
+
client_set_list();
}
-void client_shutdown()
+void client_shutdown(gboolean reconfig)
{
}
extern GList *client_list;
-void client_startup();
-void client_shutdown();
+void client_startup(gboolean reconfig);
+void client_shutdown(gboolean reconfig);
void client_add_destructor(GDestroyNotify func);
void client_remove_destructor(GDestroyNotify func);
StrutPartial dock_strut;
-void dock_startup()
+void dock_startup(gboolean reconfig)
{
XSetWindowAttributes attrib;
+ if (reconfig) {
+ dock_configure();
+ return;
+ }
+
STRUT_PARTIAL_SET(dock_strut, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0);
stacking_raise(DOCK_AS_WINDOW(dock));
}
-void dock_shutdown()
+void dock_shutdown(gboolean reconfig)
{
+ if (reconfig) return;
+
XDestroyWindow(ob_display, dock->frame);
RrAppearanceFree(dock->a_frame);
g_hash_table_remove(window_map, &dock->frame);
extern StrutPartial dock_strut;
-void dock_startup();
-void dock_shutdown();
+void dock_startup(gboolean reconfig);
+void dock_shutdown(gboolean reconfig);
void dock_configure();
void dock_hide(gboolean hide);
#endif
-void event_startup()
+void event_startup(gboolean reconfig)
{
+ if (reconfig) return;
+
mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]);
/* get lock masks that are defined by the display (not constant) */
client_add_destructor(focus_delay_client_dest);
}
-void event_shutdown()
+void event_shutdown(gboolean reconfig)
{
+ if (reconfig) return;
+
client_remove_destructor(focus_delay_client_dest);
XFreeModifiermap(modmap);
}
/*! The value of the mask for the ScrollLock modifier */
extern guint ScrollLockMask;
-void event_startup();
-void event_shutdown();
+void event_startup(gboolean reconfig);
+void event_shutdown(gboolean reconfig);
#endif
static ObClient *focus_cycle_target;
static Popup *focus_cycle_popup;
-void focus_startup()
+void focus_startup(gboolean reconfig)
{
-
focus_cycle_popup = popup_new(TRUE);
- /* start with nothing focused */
- focus_set_client(NULL);
+ if (!reconfig)
+ /* start with nothing focused */
+ focus_set_client(NULL);
}
-void focus_shutdown()
+void focus_shutdown(gboolean reconfig)
{
guint i;
- for (i = 0; i < screen_num_desktops; ++i)
- g_list_free(focus_order[i]);
- g_free(focus_order);
-
popup_free(focus_cycle_popup);
- /* reset focus to root */
- XSetInputFocus(ob_display, PointerRoot, RevertToPointerRoot,
- event_lasttime);
+ if (!reconfig) {
+ for (i = 0; i < screen_num_desktops; ++i)
+ g_list_free(focus_order[i]);
+ g_free(focus_order);
+
+ /* reset focus to root */
+ XSetInputFocus(ob_display, PointerRoot, RevertToPointerRoot,
+ event_lasttime);
+ }
}
static void push_to_top(ObClient *client)
/*! The recent focus order on each desktop */
extern GList **focus_order;
-void focus_startup();
-void focus_shutdown();
+void focus_startup(gboolean reconfig);
+void focus_shutdown(gboolean reconfig);
/*! Specify which client is currently focused, this doesn't actually
send focus anywhere, its called by the Focus event handlers */
static void flash_done(gpointer data);
static gboolean flash_timeout(gpointer data);
+static void set_theme_statics(ObFrame *self);
+static void free_theme_statics(ObFrame *self);
+
static Window createWindow(Window parent, unsigned long mask,
XSetWindowAttributes *attrib)
{
XMapWindow(ob_display, self->rgrip);
XMapWindow(ob_display, self->label);
+ self->max_press = self->close_press = self->desk_press =
+ self->iconify_press = self->shade_press = FALSE;
+ self->max_hover = self->close_hover = self->desk_hover =
+ self->iconify_hover = self->shade_hover = FALSE;
+
+ set_theme_statics(self);
+
+ return (ObFrame*)self;
+}
+
+static void set_theme_statics(ObFrame *self)
+{
/* set colors/appearance/sizes for stuff that doesn't change */
XSetWindowBorder(ob_display, self->window, ob_rr_theme->b_color->pixel);
XSetWindowBorder(ob_display, self->title, ob_rr_theme->b_color->pixel);
RrAppearanceCopy(ob_rr_theme->a_unfocused_handle);
self->a_focused_handle = RrAppearanceCopy(ob_rr_theme->a_focused_handle);
self->a_icon = RrAppearanceCopy(ob_rr_theme->a_icon);
-
- self->max_press = self->close_press = self->desk_press =
- self->iconify_press = self->shade_press = FALSE;
- self->max_hover = self->close_hover = self->desk_hover =
- self->iconify_hover = self->shade_hover = FALSE;
-
- return (ObFrame*)self;
}
-static void frame_free(ObFrame *self)
+static void free_theme_statics(ObFrame *self)
{
RrAppearanceFree(self->a_unfocused_title);
RrAppearanceFree(self->a_focused_title);
RrAppearanceFree(self->a_unfocused_handle);
RrAppearanceFree(self->a_focused_handle);
RrAppearanceFree(self->a_icon);
+}
+
+static void frame_free(ObFrame *self)
+{
+ free_theme_statics(self);
XDestroyWindow(ob_display, self->window);
}
}
+void frame_adjust_theme(ObFrame *self)
+{
+ free_theme_statics(self);
+ set_theme_statics(self);
+ frame_adjust_area(self, TRUE, TRUE, FALSE);
+}
+
void frame_adjust_shape(ObFrame *self)
{
#ifdef SHAPE
ObFrame *frame_new();
void frame_show(ObFrame *self);
void frame_hide(ObFrame *self);
+void frame_adjust_theme(ObFrame *self);
void frame_adjust_shape(ObFrame *self);
void frame_adjust_area(ObFrame *self, gboolean moved,
gboolean resized, gboolean fake);
#include <glib.h>
#include <X11/Xlib.h>
-void grab_startup();
-void grab_shutdown();
+void grab_startup(gboolean reconfig);
+void grab_shutdown(gboolean reconfig);
gboolean grab_keyboard(gboolean grab);
gboolean grab_pointer(gboolean grab, ObCursor cur);
static guint map_hash(Window *w) { return *w; }
static gboolean map_key_comp(Window *w1, Window *w2) { return *w1 == *w2; }
-void group_startup()
+void group_startup(gboolean reconfig)
{
+ if (reconfig) return;
+
group_map = g_hash_table_new((GHashFunc)map_hash,
(GEqualFunc)map_key_comp);
}
-void group_shutdown()
+void group_shutdown(gboolean reconfig)
{
+ if (reconfig) return;
+
g_hash_table_destroy(group_map);
}
extern GHashTable *group_map;
-void group_startup();
-void group_shutdown();
+void group_startup(gboolean reconfig);
+void group_shutdown(gboolean reconfig);
ObGroup *group_add(Window leader, struct _ObClient *client);
}
}
-void keyboard_startup()
+void keyboard_startup(gboolean reconfig)
{
grab_keys(TRUE);
}
-void keyboard_shutdown()
+void keyboard_shutdown(gboolean reconfig)
{
+ GSList *it;
+
tree_destroy(keyboard_firstnode);
keyboard_firstnode = NULL;
+
+ for (it = interactive_states; it; it = g_slist_next(it))
+ g_free(it->data);
+ g_slist_free(interactive_states);
+ interactive_states = NULL;
+
+ ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
grab_keys(FALSE);
+ curpos = NULL;
}
extern KeyBindingTree *keyboard_firstnode;
-void keyboard_startup();
-void keyboard_shutdown();
+void keyboard_startup(gboolean reconfig);
+void keyboard_shutdown(gboolean reconfig);
gboolean keyboard_bind(GList *keylist, ObAction *action);
menu_frame_hide_all_client(client);
}
-void menu_startup()
+void menu_startup(gboolean reconfig)
{
xmlDocPtr doc;
xmlNodePtr node;
g_assert(menu_parse_state.menus == NULL);
- client_add_destructor(client_dest);
+ if (!reconfig)
+ client_add_destructor(client_dest);
}
-void menu_shutdown()
+void menu_shutdown(gboolean reconfig)
{
- client_remove_destructor(client_dest);
+ if (!reconfig)
+ client_remove_destructor(client_dest);
parse_shutdown(menu_parse_inst);
menu_parse_inst = NULL;
} data;
};
-void menu_startup();
-void menu_shutdown();
+void menu_startup(gboolean reconfig);
+void menu_shutdown(gboolean reconfig);
ObMenu* menu_new(gchar *name, gchar *title, gpointer data);
void menu_free(ObMenu *menu);
g_free(b);
}
g_slist_free(bound_contexts[i]);
+ bound_contexts[i] = NULL;
}
}
return TRUE;
}
-void mouse_startup()
+void mouse_startup(gboolean reconfig)
{
}
-void mouse_shutdown()
+void mouse_shutdown(gboolean reconfig)
{
grab_all_clients(FALSE);
clearall();
OB_MOUSE_NUM_ACTIONS
} ObMouseAction;
-void mouse_startup();
-void mouse_shutdown();
+void mouse_startup(gboolean reconfig);
+void mouse_shutdown(gboolean reconfig);
gboolean mouse_bind(char *buttonstr, char *contextstr, ObMouseAction mact,
ObAction *action);
moveresize_end(TRUE);
}
-void moveresize_startup()
+void moveresize_startup(gboolean reconfig)
{
popup = popup_new(FALSE);
- client_add_destructor(client_dest);
+ if (!reconfig)
+ client_add_destructor(client_dest);
}
-void moveresize_shutdown()
+void moveresize_shutdown(gboolean reconfig)
{
- client_remove_destructor(client_dest);
+ if (!reconfig)
+ client_remove_destructor(client_dest);
popup_free(popup);
popup = NULL;
extern gboolean moveresize_in_progress;
extern struct _ObClient *moveresize_client;
-void moveresize_startup();
-void moveresize_shutdown();
+void moveresize_startup(gboolean reconfig);
+void moveresize_shutdown(gboolean reconfig);
void moveresize_start(struct _ObClient *c,
int x, int y, guint button, guint32 corner);
#include "keyboard.h"
#include "mouse.h"
#include "extensions.h"
+#include "menuframe.h"
#include "grab.h"
#include "group.h"
#include "config.h"
static ObState state;
static gboolean xsync;
+static gboolean reconfigure;
static gboolean restart;
static char *restart_path;
static Cursor cursors[OB_NUM_CURSORS];
int main(int argc, char **argv)
{
char *path;
- xmlDocPtr doc;
- xmlNodePtr node;
#ifdef DEBUG
ob_debug_show_output(TRUE);
/* set up signal handler */
ob_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL, NULL);
+ ob_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL, NULL);
ob_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL, NULL);
ob_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler, NULL, NULL);
ob_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler, NULL, NULL);
startup_save();
if (screen_annex()) { /* it will be ours! */
- ObParseInst *i;
-
- /* startup the parsing so everything can register sections of the rc */
- i = parse_startup();
-
- event_startup();
- grab_startup();
- /* focus_backup is used for stacking, so this needs to come before
- anything that calls stacking_add */
- focus_startup();
- window_startup();
-
- /* set up the kernel config shit */
- config_startup(i);
- /* parse/load user options */
- if (parse_load_rc(&doc, &node))
- parse_tree(i, doc, node->xmlChildrenNode);
- /* we're done with parsing now, kill it */
- xmlFreeDoc(doc);
- parse_shutdown(i);
-
- /* load the theme specified in the rc file */
- ob_rr_theme = RrThemeNew(ob_rr_inst, config_theme);
- if (ob_rr_theme == NULL)
- ob_exit_with_error("Unable to load a theme.");
-
- moveresize_startup();
- screen_startup();
- group_startup();
- client_startup();
- dock_startup();
- keyboard_startup();
- mouse_startup();
- menu_startup();
-
- /* get all the existing windows */
- client_manage_all();
-
- state = OB_STATE_RUNNING;
- ob_main_loop_run(ob_main_loop);
- state = OB_STATE_EXITING;
-
- dock_remove_all();
- client_unmanage_all();
-
- menu_shutdown();
- mouse_shutdown();
- keyboard_shutdown();
- dock_shutdown();
- client_shutdown();
- group_shutdown();
- screen_shutdown();
- focus_shutdown();
- moveresize_shutdown();
- window_shutdown();
- grab_shutdown();
- event_shutdown();
- config_shutdown();
+ do {
+ event_startup(reconfigure);
+ grab_startup(reconfigure);
+ /* focus_backup is used for stacking, so this needs to come before
+ anything that calls stacking_add */
+ focus_startup(reconfigure);
+ window_startup(reconfigure);
+
+ {
+ ObParseInst *i;
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ /* startup the parsing so everything can register sections
+ of the rc */
+ i = parse_startup();
+
+ config_startup(i);
+ /* parse/load user options */
+ if (parse_load_rc(&doc, &node))
+ parse_tree(i, doc, node->xmlChildrenNode);
+ /* we're done with parsing now, kill it */
+ xmlFreeDoc(doc);
+ parse_shutdown(i);
+ }
+
+ /* load the theme specified in the rc file */
+ ob_rr_theme = RrThemeNew(ob_rr_inst, config_theme);
+ if (ob_rr_theme == NULL)
+ ob_exit_with_error("Unable to load a theme.");
+
+ moveresize_startup(reconfigure);
+ screen_startup(reconfigure);
+ group_startup(reconfigure);
+ client_startup(reconfigure);
+ dock_startup(reconfigure);
+ keyboard_startup(reconfigure);
+ mouse_startup(reconfigure);
+ menu_startup(reconfigure);
+
+ if (!reconfigure) {
+ /* get all the existing windows */
+ client_manage_all();
+ } else {
+ GList *it;
+
+ /* redecorate all existing windows */
+ for (it = client_list; it; it = g_list_next(it)) {
+ ObClient *c = it->data;
+ frame_adjust_theme(c->frame);
+ }
+ }
+
+ reconfigure = FALSE;
+
+ state = OB_STATE_RUNNING;
+ ob_main_loop_run(ob_main_loop);
+ state = OB_STATE_EXITING;
+
+ if (!reconfigure) {
+ dock_remove_all();
+ client_unmanage_all();
+ }
+
+ menu_shutdown(reconfigure);
+ mouse_shutdown(reconfigure);
+ keyboard_shutdown(reconfigure);
+ dock_shutdown(reconfigure);
+ client_shutdown(reconfigure);
+ group_shutdown(reconfigure);
+ screen_shutdown(reconfigure);
+ focus_shutdown(reconfigure);
+ moveresize_shutdown(reconfigure);
+ window_shutdown(reconfigure);
+ grab_shutdown(reconfigure);
+ event_shutdown(reconfigure);
+ config_shutdown();
+ } while (reconfigure);
}
RrThemeFree(ob_rr_theme);
if (signal == SIGUSR1) {
fprintf(stderr, "Caught signal %d. Restarting.\n", signal);
ob_restart();
+ } else if (signal == SIGUSR2) {
+ fprintf(stderr, "Caught signal %d. Reconfiguring.\n", signal);
+ ob_reconfigure();
} else {
fprintf(stderr, "Caught signal %d. Exiting.\n", signal);
ob_exit();
g_strfreev(spl);
return ret;
}
+
+void ob_reconfigure()
+{
+ reconfigure = TRUE;
+ ob_exit();
+}
void ob_restart();
void ob_exit();
+void ob_reconfigure();
+
void ob_exit_with_error(gchar *msg);
Cursor ob_cursor(ObCursor cursor);
return TRUE;
}
-void screen_startup()
+void screen_startup(gboolean reconfig)
{
GSList *it;
guint i;
desktop_cycle_popup = popup_new(FALSE);
- /* get the initial size */
- screen_resize();
+ if (!reconfig)
+ /* get the initial size */
+ screen_resize();
/* set the names */
screen_desktop_names = g_new(char*,
g_free(screen_desktop_names); /* dont free the individual strings */
screen_desktop_names = NULL;
- screen_num_desktops = 0;
+ if (!reconfig)
+ screen_num_desktops = 0;
screen_set_num_desktops(config_desktops_num);
- if (startup_desktop >= screen_num_desktops)
- startup_desktop = 0;
- screen_desktop = startup_desktop;
- screen_set_desktop(startup_desktop);
+ if (!reconfig) {
+ if (startup_desktop >= screen_num_desktops)
+ startup_desktop = 0;
+ screen_desktop = startup_desktop;
+ screen_set_desktop(startup_desktop);
- /* don't start in showing-desktop mode */
- screen_showing_desktop = FALSE;
- PROP_SET32(RootWindow(ob_display, ob_screen),
- net_showing_desktop, cardinal, screen_showing_desktop);
+ /* don't start in showing-desktop mode */
+ screen_showing_desktop = FALSE;
+ PROP_SET32(RootWindow(ob_display, ob_screen),
+ net_showing_desktop, cardinal, screen_showing_desktop);
- screen_update_layout();
+ screen_update_layout();
#ifdef USE_LIBSN
- sn_context = sn_monitor_context_new(ob_sn_display, ob_screen,
- sn_event_func, NULL, NULL);
- sn_busy_cnt = 0;
+ sn_context = sn_monitor_context_new(ob_sn_display, ob_screen,
+ sn_event_func, NULL, NULL);
+ sn_busy_cnt = 0;
#endif
+ }
}
-void screen_shutdown()
+void screen_shutdown(gboolean reconfig)
{
Rect **r;
popup_free(desktop_cycle_popup);
- XSelectInput(ob_display, RootWindow(ob_display, ob_screen), NoEventMask);
+ if (!reconfig) {
+#ifdef USE_LIBSN
+ sn_monitor_context_unref(sn_context);
+#endif
+
+ XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
+ NoEventMask);
- /* we're not running here no more! */
- PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid);
- /* not without us */
- PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported);
- /* don't keep this mode */
- PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop);
+ /* we're not running here no more! */
+ PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid);
+ /* not without us */
+ PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported);
+ /* don't keep this mode */
+ PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop);
- XDestroyWindow(ob_display, screen_support_win);
+ XDestroyWindow(ob_display, screen_support_win);
+ }
g_strfreev(screen_desktop_names);
+ screen_desktop_names = NULL;
for (r = area; *r; ++r)
g_free(*r);
g_free(area);
+ area = NULL;
}
void screen_resize()
gboolean screen_annex();
/*! Once the screen is ours, set up its initial state */
-void screen_startup();
+void screen_startup(gboolean reconfig);
/*! Free resources */
-void screen_shutdown();
+void screen_shutdown(gboolean reconfig);
/*! Figure out the new size of the screen and adjust stuff for it */
void screen_resize();
GHashTable *window_map;
-void window_startup()
+void window_startup(gboolean reconfig)
{
+ if (reconfig) return;
+
window_map = g_hash_table_new(g_int_hash, g_int_equal);
}
-void window_shutdown()
+void window_shutdown(gboolean reconfig)
{
+ if (reconfig) return;
+
g_hash_table_destroy(window_map);
}
extern GHashTable *window_map;
-void window_startup();
-void window_shutdown();
+void window_startup(gboolean reconfig);
+void window_shutdown(gboolean reconfig);
Window window_top(ObWindow *self);
Window window_layer(ObWindow *self);