From cdbaf5c04d07e8310c661e12e354724a619e5911 Mon Sep 17 00:00:00 2001
From: Jim Ramsay <jim.ramsay@motorola.com>
Date: Fri, 28 May 2010 13:22:13 -0400
Subject: Add new focus model: StrictMouseFocus

This is not actually implemented yet, but from now on, "MouseFocus" means:
  Focus follows mouse only when you are moving the mouse, any EnterNotify events
  caused by non-mouse operations (window closing, keycommands, changing
  desktops) will *not* shift focus

And once fully-implemented, "StrictMouseFocus" will mean:
  Focus follows mouse on every EnterNotify event (except when the "ClientMenu"
  closes or during alt+tab window cycling)
---
 doc/asciidoc/fluxbox.txt |  6 ++++--
 doc/fluxbox.1.in         | 10 +++++-----
 nls/fluxbox-nls.hh       |  1 +
 src/FocusControl.cc      |  5 +++++
 src/FocusControl.hh      |  7 ++++---
 src/Screen.cc            |  7 ++++++-
 6 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/doc/asciidoc/fluxbox.txt b/doc/asciidoc/fluxbox.txt
index a324336..22d07ac 100644
--- a/doc/asciidoc/fluxbox.txt
+++ b/doc/asciidoc/fluxbox.txt
@@ -1001,10 +1001,12 @@ This specifies the width of external tabs in pixels.
 +
 Default: *64*
 
-*session.screen0.focusModel*: *ClickToFocus|MouseFocus*::
+*session.screen0.focusModel*: *ClickToFocus|MouseFocus|StrictMouseFocus*::
 This controls how windows gain focus via the mouse. With `ClickToFocus',
 the user must click on the window. With `MouseFocus', windows gain focus
