This is relevant to graphical Java applications which require it. --- AUTHORS | 3 +++ src/ewins.c | 2 +- src/focus.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++------------- src/focus.h | 1 + src/icccm.c | 11 +++++++---- 5 files changed, 63 insertions(+), 19 deletions(-)
diff --git a/AUTHORS b/AUTHORS index d2377e4..cff2470 100644 --- a/AUTHORS +++ b/AUTHORS @@ -280,5 +280,8 @@ Aron Xu <[email protected]> Daniel Manjarres <[email protected]> Improved strut handling options, other patches and suggestions. +Tim Howe <[email protected]> + Fix focus handling to support "Globally Active" model (used by Java) + And others whose names we probably forgot to add (email us and we'll put you in here) diff --git a/src/ewins.c b/src/ewins.c index 8d51cb2..5c6e240 100644 --- a/src/ewins.c +++ b/src/ewins.c @@ -703,7 +703,7 @@ EwinStateUpdate(EWin * ewin) fs_zo = ewin->state.fullscreen || ewin->state.zoomed; ewin->state.inhibit_actions = ewin->props.no_actions; - ewin->state.inhibit_focus = !ewin->icccm.need_input || + ewin->state.inhibit_focus = !(ewin->icccm.need_input || ewin->icccm.take_focus) || EwinInhGetWM(ewin, focus) || ewin->state.iconified; ewin->state.inhibit_move = EwinInhGetUser(ewin, move) || fs_zo; diff --git a/src/focus.c b/src/focus.c index 9e497b6..0217dce 100644 --- a/src/focus.c +++ b/src/focus.c @@ -309,12 +309,13 @@ doFocusToEwin(EWin * ewin, int why) case FOCUS_ENTER: case FOCUS_LEAVE: /* Unused */ case FOCUS_CLICK: + if (ewin && !FocusEwinValid(ewin, 1, why == FOCUS_CLICK, 0)) + return; + case FOCUS_SERVER: if (ewin && ewin == Mode.focuswin) return; if (!ewin) /* Unfocus */ break; - if (!FocusEwinValid(ewin, 1, why == FOCUS_CLICK, 0)) - return; break; case FOCUS_INIT: @@ -388,6 +389,8 @@ doFocusToEwin(EWin * ewin, int why) if (ewin == Mode.focuswin && focus_is_set) return; + do_focus = !ewin || ewin->icccm.need_input || why == FOCUS_SERVER; + /* Check if ewin is a valid focus window target */ if (!ewin) @@ -432,15 +435,21 @@ doFocusToEwin(EWin * ewin, int why) break; } - SoundPlay(SOUND_FOCUS_SET); + if (do_focus) + SoundPlay(SOUND_FOCUS_SET); done: ClickGrabsUpdate(); - /* Unset old focus window (if any) highlighting */ - if (Mode.focuswin) - FocusEwinSetActive(Mode.focuswin, 0); - ICCCM_Cmap(ewin); + if (do_focus) + { + /* Unset old focus window (if any) highlighting */ + if (Mode.focuswin) + FocusEwinSetActive(Mode.focuswin, 0); + + /* Set the colormap for the new focus window (if any) */ + ICCCM_Cmap(ewin); + } /* Quit if pointer is not on our screen */ @@ -450,16 +459,25 @@ doFocusToEwin(EWin * ewin, int why) return; } - /* Set new focus window (if any) highlighting */ - Mode.focuswin = ewin; - if (Mode.focuswin) - FocusEwinSetActive(Mode.focuswin, 1); + if (do_focus) + { + /* Set new focus window (if any) highlighting */ + Mode.focuswin = ewin; + if (Mode.focuswin) + FocusEwinSetActive(Mode.focuswin, 1); + } if (why == FOCUS_DESK_LEAVE) return; - ICCCM_Focus(ewin); - focus_is_set = 1; + /* Make sure this isn't a notification of existing focus. */ + if (why == FOCUS_SERVER) + HintsSetActiveWindow(EwinGetClientXwin(ewin)); + else + ICCCM_Focus(ewin); + + if (do_focus) + focus_is_set = 1; } void @@ -485,6 +503,7 @@ FocusToEWin(EWin * ewin, int why) default: if (ewin && !FocusEwinValid(ewin, 0, why == FOCUS_CLICK, 0)) break; + case FOCUS_SERVER: focus_pending_why = why; focus_pending_ewin = ewin; break; @@ -683,8 +702,26 @@ FocusHandleLeave(EWin * ewin, XEvent * ev) } void -FocusHandleChange(EWin * ewin __UNUSED__, XEvent * ev __UNUSED__) +FocusHandleChange(EWin * ewin, XEvent * ev) { + if (EDebug(EDBUG_TYPE_FOCUS)) + Eprintf("%s - %#lx (%s)\n", + (ev->type == FocusIn) ? "FocusIn" : "FocusOut", + (ewin) ? EwinGetClientXwin(ewin) : 0, + (ewin) ? EwinGetTitle(ewin) : "None"); + + if ((int)ev->xcrossing.serial - focus_request < 0) + { + /* This event was caused by a request older than the latest + * focus assignment request - ignore */ + if (EDebug(EDBUG_TYPE_FOCUS)) + Eprintf("FocusHandleChange: Ignore serial < %#x\n", focus_request); + return; + } + + if (ev->type == FocusIn && ewin != Mode.focuswin) + FocusToEWin(ewin, FOCUS_SERVER); + #if 0 /* Debug */ if (ewin == Mode.focuswin && ev->type == FocusOut) Eprintf("??? Lost focus: %s\n", EwinGetTitle(ewin)); diff --git a/src/focus.h b/src/focus.h index 031b08e..f5196ea 100644 --- a/src/focus.h +++ b/src/focus.h @@ -40,6 +40,7 @@ #define FOCUS_NEXT 10 #define FOCUS_PREV 11 #define FOCUS_CLICK 12 +#define FOCUS_SERVER 13 void FocusEnable(int on); void FocusToEWin(EWin * ewin, int why); diff --git a/src/icccm.c b/src/icccm.c index 1279c29..2a349a9 100644 --- a/src/icccm.c +++ b/src/icccm.c @@ -402,10 +402,13 @@ ICCCM_Focus(const EWin * ewin) Mode.events.time); } - XSetInputFocus(disp, EwinGetClientXwin(ewin), RevertToPointerRoot, - Mode.events.time); + if (ewin->icccm.need_input) + { + XSetInputFocus(disp, EwinGetClientXwin(ewin), RevertToPointerRoot, + Mode.events.time); - HintsSetActiveWindow(EwinGetClientXwin(ewin)); + HintsSetActiveWindow(EwinGetClientXwin(ewin)); + } } void @@ -717,7 +720,7 @@ ICCCM_GetWmProtocols(EWin * ewin) for (i = 0; i < num; i++) { if (prop[i] == ECORE_X_ATOM_WM_TAKE_FOCUS) - ewin->icccm.take_focus = ewin->icccm.need_input = 1; + ewin->icccm.take_focus = 1; else if (prop[i] == ECORE_X_ATOM_WM_DELETE_WINDOW) ewin->icccm.delete_window = 1; #if USE_XSYNC -- 1.8.1 ------------------------------------------------------------------------------ Minimize network downtime and maximize team effectiveness. Reduce network management and security costs.Learn how to hire the most talented Cisco Certified professionals. Visit the Employer Resources Portal http://www.cisco.com/web/learning/employer_resources/index.html _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
