From 2a1bc27e90ae96f14a2fc0164fef074974023389 Mon Sep 17 00:00:00 2001 From: rathnor Date: Sun, 20 Apr 2003 12:21:35 +0000 Subject: add directional focus movement (Simon) incl new keybindings FocusUp, FocusDown, FocusLeft, FocusRight --- ChangeLog | 2 ++ RoadMap | 2 +- src/Keys.cc | 6 +++- src/Keys.hh | 3 +- src/Screen.cc | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/Screen.hh | 5 +++- src/fluxbox.cc | 18 +++++++++++- 7 files changed, 121 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3b8f479..737445a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ Changes for 0.9.2: *03/04/20: * Snap to Windows (and toolbar, slit + screen edge) (Simon) Window.hh/cc + * Directional focus movement (key actions FocusUp/Down/Left/Right) (Simon) + Keys.hh/cc Screen.hh/cc fluxbox.cc Changes for 0.9.1: *03/04/16: * Fixed resize bug (Henrik) diff --git a/RoadMap b/RoadMap index aea3c79..5345594 100644 --- a/RoadMap +++ b/RoadMap @@ -103,7 +103,7 @@ Major Features: - Transparency (Henrik) Minor Features: - more keybinding actions (Both) - - directional focus movement (?) + * directional focus movement (?) - fix up focus issues (Simon) * snap to windows (Simon) - improved command-line help option (Henrik) diff --git a/src/Keys.cc b/src/Keys.cc index 02cfabd..a818e3b 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Keys.cc,v 1.25 2003/04/15 00:50:24 rathnor Exp $ +//$Id: Keys.cc,v 1.26 2003/04/20 12:21:35 rathnor Exp $ #include "Keys.hh" @@ -110,6 +110,10 @@ Keys::t_actionstr Keys::m_actionlist[] = { {"MoveTabNext", MOVETABNEXT}, {"AttachLast", ATTACHLAST}, {"DetachClient", DETACHCLIENT}, + {"FocusUp", FOCUSUP}, + {"FocusDown", FOCUSDOWN}, + {"FocusLeft", FOCUSLEFT}, + {"FocusRight", FOCUSRIGHT}, {"ShadeWindow", SHADE}, {"MaximizeWindow", MAXIMIZE}, {"StickWindow", STICK}, diff --git a/src/Keys.hh b/src/Keys.hh index 57e826c..d0eb344 100644 --- a/src/Keys.hh +++ b/src/Keys.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Keys.hh,v 1.22 2003/04/15 00:50:24 rathnor Exp $ +// $Id: Keys.hh,v 1.23 2003/04/20 12:21:35 rathnor Exp $ #ifndef KEYS_HH #define KEYS_HH @@ -52,6 +52,7 @@ public: KILLWINDOW, NEXTWINDOW, PREVWINDOW, NEXTTAB, PREVTAB, FIRSTTAB, LASTTAB, MOVETABPREV, MOVETABNEXT, ATTACHLAST, DETACHCLIENT, + FOCUSUP, FOCUSDOWN, FOCUSLEFT, FOCUSRIGHT, SHADE, MAXIMIZE, STICK, // Make Sticky EXECUTE, // Run command diff --git a/src/Screen.cc b/src/Screen.cc index 80466df..574c51a 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.127 2003/04/18 12:51:14 fluxgen Exp $ +// $Id: Screen.cc,v 1.128 2003/04/20 12:21:35 rathnor Exp $ #include "Screen.hh" @@ -1618,6 +1618,95 @@ void BScreen::setFocusedWindow(WinClient &winclient) { } } +void BScreen::dirFocus(FluxboxWindow &win, 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" + // in the given direction + + FluxboxWindow *foundwin = 0; + int weight = 999999, exposure = 0; // extreme values + int borderW = getBorderWidth(), + top = win.getYFrame(), + bottom = win.getYFrame() + win.getHeight() + 2*borderW, + left = win.getXFrame(), + right = win.getXFrame() + win.getWidth() + 2*borderW; + + Workspace::Windows &wins = getCurrentWorkspace()->getWindowList(); + Workspace::Windows::iterator it = wins.begin(); + for (; it != wins.end(); ++it) { + if ((*it) == &win) 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; + + int otop = (*it)->getYFrame(), + obottom = (*it)->getYFrame() + (*it)->getHeight() + 2*borderW, + oleft = (*it)->getXFrame(), + oright = (*it)->getXFrame() + (*it)->getWidth() + 2*borderW; + // check if they intersect + switch (dir) { + case FOCUSUP: + edge = obottom; + oedge = bottom; + upper = left; + oupper = oleft; + lower = right; + olower = oright; + break; + case FOCUSDOWN: + edge = top; + oedge = otop; + upper = left; + oupper = oleft; + lower = right; + olower = oright; + break; + case FOCUSLEFT: + edge = oright; + oedge = right; + upper = top; + oupper = otop; + lower = bottom; + olower = obottom; + break; + case FOCUSRIGHT: + edge = left; + oedge = oleft; + upper = top; + oupper = otop; + lower = bottom; + olower = obottom; + break; + } + + if (oedge < edge) continue; // not in the right direction + if (olower <= upper || oupper >= lower) { + // outside our horz bounds, get a heavy weight penalty + int myweight = 100000 + oedge - edge + abs(upper-oupper)+abs(lower-olower); + if (myweight < weight) { + foundwin = *it; + exposure = 0; + weight = myweight; + } + } else if ((oedge - edge) < weight) { + foundwin = *it; + weight = oedge - edge; + exposure = ((lower < olower)?lower:olower) - ((upper > oupper)?upper:oupper); + } else if (foundwin && oedge - edge == weight) { + int myexp = ((lower < olower)?lower:olower) - ((upper > oupper)?upper:oupper); + if (myexp > exposure) { + foundwin = *it; + // weight is same + exposure = myexp; + } + } // else not improvement + } + + if (foundwin) + foundwin->setInputFocus(); +} + void BScreen::initMenu() { I18n *i18n = I18n::instance(); diff --git a/src/Screen.hh b/src/Screen.hh index 8b4d74a..84d7f74 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.80 2003/04/16 16:17:57 rathnor Exp $ +// $Id: Screen.hh,v 1.81 2003/04/20 12:21:35 rathnor Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -278,6 +278,9 @@ public: void raiseFocus(); void setFocusedWindow(WinClient &winclient); + enum FocusDir { FOCUSUP, FOCUSDOWN, FOCUSLEFT, FOCUSRIGHT }; + void dirFocus(FluxboxWindow &win, FocusDir dir); + void reconfigure(); void rereadMenu(); void shutdown(); diff --git a/src/fluxbox.cc b/src/fluxbox.cc index a0a75f0..d2dc234 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.114 2003/04/16 16:18:06 rathnor Exp $ +// $Id: fluxbox.cc,v 1.115 2003/04/20 12:21:35 rathnor Exp $ #include "fluxbox.hh" @@ -1165,6 +1165,22 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { } screen->prevFocus(key->getParam()); break; + case Keys::FOCUSUP: + if (focused_window) + screen->dirFocus(*focused_window, BScreen::FOCUSUP); + break; + case Keys::FOCUSDOWN: + if (focused_window) + screen->dirFocus(*focused_window, BScreen::FOCUSDOWN); + break; + case Keys::FOCUSLEFT: + if (focused_window) + screen->dirFocus(*focused_window, BScreen::FOCUSLEFT); + break; + case Keys::FOCUSRIGHT: + if (focused_window) + screen->dirFocus(*focused_window, BScreen::FOCUSRIGHT); + break; case Keys::NEXTTAB: if (focused_window && focused_window->numClients() > 1) focused_window->nextClient(); -- cgit v0.11.2