some focus fixes. always set the new focus when we fallback or else weird states appear. better handling of focusin's on clients that don't exist?

This commit is contained in:
Dana Jansens 2007-05-13 20:35:44 +00:00
parent 1e5fb0d401
commit 7fddf2abc2
4 changed files with 26 additions and 35 deletions

View file

@ -28,7 +28,7 @@
#include "render/theme.h"
#define DOCK_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
EnterWindowMask | LeaveWindowMask)
EnterWindowMask | LeaveWindowMask | FocusChangeMask)
#define DOCKAPP_EVENT_MASK (StructureNotifyMask)
static ObDock *dock;

View file

@ -307,15 +307,26 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
return FALSE;
}
/* This means focus moved to the frame window */
if (detail == NotifyInferior && !in_client_only)
return TRUE;
/* It was on a client, was it a valid one?
It's possible to get a FocusIn event for a client that was managed
but has disappeared. Don't even parse those FocusIn events.
*/
{
ObWindow *w = g_hash_table_lookup(window_map, &e->xfocus.window);
if (!w || !WINDOW_IS_CLIENT(w))
return FALSE;
}
/* This means focus moved from the root window to a client */
if (detail == NotifyVirtual)
return TRUE;
/* This means focus moved from one client to another */
if (detail == NotifyNonlinearVirtual)
return TRUE;
/* This means focus moved to the frame window */
if (detail == NotifyInferior && !in_client_only)
return TRUE;
/* Otherwise.. */
return FALSE;
@ -356,13 +367,7 @@ static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg)
Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
{
ObWindow *w;
/* It is possible to get FocusIn events or unmanaged windows, meaning
they won't be for any known client */
return e->type == FocusIn && wanted_focusevent(e, TRUE) &&
(w = g_hash_table_lookup(window_map, &e->xfocus.window)) &&
WINDOW_IS_CLIENT(w);
return e->type == FocusIn && wanted_focusevent(e, TRUE);
}
static void print_focusevent(XEvent *e)
@ -475,6 +480,7 @@ static void event_process(const XEvent *ec, gpointer data)
e->xfocus.detail == NotifyInferior)
{
XEvent ce;
ob_debug_type(OB_DEBUG_FOCUS,
"Focus went to pointer root/none or to our frame "
"window\n");
@ -514,17 +520,6 @@ static void event_process(const XEvent *ec, gpointer data)
focus_fallback(TRUE);
}
}
else if (!client) {
/* It is possible to get FocusIn events or unmanaged windows,
meaning they won't be for any known client
If this happens, set the client to NULL so we know focus
has wandered off, and we'll get a focus out for it
shortly.
*/
ob_debug_type(OB_DEBUG_FOCUS, "Focus went to an invalid target\n");
focus_set_client(NULL);
}
else if (client != focus_client) {
focus_left_screen = FALSE;
frame_adjust_focus(client->frame, TRUE);

View file

@ -280,19 +280,15 @@ ObClient* focus_fallback(gboolean allow_refocus)
old = focus_client;
new = focus_fallback_target(allow_refocus, focus_client);
/* send focus somewhere if it is moving or if it was NULL before,
in which case it may not even be on the screen */
if (!old || new != old) {
/* unfocus any focused clients.. they can be focused by Pointer events
and such, and then when we try focus them, we won't get a FocusIn
event at all for them. */
focus_nothing();
/* unfocus any focused clients.. they can be focused by Pointer events
and such, and then when we try focus them, we won't get a FocusIn
event at all for them. */
focus_nothing();
if (new) {
client_focus(new);
/* remember that we tried to send focus here */
focus_tried = new;
}
if (new) {
client_focus(new);
/* remember that we tried to send focus here */
focus_tried = new;
}
return new;

View file

@ -42,7 +42,7 @@ int main () {
XSetWindowBackground(display,win,WhitePixel(display,0));
XMapWindow(display, win);
XFlush(display);
usleep(10000);
usleep(1000);
XDestroyWindow(display, win);
XSync(display, False);