static gboolean menu_hide_delay_func(gpointer data);
-/* The most recent time at which an event with a timestamp occured. */
-static Time event_lasttime = 0;
-/* The time for the current event being processed
- (it's the event_lasttime for events without times, if this is a bug then
- use CurrentTime instead, but it seems ok) */
+/* The time for the current event being processed */
Time event_curtime = CurrentTime;
/*! The value of the mask for the NumLock modifier */
return window;
}
-static void event_set_lasttime(XEvent *e)
+static void event_set_curtime(XEvent *e)
{
- Time t = 0;
+ Time t = CurrentTime;
/* grab the lasttime and hack up the state */
switch (e->type) {
break;
}
- if (t > event_lasttime) {
- event_lasttime = t;
- event_curtime = event_lasttime;
- } else if (t == 0) {
- event_curtime = event_lasttime;
- } else {
- event_curtime = t;
- }
+ event_curtime = t;
}
#define STRIP_MODS(s) \
{
gint mode = e->xfocus.mode;
gint detail = e->xfocus.detail;
+ Window win = e->xany.window;
if (e->type == FocusIn) {
/* These are the ones we want.. */
+ if (win == RootWindow(ob_display, ob_screen)) {
+ /* This means focus reverted off of a client */
+ if (detail == NotifyPointerRoot || detail == NotifyDetailNone ||
+ detail == NotifyInferior)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
/* This means focus moved from the root window to a client */
if (detail == NotifyVirtual)
return TRUE;
if (detail == NotifyNonlinearVirtual)
return TRUE;
+ /* This means focus reverted off of a client */
+ if (detail == NotifyInferior)
+ return TRUE;
+
/* Otherwise.. */
return FALSE;
} else {
if (mode == NotifyGrab)
return FALSE;
+ /* Focus left the root window revertedto state */
+ if (win == RootWindow(ob_display, ob_screen))
+ return FALSE;
+
/* These are the ones we want.. */
/* This means focus moved from a client to the root window */
}
}
-#if 0 /* focus debugging stuff */
+#if 1 /* focus debugging stuff */
if (e->type == FocusIn || e->type == FocusOut) {
gint mode = e->xfocus.mode;
gint detail = e->xfocus.detail;
ob_debug("UNKNOWN FOCUS %s (d %d, m %d) window 0x%x\n",
(e->type == FocusIn ? "IN" : "OUT"),
detail, mode, window);
+ }
#endif
- event_set_lasttime(e);
+ event_set_curtime(e);
event_hack_mods(e);
if (event_ignore(e, client)) {
if (ed)
if (e->type == ButtonPress || e->type == ButtonRelease ||
e->type == MotionNotify)
mouse_event(client, e);
- else if (e->type == KeyPress)
+ else if (e->type == KeyPress) {
keyboard_event((focus_cycle_target ? focus_cycle_target :
(focus_hilite ? focus_hilite : client)),
e);
+ }
}
}
}
+ /* if something happens and it's not from an XEvent, then we don't know
+ the time */
+ event_curtime = CurrentTime;
}
static void event_handle_root(XEvent *e)
msgtype = e->xclient.message_type;
if (msgtype == prop_atoms.net_current_desktop) {
guint d = e->xclient.data.l[0];
+ event_curtime = e->xclient.data.l[1];
if (d < screen_num_desktops)
screen_set_desktop(d);
} else if (msgtype == prop_atoms.net_number_of_desktops) {
case FocusOut:
/* Look for the followup FocusIn */
if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) {
- /* There is no FocusIn, move focus where we can still hear events*/
- focus_set_client(NULL);
+ /* There is no FocusIn, this means focus went to a window that
+ is not being managed, or a window on another screen. */
+ ob_debug("Focus went to a black hole !\n");
} else if (ce.xany.window == e->xany.window) {
/* If focus didn't actually move anywhere, there is nothing to do*/
break;
+ } else if (ce.xfocus.detail == NotifyPointerRoot ||
+ ce.xfocus.detail == NotifyDetailNone) {
+ ob_debug("Focus went to root\n");
+ /* Focus has been reverted to the root window or nothing, so fall
+ back to something other than the window which just had it. */
+ focus_fallback(FALSE);
+ } else if (ce.xfocus.detail == NotifyInferior) {
+ ob_debug("Focus went to parent\n");
+ /* Focus has been reverted to parent, which is our frame window,
+ or the root window, so fall back to something other than the
+ window which had it. */
+ focus_fallback(FALSE);
} else {
/* Focus did move, so process the FocusIn event */
- ObEventData ed;
+ ObEventData ed = { .ignored = FALSE };
event_process(&ce, &ed);
if (ed.ignored) {
/* The FocusIn was ignored, this means it was on a window
- that isn't a client? How did this happen? */
- g_assert_not_reached();
+ that isn't a client. */
+ ob_debug("Focus went to an unmanaged window 0x%x !\n",
+ ce.xfocus.window);
+ focus_fallback(TRUE);
}
}
/* This client is no longer focused, so show that */
+ focus_hilite = NULL;
frame_adjust_focus(client->frame, FALSE);
client_calc_layer(client);
break;
}
break;
case UnmapNotify:
+ ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d "
+ "ignores left %d\n",
+ client->window, e->xunmap.event, e->xunmap.from_configure,
+ client->ignore_unmaps);
if (client->ignore_unmaps) {
client->ignore_unmaps--;
break;
client_unmanage(client);
break;
case DestroyNotify:
+ ob_debug("DestroyNotify for window 0x%x\n", client->window);
client_unmanage(client);
break;
case ReparentNotify:
X server to deal with after we unmanage the window */
XPutBackEvent(ob_display, e);
+ ob_debug("ReparentNotify for window 0x%x\n", client->window);
client_unmanage(client);
break;
case MapRequest:
it can happen now when the window is on
another desktop, but we still don't
want it! */
- client_activate(client, FALSE, TRUE, CurrentTime);
+ client_activate(client, FALSE, TRUE);
break;
case ClientMessage:
/* validate cuz we query stuff off the client here */
(e->xclient.data.l[0] == 0 ? "unknown" :
(e->xclient.data.l[0] == 1 ? "application" :
(e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
- /* XXX make use of data.l[1] and [2] ! */
+ /* XXX make use of data.l[2] ! */
+ event_curtime = e->xclient.data.l[1];
client_activate(client, FALSE,
(e->xclient.data.l[0] == 0 ||
- e->xclient.data.l[0] == 2),
- e->xclient.data.l[1]);
+ e->xclient.data.l[0] == 2));
} else if (msgtype == prop_atoms.net_wm_moveresize) {
ob_debug("net_wm_moveresize for 0x%lx direction %d\n",
client->window, e->xclient.data.l[2]);
ObClient *c = data;
if (focus_client != c) {
- client_focus(c);
- if (config_focus_raise)
- client_raise(c);
+ if (client_validate(c)) {
+ client_focus(c);
+ if (config_focus_raise)
+ client_raise(c);
+ }
}
return FALSE; /* no repeat */
}