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:
parent
7d1226c57c
commit
bfb800c032
5 changed files with 61 additions and 106 deletions
|
@ -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,16 +1164,23 @@ 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) {
|
||||
/* 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 */
|
||||
/* 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);
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
void action_unfocus (union ActionData *data)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
if (client != NULL) {
|
||||
/* move to the top of the list */
|
||||
if (client != NULL)
|
||||
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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue