summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2007-04-22 19:13:38 +0000
committerDana Jansens <danakj@orodu.net>2007-04-22 19:13:38 +0000
commitbfb800c032e1dd50f5d1c37d1ce8ac9239947b01 (patch)
tree9729cf672c6490618f39926729fc5379cea41864 /openbox
parent7d1226c57cbe2c83d87174b637bcf923897f8033 (diff)
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
Diffstat (limited to 'openbox')
-rw-r--r--openbox/action.c30
-rw-r--r--openbox/event.c46
-rw-r--r--openbox/focus.c45
-rw-r--r--openbox/focus.h11
-rw-r--r--openbox/screen.c35
5 files changed, 61 insertions, 106 deletions
diff --git a/openbox/action.c b/openbox/action.c
index 5e42b68b..db49f56c 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -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();
}
}
diff --git a/openbox/event.c b/openbox/event.c
index 6f819cc1..65b94980 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -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);
diff --git a/openbox/focus.c b/openbox/focus.c
index ea3d4fab..7a686800 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -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) {
diff --git a/openbox/focus.h b/openbox/focus.h
index 1366cd08..5ed9977c 100644
--- a/openbox/focus.h
+++ b/openbox/focus.h
@@ -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);
diff --git a/openbox/screen.c b/openbox/screen.c
index c6a6b0e5..a54b2b56 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -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 */