}
}
+void setup_action_focus(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.any.client_action = OB_CLIENT_ACTION_OPTIONAL;
+}
+
void setup_client_action(ObAction **a, ObUserAction uact)
{
(*a)->data.any.client_action = OB_CLIENT_ACTION_ALWAYS;
{
"focus",
action_focus,
- setup_client_action
+ setup_action_focus
},
{
"unfocus",
void action_focus(union ActionData *data)
{
- /* similar to the openbox dock for dockapps, don't let user actions give
- focus to 3rd-party docks (panels) either (unless they ask for it
- themselves). */
- if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
- /* if using focus_delay, stop the timer now so that focus doesn't go
- moving on us */
- event_halt_focus_delay();
+ if (data->client.any.c) {
+ /* similar to the openbox dock for dockapps, don't let user actions
+ give focus to 3rd-party docks (panels) either (unless they ask for
+ it themselves). */
+ if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
+ /* if using focus_delay, stop the timer now so that focus doesn't
+ go moving on us */
+ event_halt_focus_delay();
- client_focus(data->client.any.c);
+ client_focus(data->client.any.c);
+ }
+ } else {
+ /* focus action on something other than a client, make keybindings
+ work for this openbox instance, but don't focus any specific client
+ */
+ focus_nothing();
}
}
} ObFocusDelayData;
static void event_process(const XEvent *e, gpointer data);
-static void event_client_dest(ObClient *client, gpointer data);
static void event_handle_root(XEvent *e);
static void event_handle_menu(XEvent *e);
static void event_handle_dock(ObDock *s, XEvent *e);
#endif
client_add_destructor(focus_delay_client_dest, NULL);
- client_add_destructor(event_client_dest, NULL);
}
void event_shutdown(gboolean reconfig)
#endif
client_remove_destructor(focus_delay_client_dest);
- client_remove_destructor(event_client_dest);
XFreeModifiermap(modmap);
}
switch(e->type) {
case FocusIn:
case FocusOut:
- if (!wanted_focusevent(e)) {
- ob_debug_type(OB_DEBUG_FOCUS, "focus event ignored\n");
+ if (!wanted_focusevent(e))
return TRUE;
- }
- ob_debug_type(OB_DEBUG_FOCUS, "focus event used;\n");
break;
}
return FALSE;
}
}
- if (e->type == FocusIn || e->type == FocusOut) {
- gint mode = e->xfocus.mode;
- gint detail = e->xfocus.detail;
- Window window = e->xfocus.window;
- if (detail == NotifyVirtual) {
- ob_debug_type(OB_DEBUG_FOCUS,
- "FOCUS %s NOTIFY VIRTUAL window 0x%x\n",
- (e->type == FocusIn ? "IN" : "OUT"), window);
- }
-
- else if (detail == NotifyNonlinearVirtual) {
- ob_debug_type(OB_DEBUG_FOCUS,
- "FOCUS %s NOTIFY NONLINVIRTUAL window 0x%x\n",
- (e->type == FocusIn ? "IN" : "OUT"), window);
- }
-
- else
- ob_debug_type(OB_DEBUG_FOCUS,
- "UNKNOWN FOCUS %s (d %d, m %d) window 0x%x\n",
- (e->type == FocusIn ? "IN" : "OUT"),
- detail, mode, window);
- }
-
event_set_curtime(e);
event_hack_mods(e);
if (event_ignore(e, client)) {
window which had it. */
focus_fallback(FALSE);
} else if (client && client != focus_client) {
- focus_set_client(client);
frame_adjust_focus(client->frame, TRUE);
client_calc_layer(client);
+ focus_set_client(client);
}
} else if (e->type == FocusOut) {
gboolean nomove = FALSE;
/* There is no FocusIn, this means focus went to a window that
is not being managed, or a window on another screen. */
ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n");
+ /* nothing is focused */
+ focus_set_client(NULL);
} else if (ce.xany.window == e->xany.window) {
/* If focus didn't actually move anywhere, there is nothing to do*/
nomove = TRUE;
}
if (client && !nomove) {
- /* This client is no longer focused, so show that */
- focus_hilite = NULL;
frame_adjust_focus(client->frame, FALSE);
client_calc_layer(client);
}
mouse_event(client, e);
} else if (e->type == KeyPress) {
keyboard_event((focus_cycle_target ? focus_cycle_target :
- (focus_hilite ? focus_hilite : client)),
- e);
+ client), e);
}
}
}
client, FALSE);
}
-static void event_client_dest(ObClient *client, gpointer data)
-{
- if (client == focus_hilite)
- focus_hilite = NULL;
-}
-
void event_halt_focus_delay()
{
ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
#include <glib.h>
#include <assert.h>
-ObClient *focus_client, *focus_hilite;
-GList *focus_order;
-ObClient *focus_cycle_target;
+ObClient *focus_client = NULL;
+GList *focus_order = NULL;
+ObClient *focus_cycle_target = NULL;
struct {
InternalWindow top;
client_add_destructor(focus_cycle_destructor, NULL);
/* start with nothing focused */
- focus_set_client(NULL);
+ focus_nothing();
focus_indicator.top.obwin.type = Window_Internal;
focus_indicator.left.obwin.type = Window_Internal;
void focus_set_client(ObClient *client)
{
Window active;
- ObClient *old;
ob_debug_type(OB_DEBUG_FOCUS,
"focus_set_client 0x%lx\n", client ? client->window : 0);
screen_install_colormap(focus_client, FALSE);
screen_install_colormap(client, TRUE);
- if (client == NULL) {
- ob_debug_type(OB_DEBUG_FOCUS, "actively focusing NONWINDOW\n");
-
- /* when nothing will be focused, send focus to the backup target */
- XSetInputFocus(ob_display, screen_support_win, RevertToNone,
- event_curtime);
- XSync(ob_display, FALSE);
- }
-
/* in the middle of cycling..? kill it. CurrentTime is fine, time won't
be used.
*/
if (focus_cycle_target)
focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
- old = focus_client;
focus_client = client;
- /* move to the top of the list */
- if (client != NULL)
+ if (client != NULL) {
+ /* move to the top of the list */
push_to_top(client);
+ /* remove hiliting from the window when it gets focused */
+ client_hilite(client, FALSE);
+ }
/* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
if (ob_state() != OB_STATE_EXITING) {
active = client ? client->window : None;
PROP_SET32(RootWindow(ob_display, ob_screen),
net_active_window, window, active);
-
- /* remove hiliting from the window when it gets focused */
- if (client != NULL)
- client_hilite(client, FALSE);
}
}
and such, and then when I try focus them, I won't get a FocusIn event
at all for them.
*/
- focus_set_client(NULL);
+ focus_nothing();
if ((new = focus_fallback_target(allow_refocus, old)))
client_focus(new);
}
+void focus_nothing()
+{
+ /* Install our own colormap */
+ if (focus_client != NULL) {
+ screen_install_colormap(focus_client, FALSE);
+ screen_install_colormap(NULL, TRUE);
+ }
+
+ /* when nothing will be focused, send focus to the backup target */
+ XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot,
+ event_curtime);
+}
+
static void popup_cycle(ObClient *c, gboolean show)
{
if (!show) {
/*! The client which is currently focused */
extern struct _ObClient *focus_client;
-/*! The client which is being decorated as focused, not always matching the
- real focus, but this is used to track it so that it can be resolved to match.
-
- This is for when you change desktops. We know which window is *going to be*
- focused, so we hilight it. But since it's hilighted, we also want
- keybindings to go to it, which is really what this is for.
-*/
-extern struct _ObClient *focus_hilite;
/*! The client which appears focused during a focus cycle operation */
extern struct _ObClient *focus_cycle_target;
send focus anywhere, its called by the Focus event handlers */
void focus_set_client(struct _ObClient *client);
+/*! Focus nothing, but let keyboard events be caught. */
+void focus_nothing();
+
struct _ObClient* focus_fallback_target(gboolean allow_refocus,
struct _ObClient *old);
void screen_set_desktop(guint num)
{
+ ObClient *c;
GList *it;
guint old;
}
}
- focus_hilite = focus_fallback_target(TRUE, focus_client);
- if (focus_hilite) {
- frame_adjust_focus(focus_hilite->frame, TRUE);
-
- /*!
- When this focus_client check is not used, you can end up with
- races, as demonstrated with gnome-panel, sometimes the window
- you click on another desktop ends up losing focus cuz of the
- focus change here.
- */
- /*if (!focus_client)*/
- client_focus(focus_hilite);
- }
+ /* reduce flicker by hiliting now rather than waiting for the server
+ FocusIn event */
+ if ((c = focus_fallback_target(TRUE, focus_client)))
+ frame_adjust_focus(c->frame, TRUE);
event_ignore_queued_enters();
}
break;
}
} else {
+ ObClient *c;
+
/* use NULL for the "old" argument because the desktop was focused
and we don't want to fallback to the desktop by default */
- focus_hilite = focus_fallback_target(TRUE, NULL);
- if (focus_hilite) {
- frame_adjust_focus(focus_hilite->frame, TRUE);
-
- /*!
- When this focus_client check is not used, you can end up with
- races, as demonstrated with gnome-panel, sometimes the window
- you click on another desktop ends up losing focus cuz of the
- focus change here.
- */
- /*if (!focus_client)*/
- client_focus(focus_hilite);
- }
+ if ((c = focus_fallback_target(TRUE, NULL)))
+ client_focus(c);
}
show = !!show; /* make it boolean */