From 4439b3f9b17e9c8bd9682ce967631f03249304bf Mon Sep 17 00:00:00 2001
From: rathnor <rathnor>
Date: Wed, 28 Apr 2004 14:59:12 +0000
Subject: fixes for/reimplement parts of directional focus movement

---
 ChangeLog               |  5 ++++-
 src/FbCommandFactory.cc | 14 +++++++++++++-
 src/Screen.cc           | 10 +++++++---
 src/Screen.hh           |  4 ++--
 src/WinClient.cc        |  8 +++++++-
 src/WinClient.hh        |  3 ++-
 src/WorkspaceCmd.cc     | 15 ++++++++++++++-
 src/WorkspaceCmd.hh     | 11 ++++++++++-
 8 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bc98ae0..bb8453c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
 (Format: Year/Month/Day)
 Changes for 0.9.10:
 *04/04/28:
+  * Fix key bindings for directional focus movement (Simon)
+    - reminder, key actions are: FocusUp, FocusDown, FocusLeft, FocusRight
+    WorkspaceCmd.hh/cc Screen.hh/cc WinClient.hh/cc FbCommandFactory.cc
   * Add apps file matching on WM_WINDOW_ROLE (Simon)
-    - use "role=string". Particularly useful for gaim windows
+    - use "role=string". Particularly useful for gaim+gimp windows
       [app] (role=buddy_list) ...
     ClientPattern.hh/cc FbWindow.hh/cc
 *04/04/27:
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
index 9853b50..b578759 100644
--- a/src/FbCommandFactory.cc
+++ b/src/FbCommandFactory.cc
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: FbCommandFactory.cc,v 1.29 2004/04/22 21:12:34 fluxgen Exp $
+// $Id: FbCommandFactory.cc,v 1.30 2004/04/28 14:59:11 rathnor Exp $
 
 #include "FbCommandFactory.hh"
 
@@ -69,6 +69,10 @@ FbCommandFactory::FbCommandFactory() {
         "exec",
         "execcommand",
         "execute",
+        "focusup",
+        "focusdown",
+        "focusleft",
+        "focusright",
         "iconify",
         "killwindow",
         "leftworkspace",
@@ -276,6 +280,14 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
         return new NextWindowCmd(atoi(arguments.c_str()));
     else if (command == "prevwindow")
         return new PrevWindowCmd(atoi(arguments.c_str()));
+    else if (command == "focusup")
+        return new DirFocusCmd(BScreen::FOCUSUP);
+    else if (command == "focusdown")
+        return new DirFocusCmd(BScreen::FOCUSDOWN);
+    else if (command == "focusleft")
+        return new DirFocusCmd(BScreen::FOCUSLEFT);
+    else if (command == "focusright")
+        return new DirFocusCmd(BScreen::FOCUSRIGHT);
     else if (command == "nextgroup")
         return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
     else if (command == "prevgroup")
diff --git a/src/Screen.cc b/src/Screen.cc
index eef61c4..f815f3a 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Screen.cc,v 1.275 2004/04/19 22:44:42 fluxgen Exp $
+// $Id: Screen.cc,v 1.276 2004/04/28 14:59:11 rathnor Exp $
 
 
 #include "Screen.hh"
@@ -1640,7 +1640,7 @@ void BScreen::setFocusedWindow(WinClient &winclient) {
     }
 }
 
