]> git.decadent.org.uk Git - ion3.git/blobdiff - ioncore/eventh.c
[svn-upgrade] Integrating new upstream version, ion3 (20070318)
[ion3.git] / ioncore / eventh.c
index 5e1e1fe81d9439dafebb3e4b77548b6ec725e68f..0a9a57a05bc4a1ca648cbaf5527b4ae8005190c8 100644 (file)
@@ -63,7 +63,7 @@ bool ioncore_handle_event(XEvent *ev)
         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));
@@ -305,14 +305,17 @@ void ioncore_handle_expose(const XExposeEvent *ev)
 /*{{{ 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)
@@ -323,7 +326,12 @@ static void do_handle_enter_window(XEvent *ev)
         
     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.)
@@ -337,20 +345,11 @@ static void do_handle_enter_window(XEvent *ev)
         }
     }
     
-    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;
+    }
 }
 
 
@@ -367,8 +366,7 @@ static bool pointer_in_root(Window root1)
 }
 
 
-
-void ioncore_handle_focus_in(const XFocusChangeEvent *ev, bool skip)
+void ioncore_handle_focus_in(const XFocusChangeEvent *ev)
 {
     WRegion *reg;
     WWindow *wwin;
@@ -386,18 +384,6 @@ void ioncore_handle_focus_in(const XFocusChangeEvent *ev, bool skip)
     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;
@@ -409,6 +395,25 @@ void ioncore_handle_focus_in(const XFocusChangeEvent *ev, bool skip)
         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;
+    }
 }
 
 
@@ -496,7 +501,7 @@ void ioncore_handle_buttonpress(XEvent *ev)
             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));