-whenever the mouse moves over them.
+whenever the mouse moves over them, but only when the mouse is moving. With
+`StrictMouseFocus', windows gain focus whenever the mouse enters any exposed
+area, even if this is due to layer changes, window movement, changing desktops, closing windows, etc.
 +
 Default: *ClickToFocus*
       
diff --git a/doc/fluxbox.1.in b/doc/fluxbox.1.in
index 7e36b8c..c65545f 100644
--- a/doc/fluxbox.1.in
+++ b/doc/fluxbox.1.in
@@ -1,13 +1,13 @@
 '\" t
 .\"     Title: fluxbox
 .\"    Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.1 <http://docbook.sf.net/>
-.\"      Date: 01/14/2010
+.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\"      Date: 05/28/2010
 .\"    Manual: Fluxbox Manual
 .\"    Source: fluxbox.txt
 .\"  Language: English
 .\"
-.TH "FLUXBOX" "1" "01/14/2010" "fluxbox\&.txt" "Fluxbox Manual"
+.TH "FLUXBOX" "1" "05/28/2010" "fluxbox\&.txt" "Fluxbox Manual"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -1693,9 +1693,9 @@ Default:
 \fB64\fR
 .RE
 .PP
-\fBsession\&.screen0\&.focusModel\fR: \fBClickToFocus|MouseFocus\fR
+\fBsession\&.screen0\&.focusModel\fR: \fBClickToFocus|MouseFocus|StrictMouseFocus\fR
 .RS 4
-This controls how windows gain focus via the mouse\&. With \(oqClickToFocus\(cq, the user must click on the window\&. With \(oqMouseFocus\(cq, windows gain focus whenever the mouse moves over them\&.
+This controls how windows gain focus via the mouse\&. With \(oqClickToFocus\(cq, the user must click on the window\&. With \(oqMouseFocus\(cq, windows gain focus whenever the mouse moves over them, but only when the mouse is moving\&. With \(oqStrictMouseFocus\(cq, windows gain focus whenever the mouse enters any exposed area, even if this is due to layer changes, window movement, changing desktops, closing windows, etc\&.
 .sp
 Default:
 \fBClickToFocus\fR
diff --git a/nls/fluxbox-nls.hh b/nls/fluxbox-nls.hh
index 7e461ca..7ddc978 100644
--- a/nls/fluxbox-nls.hh
+++ b/nls/fluxbox-nls.hh
@@ -84,6 +84,7 @@ enum {
         ConfigmenuMaxIgnoreInc = 27,
         ConfigmenuMaxDisableMove = 28,
         ConfigmenuMaxDisableResize = 29,
+	ConfigmenuStrictMouseFocus = 30,
 
 	EwmhSet = 5,
 	EwmhOutOfMemoryClientList = 1,
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index 3ba9dc6..eeacc3b 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -489,6 +489,7 @@ void FocusControl::revertFocus(BScreen &screen) {
         else {
             switch (screen.focusControl().focusModel()) {
             case FocusControl::MOUSEFOCUS:
+            case FocusControl::STRICTMOUSEFOCUS:
                 XSetInputFocus(screen.rootWindow().display(),
                                PointerRoot, None, CurrentTime);
                 break;
@@ -593,6 +594,8 @@ std::string FbTk::Resource<FocusControl::FocusModel>::getString() const {
     switch (m_value) {
     case FocusControl::MOUSEFOCUS:
         return string("MouseFocus");
+    case FocusControl::STRICTMOUSEFOCUS:
+        return string("StrictMouseFocus");
     case FocusControl::CLICKFOCUS:
         return string("ClickFocus");
     }
@@ -605,6 +608,8 @@ void FbTk::Resource<FocusControl::FocusModel>::
 setFromString(char const *strval) {
     if (strcasecmp(strval, "MouseFocus") == 0)
         m_value = FocusControl::MOUSEFOCUS;
+    else if (strcasecmp(strval, "StrictMouseFocus") == 0)
+        m_value = FocusControl::STRICTMOUSEFOCUS;
     else if (strcasecmp(strval, "ClickToFocus") == 0)
         m_value = FocusControl::CLICKFOCUS;
     else
diff --git a/src/FocusControl.hh b/src/FocusControl.hh
index 91681ab..72eec11 100644
--- a/src/FocusControl.hh
+++ b/src/FocusControl.hh
@@ -42,8 +42,9 @@ public:
     typedef std::list<Focusable *> Focusables;
     /// main focus model
     enum FocusModel { 
-        MOUSEFOCUS = 0, ///< focus follows mouse
-        CLICKFOCUS      ///< focus on click
+        MOUSEFOCUS = 0,  ///< focus follows mouse, but only when the mouse is moving
+        CLICKFOCUS,      ///< focus on click
+        STRICTMOUSEFOCUS ///< focus always follows mouse, even when stationary
     };
     /// focus model for tabs
     enum TabFocusModel { 
@@ -90,7 +91,7 @@ public:
      */
     void dirFocus(FluxboxWindow &win, FocusDir dir);
     /// @return true if focus mode is mouse focus
-    bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; }
+    bool isMouseFocus() const { return focusModel() != CLICKFOCUS; }
     /// @return true if tab focus mode is mouse tab focus
     bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; }
 
diff --git a/src/Screen.cc b/src/Screen.cc
index b712b81..44649c0 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -1555,8 +1555,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
                "Click To Focus", "Click to focus",
                FocusControl::CLICKFOCUS);
     _FOCUSITEM(Configmenu, MouseFocus,
-               "Mouse Focus", "Mouse Focus",
+               "Mouse Focus (Keyboard Friendly)",
+               "Mouse Focus (Keyboard Friendly)",
                FocusControl::MOUSEFOCUS);
+    _FOCUSITEM(Configmenu, StrictMouseFocus,
+               "Mouse Focus (Strict)",
+               "Mouse Focus (Strict)",
+               FocusControl::STRICTMOUSEFOCUS);
 #undef _FOCUSITEM
 
     focus_menu->insert(new FbTk::MenuSeparator());
-- 
cgit v0.11.2