-void BScreen::dirFocus(FluxboxWindow &win, FocusDir dir) {
+void BScreen::dirFocus(FluxboxWindow &win, const FocusDir dir) {
     // change focus to the window in direction dir from the given window
 
     // we scan through the list looking for the window that is "closest"
@@ -1657,7 +1657,11 @@ void BScreen::dirFocus(FluxboxWindow &win, FocusDir dir) {
     Workspace::Windows &wins = currentWorkspace()->windowList();
     Workspace::Windows::iterator it = wins.begin();
     for (; it != wins.end(); ++it) {
-        if ((*it) == &win) continue; // skip slef
+        if ((*it) == &win 
+            || (*it)->isIconic() 
+            || (*it)->isFocusHidden() 
+            || !(*it)->winClient().acceptsFocus()) 
+            continue; // skip self
         
         // we check things against an edge, and within the bounds (draw a picture)
         int edge=0, upper=0, lower=0, oedge=0, oupper=0, olower=0;
diff --git a/src/Screen.hh b/src/Screen.hh
index cb08d06..381eea5 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Screen.hh,v 1.139 2004/04/19 22:44:42 fluxgen Exp $
+// $Id: Screen.hh,v 1.140 2004/04/28 14:59:11 rathnor Exp $
 
 #ifndef	 SCREEN_HH
 #define	 SCREEN_HH
@@ -259,7 +259,7 @@ public:
     void setFocusedWindow(WinClient &winclient);
 
 
-    void dirFocus(FluxboxWindow &win, FocusDir dir);
+    void dirFocus(FluxboxWindow &win, const FocusDir dir);
 
     void reconfigure();	
     void rereadMenu();
diff --git a/src/WinClient.cc b/src/WinClient.cc
index 2265f2f..3911d6c 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: WinClient.cc,v 1.38 2004/04/01 14:06:42 rathnor Exp $
+// $Id: WinClient.cc,v 1.39 2004/04/28 14:59:12 rathnor Exp $
 
 #include "WinClient.hh"
 
@@ -147,6 +147,12 @@ void WinClient::updateRect(int x, int y,
 
 }
 
+bool WinClient::acceptsFocus() const {
+    return (m_focus_mode == F_LOCALLYACTIVE || 
+            m_focus_mode == F_PASSIVE || 
+            m_focus_mode == F_GLOBALLYACTIVE && send_focus_message);
+}
+
 bool WinClient::sendFocus() {
     if (!send_focus_message)
         return false;
diff --git a/src/WinClient.hh b/src/WinClient.hh
index a3fa8d9..af912e1 100644
--- a/src/WinClient.hh
+++ b/src/WinClient.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: WinClient.hh,v 1.16 2003/12/17 01:20:49 fluxgen Exp $
+// $Id: WinClient.hh,v 1.17 2004/04/28 14:59:12 rathnor Exp $
 
 #ifndef WINCLIENT_HH
 #define WINCLIENT_HH
@@ -54,6 +54,7 @@ public:
 
     bool sendFocus(); // returns whether we sent a message or not 
                       // i.e. whether we assume the focus will get taken
+    bool acceptsFocus() const; // will this window accept focus (according to hints)
     void sendClose(bool forceful = false);
     // not aware of anything that makes this false at present
     inline bool isClosable() const { return true; }
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 33ff818..946f84b 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -20,7 +20,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: WorkspaceCmd.cc,v 1.10 2004/01/16 09:21:31 fluxgen Exp $
+// $Id: WorkspaceCmd.cc,v 1.11 2004/04/28 14:59:12 rathnor Exp $
 
 #include "WorkspaceCmd.hh"
 
@@ -28,6 +28,7 @@
 #include "Window.hh"
 #include "Screen.hh"
 #include "fluxbox.hh"
+#include "WinClient.hh"
 
 #include "FbTk/KeyUtil.hh"
 
@@ -79,6 +80,18 @@ void PrevWindowCmd::execute() {
     }
 }
 
+void DirFocusCmd::execute() {
+    BScreen *screen = Fluxbox::instance()->keyScreen();
+    if (screen == 0)
+        return;
+
+    WinClient *client = Fluxbox::instance()->getFocusedWindow();
+    if (client == 0 || client->fbwindow() == 0)
+        return;
+
+    screen->dirFocus(*client->fbwindow(), m_dir);
+}
+
 void NextWorkspaceCmd::execute() {
     BScreen *screen = Fluxbox::instance()->mouseScreen();
     if (screen != 0)
diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh
index 8a23bff..9a9c960 100644
--- a/src/WorkspaceCmd.hh
+++ b/src/WorkspaceCmd.hh
@@ -20,11 +20,12 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: WorkspaceCmd.hh,v 1.2 2003/07/01 09:47:41 fluxgen Exp $
+// $Id: WorkspaceCmd.hh,v 1.3 2004/04/28 14:59:12 rathnor Exp $
 
 #ifndef WORKSPACECMD_HH
 #define WORKSPACECMD_HH
 #include "Command.hh"
+#include "Screen.hh"
 
 class NextWindowCmd: public FbTk::Command {
 public:
@@ -42,6 +43,14 @@ private:
     const int m_option;
 };
 
+class DirFocusCmd: public FbTk::Command {
+public:
+    explicit DirFocusCmd(const BScreen::FocusDir dir): m_dir(dir) { }
+    void execute();
+private:
+    const BScreen::FocusDir m_dir;
+};
+
 class NextWorkspaceCmd: public FbTk::Command {
 public:
     void execute();
-- 
cgit v0.11.2