diff --git a/.cvsignore b/.cvsignore index 1783f83..603495c 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,3 +1,2 @@ setlayout.c -openbox-3.4.9.tar.gz openbox-3.4.10.tar.gz diff --git a/openbox-3.4.10-focuscycle.patch b/openbox-3.4.10-focuscycle.patch new file mode 100644 index 0000000..235e572 --- /dev/null +++ b/openbox-3.4.10-focuscycle.patch @@ -0,0 +1,1335 @@ +commit d3a01a40f35cb3ae6c5ad8329291e86e2e599691 +Author: Dana Jansens +Date: Mon Jan 11 11:02:48 2010 -0500 + + If a window is added to the focus order while focus cycling, stop the focus cycling istead of crashing (See bug #4411) + +diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c +index c92b5a5..5849d7d 100644 +--- a/openbox/focus_cycle.c ++++ b/openbox/focus_cycle.c +@@ -55,10 +55,18 @@ void focus_cycle_stop(ObClient *ifclient) + { + /* stop focus cycling if the given client is a valid focus target, + and so the cycling is being disrupted */ +- if (focus_cycle_target && +- ((ifclient && (ifclient == focus_cycle_target || +- focus_cycle_popup_is_showing(ifclient))) || +- !ifclient)) ++ if (focus_cycle_target && ifclient && ++ /* shortcut check, it is what we are pointing at right now */ ++ (ifclient == focus_cycle_target || ++ /* it's shown but it shouldn't be anymore */ ++ focus_cycle_popup_is_showing(ifclient) || ++ /* it's not shown but it should be */ ++ focus_valid_target(ifclient, TRUE, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows, ++ FALSE))) + { + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE); + focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); +commit 12653a4153bccd5d9a46998753e7a1bc17479505 +Author: Dana Jansens +Date: Mon Jan 11 12:47:59 2010 -0500 + + Redraw the focus cycle popup when the list of focusable windows changes, rather than closing it + +diff --git a/openbox/client.c b/openbox/client.c +index e3a7d6e..ae87ff0 100644 +--- a/openbox/client.c ++++ b/openbox/client.c +@@ -304,6 +304,7 @@ void client_manage(Window window, ObPrompt *prompt) + self->obwin.type = Window_Client; + self->window = window; + self->prompt = prompt; ++ self->managed = TRUE; + + /* non-zero defaults */ + self->wmstate = WithdrawnState; /* make sure it gets updated first time */ +@@ -633,6 +634,8 @@ void client_unmanage(ObClient *self) + + mouse_grab_for_client(self, FALSE); + ++ self->managed = FALSE; ++ + /* remove the window from our save set, unless we are managing an internal + ObPrompt window */ + if (!self->prompt) +diff --git a/openbox/client.h b/openbox/client.h +index 3b1e042..e5a61d5 100644 +--- a/openbox/client.h ++++ b/openbox/client.h +@@ -73,6 +73,7 @@ struct _ObClient + { + ObWindow obwin; + Window window; ++ gboolean managed; + + /*! If this client is managing an ObPrompt window, then this is set to the + prompt */ +diff --git a/openbox/focus.c b/openbox/focus.c +index a0e9c66..c82c4f6 100644 +--- a/openbox/focus.c ++++ b/openbox/focus.c +@@ -98,6 +98,9 @@ void focus_set_client(ObClient *client) + PROP_SET32(RootWindow(ob_display, ob_screen), + net_active_window, window, active); + } ++ ++ /* make sure the focus cycle popup shows things in the right order */ ++ focus_cycle_reorder(); + } + + static ObClient* focus_fallback_target(gboolean allow_refocus, +@@ -206,16 +209,14 @@ void focus_order_add_new(ObClient *c) + focus_order = g_list_insert(focus_order, c, 1); + } + +- /* in the middle of cycling..? kill it. */ +- focus_cycle_stop(c); ++ focus_cycle_add(c); + } + + void focus_order_remove(ObClient *c) + { + focus_order = g_list_remove(focus_order, c); + +- /* in the middle of cycling..? kill it. */ +- focus_cycle_stop(c); ++ focus_cycle_remove(c); + } + + void focus_order_to_top(ObClient *c) +@@ -293,6 +294,9 @@ gboolean focus_valid_target(ObClient *ft, + { + gboolean ok = FALSE; + ++ /* see if the window is still managed or is going away */ ++ if (!ft->managed) return FALSE; ++ + /* it's on this desktop unless you want all desktops. + + do this check first because it will usually filter out the most +diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c +index 5849d7d..07cc2e8 100644 +--- a/openbox/focus_cycle.c ++++ b/openbox/focus_cycle.c +@@ -31,6 +31,7 @@ + #include + + ObClient *focus_cycle_target = NULL; ++static gboolean focus_cycle_directional = FALSE; + static gboolean focus_cycle_iconic_windows; + static gboolean focus_cycle_all_desktops; + static gboolean focus_cycle_dock_windows; +@@ -51,26 +52,64 @@ void focus_cycle_shutdown(gboolean reconfig) + if (reconfig) return; + } + +-void focus_cycle_stop(ObClient *ifclient) ++void focus_cycle_add(ObClient *ifclient) + { +- /* stop focus cycling if the given client is a valid focus target, +- and so the cycling is being disrupted */ +- if (focus_cycle_target && ifclient && +- /* shortcut check, it is what we are pointing at right now */ +- (ifclient == focus_cycle_target || +- /* it's shown but it shouldn't be anymore */ +- focus_cycle_popup_is_showing(ifclient) || +- /* it's not shown but it should be */ +- focus_valid_target(ifclient, TRUE, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows, +- FALSE))) +- { +- focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE); +- focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); ++ if (!(focus_cycle_target && ifclient && !focus_cycle_directional)) ++ return; ++ ++ if (focus_valid_target(ifclient, TRUE, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows, ++ FALSE)) ++ focus_cycle_popup_refresh(focus_cycle_target, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows); ++} ++ ++void focus_cycle_remove(ObClient *ifclient) ++{ ++ if (!(focus_cycle_target && ifclient)) ++ return; ++ ++ if (focus_cycle_directional) { ++ if (focus_cycle_target == ifclient) { ++ focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, ++ TRUE, TRUE, TRUE); ++ } + } ++ else { ++ if (!focus_valid_target(ifclient, TRUE, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows, ++ FALSE)) { ++ if (focus_cycle_target == ifclient) { ++ focus_cycle_target = ++ focus_cycle_popup_revert(focus_cycle_target); ++ focus_cycle_update_indicator(focus_cycle_target); ++ } ++ focus_cycle_popup_refresh(focus_cycle_target, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows); ++ } ++ } ++} ++ ++void focus_cycle_reorder() ++{ ++ if (focus_cycle_target && !focus_cycle_directional) ++ focus_cycle_popup_refresh(focus_cycle_target, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows); + } + + ObClient* focus_cycle(gboolean forward, gboolean all_desktops, +@@ -87,6 +126,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + if (interactive) { + if (cancel) { + focus_cycle_target = NULL; ++ focus_cycle_directional = FALSE; + goto done_cycle; + } else if (done) + goto done_cycle; +@@ -134,6 +174,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + if (interactive) { + if (ft != focus_cycle_target) { /* prevents flicker */ + focus_cycle_target = ft; ++ focus_cycle_directional = FALSE; + focus_cycle_draw_indicator(showbar ? ft : NULL); + } + if (dialog) +@@ -146,6 +187,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + return focus_cycle_target; + } else if (ft != focus_cycle_target) { + focus_cycle_target = ft; ++ focus_cycle_directional = FALSE; + done = TRUE; + break; + } +@@ -156,6 +198,7 @@ done_cycle: + if (done && !cancel) ret = focus_cycle_target; + + focus_cycle_target = NULL; ++ focus_cycle_directional = FALSE; + g_list_free(order); + order = NULL; + +@@ -275,6 +318,7 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, + + if (cancel) { + focus_cycle_target = NULL; ++ focus_cycle_directional = FALSE; + goto done_cycle; + } else if (done && interactive) + goto done_cycle; +@@ -310,6 +354,7 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, + + if (ft && ft != focus_cycle_target) {/* prevents flicker */ + focus_cycle_target = ft; ++ focus_cycle_directional = TRUE; + if (!interactive) + goto done_cycle; + focus_cycle_draw_indicator(showbar ? ft : NULL); +@@ -328,6 +373,7 @@ done_cycle: + + first = NULL; + focus_cycle_target = NULL; ++ focus_cycle_directional = FALSE; + + focus_cycle_draw_indicator(NULL); + focus_cycle_popup_single_hide(); +diff --git a/openbox/focus_cycle.h b/openbox/focus_cycle.h +index 6e1c2c9..c074a52 100644 +--- a/openbox/focus_cycle.h ++++ b/openbox/focus_cycle.h +@@ -47,6 +47,8 @@ struct _ObClient* focus_directional_cycle(ObDirection dir, + gboolean dialog, + gboolean done, gboolean cancel); + +-void focus_cycle_stop(struct _ObClient *ifclient); ++void focus_cycle_add(struct _ObClient *ifclient); ++void focus_cycle_remove(struct _ObClient *ifclient); ++void focus_cycle_reorder(); + + #endif +diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c +index d01be03..aff8457 100644 +--- a/openbox/focus_cycle_popup.c ++++ b/openbox/focus_cycle_popup.c +@@ -217,6 +217,22 @@ static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets, + p->maxtextw = maxwidth; + } + ++static void popup_cleanup(void) ++{ ++ while(popup.targets) { ++ ObFocusCyclePopupTarget *t = popup.targets->data; ++ ++ RrImageUnref(t->icon); ++ g_free(t->text); ++ XDestroyWindow(ob_display, t->win); ++ g_free(t); ++ ++ popup.targets = g_list_delete_link(popup.targets, popup.targets); ++ } ++ popup.n_targets = 0; ++ popup.last_target = NULL; ++} ++ + static gchar *popup_get_name(ObClient *c) + { + ObClient *p; +@@ -479,18 +495,7 @@ void focus_cycle_popup_hide(void) + + popup.mapped = FALSE; + +- while(popup.targets) { +- ObFocusCyclePopupTarget *t = popup.targets->data; +- +- RrImageUnref(t->icon); +- g_free(t->text); +- XDestroyWindow(ob_display, t->win); +- g_free(t); +- +- popup.targets = g_list_delete_link(popup.targets, popup.targets); +- } +- popup.n_targets = 0; +- popup.last_target = NULL; ++ popup_cleanup(); + + g_free(popup.hilite_rgba); + popup.hilite_rgba = NULL; +@@ -536,7 +541,7 @@ void focus_cycle_popup_single_hide(void) + icon_popup_hide(single_popup); + } + +-gboolean focus_cycle_popup_is_showing(ObClient *client) ++GList* focus_cycle_popup_is_showing(ObClient *client) + { + if (popup.mapped) { + GList *it; +@@ -544,8 +549,46 @@ gboolean focus_cycle_popup_is_showing(ObClient *client) + for (it = popup.targets; it; it = g_list_next(it)) { + ObFocusCyclePopupTarget *t = it->data; + if (t->client == client) +- return TRUE; ++ return it; ++ } ++ } ++ return NULL; ++} ++ ++ObClient* focus_cycle_popup_revert(ObClient *target) ++{ ++ GList *it; ++ ++ if (!popup.mapped) return NULL; ++ ++ for (it = popup.targets; it; it = g_list_next(it)) { ++ ObFocusCyclePopupTarget *t = it->data; ++ if (t->client == target) { ++ if (it->prev) ++ return ((ObFocusCyclePopupTarget*)it->prev->data)->client; ++ else if (it->next) ++ return ((ObFocusCyclePopupTarget*)it->next->data)->client; ++ else ++ return NULL; + } + } +- return FALSE; ++ g_assert_not_reached(); ++} ++ ++void focus_cycle_popup_refresh(ObClient *target, ++ gboolean iconic_windows, ++ gboolean all_desktops, ++ gboolean dock_windows, ++ gboolean desktop_windows) ++{ ++ if (!popup.mapped) return; ++ ++ popup_cleanup(); ++ popup_setup(&popup, TRUE, iconic_windows, all_desktops, ++ dock_windows, desktop_windows); ++ ++ popup.mapped = FALSE; ++ popup_render(&popup, target); ++ XFlush(ob_display); ++ popup.mapped = TRUE; + } +diff --git a/openbox/focus_cycle_popup.h b/openbox/focus_cycle_popup.h +index 19279a6..b4c9e35 100644 +--- a/openbox/focus_cycle_popup.h ++++ b/openbox/focus_cycle_popup.h +@@ -39,7 +39,13 @@ void focus_cycle_popup_single_show(struct _ObClient *c, + gboolean desktop_windows); + void focus_cycle_popup_single_hide(); + +-/*! Returns TRUE if the popup is showing the client, otherwise FALSE. */ +-gboolean focus_cycle_popup_is_showing(struct _ObClient *client); ++/*! Reverts from the current @target to a new focus cycle target window */ ++struct _ObClient* focus_cycle_popup_revert(struct _ObClient *target); ++/*! Redraws the focus cycle popup */ ++void focus_cycle_popup_refresh(struct _ObClient *target, ++ gboolean iconic_windows, ++ gboolean all_desktops, ++ gboolean dock_windows, ++ gboolean desktop_windows); + + #endif +diff --git a/openbox/screen.c b/openbox/screen.c +index d88be43..075d307 100644 +--- a/openbox/screen.c ++++ b/openbox/screen.c +@@ -708,7 +708,8 @@ void screen_set_desktop(guint num, gboolean dofocus) + for (it = stacking_list; it; it = g_list_next(it)) { + if (WINDOW_IS_CLIENT(it->data)) { + ObClient *c = it->data; +- client_show(c); ++ if (client_show(c)) ++ focus_cycle_add(c); + } + } + +@@ -719,8 +720,7 @@ void screen_set_desktop(guint num, gboolean dofocus) + if (WINDOW_IS_CLIENT(it->data)) { + ObClient *c = it->data; + if (client_hide(c)) { +- /* in the middle of cycling..? kill it. */ +- focus_cycle_stop(c); ++ focus_cycle_remove(c); + + if (c == focus_client) { + /* c was focused and we didn't do fallback clearly so make +commit b8e994e837d260860a4dc0a1ee3a680e2cdfc75a +Author: Dana Jansens +Date: Mon Jan 11 13:12:09 2010 -0500 + + Reuse ObFocusCyclePopupTargets when refreshing the focus cycle dialog + +diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c +index aff8457..b97bc97 100644 +--- a/openbox/focus_cycle_popup.c ++++ b/openbox/focus_cycle_popup.c +@@ -75,15 +75,16 @@ static ObFocusCyclePopup popup; + /*! This popup shows a single window */ + static ObIconPopup *single_popup; + +-static gchar *popup_get_name (ObClient *c); +-static void popup_setup (ObFocusCyclePopup *p, +- gboolean create_targets, +- gboolean iconic_windows, +- gboolean all_desktops, +- gboolean dock_windows, +- gboolean desktop_windows); +-static void popup_render (ObFocusCyclePopup *p, +- const ObClient *c); ++static gchar *popup_get_name (ObClient *c); ++static gboolean popup_setup (ObFocusCyclePopup *p, ++ gboolean create_targets, ++ gboolean refresh_targets, ++ gboolean iconic_windows, ++ gboolean all_desktops, ++ gboolean dock_windows, ++ gboolean desktop_windows); ++static void popup_render (ObFocusCyclePopup *p, ++ const ObClient *c); + + static Window create_window(Window parent, guint bwidth, gulong mask, + XSetWindowAttributes *attr) +@@ -162,12 +163,36 @@ void focus_cycle_popup_shutdown(gboolean reconfig) + RrAppearanceFree(popup.a_bg); + } + +-static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets, +- gboolean iconic_windows, gboolean all_desktops, +- gboolean dock_windows, gboolean desktop_windows) ++static void popup_target_free(ObFocusCyclePopupTarget *t) ++{ ++ RrImageUnref(t->icon); ++ g_free(t->text); ++ XDestroyWindow(ob_display, t->win); ++ g_free(t); ++} ++ ++static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, ++ gboolean refresh_targets, ++ gboolean iconic_windows, gboolean all_desktops, ++ gboolean dock_windows, gboolean desktop_windows) + { + gint maxwidth, n; + GList *it; ++ GList *rtargets; /* old targets for refresh */ ++ GList *rtlast; ++ gboolean change; ++ ++ if (refresh_targets) { ++ rtargets = p->targets; ++ rtlast = g_list_last(rtargets); ++ p->targets = NULL; ++ p->n_targets = 0; ++ change = FALSE; ++ } ++ else { ++ rtargets = rtlast = NULL; ++ change = TRUE; ++ } + + g_assert(p->targets == NULL); + g_assert(p->n_targets == 0); +@@ -188,45 +213,76 @@ static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets, + desktop_windows, + FALSE)) + { +- gchar *text = popup_get_name(ft); ++ GList *rit; ++ ++ /* reuse the target if possible during refresh */ ++ for (rit = rtlast; rit; rit = g_list_previous(rit)) { ++ ObFocusCyclePopupTarget *t = rit->data; ++ if (t->client == ft) { ++ if (rit == rtlast) ++ rtlast = g_list_previous(rit); ++ rtargets = g_list_remove_link(rtargets, rit); ++ ++ p->targets = g_list_concat(rit, p->targets); ++ ++n; ++ ++ if (rit != rtlast) ++ change = TRUE; /* order changed */ ++ break; ++ } ++ } ++ ++ if (!rit) { ++ gchar *text = popup_get_name(ft); + +- /* measure */ +- p->a_text->texture[0].data.text.string = text; +- maxwidth = MAX(maxwidth, RrMinWidth(p->a_text)); ++ /* measure */ ++ p->a_text->texture[0].data.text.string = text; ++ maxwidth = MAX(maxwidth, RrMinWidth(p->a_text)); + +- if (!create_targets) +- g_free(text); +- else { +- ObFocusCyclePopupTarget *t = g_new(ObFocusCyclePopupTarget, 1); ++ if (!create_targets) ++ g_free(text); ++ else { ++ ObFocusCyclePopupTarget *t = ++ g_new(ObFocusCyclePopupTarget, 1); ++ ++ t->client = ft; ++ t->text = text; ++ t->icon = client_icon(t->client); ++ RrImageRef(t->icon); /* own the icon so it won't go away */ ++ t->win = create_window(p->bg, 0, 0, NULL); + +- t->client = ft; +- t->text = text; +- t->icon = client_icon(t->client); +- RrImageRef(t->icon); /* own the icon so it won't go away */ +- t->win = create_window(p->bg, 0, 0, NULL); ++ XMapWindow(ob_display, t->win); + +- XMapWindow(ob_display, t->win); ++ p->targets = g_list_prepend(p->targets, t); ++ ++n; + +- p->targets = g_list_prepend(p->targets, t); +- ++n; ++ change = TRUE; /* added a window */ ++ } + } + } + } + ++ if (rtargets) { ++ change = TRUE; /* removed a window */ ++ ++ while (rtargets) { ++ popup_target_free(rtargets->data); ++ rtargets = g_list_delete_link(rtargets, rtargets); ++ ++ popup.targets = g_list_delete_link(popup.targets, popup.targets); ++ } ++ } ++ + p->n_targets = n; + p->maxtextw = maxwidth; ++ ++ return change; + } + + static void popup_cleanup(void) + { + while(popup.targets) { +- ObFocusCyclePopupTarget *t = popup.targets->data; +- +- RrImageUnref(t->icon); +- g_free(t->text); +- XDestroyWindow(ob_display, t->win); +- g_free(t); +- ++ popup_target_free(popup.targets->data); + popup.targets = g_list_delete_link(popup.targets, popup.targets); + } + popup.n_targets = 0; +@@ -467,7 +523,7 @@ void focus_cycle_popup_show(ObClient *c, gboolean iconic_windows, + + /* do this stuff only when the dialog is first showing */ + if (!popup.mapped) +- popup_setup(&popup, TRUE, iconic_windows, all_desktops, ++ popup_setup(&popup, TRUE, FALSE, iconic_windows, all_desktops, + dock_windows, desktop_windows); + g_assert(popup.targets != NULL); + +@@ -515,7 +571,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c, + if (!popup.mapped) { + Rect *a; + +- popup_setup(&popup, FALSE, iconic_windows, all_desktops, ++ popup_setup(&popup, FALSE, FALSE, iconic_windows, all_desktops, + dock_windows, desktop_windows); + g_assert(popup.targets == NULL); + +@@ -583,12 +639,12 @@ void focus_cycle_popup_refresh(ObClient *target, + { + if (!popup.mapped) return; + +- popup_cleanup(); +- popup_setup(&popup, TRUE, iconic_windows, all_desktops, +- dock_windows, desktop_windows); +- +- popup.mapped = FALSE; +- popup_render(&popup, target); +- XFlush(ob_display); +- popup.mapped = TRUE; ++ if (popup_setup(&popup, TRUE, TRUE, iconic_windows, all_desktops, ++ dock_windows, desktop_windows)) ++ { ++ popup.mapped = FALSE; ++ popup_render(&popup, target); ++ XFlush(ob_display); ++ popup.mapped = TRUE; ++ } + } +commit 14180a6b0dee05e73fd193db28fd94b4ef3046d1 +Author: Dana Jansens +Date: Mon Jan 11 15:13:55 2010 -0500 + + More work on refreshing the focus cycle dialog when windows are added/removed from the valid focus order + +diff --git a/openbox/client.c b/openbox/client.c +index 6799654..afea324 100644 +--- a/openbox/client.c ++++ b/openbox/client.c +@@ -34,6 +34,7 @@ + #include "grab.h" + #include "prompt.h" + #include "focus.h" ++#include "focus_cycle.h" + #include "stacking.h" + #include "openbox.h" + #include "group.h" +@@ -1996,6 +1997,8 @@ void client_update_wmhints(ObClient *self) + + XFree(hints); + } ++ ++ focus_cycle_addremove(self, TRUE); + } + + void client_update_title(ObClient *self) +@@ -3254,7 +3257,7 @@ static void client_iconify_recursive(ObClient *self, + self->iconic = iconic; + + /* update the focus lists.. iconic windows go to the bottom of +- the list */ ++ the list. this will also call focus_cycle_addremove(). */ + focus_order_to_bottom(self); + + changed = TRUE; +@@ -3266,9 +3269,10 @@ static void client_iconify_recursive(ObClient *self, + self->desktop != DESKTOP_ALL) + client_set_desktop(self, screen_desktop, FALSE, FALSE); + +- /* this puts it after the current focused window */ +- focus_order_remove(self); +- focus_order_add_new(self); ++ /* this puts it after the current focused window, this will ++ also cause focus_cycle_addremove() to be called for the ++ client */ ++ focus_order_like_new(self); + + changed = TRUE; + } +@@ -3601,6 +3605,8 @@ static void client_set_desktop_recursive(ObClient *self, + /* the new desktop's geometry may be different, so we may need to + resize, for example if we are maximized */ + client_reconfigure(self, FALSE); ++ ++ focus_cycle_addremove(self, FALSE); + } + + /* move all transients */ +@@ -3616,6 +3622,8 @@ void client_set_desktop(ObClient *self, guint target, + { + self = client_search_top_direct_parent(self); + client_set_desktop_recursive(self, target, donthide, dontraise); ++ ++ focus_cycle_addremove(NULL, TRUE); + } + + gboolean client_is_direct_child(ObClient *parent, ObClient *child) +@@ -3864,6 +3872,8 @@ void client_set_state(ObClient *self, Atom action, glong data1, glong data2) + client_hilite(self, demands_attention); + + client_change_state(self); /* change the hint to reflect these changes */ ++ ++ focus_cycle_addremove(self, TRUE); + } + + ObClient *client_focus_target(ObClient *self) +diff --git a/openbox/focus.c b/openbox/focus.c +index c82c4f6..36d754f 100644 +--- a/openbox/focus.c ++++ b/openbox/focus.c +@@ -90,6 +90,9 @@ void focus_set_client(ObClient *client) + push_to_top(client); + /* remove hiliting from the window when it gets focused */ + client_hilite(client, FALSE); ++ ++ /* make sure the focus cycle popup shows things in the right order */ ++ focus_cycle_reorder(); + } + + /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */ +@@ -98,9 +101,6 @@ void focus_set_client(ObClient *client) + PROP_SET32(RootWindow(ob_display, ob_screen), + net_active_window, window, active); + } +- +- /* make sure the focus cycle popup shows things in the right order */ +- focus_cycle_reorder(); + } + + static ObClient* focus_fallback_target(gboolean allow_refocus, +@@ -201,7 +201,7 @@ void focus_order_add_new(ObClient *c) + focus_order_to_top(c); + else { + g_assert(!g_list_find(focus_order, c)); +- /* if there are any iconic windows, put this above them in the order, ++ /* if there are only iconic windows, put this above them in the order, + but if there are not, then put it under the currently focused one */ + if (focus_order && ((ObClient*)focus_order->data)->iconic) + focus_order = g_list_insert(focus_order, c, 0); +@@ -209,14 +209,20 @@ void focus_order_add_new(ObClient *c) + focus_order = g_list_insert(focus_order, c, 1); + } + +- focus_cycle_add(c); ++ focus_cycle_addremove(c, TRUE); + } + + void focus_order_remove(ObClient *c) + { + focus_order = g_list_remove(focus_order, c); + +- focus_cycle_remove(c); ++ focus_cycle_addremove(c, TRUE); ++} ++ ++void focus_order_like_new(struct _ObClient *c) ++{ ++ focus_order = g_list_remove(focus_order, c); ++ focus_order_add_new(c); + } + + void focus_order_to_top(ObClient *c) +@@ -232,6 +238,8 @@ void focus_order_to_top(ObClient *c) + it && !((ObClient*)it->data)->iconic; it = g_list_next(it)); + focus_order = g_list_insert_before(focus_order, it, c); + } ++ ++ focus_cycle_reorder(); + } + + void focus_order_to_bottom(ObClient *c) +@@ -247,6 +255,8 @@ void focus_order_to_bottom(ObClient *c) + it && !((ObClient*)it->data)->iconic; it = g_list_next(it)); + focus_order = g_list_insert_before(focus_order, it, c); + } ++ ++ focus_cycle_reorder(); + } + + ObClient *focus_order_find_first(guint desktop) +@@ -292,6 +302,10 @@ gboolean focus_valid_target(ObClient *ft, + gboolean desktop_windows, + gboolean user_request) + { ++ /* NOTE: if any of these things change on a client, then they should call ++ focus_cycle_addremove() to make sure the client is not shown/hidden ++ when it should not be */ ++ + gboolean ok = FALSE; + + /* see if the window is still managed or is going away */ +diff --git a/openbox/focus.h b/openbox/focus.h +index 19ab406..c8af110 100644 +--- a/openbox/focus.h ++++ b/openbox/focus.h +@@ -58,6 +58,10 @@ void focus_order_remove(struct _ObClient *c); + /*! Move a client to the top of the focus order */ + void focus_order_to_top(struct _ObClient *c); + ++/*! Move a client to where it would be if it was newly added to the focus order ++ */ ++void focus_order_like_new(struct _ObClient *c); ++ + /*! Move a client to the bottom of the focus order (keeps iconic windows at the + very bottom always though). */ + void focus_order_to_bottom(struct _ObClient *c); +diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c +index 07cc2e8..4043668 100644 +--- a/openbox/focus_cycle.c ++++ b/openbox/focus_cycle.c +@@ -30,8 +30,14 @@ + #include + #include + ++typedef enum { ++ OB_CYCLE_NONE = 0, ++ OB_CYCLE_NORMAL, ++ OB_CYCLE_DIRECTIONAL ++} ObCycleType; ++ + ObClient *focus_cycle_target = NULL; +-static gboolean focus_cycle_directional = FALSE; ++static ObCycleType focus_cycle_type = OB_CYCLE_NONE; + static gboolean focus_cycle_iconic_windows; + static gboolean focus_cycle_all_desktops; + static gboolean focus_cycle_dock_windows; +@@ -52,64 +58,43 @@ void focus_cycle_shutdown(gboolean reconfig) + if (reconfig) return; + } + +-void focus_cycle_add(ObClient *ifclient) +-{ +- if (!(focus_cycle_target && ifclient && !focus_cycle_directional)) +- return; +- +- if (focus_valid_target(ifclient, TRUE, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows, +- FALSE)) +- focus_cycle_popup_refresh(focus_cycle_target, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows); +-} +- +-void focus_cycle_remove(ObClient *ifclient) ++void focus_cycle_addremove(ObClient *c, gboolean redraw) + { +- if (!(focus_cycle_target && ifclient)) ++ if (!focus_cycle_type) + return; + +- if (focus_cycle_directional) { +- if (focus_cycle_target == ifclient) { ++ if (focus_cycle_type == OB_CYCLE_DIRECTIONAL) { ++ if (c && focus_cycle_target == c) { + focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, TRUE); + } + } +- else { +- if (!focus_valid_target(ifclient, TRUE, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows, +- FALSE)) { +- if (focus_cycle_target == ifclient) { +- focus_cycle_target = +- focus_cycle_popup_revert(focus_cycle_target); +- focus_cycle_update_indicator(focus_cycle_target); +- } +- focus_cycle_popup_refresh(focus_cycle_target, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows); ++ else if (c && redraw) { ++ gboolean v, s; ++ ++ v = focus_cycle_valid(c); ++ s = focus_cycle_popup_is_showing(c); ++ ++ if (v != s) { ++ focus_cycle_target = ++ focus_cycle_popup_refresh(focus_cycle_target, redraw); + } + } ++ else if (redraw) { ++ focus_cycle_reorder(); ++ } + } + + void focus_cycle_reorder() + { +- if (focus_cycle_target && !focus_cycle_directional) +- focus_cycle_popup_refresh(focus_cycle_target, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows); ++ if (focus_cycle_type == OB_CYCLE_NORMAL) { ++ focus_cycle_target = focus_cycle_popup_refresh(focus_cycle_target, ++ TRUE); ++ focus_cycle_update_indicator(focus_cycle_target); ++ if (!focus_cycle_target) ++ focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, ++ TRUE, TRUE, TRUE, TRUE, TRUE); ++ } + } + + ObClient* focus_cycle(gboolean forward, gboolean all_desktops, +@@ -126,7 +111,6 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + if (interactive) { + if (cancel) { + focus_cycle_target = NULL; +- focus_cycle_directional = FALSE; + goto done_cycle; + } else if (done) + goto done_cycle; +@@ -164,17 +148,11 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + if (it == NULL) it = g_list_last(list); + } + ft = it->data; +- if (focus_valid_target(ft, TRUE, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows, +- FALSE)) +- { ++ if (focus_cycle_valid(ft)) { + if (interactive) { + if (ft != focus_cycle_target) { /* prevents flicker */ + focus_cycle_target = ft; +- focus_cycle_directional = FALSE; ++ focus_cycle_type = OB_CYCLE_NORMAL; + focus_cycle_draw_indicator(showbar ? ft : NULL); + } + if (dialog) +@@ -187,7 +165,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, + return focus_cycle_target; + } else if (ft != focus_cycle_target) { + focus_cycle_target = ft; +- focus_cycle_directional = FALSE; ++ focus_cycle_type = OB_CYCLE_NORMAL; + done = TRUE; + break; + } +@@ -198,7 +176,7 @@ done_cycle: + if (done && !cancel) ret = focus_cycle_target; + + focus_cycle_target = NULL; +- focus_cycle_directional = FALSE; ++ focus_cycle_type = OB_CYCLE_NONE; + g_list_free(order); + order = NULL; + +@@ -238,8 +216,7 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, + /* the currently selected window isn't interesting */ + if (cur == c) + continue; +- if (!focus_valid_target(it->data, TRUE, FALSE, FALSE, dock_windows, +- desktop_windows, FALSE)) ++ if (!focus_cycle_valid(it->data)) + continue; + + /* find the centre coords of this window, from the +@@ -318,7 +295,6 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, + + if (cancel) { + focus_cycle_target = NULL; +- focus_cycle_directional = FALSE; + goto done_cycle; + } else if (done && interactive) + goto done_cycle; +@@ -344,17 +320,15 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, + GList *it; + + for (it = focus_order; it; it = g_list_next(it)) +- if (focus_valid_target(it->data, TRUE, +- focus_cycle_iconic_windows, +- focus_cycle_all_desktops, +- focus_cycle_dock_windows, +- focus_cycle_desktop_windows, FALSE)) ++ if (focus_cycle_valid(it->data)) { + ft = it->data; ++ break; ++ } + } + + if (ft && ft != focus_cycle_target) {/* prevents flicker */ + focus_cycle_target = ft; +- focus_cycle_directional = TRUE; ++ focus_cycle_type = OB_CYCLE_DIRECTIONAL; + if (!interactive) + goto done_cycle; + focus_cycle_draw_indicator(showbar ? ft : NULL); +@@ -373,10 +347,20 @@ done_cycle: + + first = NULL; + focus_cycle_target = NULL; +- focus_cycle_directional = FALSE; ++ focus_cycle_type = OB_CYCLE_NONE; + + focus_cycle_draw_indicator(NULL); + focus_cycle_popup_single_hide(); + + return ret; + } ++ ++gboolean focus_cycle_valid(struct _ObClient *client) ++{ ++ return focus_valid_target(client, TRUE, ++ focus_cycle_iconic_windows, ++ focus_cycle_all_desktops, ++ focus_cycle_dock_windows, ++ focus_cycle_desktop_windows, ++ FALSE); ++} +diff --git a/openbox/focus_cycle.h b/openbox/focus_cycle.h +index c074a52..4a97c10 100644 +--- a/openbox/focus_cycle.h ++++ b/openbox/focus_cycle.h +@@ -47,8 +47,10 @@ struct _ObClient* focus_directional_cycle(ObDirection dir, + gboolean dialog, + gboolean done, gboolean cancel); + +-void focus_cycle_add(struct _ObClient *ifclient); +-void focus_cycle_remove(struct _ObClient *ifclient); ++/*! Set @redraw to FALSE if there are more clients to be added/removed first */ ++void focus_cycle_addremove(struct _ObClient *ifclient, gboolean redraw); + void focus_cycle_reorder(); + ++gboolean focus_cycle_valid(struct _ObClient *client); ++ + #endif +diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c +index b97bc97..1652280 100644 +--- a/openbox/focus_cycle_popup.c ++++ b/openbox/focus_cycle_popup.c +@@ -18,6 +18,7 @@ + */ + + #include "focus_cycle_popup.h" ++#include "focus_cycle.h" + #include "popup.h" + #include "client.h" + #include "screen.h" +@@ -78,11 +79,7 @@ static ObIconPopup *single_popup; + static gchar *popup_get_name (ObClient *c); + static gboolean popup_setup (ObFocusCyclePopup *p, + gboolean create_targets, +- gboolean refresh_targets, +- gboolean iconic_windows, +- gboolean all_desktops, +- gboolean dock_windows, +- gboolean desktop_windows); ++ gboolean refresh_targets); + static void popup_render (ObFocusCyclePopup *p, + const ObClient *c); + +@@ -172,9 +169,7 @@ static void popup_target_free(ObFocusCyclePopupTarget *t) + } + + static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, +- gboolean refresh_targets, +- gboolean iconic_windows, gboolean all_desktops, +- gboolean dock_windows, gboolean desktop_windows) ++ gboolean refresh_targets) + { + gint maxwidth, n; + GList *it; +@@ -206,13 +201,7 @@ static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, + for (it = g_list_last(focus_order); it; it = g_list_previous(it)) { + ObClient *ft = it->data; + +- if (focus_valid_target(ft, TRUE, +- iconic_windows, +- all_desktops, +- dock_windows, +- desktop_windows, +- FALSE)) +- { ++ if (focus_cycle_valid(ft)) { + GList *rit; + + /* reuse the target if possible during refresh */ +@@ -268,8 +257,6 @@ static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, + while (rtargets) { + popup_target_free(rtargets->data); + rtargets = g_list_delete_link(rtargets, rtargets); +- +- popup.targets = g_list_delete_link(popup.targets, popup.targets); + } + } + +@@ -523,8 +510,7 @@ void focus_cycle_popup_show(ObClient *c, gboolean iconic_windows, + + /* do this stuff only when the dialog is first showing */ + if (!popup.mapped) +- popup_setup(&popup, TRUE, FALSE, iconic_windows, all_desktops, +- dock_windows, desktop_windows); ++ popup_setup(&popup, TRUE, FALSE); + g_assert(popup.targets != NULL); + + popup_render(&popup, c); +@@ -571,8 +557,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c, + if (!popup.mapped) { + Rect *a; + +- popup_setup(&popup, FALSE, FALSE, iconic_windows, all_desktops, +- dock_windows, desktop_windows); ++ popup_setup(&popup, FALSE, FALSE); + g_assert(popup.targets == NULL); + + /* position the popup */ +@@ -597,54 +582,67 @@ void focus_cycle_popup_single_hide(void) + icon_popup_hide(single_popup); + } + +-GList* focus_cycle_popup_is_showing(ObClient *client) ++gboolean focus_cycle_popup_is_showing(ObClient *c) + { + if (popup.mapped) { + GList *it; + + for (it = popup.targets; it; it = g_list_next(it)) { + ObFocusCyclePopupTarget *t = it->data; +- if (t->client == client) +- return it; ++ if (t->client == c) ++ return TRUE; + } + } +- return NULL; ++ return FALSE; + } + +-ObClient* focus_cycle_popup_revert(ObClient *target) ++static ObClient* popup_revert(ObClient *target) + { +- GList *it; +- +- if (!popup.mapped) return NULL; ++ GList *it, *itt; + + for (it = popup.targets; it; it = g_list_next(it)) { + ObFocusCyclePopupTarget *t = it->data; + if (t->client == target) { +- if (it->prev) +- return ((ObFocusCyclePopupTarget*)it->prev->data)->client; +- else if (it->next) +- return ((ObFocusCyclePopupTarget*)it->next->data)->client; +- else +- return NULL; ++ /* move to a previous window if possible */ ++ for (itt = it->prev; itt; itt = g_list_previous(itt)) { ++ ObFocusCyclePopupTarget *t2 = it->data; ++ if (focus_cycle_valid(t2->client)) ++ return t2->client; ++ } ++ ++ /* otherwise move to a following window if possible */ ++ for (itt = it->next; itt; itt = g_list_next(itt)) { ++ ObFocusCyclePopupTarget *t2 = it->data; ++ if (focus_cycle_valid(t2->client)) ++ return t2->client; ++ } ++ ++ /* otherwise, we can't go anywhere there is nowhere valid to go */ ++ return NULL; + } + } +- g_assert_not_reached(); ++ return NULL; + } + +-void focus_cycle_popup_refresh(ObClient *target, +- gboolean iconic_windows, +- gboolean all_desktops, +- gboolean dock_windows, +- gboolean desktop_windows) ++ObClient* focus_cycle_popup_refresh(ObClient *target, ++ gboolean redraw) + { +- if (!popup.mapped) return; ++ if (!popup.mapped) return NULL; + +- if (popup_setup(&popup, TRUE, TRUE, iconic_windows, all_desktops, +- dock_windows, desktop_windows)) +- { ++ if (!focus_cycle_valid(target)) ++ target = popup_revert(target); ++ ++ redraw = popup_setup(&popup, TRUE, TRUE) && redraw; ++ ++ if (!target && popup.targets) ++ target = ((ObFocusCyclePopupTarget*)popup.targets->data)->client; ++ ++ if (target && redraw) { + popup.mapped = FALSE; + popup_render(&popup, target); + XFlush(ob_display); + popup.mapped = TRUE; + } ++ ++ return target; + } +diff --git a/openbox/focus_cycle_popup.h b/openbox/focus_cycle_popup.h +index b4c9e35..934d9a6 100644 +--- a/openbox/focus_cycle_popup.h ++++ b/openbox/focus_cycle_popup.h +@@ -39,13 +39,13 @@ void focus_cycle_popup_single_show(struct _ObClient *c, + gboolean desktop_windows); + void focus_cycle_popup_single_hide(); + +-/*! Reverts from the current @target to a new focus cycle target window */ +-struct _ObClient* focus_cycle_popup_revert(struct _ObClient *target); +-/*! Redraws the focus cycle popup */ +-void focus_cycle_popup_refresh(struct _ObClient *target, +- gboolean iconic_windows, +- gboolean all_desktops, +- gboolean dock_windows, +- gboolean desktop_windows); ++gboolean focus_cycle_popup_is_showing(struct _ObClient *c); ++ ++/*! Redraws the focus cycle popup, and returns the current target. If ++ the target given to the function is no longer valid, this will return ++ a different target that is valid, and which should be considered the ++ current focus cycling target. */ ++struct _ObClient *focus_cycle_popup_refresh(struct _ObClient *target, ++ gboolean redraw); + + #endif +diff --git a/openbox/screen.c b/openbox/screen.c +index 5ae0790..55fd58d 100644 +--- a/openbox/screen.c ++++ b/openbox/screen.c +@@ -713,8 +713,7 @@ void screen_set_desktop(guint num, gboolean dofocus) + for (it = stacking_list; it; it = g_list_next(it)) { + if (WINDOW_IS_CLIENT(it->data)) { + ObClient *c = it->data; +- if (client_show(c)) +- focus_cycle_add(c); ++ client_show(c); + } + } + +@@ -725,8 +724,6 @@ void screen_set_desktop(guint num, gboolean dofocus) + if (WINDOW_IS_CLIENT(it->data)) { + ObClient *c = it->data; + if (client_hide(c)) { +- focus_cycle_remove(c); +- + if (c == focus_client) { + /* c was focused and we didn't do fallback clearly so make + sure openbox doesnt still consider the window focused. +@@ -742,6 +739,8 @@ void screen_set_desktop(guint num, gboolean dofocus) + } + } + ++ focus_cycle_addremove(NULL, TRUE); ++ + event_end_ignore_all_enters(ignore_start); + + if (event_curtime != CurrentTime) +commit bd864012cd17f68c3a25ccfc2fc6cfd304c557f2 +Author: Dana Jansens +Date: Mon Jan 11 15:35:47 2010 -0500 + + Make the focus cycle indicator follow target fallback in the popup + +diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c +index 4043668..da9cd4c 100644 +--- a/openbox/focus_cycle.c ++++ b/openbox/focus_cycle.c +@@ -75,10 +75,8 @@ void focus_cycle_addremove(ObClient *c, gboolean redraw) + v = focus_cycle_valid(c); + s = focus_cycle_popup_is_showing(c); + +- if (v != s) { +- focus_cycle_target = +- focus_cycle_popup_refresh(focus_cycle_target, redraw); +- } ++ if (v != s) ++ focus_cycle_reorder(); + } + else if (redraw) { + focus_cycle_reorder(); +commit e8200ae603f33b70824c125ba6b37bfaec7d89ea +Author: Dana Jansens +Date: Mon Jan 11 15:37:36 2010 -0500 + + make focus cycle target fallback work right by going to the next prev window + +diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c +index 1652280..d7ac9f5 100644 +--- a/openbox/focus_cycle_popup.c ++++ b/openbox/focus_cycle_popup.c +@@ -605,14 +605,14 @@ static ObClient* popup_revert(ObClient *target) + if (t->client == target) { + /* move to a previous window if possible */ + for (itt = it->prev; itt; itt = g_list_previous(itt)) { +- ObFocusCyclePopupTarget *t2 = it->data; ++ ObFocusCyclePopupTarget *t2 = itt->data; + if (focus_cycle_valid(t2->client)) + return t2->client; + } + + /* otherwise move to a following window if possible */ + for (itt = it->next; itt; itt = g_list_next(itt)) { +- ObFocusCyclePopupTarget *t2 = it->data; ++ ObFocusCyclePopupTarget *t2 = itt->data; + if (focus_cycle_valid(t2->client)) + return t2->client; + } diff --git a/openbox-3.4.10-gnomesession.patch b/openbox-3.4.10-gnomesession.patch new file mode 100644 index 0000000..98a90d9 --- /dev/null +++ b/openbox-3.4.10-gnomesession.patch @@ -0,0 +1,19 @@ +commit 62e36ad0410ce888e7097e7bce5cbbf67b5b6290 +Author: Dana Jansens +Date: Tue Jan 12 13:59:25 2010 -0500 + + Fixes bug #4492 (mis-using the return value of grep -q in openbox-gnome-session script + +diff --git a/data/xsession/openbox-gnome-session.in b/data/xsession/openbox-gnome-session.in +index 6765ae8..1f17edb 100644 +--- a/data/xsession/openbox-gnome-session.in ++++ b/data/xsession/openbox-gnome-session.in +@@ -37,7 +37,7 @@ else + if test -z "$SESSION"; then + # if its empty then just run openbox + SESSION="[openbox]" +- elif test -z $(echo "$SESSION" | grep -q openbox); then ++ elif echo "$SESSION" | grep -q openbox; then + # if openbox isn't in the session then append it + SESSION="${SESSION%]},openbox]" + fi diff --git a/openbox.spec b/openbox.spec index 0cdade4..41170e2 100644 --- a/openbox.spec +++ b/openbox.spec @@ -1,6 +1,6 @@ Name: openbox Version: 3.4.10 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A highly configurable and standards-compliant X11 window manager Group: User Interface/Desktops @@ -14,6 +14,8 @@ Source4: openbox.desktop Patch0: openbox-3.4.9-autostartdir.patch Patch1: openbox-3.4.10-obxpropman.patch +Patch2: openbox-3.4.10-focuscycle.patch +Patch3: openbox-3.4.10-gnomesession.patch Patch4: openbox-3.4.7.2-24bit.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -73,6 +75,8 @@ The %{name}-libs package contains shared libraries used by %{name}. %setup -q %patch0 -p1 -b .autostartdir %patch1 -p1 -b .obxpropman +%patch2 -p1 -b .focuscycle -F 2 +%patch3 -p1 -b .gnomesession %patch4 -p1 -b .24bit @@ -146,6 +150,10 @@ rm -rf %{buildroot} %changelog +* Mon Jan 18 2010 Miroslav Lichvar - 3.4.10-2 +- fix crash when window is added to focus order while focus cycling +- fix gnome-session script + * Fri Jan 08 2010 Miroslav Lichvar - 3.4.10-1 - Update to 3.4.10 diff --git a/sources b/sources index 94bb245..2fb5b31 100644 --- a/sources +++ b/sources @@ -1,3 +1,2 @@ 16ca0d290cae2f4c16a35e9cdfb6f503 setlayout.c -2f30670f7067e3e17567019d2eef21a0 openbox-3.4.9.tar.gz daccf153c7808950313eb00bc250f9bc openbox-3.4.10.tar.gz