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:
parent
1e5fb0d401
commit
7fddf2abc2
4 changed files with 26 additions and 35 deletions
|
@ -28,7 +28,7 @@
|
||||||
#include "render/theme.h"
|
#include "render/theme.h"
|
||||||
|
|
||||||
#define DOCK_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
|
#define DOCK_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
|
||||||
EnterWindowMask | LeaveWindowMask)
|
EnterWindowMask | LeaveWindowMask | FocusChangeMask)
|
||||||
#define DOCKAPP_EVENT_MASK (StructureNotifyMask)
|
#define DOCKAPP_EVENT_MASK (StructureNotifyMask)
|
||||||
|
|
||||||
static ObDock *dock;
|
static ObDock *dock;
|
||||||
|
|
|
@ -307,15 +307,26 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
|
||||||
return FALSE;
|
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 */
|
/* This means focus moved from the root window to a client */
|
||||||
if (detail == NotifyVirtual)
|
if (detail == NotifyVirtual)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* This means focus moved from one client to another */
|
/* This means focus moved from one client to another */
|
||||||
if (detail == NotifyNonlinearVirtual)
|
if (detail == NotifyNonlinearVirtual)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* This means focus moved to the frame window */
|
|
||||||
if (detail == NotifyInferior && !in_client_only)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Otherwise.. */
|
/* Otherwise.. */
|
||||||
return FALSE;
|
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)
|
Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
|
||||||
{
|
{
|
||||||
ObWindow *w;
|
return e->type == FocusIn && wanted_focusevent(e, TRUE);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_focusevent(XEvent *e)
|
static void print_focusevent(XEvent *e)
|
||||||
|
@ -475,6 +480,7 @@ static void event_process(const XEvent *ec, gpointer data)
|
||||||
e->xfocus.detail == NotifyInferior)
|
e->xfocus.detail == NotifyInferior)
|
||||||
{
|
{
|
||||||
XEvent ce;
|
XEvent ce;
|
||||||
|
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug_type(OB_DEBUG_FOCUS,
|
||||||
"Focus went to pointer root/none or to our frame "
|
"Focus went to pointer root/none or to our frame "
|
||||||
"window\n");
|
"window\n");
|
||||||
|
@ -514,17 +520,6 @@ static void event_process(const XEvent *ec, gpointer data)
|
||||||
focus_fallback(TRUE);
|
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) {
|
else if (client != focus_client) {
|
||||||
focus_left_screen = FALSE;
|
focus_left_screen = FALSE;
|
||||||
frame_adjust_focus(client->frame, TRUE);
|
frame_adjust_focus(client->frame, TRUE);
|
||||||
|
|
|
@ -280,19 +280,15 @@ ObClient* focus_fallback(gboolean allow_refocus)
|
||||||
old = focus_client;
|
old = focus_client;
|
||||||
new = focus_fallback_target(allow_refocus, focus_client);
|
new = focus_fallback_target(allow_refocus, focus_client);
|
||||||
|
|
||||||
/* send focus somewhere if it is moving or if it was NULL before,
|
/* unfocus any focused clients.. they can be focused by Pointer events
|
||||||
in which case it may not even be on the screen */
|
and such, and then when we try focus them, we won't get a FocusIn
|
||||||
if (!old || new != old) {
|
event at all for them. */
|
||||||
/* unfocus any focused clients.. they can be focused by Pointer events
|
focus_nothing();
|
||||||
and such, and then when we try focus them, we won't get a FocusIn
|
|
||||||
event at all for them. */
|
|
||||||
focus_nothing();
|
|
||||||
|
|
||||||
if (new) {
|
if (new) {
|
||||||
client_focus(new);
|
client_focus(new);
|
||||||
/* remember that we tried to send focus here */
|
/* remember that we tried to send focus here */
|
||||||
focus_tried = new;
|
focus_tried = new;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
|
|
|
@ -42,7 +42,7 @@ int main () {
|
||||||
XSetWindowBackground(display,win,WhitePixel(display,0));
|
XSetWindowBackground(display,win,WhitePixel(display,0));
|
||||||
XMapWindow(display, win);
|
XMapWindow(display, win);
|
||||||
XFlush(display);
|
XFlush(display);
|
||||||
usleep(10000);
|
usleep(1000);
|
||||||
XDestroyWindow(display, win);
|
XDestroyWindow(display, win);
|
||||||
XSync(display, False);
|
XSync(display, False);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue