diff -Napur openbox-3.5.0.orig/openbox/actions/cyclewindows.c openbox-3.5.0/openbox/actions/cyclewindows.c --- openbox-3.5.0.orig/openbox/actions/cyclewindows.c 2011-08-02 00:14:58.000000000 +0400 +++ openbox-3.5.0/openbox/actions/cyclewindows.c 2012-05-21 08:53:36.000000000 +0400 @@ -16,6 +16,7 @@ typedef struct { gboolean forward; gboolean bar; gboolean raise; + gboolean focus; ObFocusCyclePopupMode dialog_mode; GSList *actions; @@ -82,6 +83,8 @@ static gpointer setup_func(xmlNodePtr no o->bar = obt_xml_node_bool(n); if ((n = obt_xml_find_node(node, "raise"))) o->raise = obt_xml_node_bool(n); + if ((n = obt_xml_find_node(node, "focus"))) + o->focus = obt_xml_node_bool(n); if ((n = obt_xml_find_node(node, "panels"))) o->dock_windows = obt_xml_node_bool(n); if ((n = obt_xml_find_node(node, "hilite"))) @@ -166,6 +169,8 @@ static gboolean run_func(ObActionsData * o->dialog_mode, FALSE, FALSE); + if (o->focus && ft) focus_temp_set_client(ft); + stacking_restore(); if (o->raise && ft) stacking_temp_raise(CLIENT_AS_WINDOW(ft)); @@ -239,6 +244,8 @@ static void i_post_func(gpointer options o->dialog_mode, TRUE, o->cancel); + focus_restore(); + if (ft) actions_run_acts(o->actions, OB_USER_ACTION_KEYBOARD_KEY, o->state, -1, -1, 0, OB_FRAME_CONTEXT_NONE, ft); diff -Napur openbox-3.5.0.orig/openbox/client.c openbox-3.5.0/openbox/client.c --- openbox-3.5.0.orig/openbox/client.c 2011-08-02 00:14:58.000000000 +0400 +++ openbox-3.5.0/openbox/client.c 2012-05-21 00:33:49.000000000 +0400 @@ -3903,7 +3903,7 @@ gboolean client_can_focus(ObClient *self return TRUE; } -gboolean client_focus(ObClient *self) +static gboolean client_focus_permanently(ObClient *self, gboolean perm) { if (!client_validate(self)) return FALSE; @@ -3926,7 +3926,8 @@ gboolean client_focus(ObClient *self) /* if using focus_delay, stop the timer now so that focus doesn't go moving on us */ - event_halt_focus_delay(); + if (perm) + event_halt_focus_delay(); obt_display_ignore_errors(TRUE); @@ -3937,7 +3938,7 @@ gboolean client_focus(ObClient *self) event_time()); } - if (self->focus_notify) { + if (perm && self->focus_notify) { XEvent ce; ce.xclient.type = ClientMessage; ce.xclient.message_type = OBT_PROP_ATOM(WM_PROTOCOLS); @@ -3959,6 +3960,16 @@ gboolean client_focus(ObClient *self) return !obt_display_error_occured; } +gboolean client_temp_focus(ObClient *self) +{ + return client_focus_permanently(self, FALSE); +} + +gboolean client_focus(ObClient *self) +{ + return client_focus_permanently(self, TRUE); +} + static void client_present(ObClient *self, gboolean here, gboolean raise, gboolean unshade) { diff -Napur openbox-3.5.0.orig/openbox/client.h openbox-3.5.0/openbox/client.h --- openbox-3.5.0.orig/openbox/client.h 2011-08-02 00:14:58.000000000 +0400 +++ openbox-3.5.0/openbox/client.h 2012-05-20 20:10:40.000000000 +0400 @@ -579,6 +579,7 @@ gboolean client_can_focus(ObClient *self /*! Attempt to focus the client window */ gboolean client_focus(ObClient *self); +gboolean client_temp_focus(ObClient *self); /*! Activates the client for use, focusing, uniconifying it, etc. To be used when the user deliberately selects a window for use. diff -Napur openbox-3.5.0.orig/openbox/focus.c openbox-3.5.0/openbox/focus.c --- openbox-3.5.0.orig/openbox/focus.c 2011-08-02 00:14:58.000000000 +0400 +++ openbox-3.5.0/openbox/focus.c 2012-05-21 08:54:25.000000000 +0400 @@ -39,6 +39,8 @@ ObClient *focus_client = NULL; GList *focus_order = NULL; +static ObClient *focus_temp_client = NULL; + void focus_startup(gboolean reconfig) { if (reconfig) return; @@ -69,10 +71,43 @@ static void push_to_top(ObClient *client focus_order = g_list_prepend(focus_order, client); } +static void move_visual_focus (ObClient *from, ObClient *to) +{ + Window active; + + if (to == from) return; + + client_temp_focus(to); + + screen_install_colormap(from, FALSE); + screen_install_colormap(to, TRUE); + client_hilite(to, FALSE); + + active = to ? to->window : None; + OBT_PROP_SET32(obt_root(ob_screen), NET_ACTIVE_WINDOW, WINDOW, active); +} + +void focus_restore() +{ + if (focus_temp_client) { + move_visual_focus(focus_temp_client, focus_client); + focus_temp_client = NULL; + } +} + +void focus_temp_set_client(ObClient *client) +{ + ObClient *from = focus_temp_client ? focus_temp_client : focus_client + move_visual_focus(from, focus_temp_client = client); +} + + void focus_set_client(ObClient *client) { Window active; + if (focus_temp_client) return; + ob_debug_type(OB_DEBUG_FOCUS, "focus_set_client 0x%lx", client ? client->window : 0);