*
* Copyright (c) Tuomo Valkonen 1999-2007.
*
- * Ion is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
*/
#include <stdlib.h>
ioncore_handle_property(&(ev->xproperty));
break;
CASE_EVENT(FocusIn)
- ioncore_handle_focus_in(&(ev->xfocus), FALSE);
+ ioncore_handle_focus_in(&(ev->xfocus));
break;
CASE_EVENT(FocusOut)
ioncore_handle_focus_out(&(ev->xfocus));
/*{{{ Enter window, focus */
-static void do_handle_enter_window(XEvent *ev)
+void ioncore_handle_enter_window(XEvent *ev)
{
XEnterWindowEvent *eev=&(ev->xcrossing);
WRegion *reg=NULL;
if(ioncore_g.input_mode!=IONCORE_INPUTMODE_NORMAL)
return;
-
+
+ if(eev->mode!=NotifyNormal && !ioncore_g.warp_enabled)
+ return;
+
reg=XWINDOW_REGION_OF_T(eev->window, WRegion);
if(reg==NULL)
if(region_skip_focus(reg))
return;
-
+
+ if(ioncore_g.focus_next!=NULL &&
+ ioncore_g.focus_next_source<IONCORE_FOCUSNEXT_ENTERWINDOW){
+ return;
+ }
+
/* If a child of 'reg' is to be focused, do not process this
* event. (ioncore_g.focus_next should only be set here by
* another call to use from ioncore_handle_enter_window below.)
}
}
- region_goto_flags(reg, (REGION_GOTO_FOCUS|
- REGION_GOTO_NOWARP|
- REGION_GOTO_ENTERWINDOW));
-}
-
-
-void ioncore_handle_enter_window(XEvent *ev)
-{
- do{
- /* *sigh*, it doesn't seem reasonably simply possible to
- * process events in-order.
- */
- do_handle_enter_window(ev);
- }while(XCheckMaskEvent(ioncore_g.dpy, EnterWindowMask, ev));
+ if(region_goto_flags(reg, (REGION_GOTO_FOCUS|
+ REGION_GOTO_NOWARP|
+ REGION_GOTO_ENTERWINDOW))){
+ ioncore_g.focus_next_source=IONCORE_FOCUSNEXT_ENTERWINDOW;
+ }
}
}
-
-void ioncore_handle_focus_in(const XFocusChangeEvent *ev, bool skip)
+void ioncore_handle_focus_in(const XFocusChangeEvent *ev)
{
WRegion *reg;
WWindow *wwin;
if(ev->detail==NotifyPointer)
return;
- if(ev->window==region_root_of(reg)){ /* OBJ_IS(reg, WRootWin) */
- D(fprintf(stderr, "scr-in %d %d %d\n", ROOTWIN_OF(reg)->xscr,
- ev->mode, ev->detail));
- if((ev->detail==NotifyPointerRoot || ev->detail==NotifyDetailNone) &&
- pointer_in_root(ev->window) && ioncore_g.focus_next==NULL){
- /* Restore focus */
- if(!skip)
- region_set_focus(reg);
- return;
- }
- }
-
/* Input contexts */
if(OBJ_IS(reg, WWindow)){
wwin=(WWindow*)reg;
netwm_set_active(reg);
region_got_focus(reg);
+
+ if(ioncore_g.focus_next!=NULL &&
+ ioncore_g.focus_next_source<IONCORE_FOCUSNEXT_FALLBACK){
+ return;
+ }
+
+ if((ev->detail==NotifyPointerRoot || ev->detail==NotifyDetailNone)
+ && ev->window==region_root_of(reg) /* OBJ_IS(reg, WRootWin) */){
+ /* Restore focus if it was returned to a root window and we don't
+ * know of a pending focus change.
+ */
+ if(pointer_in_root(ev->window)){
+ region_set_focus(reg);
+ ioncore_g.focus_next_source=IONCORE_FOCUSNEXT_FALLBACK;
+ }
+ }else{
+ /* Something got the focus, don't use fallback. */
+ ioncore_g.focus_next=NULL;
+ }
}
ioncore_handle_grabs(ev);
break;
CASE_EVENT(FocusIn)
- ioncore_handle_focus_in(&(ev->xfocus), FALSE);
+ ioncore_handle_focus_in(&(ev->xfocus));
break;
CASE_EVENT(FocusOut)
ioncore_handle_focus_out(&(ev->xfocus));