combined code for saved window positions and MoveTo key command

added left, right, top, and bottom center reference points
This commit is contained in:
Mark Tiefenbruck 2008-08-18 05:12:30 -07:00
parent 2ab539073b
commit 37b18a9694
12 changed files with 172 additions and 151 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -410,65 +410,38 @@ FbTk::Command<void> *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;
int x = m_pos_x, y = m_pos_y;
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;
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);

View file

@ -206,25 +206,21 @@ private:
class MoveToCmd: public WindowHelperCmd {
public:
enum {
LEFT = 1 << 0,
RIGHT = 1 << 1,
UPPER = 1 << 2,
LOWER = 1 << 3,
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) { }
IGNORE_X = 1 << 8,
IGNORE_Y = 1 << 9
};
explicit MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc);
static FbTk::Command<void> *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

View file

@ -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<FluxboxWindow::ResizeDirection>(ce.data.l[2]));
static_cast<FluxboxWindow::ReferenceCorner>(ce.data.l[2]));
break;
case _NET_WM_MOVERESIZE_MOVE:
case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:

View file

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

View file

@ -81,8 +81,7 @@ public:
POS_UPPERRIGHT,
POS_LOWERLEFT,
POS_LOWERRIGHT,
POS_CENTER,
POS_WINCENTER
POS_CENTER
};

View file

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

View file

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