add directional focus movement (Simon)

incl new keybindings FocusUp, FocusDown, FocusLeft, FocusRight
This commit is contained in:
rathnor 2003-04-20 12:21:35 +00:00
parent e75378d0e6
commit 2a1bc27e90
7 changed files with 121 additions and 6 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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},

View file

@ -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

View file

@ -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();

View file

@ -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();

View file

@ -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();