#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;
be used
*/
if (focus_cycle_target == client)
- focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime);
+ focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
}
static Window createWindow(Window parent, gulong mask,
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;
-#ifdef DEBUG_FOCUS
- ob_debug("focus_set_client 0x%lx\n", client ? client->window : 0);
-#endif
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "focus_set_client 0x%lx\n", client ? client->window : 0);
/* uninstall the old colormap, and install the new one */
screen_install_colormap(focus_client, FALSE);
screen_install_colormap(client, TRUE);
- if (client == NULL) {
-#ifdef DEBUG_FOCUS
- ob_debug("actively focusing NONWINDOW\n");
-#endif
- /* 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, CurrentTime);
+ 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);
}
}
ObClient *target = NULL;
ObClient *desktop = NULL;
- ob_debug("trying pointer stuff\n");
+ ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n");
if (config_focus_follow && !config_focus_last)
{
if ((target = client_under_pointer()))
if (allow_refocus || target != old)
- if (client_normal(target) && client_can_focus(target) &&
- client_validate(target)) {
- ob_debug("found in pointer stuff\n");
+ if (client_normal(target) && client_can_focus(target)) {
+ ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
return target;
}
}
}
#endif
- ob_debug("trying omnipresentness\n");
- if (old && old->desktop == DESKTOP_ALL)
+ ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
+ if (allow_refocus && old && old->desktop == DESKTOP_ALL)
return old;
- ob_debug("trying the focus order\n");
+ ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n");
for (it = focus_order; it; it = g_list_next(it))
if (allow_refocus || it->data != old) {
ObClient *c = it->data;
a splashscreen or a desktop window (save the desktop as a
backup fallback though)
*/
- if (client_can_focus(c) && client_validate(c) &&
- c->desktop == screen_desktop && !c->iconic)
+ if (client_can_focus(c) && c->desktop == screen_desktop &&
+ !c->iconic)
{
if (client_normal(c)) {
- ob_debug("found in focus order\n");
+ ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
return it->data;
} else if (c->type == OB_CLIENT_TYPE_DESKTOP && !desktop)
desktop = c;
void focus_fallback(gboolean allow_refocus)
{
ObClient *new;
- ObClient *old;
-
- /* save this before moving focus away to nothing */
- old = focus_client;
+ ObClient *old = focus_client;
/* unfocus any focused clients.. they can be focused by Pointer events
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);
+ }
+
+ focus_client = NULL;
+
+ /* 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) {
void focus_cycle_draw_indicator()
{
if (!focus_cycle_target) {
+ XEvent e;
+
XUnmapWindow(ob_display, focus_indicator.top.win);
XUnmapWindow(ob_display, focus_indicator.left.win);
XUnmapWindow(ob_display, focus_indicator.right.win);
XUnmapWindow(ob_display, focus_indicator.bottom.win);
+
+ /* kill enter events cause by this unmapping */
+ XSync(ob_display, FALSE);
+ while (XCheckTypedEvent(ob_display, EnterNotify, &e));
} else {
/*
if (focus_cycle_target)
}
void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
- gboolean dialog, gboolean done, gboolean cancel, Time time)
+ gboolean dialog, gboolean done, gboolean cancel)
{
static ObClient *first = NULL;
static ObClient *t = NULL;
done_cycle:
if (done && focus_cycle_target)
- client_activate(focus_cycle_target, FALSE, TRUE, time);
+ client_activate(focus_cycle_target, FALSE, TRUE);
t = NULL;
first = NULL;
}
void focus_directional_cycle(ObDirection dir, gboolean interactive,
- gboolean dialog, gboolean done, gboolean cancel,
- Time time)
+ gboolean dialog, gboolean done, gboolean cancel)
{
static ObClient *first = NULL;
ObClient *ft = NULL;
done_cycle:
if (done && focus_cycle_target)
- client_activate(focus_cycle_target, FALSE, TRUE, time);
+ client_activate(focus_cycle_target, FALSE, TRUE);
first = NULL;
focus_cycle_target = NULL;