a) remove focus_hilite, it is not needed and complicated things

b) set focus_client to null when nothing is actually focused, but still allow
   focus to go to black holes
c) allow the focus action to be performed without a client, this will focus
   the openbox instance (i.e. the screen in multihead setups)

big thanks to syscrash for the ideas on how to go about this
This commit is contained in:
Dana Jansens 2007-04-22 19:13:38 +00:00
parent 7d1226c57c
commit bfb800c032
5 changed files with 61 additions and 106 deletions

View file

@ -434,6 +434,11 @@ void setup_action_showmenu(ObAction **a, ObUserAction uact)
}
}
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;
@ -494,7 +499,7 @@ ActionString actionstrings[] =
{
"focus",
action_focus,
setup_client_action
setup_action_focus
},
{
"unfocus",
@ -1159,15 +1164,22 @@ void action_activate(union ActionData *data)
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();
}
}

View file

@ -71,7 +71,6 @@ typedef struct
} 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);
@ -164,7 +163,6 @@ void event_startup(gboolean reconfig)
#endif
client_add_destructor(focus_delay_client_dest, NULL);
client_add_destructor(event_client_dest, NULL);
}
void event_shutdown(gboolean reconfig)
@ -176,7 +174,6 @@ void event_shutdown(gboolean reconfig)
#endif
client_remove_destructor(focus_delay_client_dest);
client_remove_destructor(event_client_dest);
XFreeModifiermap(modmap);
}
@ -395,11 +392,8 @@ static gboolean event_ignore(XEvent *e, ObClient *client)
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;
@ -442,29 +436,6 @@ static void event_process(const XEvent *ec, gpointer data)
}
}
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)) {
@ -495,9 +466,9 @@ static void event_process(const XEvent *ec, gpointer data)
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;
@ -510,6 +481,8 @@ static void event_process(const XEvent *ec, gpointer data)
/* 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;
@ -528,8 +501,6 @@ static void event_process(const XEvent *ec, gpointer data)
}
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);
}
@ -594,8 +565,7 @@ static void event_process(const XEvent *ec, gpointer data)
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);
}
}
}
@ -1376,12 +1346,6 @@ static void focus_delay_client_dest(ObClient *client, gpointer data)
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);

View file

@ -37,9 +37,9 @@
#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;
@ -81,7 +81,7 @@ void focus_startup(gboolean reconfig)
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;
@ -156,7 +156,6 @@ static void push_to_top(ObClient *client)
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);
@ -165,37 +164,26 @@ void focus_set_client(ObClient *client)
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);
}
}
@ -280,12 +268,25 @@ void focus_fallback(gboolean allow_refocus)
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) {

View file

@ -29,14 +29,6 @@ struct _ObClient;
/*! 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;
@ -50,6 +42,9 @@ void focus_shutdown(gboolean reconfig);
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);

View file

@ -422,6 +422,7 @@ void screen_set_num_desktops(guint num)
void screen_set_desktop(guint num)
{
ObClient *c;
GList *it;
guint old;
@ -459,19 +460,10 @@ void screen_set_desktop(guint num)
}
}
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();
}
@ -895,21 +887,12 @@ void screen_show_desktop(gboolean show)
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 */