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

Reply via email to