X-Git-Url: https://git.decadent.org.uk/gitweb/?p=ion3.git;a=blobdiff_plain;f=ioncore%2Ffocus.c;h=ee3fd86ab796625077e6101b5b8460bdf2d9cc1b;hp=c25ec716ff1750906c2a9ad50927eccca32f0cb9;hb=HEAD;hpb=471a5e5f9928e2d324b2e10422a420f458bd63ff diff --git a/ioncore/focus.c b/ioncore/focus.c index c25ec71..ee3fd86 100644 --- a/ioncore/focus.c +++ b/ioncore/focus.c @@ -1,12 +1,9 @@ /* * ion/ioncore/focus.c * - * Copyright (c) Tuomo Valkonen 1999-2007. + * Copyright (c) Tuomo Valkonen 1999-2009. * - * 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 @@ -104,7 +101,8 @@ WRegion *ioncore_goto_previous() /*EXTL_DOC * Iterate over focus history until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_EXPORT @@ -166,10 +164,8 @@ void region_set_await_focus(WRegion *reg) } -static bool region_is_await(WRegion *reg) +static bool region_is_parent(WRegion *reg, WRegion *aw) { - WRegion *aw=(WRegion*)await_watch.obj; - while(aw!=NULL){ if(aw==reg) return TRUE; @@ -180,6 +176,18 @@ static bool region_is_await(WRegion *reg) } +static bool region_is_await(WRegion *reg) +{ + return region_is_parent(reg, (WRegion*)await_watch.obj); +} + + +static bool region_is_focusnext(WRegion *reg) +{ + return region_is_parent(reg, ioncore_g.focus_next); +} + + /* Only keep await status if focus event is to an ancestor of the await * region. */ @@ -293,9 +301,22 @@ void region_lost_focus(WRegion *reg) */ EXTL_SAFE EXTL_EXPORT_MEMBER -bool region_is_active(WRegion *reg) +bool region_is_active(WRegion *reg, bool pseudoact_ok) { - return REGION_IS_ACTIVE(reg); + return (REGION_IS_ACTIVE(reg) || + (pseudoact_ok && REGION_IS_PSEUDOACTIVE(reg))); +} + + +bool region_manager_is_focusnext(WRegion *reg) +{ + if(reg==NULL || ioncore_g.focus_next==NULL) + return FALSE; + + if(reg==ioncore_g.focus_next) + return TRUE; + + return region_manager_is_focusnext(REGION_MANAGER(reg)); } @@ -306,8 +327,11 @@ bool region_may_control_focus(WRegion *reg) if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg)) return TRUE; - - if(region_is_await(reg)) + + if(region_is_await(reg) || region_is_focusnext(reg)) + return TRUE; + + if(region_manager_is_focusnext(reg)) return TRUE; return FALSE; @@ -328,6 +352,9 @@ void region_finalise_focusing(WRegion* reg, Window win, bool warp) if(warp) region_do_warp(reg); + if(REGION_IS_ACTIVE(reg) && ioncore_await_focus()==NULL) + return; + region_set_await_focus(reg); /*xwindow_do_set_focus(win);*/ XSetInputFocus(ioncore_g.dpy, win, RevertToParent, @@ -388,6 +415,7 @@ void region_do_warp(WRegion *reg) void region_maybewarp(WRegion *reg, bool warp) { ioncore_g.focus_next=reg; + ioncore_g.focus_next_source=IONCORE_FOCUSNEXT_OTHER; ioncore_g.warp_next=(warp && ioncore_g.warp_enabled); } @@ -396,7 +424,7 @@ void region_maybewarp_now(WRegion *reg, bool warp) { ioncore_g.focus_next=NULL; /* TODO: what if focus isn't set? Should focus_next be reset then? */ - region_do_set_focus(reg, warp); + region_do_set_focus(reg, warp && ioncore_g.warp_enabled); } @@ -450,34 +478,33 @@ WRegion *ioncore_current() */ void region_pointer_focus_hack(WRegion *reg) { - WRegion *act=ioncore_await_focus(); - const WRectangle *g=®ION_GEOM(reg); - int x, y; + WRegion *act; if(ioncore_g.opmode!=IONCORE_OPMODE_NORMAL) return; - - if(!REGION_IS_ACTIVE(reg) && act==NULL) - act=ioncore_g.focus_current; - if(act==NULL || OBJ_IS_BEING_DESTROYED(act)) + if(ioncore_g.focus_next!=NULL && + ioncore_g.focus_next_source<=IONCORE_FOCUSNEXT_POINTERHACK){ return; - - /* Ok, anything under us should not get focus as we're unmapped: - * Either we don't have the focus, or focus change somewhere else - * is pending. - * - * It might be possible to do the pointer check more efficiently - * by trying to maintain our internal pointer containment state - * by tracking Enter/Leave events... - */ + } - xwindow_pointer_pos(region_xwindow(reg), &x, &y); + act=ioncore_await_focus(); + + if((REGION_IS_ACTIVE(reg) && act==NULL) || !region_is_fully_mapped(reg)) + return; - if(x>=0 && y>=0 && xw && yh){ - D(fprintf(stderr, "Pointer here and shouldn't alter focus!\n")); - region_set_focus(act); + if(act==NULL) + act=ioncore_g.focus_current; + + if(act==NULL || + OBJ_IS_BEING_DESTROYED(act) || + !region_is_fully_mapped(act) || + region_skip_focus(act)){ + return; } + + region_set_focus(act); + ioncore_g.focus_next_source=IONCORE_FOCUSNEXT_POINTERHACK; }