From 37b18a9694122e285286757df2a74213b8d27a3e Mon Sep 17 00:00:00 2001 From: Mark Tiefenbruck Date: Mon, 18 Aug 2008 05:12:30 -0700 Subject: combined code for saved window positions and MoveTo key command added left, right, top, and bottom center reference points --- ChangeLog | 10 +++++ doc/asciidoc/fluxbox-keys.txt | 2 +- doc/asciidoc/fluxbox.1 | 22 ++++++++--- doc/asciidoc/fluxbox.txt | 13 ++++--- doc/fluxbox.1.in | 22 ++++++++--- src/CurrentWindowCmd.cc | 59 ++++++++-------------------- src/CurrentWindowCmd.hh | 22 +++++------ src/Ewmh.cc | 2 +- src/Remember.cc | 91 ++++++++++++++----------------------------- src/Remember.hh | 3 +- src/Window.cc | 52 ++++++++++++++++++++++--- src/Window.hh | 27 +++++++------ 12 files changed, 173 insertions(+), 152 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c0b78c..e0bd9ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,16 @@ (Format: Year/Month/Day) Changes for 1.1 *08/08/18: + * Combined code for MoveTo key command and saved window positions (Mark) + Side effects: + - both now have the following options: TopLeft Left BottomLeft Top Center + Bottom TopRight Right BottomRight + - the CENTER reference in apps now behaves like WINCENTER + - some previously saved positions will be wrong, since they are now + computed relative to the toolbar and slit + - CENTER/WINCENTER will now work properly with Xinerama when placing the + window on a head other than the top left one + CurrentWindowCmd.cc/hh Remember.cc Window.cc/hh * Add Top Center, Left Center, Right Center, and Bottom Center tab placement options (Mark) FbWinFrame.cc/hh Screen.cc FbTk/Container.cc/hh diff --git a/doc/asciidoc/fluxbox-keys.txt b/doc/asciidoc/fluxbox-keys.txt index e52ffa8..771621d 100644 --- a/doc/asciidoc/fluxbox-keys.txt +++ b/doc/asciidoc/fluxbox-keys.txt @@ -246,7 +246,7 @@ If either 'x' or 'y' is set to *\**, that coordinate will be ignored, and the movement will only take place in one dimension. + The default 'anchor' is the upper left corner, but this may be overridden with one of:;; -*UpperLeft LowerLeft UpperRight LowerRight* +*TopLeft Left BottomLeft Top Center Bottom TopRight Right BottomRight* *Move* 'delta-x' 'delta-y':: Moves the window relative to its current position. Positive numbers diff --git a/doc/asciidoc/fluxbox.1 b/doc/asciidoc/fluxbox.1 index a5d394f..092b095 100644 --- a/doc/asciidoc/fluxbox.1 +++ b/doc/asciidoc/fluxbox.1 @@ -1247,7 +1247,19 @@ The following are the properties that can be defined in each [app] entry\. Each \h'-04'\(bu\h'+03'[Position] (\fBrefspot\fR)) {X Y}: Position the application at a particular spot: .sp .RS 4 -\h'-04'\(bu\h'+03'WINCENTER +\h'-04'\(bu\h'+03'TOPLEFT +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'TOP +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'TOPRIGHT +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'LEFT .RE .sp .RS 4 @@ -1255,19 +1267,19 @@ The following are the properties that can be defined in each [app] entry\. Each .RE .sp .RS 4 -\h'-04'\(bu\h'+03'UPPERLEFT +\h'-04'\(bu\h'+03'RIGHT .RE .sp .RS 4 -\h'-04'\(bu\h'+03'UPPERRIGHT +\h'-04'\(bu\h'+03'BOTTOMLEFT .RE .sp .RS 4 -\h'-04'\(bu\h'+03'LOWERLEFT +\h'-04'\(bu\h'+03'BOTTOM .RE .sp .RS 4 -\h'-04'\(bu\h'+03'LOWERRIGHT +\h'-04'\(bu\h'+03'BOTTOMRIGHT .sp .RS 4 .nf diff --git a/doc/asciidoc/fluxbox.txt b/doc/asciidoc/fluxbox.txt index 4c41474..7f7764e 100644 --- a/doc/asciidoc/fluxbox.txt +++ b/doc/asciidoc/fluxbox.txt @@ -1170,12 +1170,15 @@ curly brackets: - [Position] (*refspot*)) {X Y}: Position the application at a particular spot: + - * WINCENTER + * TOPLEFT + * TOP + * TOPRIGHT + * LEFT * CENTER - * UPPERLEFT - * UPPERRIGHT - * LOWERLEFT - * LOWERRIGHT + * RIGHT + * BOTTOMLEFT + * BOTTOM + * BOTTOMRIGHT + You can optionally specify what X and Y are relative to. By default the diff --git a/doc/fluxbox.1.in b/doc/fluxbox.1.in index a5d394f..092b095 100644 --- a/doc/fluxbox.1.in +++ b/doc/fluxbox.1.in @@ -1247,7 +1247,19 @@ The following are the properties that can be defined in each [app] entry\. Each \h'-04'\(bu\h'+03'[Position] (\fBrefspot\fR)) {X Y}: Position the application at a particular spot: .sp .RS 4 -\h'-04'\(bu\h'+03'WINCENTER +\h'-04'\(bu\h'+03'TOPLEFT +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'TOP +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'TOPRIGHT +.RE +.sp +.RS 4 +\h'-04'\(bu\h'+03'LEFT .RE .sp .RS 4 @@ -1255,19 +1267,19 @@ The following are the properties that can be defined in each [app] entry\. Each .RE .sp .RS 4 -\h'-04'\(bu\h'+03'UPPERLEFT +\h'-04'\(bu\h'+03'RIGHT .RE .sp .RS 4 -\h'-04'\(bu\h'+03'UPPERRIGHT +\h'-04'\(bu\h'+03'BOTTOMLEFT .RE .sp .RS 4 -\h'-04'\(bu\h'+03'LOWERLEFT +\h'-04'\(bu\h'+03'BOTTOM .RE .sp .RS 4 -\h'-04'\(bu\h'+03'LOWERRIGHT +\h'-04'\(bu\h'+03'BOTTOMRIGHT .sp .RS 4 .nf diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc index f8c7b4b..28d7ecd 100644 --- a/src/CurrentWindowCmd.cc +++ b/src/CurrentWindowCmd.cc @@ -410,65 +410,38 @@ FbTk::Command *MoveToCmd::parse(const string &cmd, const string &args, if (tokens.size() < 2) return 0; - unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT; - int dx = 0, dy = 0; + FluxboxWindow::ReferenceCorner refc = FluxboxWindow::LEFTTOP; + int x = 0, y = 0; + bool ignore_x = false, ignore_y = false; if (tokens[0][0] == '*') - refc |= MoveToCmd::IGNORE_X; + ignore_x = true; else - dx = atoi(tokens[0].c_str()); + x = atoi(tokens[0].c_str()); - if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X)) - refc |= MoveToCmd::IGNORE_Y; + if (tokens[1][0] == '*' && !ignore_x) + ignore_y = true; else - dy = atoi(tokens[1].c_str()); + y = atoi(tokens[1].c_str()); if (tokens.size() >= 3) { - tokens[2] = FbTk::StringUtil::toLower(tokens[2]); - if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") { - refc |= MoveToCmd::LEFT; - refc &= ~MoveToCmd::RIGHT; - } else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") { - refc |= MoveToCmd::RIGHT; - refc &= ~MoveToCmd::LEFT; - } - - if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") { - refc |= MoveToCmd::UPPER; - refc &= ~MoveToCmd::LOWER; - } else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") { - refc |= MoveToCmd::LOWER; - refc &= ~MoveToCmd::UPPER; - } + refc = FluxboxWindow::getCorner(tokens[2]); + if (refc == FluxboxWindow::ERROR) + refc = FluxboxWindow::LEFTTOP; } - return new MoveToCmd(dx, dy, refc); - + return new MoveToCmd(x, y, ignore_x, ignore_y, refc); } REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse, void); -MoveToCmd::MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc) : - m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_refc(refc) { } - void MoveToCmd::real_execute() { - int x = 0; - int y = 0; - - const int head = fbwindow().screen().getHead(fbwindow().fbWindow()); - - if (m_refc & MoveToCmd::LOWER) - y = fbwindow().screen().maxBottom(head) - fbwindow().height() - 2 * fbwindow().frame().window().borderWidth() - m_step_size_y; - if (m_refc & MoveToCmd::UPPER) - y = fbwindow().screen().maxTop(head) + m_step_size_y; - if (m_refc & MoveToCmd::RIGHT) - x = fbwindow().screen().maxRight(head) - fbwindow().width() - 2 * fbwindow().frame().window().borderWidth() - m_step_size_x; - if (m_refc & MoveToCmd::LEFT) - x = fbwindow().screen().maxLeft(head) + m_step_size_x; + int x = m_pos_x, y = m_pos_y; - if (m_refc & MoveToCmd::IGNORE_X) + fbwindow().translateCoords(x, y, m_corner); + if (m_ignore_x) x = fbwindow().x(); - if (m_refc & MoveToCmd::IGNORE_Y) + if (m_ignore_y) y = fbwindow().y(); fbwindow().move(x, y); diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh index 4c3f91b..2d33847 100644 --- a/src/CurrentWindowCmd.hh +++ b/src/CurrentWindowCmd.hh @@ -206,25 +206,21 @@ private: class MoveToCmd: public WindowHelperCmd { public: - enum { - LEFT = 1 << 0, - RIGHT = 1 << 1, - UPPER = 1 << 2, - LOWER = 1 << 3, - - IGNORE_X = 1 << 8, - IGNORE_Y = 1 << 9 - }; - explicit MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc); + explicit MoveToCmd(int pos_x, int pos_y, bool ignore_x, bool ignore_y, + FluxboxWindow::ReferenceCorner refc): + m_pos_x(pos_x), m_pos_y(pos_y), + m_ignore_x(ignore_x), m_ignore_y(ignore_y), + m_corner(refc) { } + static FbTk::Command *parse(const std::string &command, const std::string &args, bool trusted); protected: void real_execute(); private: - const int m_step_size_x; - const int m_step_size_y; - const unsigned int m_refc; + int m_pos_x, m_pos_y; + bool m_ignore_x, m_ignore_y; + FluxboxWindow::ReferenceCorner m_corner; }; // resize cmd diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 8938e7d..06a1b1a 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -1191,7 +1191,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, winclient->fbwindow()->frame().window().borderWidth(), ce.data.l[1] - winclient->fbwindow()->y() - winclient->fbwindow()->frame().window().borderWidth(), - static_cast(ce.data.l[2])); + static_cast(ce.data.l[2])); break; case _NET_WM_MOVERESIZE_MOVE: case _NET_WM_MOVERESIZE_MOVE_KEYBOARD: diff --git a/src/Remember.cc b/src/Remember.cc index 3e9e16a..d5b2ece 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -103,7 +103,8 @@ public: { focushiddenstate= state; focushiddenstate_remember= true; } void rememberIconHiddenstate(bool state) { iconhiddenstate= state; iconhiddenstate_remember= true; } - void rememberPosition(int posx, int posy, unsigned char rfc= 0 ) + void rememberPosition(int posx, int posy, + FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP) { x = posx; y = posy; refc = rfc; position_remember = true; } void rememberShadedstate(bool state) { shadedstate = state; shadedstate_remember = true; } @@ -139,10 +140,7 @@ public: bool position_remember; int x,y; - unsigned char refc; // referenceCorner-> 0 - upperleft - // 1 - upperight - // 2 - lowerleft - // 3 - lowerright + FluxboxWindow::ReferenceCorner refc; bool alpha_remember; int focused_alpha; @@ -477,27 +475,16 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) { else had_error = true; } else if (str_key == "position") { - unsigned int r= 0; - unsigned int x= 0; - unsigned int y= 0; + FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP; + int x = 0, y = 0; // more info about the parameter // in ::rememberPosition - str_option == FbTk::StringUtil::toUpper(str_option); - if ( str_option.length() ) - { - if (str_option == "UPPERLEFT") r= Remember::POS_UPPERLEFT; - else if (str_option == "UPPERRIGHT") r= Remember::POS_UPPERRIGHT; - else if (str_option == "LOWERLEFT") r= Remember::POS_LOWERLEFT; - else if (str_option == "LOWERRIGHT") r= Remember::POS_LOWERRIGHT; - else if (str_option == "CENTER") r= Remember::POS_CENTER; - else if (str_option == "WINCENTER") r= Remember::POS_WINCENTER; - else if (!getuint(str_option.c_str(), r)) { - had_error = 1; - } - } + if (str_option.length()) + r = FluxboxWindow::getCorner(str_option); + had_error = (r == FluxboxWindow::ERROR); - if (!had_error && sscanf(str_label.c_str(), "%u %u", &x, &y) == 2) + if (!had_error && sscanf(str_label.c_str(), "%d %d", &x, &y) == 2) app.rememberPosition(x, y, r); else had_error = true; @@ -916,21 +903,30 @@ void Remember::save() { if (a.position_remember) { apps_file << " [Position]\t("; switch(a.refc) { - case POS_WINCENTER: - apps_file << "WINCENTER"; - break; - case POS_CENTER: + case FluxboxWindow::CENTER: apps_file << "CENTER"; break; - case POS_LOWERLEFT: + case FluxboxWindow::LEFTBOTTOM: apps_file << "LOWERLEFT"; break; - case POS_LOWERRIGHT: + case FluxboxWindow::RIGHTBOTTOM: apps_file << "LOWERRIGHT"; break; - case POS_UPPERRIGHT: + case FluxboxWindow::RIGHTTOP: apps_file << "UPPERRIGHT"; break; + case FluxboxWindow::LEFT: + apps_file << "LEFT"; + break; + case FluxboxWindow::RIGHT: + apps_file << "RIGHT"; + break; + case FluxboxWindow::TOP: + apps_file << "TOP"; + break; + case FluxboxWindow::BOTTOM: + apps_file << "BOTTOM"; + break; default: apps_file << "UPPERLEFT"; } @@ -1114,8 +1110,8 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) { break; case REM_POSITION: { int head = win->screen().getHead(win->fbWindow()); - int head_x = win->screen().getHeadX(head); - int head_y = win->screen().getHeadY(head); + int head_x = win->screen().maxLeft(head); + int head_y = win->screen().maxTop(head); app->rememberPosition(win->normalX() - head_x, win->normalY() - head_y); break; } @@ -1275,37 +1271,10 @@ void Remember::setupFrame(FluxboxWindow &win) { if (app->dimensions_remember) win.resize(app->w, app->h); - int head = screen.getHead(win.fbWindow()); - if (app->position_remember) { - - switch (app->refc) { - default: - case POS_UPPERLEFT: // upperleft corner - win.move(screen.getHeadX(head) + app->x, - screen.getHeadY(head) + app->y); - break; - case POS_UPPERRIGHT: // upperright corner - win.move(screen.getHeadX(head) + screen.getHeadWidth(head) - win.width() - app->x, - screen.getHeadY(head) + app->y); - break; - case POS_LOWERLEFT: // lowerleft corner - win.move(screen.getHeadX(head) + app->x, - screen.getHeadHeight(head) - win.height() - app->y); - break; - case POS_LOWERRIGHT: // lowerright corner - win.move(screen.getHeadWidth(head) - win.width() - app->x, - screen.getHeadHeight(head) - win.height() - app->y); - break; - case POS_CENTER: // center of the screen, windows topleft corner is on the center - win.move((screen.getHeadWidth(head) / 2) + app->x, - (screen.getHeadHeight(head) / 2) + app->y); - break; - case POS_WINCENTER: // the window is centered REALLY upon the center - win.move((screen.getHeadWidth(head) / 2) - ( win.width() / 2 ) + app->x, - (screen.getHeadHeight(head) / 2) - ( win.height() / 2 ) + app->y); - break; - }; + int newx = app->x, newy = app->y; + win.translateCoords(newx, newy, app->refc); + win.move(newx, newy); } if (app->shadedstate_remember) diff --git a/src/Remember.hh b/src/Remember.hh index a401abb..fb58a5e 100644 --- a/src/Remember.hh +++ b/src/Remember.hh @@ -81,8 +81,7 @@ public: POS_UPPERRIGHT, POS_LOWERLEFT, POS_LOWERRIGHT, - POS_CENTER, - POS_WINCENTER + POS_CENTER }; diff --git a/src/Window.cc b/src/Window.cc index 269665e..d5679d4 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -2789,7 +2789,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { if (! resizing) { - ResizeDirection resize_corner = RIGHTBOTTOM; + ReferenceCorner resize_corner = RIGHTBOTTOM; if (me.window == frame().gripRight()) resize_corner = RIGHTBOTTOM; else if (me.window == frame().gripLeft()) @@ -2834,7 +2834,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { if (m_resize_corner == RIGHTBOTTOM || m_resize_corner == RIGHTTOP || m_resize_corner == RIGHT) m_last_resize_w = frame().width() + dx; - if (m_resize_corner == ALLCORNERS) { + if (m_resize_corner == CENTER) { // dx or dy must be at least 2 if (abs(dx) >= 2 || abs(dy) >= 2) { // take max and make it even @@ -3339,12 +3339,12 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { } -FluxboxWindow::ResizeDirection FluxboxWindow::getResizeDirection(int x, int y, +FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y, ResizeModel model) const { int cx = frame().width() / 2; int cy = frame().height() / 2; if (model == CENTERRESIZE) - return ALLCORNERS; + return CENTER; if (model == NEARESTEDGERESIZE) { if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest return (y > cy) ? BOTTOM : TOP; @@ -3365,7 +3365,7 @@ FluxboxWindow::ResizeDirection FluxboxWindow::getResizeDirection(int x, int y, return RIGHTBOTTOM; } -void FluxboxWindow::startResizing(int x, int y, ResizeDirection dir) { +void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) { if (s_num_grabs > 0 || isShaded() || isIconic() ) return; @@ -4038,6 +4038,48 @@ void FluxboxWindow::associateClient(WinClient &client) { client.titleSig().attach(this); } +FluxboxWindow::ReferenceCorner FluxboxWindow::getCorner(string str) { + str = FbTk::StringUtil::toLower(str); + if (str == "lefttop" || str == "topleft" || str == "upperleft" || str == "") + return LEFTTOP; + if (str == "top" || str == "upper" || str == "topcenter") + return TOP; + if (str == "righttop" || str == "topright" || str == "upperright") + return RIGHTTOP; + if (str == "left" || str == "leftcenter") + return LEFT; + if (str == "center" || str == "wincenter") + return CENTER; + if (str == "right" || str == "rightcenter") + return RIGHT; + if (str == "leftbottom" || str == "bottomleft" || str == "lowerleft") + return LEFTBOTTOM; + if (str == "bottom" || str == "bottomcenter") + return BOTTOM; + if (str == "rightbottom" || str == "bottomright" || str == "lowerright") + return RIGHTBOTTOM; + return ERROR; +} + +void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const { + int head = getOnHead(), bw = 2 * frame().window().borderWidth(), + left = screen().maxLeft(head), right = screen().maxRight(head), + top = screen().maxTop(head), bottom = screen().maxBottom(head); + + if (dir == LEFTTOP || dir == LEFT || dir == LEFTBOTTOM) + x += left; + if (dir == RIGHTTOP || dir == RIGHT || dir == RIGHTBOTTOM) + x = right - width() - bw - x; + if (dir == TOP || dir == CENTER || dir == BOTTOM) + x += (left + right - width() - bw)/2; + if (dir == LEFTTOP || dir == TOP || dir == RIGHTTOP) + y += top; + if (dir == LEFTBOTTOM || dir == BOTTOM || dir == RIGHTBOTTOM) + y = bottom - height() - bw - y; + if (dir == LEFT || dir == CENTER || dir == RIGHT) + y += (top + bottom - height() - bw)/2; +} + int FluxboxWindow::getOnHead() const { return screen().getHead(fbWindow()); } diff --git a/src/Window.hh b/src/Window.hh index d533dfc..9780ef2 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -126,19 +126,19 @@ public: }; /** - * Resize direction while resizing + * Reference corner for moves and resizes */ - enum ResizeDirection { - NOCORNER = -1, - LEFTTOP = 0, - TOP = 1, - RIGHTTOP = 2, - RIGHT = 3, + enum ReferenceCorner { + ERROR = -1, + LEFTTOP = 0, + TOP = 1, + RIGHTTOP = 2, + RIGHT = 3, RIGHTBOTTOM = 4, BOTTOM = 5, LEFTBOTTOM = 6, LEFT = 7, - ALLCORNERS = 8 + CENTER = 8 }; /// holds old blackbox attributes @@ -371,14 +371,19 @@ public: * @param y start position * @param dir the resize direction */ - void startResizing(int x, int y, ResizeDirection dir); + void startResizing(int x, int y, ReferenceCorner dir); /// determine which edge or corner to resize - ResizeDirection getResizeDirection(int x, int y, ResizeModel model) const; + ReferenceCorner getResizeDirection(int x, int y, ResizeModel model) const; /// stops the resizing void stopResizing(bool interrupted = false); /// starts tabbing void startTabbing(const XButtonEvent &be); + /// determine the reference corner from a string + static ReferenceCorner getCorner(std::string str); + /// convert to coordinates on the root window + void translateCoords(int &x, int &y, ReferenceCorner dir = LEFTTOP) const; + /** @name accessors */ @@ -624,7 +629,7 @@ private: FbTk::FbWindow &m_parent; ///< window on which we draw move/resize rectangle (the "root window") - ResizeDirection m_resize_corner; //< the current resize corner used while resizing + ReferenceCorner m_resize_corner; //< the current corner used while resizing static int s_num_grabs; ///< number of XGrabPointer's }; -- cgit v0.11.2