Index: nls/blackbox-nls.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/nls/blackbox-nls.hh,v retrieving revision 1.14 diff -a -b -B -p -u -r1.14 blackbox-nls.hh --- nls/blackbox-nls.hh 30 Mar 2004 13:52:21 -0000 1.14 +++ nls/blackbox-nls.hh 5 May 2004 14:36:31 -0000 @@ -45,6 +45,7 @@ enum { ConfigmenuDesktopWheeling = 0x1b, ConfigmenuAntiAlias = 0x1c, ConfigmenuDecorateTransient = 0x1d, + ConfigmenuClickRaises = 0x1e, IconSet = 0x4, IconIcons = 0x1, @@ -127,6 +128,7 @@ enum { WindowmenuKillClient = 0x9, WindowmenuClose = 0xa, WindowmenuTab = 0xb, + WindowmenuLayer = 0xc, WorkspaceSet = 0xb, WorkspaceDefaultNameFormat = 0x1, Index: src/FbCommandFactory.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/FbCommandFactory.cc,v retrieving revision 1.31 diff -a -b -B -p -u -r1.31 FbCommandFactory.cc --- src/FbCommandFactory.cc 2 May 2004 21:13:08 -0000 1.31 +++ src/FbCommandFactory.cc 5 May 2004 14:36:31 -0000 @@ -83,6 +83,7 @@ FbCommandFactory::FbCommandFactory() { "maximizehorizontal", "maximizevertical", "maximizewindow", + "maximizespace", "minimize", "minimizewindow", "moveto", @@ -195,6 +196,8 @@ FbTk::Command *FbCommandFactory::stringT return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical); else if (command == "maximizehorizontal") return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal); + else if (command == "maximizespace") + return new CurrentWindowCmd(&FluxboxWindow::maximizeSpace); else if (command == "resize") { FB_istringstream is(arguments.c_str()); int dx = 0, dy = 0; @@ -284,13 +287,13 @@ FbTk::Command *FbCommandFactory::stringT else if (command == "prevwindow") return new PrevWindowCmd(atoi(arguments.c_str())); else if (command == "focusup") - return new DirFocusCmd(BScreen::FOCUSUP); + return new DirFocusCmd(BScreen::FIND_WIN_UP); else if (command == "focusdown") - return new DirFocusCmd(BScreen::FOCUSDOWN); + return new DirFocusCmd(BScreen::FIND_WIN_DOWN); else if (command == "focusleft") - return new DirFocusCmd(BScreen::FOCUSLEFT); + return new DirFocusCmd(BScreen::FIND_WIN_LEFT); else if (command == "focusright") - return new DirFocusCmd(BScreen::FOCUSRIGHT); + return new DirFocusCmd(BScreen::FIND_WIN_RIGHT); else if (command == "nextgroup") return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS); else if (command == "prevgroup") Index: src/MenuCreator.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/MenuCreator.cc,v retrieving revision 1.5 diff -a -b -B -p -u -r1.5 MenuCreator.cc --- src/MenuCreator.cc 3 May 2004 21:37:01 -0000 1.5 +++ src/MenuCreator.cc 5 May 2004 14:36:31 -0000 @@ -372,6 +372,9 @@ bool MenuCreator::createWindowMenuItem(c maximize_item->setCommand(2, maximize_vert_cmd); maximize_item->setCommand(3, maximize_horiz_cmd); menu.insert(maximize_item); + } else if (type == "maxspace") { + RefCmd maxspace_cmd(new WindowCmd(win, &FluxboxWindow::maximizeSpace)); + menu.insert(type.c_str(), maxspace_cmd); } else if (type == "iconify") { WINDOWNLS(WindowmenuIconify, "Iconify"); RefCmd iconify_cmd(new WindowCmd(win, &FluxboxWindow::iconify)); Index: src/Screen.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Screen.cc,v retrieving revision 1.277 diff -a -b -B -p -u -r1.277 Screen.cc --- src/Screen.cc 2 May 2004 21:12:22 -0000 1.277 +++ src/Screen.cc 5 May 2004 14:36:34 -0000 @@ -1548,13 +1548,15 @@ void BScreen::setFocusedWindow(WinClient } } -void BScreen::dirFocus(FluxboxWindow &win, const FocusDir dir) { - // change focus to the window in direction dir from the given window +FluxboxWindow* BScreen::findClosestWindowInDir(FluxboxWindow &win, + const FindWinDir dir, + const SkipWindowFunctor& skip) { + + FluxboxWindow* foundwin = 0; // 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 = winFrameTheme().border().width(), top = win.y(), @@ -1565,10 +1567,7 @@ void BScreen::dirFocus(FluxboxWindow &wi Workspace::Windows &wins = currentWorkspace()->windowList(); Workspace::Windows::iterator it = wins.begin(); for (; it != wins.end(); ++it) { - if ((*it) == &win - || (*it)->isIconic() - || (*it)->isFocusHidden() - || !(*it)->winClient().acceptsFocus()) + if (skip(*it)) continue; // skip self // we check things against an edge, and within the bounds (draw a picture) @@ -1580,7 +1579,7 @@ void BScreen::dirFocus(FluxboxWindow &wi oright = (*it)->x() + (*it)->width() + 2*borderW; // check if they intersect switch (dir) { - case FOCUSUP: + case FIND_WIN_UP: edge = obottom; oedge = bottom; upper = left; @@ -1588,7 +1587,7 @@ void BScreen::dirFocus(FluxboxWindow &wi lower = right; olower = oright; break; - case FOCUSDOWN: + case FIND_WIN_DOWN: edge = top; oedge = otop; upper = left; @@ -1596,7 +1595,7 @@ void BScreen::dirFocus(FluxboxWindow &wi lower = right; olower = oright; break; - case FOCUSLEFT: + case FIND_WIN_LEFT: edge = oright; oedge = right; upper = top; @@ -1604,7 +1603,7 @@ void BScreen::dirFocus(FluxboxWindow &wi lower = bottom; olower = obottom; break; - case FOCUSRIGHT: + case FIND_WIN_RIGHT: edge = left; oedge = oleft; upper = top; @@ -1637,6 +1637,33 @@ void BScreen::dirFocus(FluxboxWindow &wi } // else not improvement } + return foundwin; +} + +void BScreen::dirFocus(FluxboxWindow &win, const FindWinDir dir) { + // change focus to the window in direction dir from the given window + + class SkipIconedWindowFunctor : public SkipWindowFunctor { + public: + SkipIconedWindowFunctor(const FluxboxWindow* win) : + m_win(win) { }; + bool operator() (const FluxboxWindow* win) const { + return (!win + || win == m_win + || win->isIconic() + || win->isFocusHidden() + || !win->winClient().acceptsFocus()); + }; + private: + const FluxboxWindow* m_win; + }; + + + + SkipIconedWindowFunctor skip(&win); + FluxboxWindow* foundwin = 0; + + foundwin = findClosestWindowInDir(win, dir, skip); if (foundwin) foundwin->setInputFocus(); } Index: src/Screen.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Screen.hh,v retrieving revision 1.141 diff -a -b -B -p -u -r1.141 Screen.hh --- src/Screen.hh 2 May 2004 21:10:30 -0000 1.141 +++ src/Screen.hh 5 May 2004 14:36:34 -0000 @@ -73,9 +73,8 @@ class Subject; class BScreen : public FbTk::Observer, private FbTk::NotCopyable { public: enum FocusModel { SLOPPYFOCUS=0, SEMISLOPPYFOCUS, CLICKTOFOCUS }; - enum FocusDir { FOCUSUP, FOCUSDOWN, FOCUSLEFT, FOCUSRIGHT }; - enum PlacementPolicy { ROWSMARTPLACEMENT, COLSMARTPLACEMENT, - CASCADEPLACEMENT, UNDERMOUSEPLACEMENT}; + enum FindWinDir { FIND_WIN_UP, FIND_WIN_DOWN, FIND_WIN_LEFT, FIND_WIN_RIGHT }; + enum PlacementPolicy { ROWSMARTPLACEMENT, COLSMARTPLACEMENT, CASCADEPLACEMENT, UNDERMOUSEPLACEMENT}; enum RowDirection { LEFTRIGHT, RIGHTLEFT}; enum ColumnDirection { TOPBOTTOM, BOTTOMTOP}; // prevFocus/nextFocus option bits @@ -266,7 +265,14 @@ public: void setFocusedWindow(WinClient &winclient); - void dirFocus(FluxboxWindow &win, const FocusDir dir); + class SkipWindowFunctor { + public: + virtual bool operator()(const FluxboxWindow* win) const = 0; + }; + FluxboxWindow* findClosestWindowInDir(FluxboxWindow& win, + const FindWinDir dir, + const SkipWindowFunctor& skip); + void dirFocus(FluxboxWindow &win, const FindWinDir dir); void reconfigure(); void rereadMenu(); Index: src/Window.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Window.cc,v retrieving revision 1.286 diff -a -b -B -p -u -r1.286 Window.cc --- src/Window.cc 3 May 2004 13:45:23 -0000 1.286 +++ src/Window.cc 5 May 2004 14:36:36 -0000 @@ -245,6 +245,34 @@ private: WinClient &m_client; }; + +// does a window 'a' overlap somehow a window 'b' ? +bool overlap(int a_upper_x, int a_upper_y, + int a_lower_x, int a_lower_y, + Workspace::Windows& wins, + BScreen::SkipWindowFunctor& skip) { + + int b_upper_x, b_upper_y, b_lower_x, b_lower_y; + Workspace::Windows::iterator it; + for(it = wins.begin(); it != wins.end(); it++) { + + if(skip(*it)) continue; + + b_upper_x = (*it)->x(); + b_upper_y = (*it)->y(); + b_lower_x = (*it)->x() + (*it)->width() + 2 * (*it)->frame().window().borderWidth(); + b_lower_y = (*it)->y() + (*it)->height() + 2 * (*it)->frame().window().borderWidth(); + + if(!(a_upper_x >= b_lower_x || // 'a' lays right from 'b' + a_lower_x <= b_upper_x || // 'a' lays left from 'b' + a_upper_y >= b_lower_y || // 'a' lays below 'b' + a_lower_y <= b_upper_y )) // 'a' lays above 'b' + return true; + } + + return false; +} + }; @@ -1396,7 +1424,129 @@ void FluxboxWindow::maximize(int type) { int new_x = frame().x(), new_y = frame().y(), new_w = frame().width(), - new_h = frame().height(); + new_h = frame().height(), + new_lower_x = new_x + new_w, + new_lower_y = new_y + new_h; + + + // use as much space as we can get for the window + if (type & MAX_SPACE) { + + class SkipIconedWindowFunctor : public BScreen::SkipWindowFunctor { + public: + SkipIconedWindowFunctor(const FluxboxWindow* win) : m_win(win) { }; + bool operator() (const FluxboxWindow* win) const { + + return !win + || win == m_win + || win->layerNum() != m_win->layerNum() + || win->isIconic(); + } + private: + const FluxboxWindow* m_win; + }; + + SkipIconedWindowFunctor skip(this); + + + // phase 1: found free space + FluxboxWindow* neighbour = 0; + int nb_x, nb_y, nb_lower_x, nb_lower_y; // neighbour + + if ((neighbour = screen().findClosestWindowInDir(*this, BScreen::FIND_WIN_UP, skip))) { + nb_y = neighbour->y(); + nb_lower_y = neighbour->y() + neighbour->height() + 2 * neighbour->frame().window().borderWidth(); + new_y = (abs(nb_y - new_y) < abs(nb_lower_y - new_y) ? nb_y : nb_lower_y); + } else new_y = screen().maxTop(head); + if ((neighbour = screen().findClosestWindowInDir(*this, BScreen::FIND_WIN_DOWN, skip))) { + nb_y = neighbour->y(); + nb_lower_y = neighbour->y() + neighbour->height() + 2 * neighbour->frame().window().borderWidth(); + new_lower_y = (abs(nb_y - new_lower_y) < abs(nb_lower_y - new_lower_y) ? nb_y : nb_lower_y); + } else new_lower_y = screen().maxBottom(head); + + if ((neighbour = screen().findClosestWindowInDir(*this, BScreen::FIND_WIN_LEFT, skip))) { + nb_x = neighbour->x(); + nb_lower_x = neighbour->x() + neighbour->width() + 2 * neighbour->frame().window().borderWidth(); + new_x = (abs(nb_x - new_x) < abs(nb_lower_x - new_x) ? nb_x : nb_lower_x); + } else new_x = screen().maxLeft(head); + + if ((neighbour = screen().findClosestWindowInDir(*this, BScreen::FIND_WIN_RIGHT, skip))) { + nb_x = neighbour->x(); + nb_lower_x = neighbour->x() + neighbour->width() + 2 * neighbour->frame().window().borderWidth(); + new_lower_x = (abs(nb_x - new_lower_x) < abs(nb_lower_x - new_lower_x) ? nb_x : nb_lower_x); + } else new_lower_x = screen().maxRight(head); + +/* + new_w = new_lower_x - new_x; + new_h = new_lower_y - new_y; + std::cerr << "PHASE 1 " << new_x << " " << new_y << " " + << new_lower_x << " " << new_lower_y << " | " + << new_w << " " << new_h << "\n"; +*/ + Workspace::Windows &wins = screen().currentWorkspace()->windowList(); + bool expand[] = { true, true, true, true}; // up, down, left, right + + enum { UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3 }; + + // phase 2: expand inside this space + // expand in each direction one pixel and check, if + // someone is hurt + while (expand[UP] || expand[DOWN] || expand[LEFT] || expand[RIGHT]) { + + if (expand[UP]) { + if(overlap(new_x, new_y - 1, new_lower_x, new_lower_y, wins, skip)) { + expand[UP] = false; + } else new_y--; + if (new_y <= static_cast(screen().maxTop(head))) { + new_y = screen().maxTop(head); + expand[UP] = false; + } + } + + if (expand[DOWN]) { + if(overlap(new_x, new_y, new_lower_x, new_lower_y + 1, wins, skip)) { + expand[DOWN] = false; + } else new_lower_y++; + if (new_lower_y >= static_cast(screen().maxBottom(head))) { + new_lower_y = screen().maxBottom(head); + expand[DOWN] = false; + } + } + + if (expand[LEFT]) { + if(overlap(new_x - 1, new_y, new_lower_x, new_lower_y, wins, skip)) { + expand[LEFT] = false; + } else new_x--; + if ( new_x <= static_cast(screen().maxLeft(head)) ) { + new_x = screen().maxLeft(head); + expand[LEFT] = false; + } + } + + if (expand[RIGHT]) { + if(overlap(new_x, new_y, new_lower_x + 1, new_lower_y, wins, skip)) { + expand[RIGHT] = false; + } else new_lower_x++; + if (new_lower_x >= static_cast(screen().maxRight(head))) { + new_lower_x = screen().maxRight(head); + expand[RIGHT] = false; + } + } + } +/* + new_w = new_lower_x - new_x; + new_h = new_lower_y - new_y; + std::cerr << "PHASE 2 " << new_x << " " << new_y << " " + << new_lower_x << " " << new_lower_y << " | " + << new_w << " " << new_h << "\n"; +*/ + if (new_x < 0 || new_y < 0 || new_w < 0 || new_h < 0 ) { + cerr << " something wrong\n"; + return; + } + + + } else { int orig_max = maximized; @@ -1460,6 +1610,7 @@ void FluxboxWindow::maximize(int type) { } maximized ^= MAX_HORZ; } + } moveResize(new_x, new_y, new_w, new_h); @@ -1485,6 +1636,12 @@ void FluxboxWindow::maximizeFull() { maximize(MAX_FULL); } +/** + * Maximize window to as much space we can get + */ +void FluxboxWindow::maximizeSpace() { + maximize(MAX_SPACE); +} void FluxboxWindow::setWorkspace(int n) { unsigned int old_wkspc = m_workspace_number; Index: src/Window.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Window.hh,v retrieving revision 1.113 diff -a -b -B -p -u -r1.113 Window.hh --- src/Window.hh 2 May 2004 21:06:27 -0000 1.113 +++ src/Window.hh 5 May 2004 14:36:36 -0000 @@ -111,7 +111,8 @@ public: MAX_NONE = 0, ///< normal state MAX_HORZ = 1, ///< maximize horizontal MAX_VERT = 2, ///< maximize vertical - MAX_FULL = 3 ///< maximize full + MAX_FULL = 3, ///< maximize full + MAX_SPACE = 4 ///< use as much space as available }; /** This enumeration represents individual decoration @@ -199,6 +200,9 @@ public: void maximizeVertical(); /// maximizes the window fully void maximizeFull(); + /// TODO: crappy description -> akira's fault + //maximize the window to as much space we can get + void maximizeSpace(); /// toggles shade void shade(); /// toggles sticky Index: src/WorkspaceCmd.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/WorkspaceCmd.hh,v retrieving revision 1.3 diff -a -b -B -p -u -r1.3 WorkspaceCmd.hh --- src/WorkspaceCmd.hh 28 Apr 2004 14:59:12 -0000 1.3 +++ src/WorkspaceCmd.hh 5 May 2004 14:36:36 -0000 @@ -45,10 +45,10 @@ private: class DirFocusCmd: public FbTk::Command { public: - explicit DirFocusCmd(const BScreen::FocusDir dir): m_dir(dir) { } + explicit DirFocusCmd(const BScreen::FindWinDir dir): m_dir(dir) { } void execute(); private: - const BScreen::FocusDir m_dir; + const BScreen::FindWinDir m_dir; }; class NextWorkspaceCmd: public FbTk::Command {