Allow percentage values for some Window commands

This commit is contained in:
Lajos Koszti 2012-04-06 14:10:24 +02:00 committed by Mathias Gumz
parent 5d56046b68
commit 7b6dc2ad72
15 changed files with 415 additions and 101 deletions

8
.gitignore vendored
View file

@ -51,5 +51,13 @@ util/startfluxbox
version.h
install-sh
missing
src/tests/testFont
src/tests/testFullscreen
src/tests/testDemandAttention
src/tests/testKeys
src/tests/testRectangleUtil
src/tests/testSignals
src/tests/testStringUtil
src/tests/testTexture
*~
.*.swp

View file

@ -114,14 +114,17 @@ respectively.
number. The named ones are: 2-AboveDock, 4-Dock, 6-Top, 8-Normal, 10-Bottom,
12-Desktop.
*[Dimensions]* {'width' 'height'}::
*[Dimensions]* {'width[%]' 'height[%]'}::
Opens the application with the specified 'width' and 'height', in pixels.
If the value is given in percent, then the window size will be based on
the current screen's size.
*[Position]* ('anchor') {'X' 'Y'}::
*[Position]* ('anchor') {'X[%]' 'Y[%]'}::
Position the application at a particular spot. By default the upper-left corner
is placed at screen coordinates ('X','Y'). If you specify an 'anchor', say
BottomRight, then the lower-right corner of the window is positioned ('X','Y')
pixels from the lower-right corner of the screen.
pixels from the lower-right corner of the screen. If the value is given in
percent, then the coordinates will be based on the current screen's size.
+
'anchor' may be set to one of:;;
*TopLeft Left BottomLeft Top Center Bottom TopRight Right BottomRight*

View file

@ -259,17 +259,22 @@ These commands ordinarily affect only the currently focused window. The
*DetachClient*::
Remove the current tab from the tab group, placing it in its own window.
*ResizeTo* 'width' 'height'::
Resizes the window to the given width and height.
*ResizeTo* 'width[%]' 'height[%]'::
Resizes the window to the given width and height. If the value is given in
percent, then the window size will be based on the current screen's size.
*Resize* 'delta-width' 'delta-height'::
Resizes the window relative to the current width and height.
*Resize* 'delta-width[%]' 'delta-height[%]'::
Resizes the window relative to the current width and height. If the value
is given in percent, then the window size will be based on the current
window's size.
*ResizeHorizontal* 'delta-width' / *ResizeVertical* 'delta-height'::
Resizes the window in one dimension only
*ResizeHorizontal* 'delta-width[%]' / *ResizeVertical* 'delta-height[%]'::
Resizes the window in one dimension only. If the value is given in
percent, then the window size will be based on the current window's size.
*MoveTo* 'x' 'y' ['anchor']::
Moves the window to the given coordinates, given in pixels.
*MoveTo* 'x[%]' 'y[%]' ['anchor']::
Moves the window to the given coordinates, given in pixels or relatively to
the current screen size if % is specified after the value.
+
If either 'x' or 'y' is set to *\**, that coordinate will be ignored, and the
movement will only take place in one dimension.

View file

@ -36,6 +36,7 @@
#include "FbTk/stringstream.hh"
#include "FbTk/StringUtil.hh"
#include "FbTk/Util.hh"
#include "FbTk/RelCalcHelper.hh"
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -47,7 +48,6 @@
#include <stdlib.h>
#endif
using FbTk::Command;
namespace {
@ -477,21 +477,59 @@ void MoveCmd::real_execute() {
fbwindow().move(fbwindow().x() + m_step_size_x, fbwindow().y() + m_step_size_y);
}
namespace {
template <typename Container>
static void parseToken(Container &container, int &d, bool &is_relative, bool &ignore) {
if (container.size() < 1)
return;
d = 0;
is_relative = false;
ignore = false;
if (container[0] == '*') {
ignore = true;
} else if (container[container.size() - 1] == '%') {
// its a percent
is_relative = true;
d = atoi(container.substr(0, container.size() - 1).c_str());
} else {
d = atoi(container.c_str());
}
}
}
FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk_istringstream is(args.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
if (command == "resizehorizontal")
dy = 0;
else if (command == "resizevertical") {
dy = dx;
dx = 0;
typedef std::vector<string> StringTokens;
StringTokens tokens;
FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
if (tokens.size() < 1) {
return 0;
}
if (command == "resizeto")
return new ResizeToCmd(dx, dy);
return new ResizeCmd(dx, dy);
int dx, dy;
bool is_relative_x = false, is_relative_y = false, ignore_x = false, ignore_y = false;
if (command == "resizehorizontal") {
parseToken(tokens[0], dx, is_relative_x, ignore_x);
dy = 0;
} else if (command == "resizevertical") {
parseToken(tokens[0], dy, is_relative_y, ignore_y);
dx = 0;
} else {
if (tokens.size() < 2) {
return 0;
}
parseToken(tokens[0], dx, is_relative_x, ignore_x);
parseToken(tokens[1], dy, is_relative_y, ignore_y);
}
if (command == "resizeto") {
return new ResizeToCmd(dx, dy, is_relative_x, is_relative_y);
}
return new ResizeCmd(dx, dy, is_relative_x, is_relative_y);
}
REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse, void);
@ -499,8 +537,8 @@ REGISTER_COMMAND_PARSER(resizeto, ResizeCmd::parse, void);
REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse, void);
REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse, void);
ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y, bool is_relative_x, bool is_relative_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_is_relative_x(is_relative_x), m_is_relative_y(is_relative_y) { }
void ResizeCmd::real_execute() {
@ -512,11 +550,27 @@ void ResizeCmd::real_execute() {
disableMaximizationIfNeeded(fbwindow());
int w = std::max<int>(static_cast<int>(fbwindow().width() +
m_step_size_x * fbwindow().winClient().widthInc()),
int dx = m_step_size_x, dy = m_step_size_y;
int windowWidth = fbwindow().width(), windowHeight = fbwindow().height();
unsigned int widthInc = fbwindow().winClient().widthInc(),
heightInc = fbwindow().winClient().heightInc();
if (m_is_relative_x) {
// dx = floor(windowWidth * m_step_size_x / 100 / widthInc + 0.5);
dx = static_cast<int>(FbTk::RelCalcHelper::calPercentageValueOf(windowWidth, m_step_size_x) / widthInc);
}
if (m_is_relative_y) {
// dy = floor(windowHeight * m_step_size_y / 100 / heightInc + 0.5);
dy = static_cast<int>(FbTk::RelCalcHelper::calPercentageValueOf(windowHeight, m_step_size_y) / heightInc);
}
int w = std::max<int>(static_cast<int>(windowWidth +
dx * widthInc),
fbwindow().frame().titlebarHeight() * 2 + 10);
int h = std::max<int>(static_cast<int>(fbwindow().height() +
m_step_size_y * fbwindow().winClient().heightInc()),
int h = std::max<int>(static_cast<int>(windowHeight +
dy * heightInc),
fbwindow().frame().titlebarHeight() + 10);
fbwindow().resize(w, h);
@ -533,17 +587,10 @@ FbTk::Command<void> *MoveToCmd::parse(const string &cmd, const string &args,
FluxboxWindow::ReferenceCorner refc = FluxboxWindow::LEFTTOP;
int x = 0, y = 0;
bool ignore_x = false, ignore_y = false;
bool ignore_x = false, ignore_y = false, is_relative_x = false, is_relative_y = false;
if (tokens[0][0] == '*')
ignore_x = true;
else
x = atoi(tokens[0].c_str());
if (tokens[1][0] == '*' && !ignore_x)
ignore_y = true;
else
y = atoi(tokens[1].c_str());
parseToken(tokens[0], x, is_relative_x, ignore_x);
parseToken(tokens[1], y, is_relative_y, ignore_y);
if (tokens.size() >= 3) {
refc = FluxboxWindow::getCorner(tokens[2]);
@ -551,7 +598,7 @@ FbTk::Command<void> *MoveToCmd::parse(const string &cmd, const string &args,
refc = FluxboxWindow::LEFTTOP;
}
return new MoveToCmd(x, y, ignore_x, ignore_y, refc);
return new MoveToCmd(x, y, ignore_x, ignore_y, is_relative_x, is_relative_y, refc);
}
REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse, void);
@ -568,19 +615,31 @@ void MoveToCmd::real_execute() {
int x = m_pos_x, y = m_pos_y;
int head = fbwindow().getOnHead();
fbwindow().translateCoords(x, y, m_corner);
if (m_ignore_x)
if (m_ignore_x) {
x = fbwindow().x();
if (m_ignore_y)
} else {
if (m_is_relative_x) {
x = fbwindow().screen().calRelativeWidth(head, x);
}
fbwindow().translateXCoords(x, m_corner);
}
if (m_ignore_y) {
y = fbwindow().y();
} else {
if (m_is_relative_y) {
y = fbwindow().screen().calRelativeHeight(head, y);
}
fbwindow().translateYCoords(y, m_corner);
}
fbwindow().move(x, y);
}
ResizeToCmd::ResizeToCmd(const int step_size_x, const int step_size_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
ResizeToCmd::ResizeToCmd(const int step_size_x, const int step_size_y, const bool is_relative_x, const bool is_relative_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_is_relative_x(is_relative_x), m_is_relative_y(is_relative_y) { }
void ResizeToCmd::real_execute() {
@ -592,9 +651,31 @@ void ResizeToCmd::real_execute() {
disableMaximizationIfNeeded(fbwindow());
int dx = m_step_size_x, dy = m_step_size_y;
int head = fbwindow().getOnHead();
if (m_step_size_x > 0 && m_step_size_y > 0)
fbwindow().resize(m_step_size_x, m_step_size_y);
if (m_is_relative_x) {
dx = fbwindow().screen().calRelativeWidth(head, dx);
if(dx <= 0) {
dx = fbwindow().width();
}
}
if (m_is_relative_y) {
dy = fbwindow().screen().calRelativeHeight(head, dy);
if(dy <= 0) {
dy = fbwindow().height();
}
}
if (dx == 0) {
dx = fbwindow().width();
}
if (dy == 0) {
dy = fbwindow().height();
}
fbwindow().resize(dx, dy);
}
REGISTER_COMMAND(fullscreen, FullscreenCmd, void);
@ -720,7 +801,7 @@ void SetAlphaCmd::real_execute() {
return;
}
fbwindow().setFocusedAlpha(m_relative
fbwindow().setFocusedAlpha(m_relative
? FbTk::Util::clamp(fbwindow().getFocusedAlpha() + m_focus, 0, 255)
: m_focus);

View file

@ -158,24 +158,26 @@ private:
// resize cmd, relative size
class ResizeCmd: public WindowHelperCmd{
public:
explicit ResizeCmd(int step_size_x, int step_size_y);
explicit ResizeCmd(int step_size_x, int step_size_y, bool is_relative_x, bool is_relative_y);
static FbTk::Command<void> *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
void real_execute();
private:
const int m_step_size_x;
const int m_step_size_y;
const int m_step_size_x;
const int m_step_size_y;
const bool m_is_relative_x;
const bool m_is_relative_y;
};
class MoveToCmd: public WindowHelperCmd {
public:
explicit MoveToCmd(int pos_x, int pos_y, bool ignore_x, bool ignore_y,
explicit MoveToCmd(int pos_x, int pos_y, bool ignore_x, bool ignore_y, bool is_relative_x, bool is_relative_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_is_relative_x(is_relative_x), m_is_relative_y(is_relative_y),
m_corner(refc) { }
static FbTk::Command<void> *parse(const std::string &command,
@ -185,19 +187,21 @@ protected:
private:
int m_pos_x, m_pos_y;
bool m_ignore_x, m_ignore_y;
bool m_ignore_x, m_ignore_y, m_is_relative_x, m_is_relative_y;
FluxboxWindow::ReferenceCorner m_corner;
};
// resize cmd
class ResizeToCmd: public WindowHelperCmd{
public:
explicit ResizeToCmd(int step_size_x, int step_size_y);
explicit ResizeToCmd(int step_size_x, int step_size_y, bool is_relative_x, bool is_relative_y);
protected:
void real_execute();
private:
const int m_step_size_x;
const int m_step_size_y;
const bool m_is_relative_x;
const bool m_is_relative_y;
};
class FullscreenCmd: public WindowHelperCmd{

View file

@ -28,6 +28,12 @@
#include <string>
#include <set>
#ifdef HAVE_CMATH
#include <cmath>
#else
#include <math.h>
#endif
namespace FbTk {
class Color;
@ -259,6 +265,7 @@ public:
};
} // end namespace FbTk
#endif // FBTK_FBWINDOW_HH

View file

@ -64,6 +64,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
CachedPixmap.hh CachedPixmap.cc \
Slot.hh Signal.hh MemFun.hh SelectArg.hh \
Util.hh \
RelCalcHelper.hh RelCalcHelper.cc \
${xpm_SOURCE} \
${xft_SOURCE} \
${xmb_SOURCE} \

38
src/FbTk/RelCalcHelper.cc Normal file
View file

@ -0,0 +1,38 @@
// RelCalcHelper.hh for Fluxbox - an X11 Window manager
// Copyright (c) 2012 Lajos Koszti (ajnasz at ajnasz.hu)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "RelCalcHelper.hh"
namespace FbTk {
namespace RelCalcHelper {
int calPercentageValueOf(int i, int j) {
return floor(i * j / 100 + 0.5);
}
int calPercentageOf(int i, int j) {
return floor((float) i / (float) j * 100 + 0.5);
}
}
}

43
src/FbTk/RelCalcHelper.hh Normal file
View file

@ -0,0 +1,43 @@
// RelCalcHelper.cc for Fluxbox - an X11 Window manager
// Copyright (c) 2012 Lajos Koszti (ajnasz at ajnasz.hu)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef FBTK_RELCALCHELPER_HH
#define FBTK_RELCALCHELPER_HH
#ifdef HAVE_CMATH
#include <cmath>
#else
#include <math.h>
#endif
namespace FbTk {
namespace RelCalcHelper {
int calPercentageOf(int i, int j);
int calPercentageValueOf(int i, int j);
}
}
#endif // FBTK_RELCALCHELPER_HH

View file

@ -54,7 +54,6 @@
#define _GNU_SOURCE
#endif // _GNU_SOURCE
#include <iostream>
#include <set>
@ -99,15 +98,24 @@ public:
{ workspace = ws; workspace_remember = true; }
void rememberHead(int h)
{ head = h; head_remember = true; }
void rememberDimensions(int width, int height)
{ w = width; h = height; dimensions_remember = true; }
void rememberDimensions(int width, int height, bool is_relative)
{
dimension_is_relative = is_relative;
w = width; h = height;
dimensions_remember = true;
}
void rememberFocusHiddenstate(bool state)
{ focushiddenstate= state; focushiddenstate_remember= true; }
void rememberIconHiddenstate(bool state)
{ iconhiddenstate= state; iconhiddenstate_remember= true; }
void rememberPosition(int posx, int posy,
void rememberPosition(int posx, int posy, bool is_relative,
FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP)
{ x = posx; y = posy; refc = rfc; position_remember = true; }
{
position_is_relative = is_relative;
x = posx; y = posy;
refc = rfc;
position_remember = true;
}
void rememberShadedstate(bool state)
{ shadedstate = state; shadedstate_remember = true; }
void rememberTabstate(bool state)
@ -120,7 +128,7 @@ public:
{ focusnewwindow = state; focusnewwindow_remember = true; }
void rememberJumpworkspace(bool state)
{ jumpworkspace = state; jumpworkspace_remember = true; }
void rememberLayer(int layernum)
void rememberLayer(int layernum)
{ layer = layernum; layer_remember = true; }
void rememberSaveOnClose(bool state)
{ save_on_close = state; save_on_close_remember = true; }
@ -141,9 +149,11 @@ public:
bool dimensions_remember;
int w,h; // width, height
bool dimension_is_relative;
bool position_remember;
int x,y;
bool position_is_relative;
FluxboxWindow::ReferenceCorner refc;
bool alpha_remember;
@ -483,10 +493,13 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
app.rememberLayer(l);
} else if (str_key == "dimensions") {
unsigned int h,w;
if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2)
app.rememberDimensions(w, h);
else
if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2) {
app.rememberDimensions(w, h, false);
} else if(sscanf(str_label.c_str(), "%u%% %u%%", &w, &h) == 2) {
app.rememberDimensions(w, h, true);
} else {
had_error = true;
}
} else if (str_key == "position") {
FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP;
int x = 0, y = 0;
@ -497,10 +510,15 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
r = FluxboxWindow::getCorner(str_option);
had_error = (r == FluxboxWindow::ERROR);
if (!had_error && sscanf(str_label.c_str(), "%d %d", &x, &y) == 2)
app.rememberPosition(x, y, r);
else
if (!had_error){
if(sscanf(str_label.c_str(), "%d %d", &x, &y) == 2) {
app.rememberPosition(x, y, false, r);
} else if (sscanf(str_label.c_str(), "%d%% %d%%", &x, &y) == 2){
app.rememberPosition(x, y, true, r);
}
} else {
had_error = true;
}
} else if (str_key == "shaded") {
app.rememberShadedstate((strcasecmp(str_label.c_str(), "yes") == 0));
} else if (str_key == "tab") {
@ -910,7 +928,11 @@ void Remember::save() {
apps_file << " [Head]\t{" << a.head << "}" << endl;
}
if (a.dimensions_remember) {
apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl;
if(a.dimension_is_relative) {
apps_file << " [Dimensions]\t{" << a.w << "% " << a.h << "%}" << endl;
} else {
apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl;
}
}
if (a.position_remember) {
apps_file << " [Position]\t(";
@ -942,7 +964,11 @@ void Remember::save() {
default:
apps_file << "UPPERLEFT";
}
apps_file << ")\t{" << a.x << " " << a.y << "}" << endl;
if(a.position_is_relative) {
apps_file << ")\t{" << a.x << "% " << a.y << "%}" << endl;
} else {
apps_file << ")\t{" << a.x << " " << a.y << "}" << endl;
}
}
if (a.shadedstate_remember) {
apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl;
@ -1029,7 +1055,7 @@ void Remember::save() {
if (a.alpha_remember) {
if (a.focused_alpha == a.unfocused_alpha)
apps_file << " [Alpha]\t{" << a.focused_alpha << "}" << endl;
else
else
apps_file << " [Alpha]\t{" << a.focused_alpha << " " << a.unfocused_alpha << "}" << endl;
}
apps_file << "[end]" << endl;
@ -1110,6 +1136,7 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
app = add(winclient);
if (!app) return;
}
int head, head_x, head_y, win_w, win_h, percx, percy;
switch (attrib) {
case REM_WORKSPACE:
app->rememberWorkspace(win->workspaceNumber());
@ -1117,16 +1144,18 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
case REM_HEAD:
app->rememberHead(win->screen().getHead(win->fbWindow()));
break;
case REM_DIMENSIONS:
app->rememberDimensions(win->normalWidth(),
win->normalHeight());
case REM_DIMENSIONS: {
head = win->screen().getHead(win->fbWindow());
int percx = win->screen().calRelativeDimensionWidth(head, win->normalWidth());
int percy = win->screen().calRelativeDimensionHeight(head, win->normalHeight());
app->rememberDimensions(percx, percy, true);
break;
}
case REM_POSITION: {
int head = win->screen().getHead(win->fbWindow());
int head_x = win->screen().maxLeft(head);
int head_y = win->screen().maxTop(head);
app->rememberPosition(win->normalX() - head_x,
win->normalY() - head_y);
head = win->screen().getHead(win->fbWindow());
int percx = win->screen().calRelativePositionWidth(head, win->normalX());
int percy = win->screen().calRelativePositionHeight(head, win->normalY());
app->rememberPosition(percx, percy, true);
break;
}
case REM_FOCUSHIDDENSTATE:
@ -1288,13 +1317,32 @@ void Remember::setupFrame(FluxboxWindow &win) {
win.setOnHead(app->head);
}
if (app->dimensions_remember)
win.resize(app->w, app->h);
if (app->dimensions_remember) {
int win_w, win_h;
if(app->dimension_is_relative) {
int head = screen.getHead(win.fbWindow());
int screen_y = screen.maxBottom(head) - screen.maxTop(head);
win_w = screen.calRelativeWidth(head, app->w);
win_h = screen.calRelativeHeight(head, app->h);
} else {
win_w = app->w;
win_h = app->h;
}
win.resize(win_w, win_h);
}
if (app->position_remember) {
int newx = app->x, newy = app->y;
win.translateCoords(newx, newy, app->refc);
win.move(newx, newy);
int newx, newy;
if(app->position_is_relative) {
int head = screen.getHead(win.fbWindow());
newx = screen.calRelativeWidth(head, app->x);
newy = screen.calRelativeHeight(head, app->y);
} else {
newx = app->x, newy = app->y;
}
win.translateCoords(newx, newy, app->refc);
win.move(newx, newy);
}
if (app->shadedstate_remember)

View file

@ -1485,6 +1485,55 @@ void BScreen::addManagedResource(FbTk::Resource_base *resource) {
m_managed_resources.push_back(resource);
}
int BScreen::getGap(int head, const char type) {
return type == 'w' ? getXGap(head) : getYGap(head);
}
int BScreen::calRelativeSize(int head, int i, char type) {
// return floor(i * getGap(head, type) / 100 + 0.5);
return FbTk::RelCalcHelper::calPercentageValueOf(i, getGap(head, type));
}
int BScreen::calRelativeWidth(int head, int i) {
return calRelativeSize(head, i, 'w');
}
int BScreen::calRelativeHeight(int head, int i) {
return calRelativeSize(head, i, 'h');
}
int BScreen::calRelativePosition(int head, int i, char type) {
int max = type == 'w' ? maxLeft(head) : maxTop(head);
// return floor((i - min) / getGap(head, type) * 100 + 0.5);
return FbTk::RelCalcHelper::calPercentageOf((i - max), getGap(head, type));
}
// returns a pixel, which is relative to the width of the screen
// screen starts from 0, 1000 px width, if i is 10 then it should return 100
int BScreen::calRelativePositionWidth(int head, int i) {
return calRelativePosition(head, i, 'w');
}
// returns a pixel, which is relative to the height of th escreen
// screen starts from 0, 1000 px height, if i is 10 then it should return 100
int BScreen::calRelativePositionHeight(int head, int i) {
return calRelativePosition(head, i, 'h');
}
int BScreen::calRelativeDimension(int head, int i, char type) {
// return floor(i / getGap(head, type) * 100 + 0.5);
return FbTk::RelCalcHelper::calPercentageOf(i, getGap(head, type));
}
int BScreen::calRelativeDimensionWidth(int head, int i) {
return calRelativeDimension(head, i, 'w');
}
int BScreen::calRelativeDimensionHeight(int head, int i) {
return calRelativeDimension(head, i, 'h');
}
float BScreen::getXGap(int head) {
return maxRight(head) - maxLeft(head);
}
float BScreen::getYGap(int head) {
return maxBottom(head) - maxTop(head);
}
void BScreen::setupConfigmenu(FbTk::Menu &menu) {
_FB_USES_NLS;

View file

@ -38,6 +38,7 @@
#include "FbTk/MultLayers.hh"
#include "FbTk/NotCopyable.hh"
#include "FbTk/Signal.hh"
#include "FbTk/RelCalcHelper.hh"
#include "FocusControl.hh"
@ -453,12 +454,28 @@ public:
/// when screen dies
void addManagedResource(FbTk::Resource_base *resource);
int calRelativeSize(int head, int i, char type);
int calRelativeWidth(int head, int i);
int calRelativeHeight(int head, int i);
int calRelativePosition(int head, int i, char type);
int calRelativePositionWidth(int head, int i);
int calRelativePositionHeight(int head, int i);
int calRelativeDimension(int head, int i, char type);
int calRelativeDimensionWidth(int head, int i);
int calRelativeDimensionHeight(int head, int i);
private:
void setupConfigmenu(FbTk::Menu &menu);
void renderGeomWindow();
void renderPosWindow();
void focusedWinFrameThemeReconfigured();
int getGap(int head, const char type);
float getXGap(int head);
float getYGap(int head);
const Strut* availableWorkspaceArea(int head) const;
FbTk::SignalTracker m_tracker;

View file

@ -3714,10 +3714,9 @@ FluxboxWindow::ReferenceCorner FluxboxWindow::getCorner(string str) {
return ERROR;
}
void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
void FluxboxWindow::translateXCoords(int &x, 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);
left = screen().maxLeft(head), right = screen().maxRight(head);
if (dir == LEFTTOP || dir == LEFT || dir == LEFTBOTTOM)
x += left;
@ -3725,6 +3724,12 @@ void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
x = right - width() - bw - x;
if (dir == TOP || dir == CENTER || dir == BOTTOM)
x += (left + right - width() - bw)/2;
}
void FluxboxWindow::translateYCoords(int &y, ReferenceCorner dir) const {
int head = getOnHead(), bw = 2 * frame().window().borderWidth(),
top = screen().maxTop(head), bottom = screen().maxBottom(head);
if (dir == LEFTTOP || dir == TOP || dir == RIGHTTOP)
y += top;
if (dir == LEFTBOTTOM || dir == BOTTOM || dir == RIGHTBOTTOM)
@ -3733,6 +3738,11 @@ void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
y += (top + bottom - height() - bw)/2;
}
void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
translateXCoords(x, dir);
translateYCoords(y, dir);
}
int FluxboxWindow::getOnHead() const {
return screen().getHead(fbWindow());
}

View file

@ -350,6 +350,8 @@ public:
/// determine the reference corner from a string
static ReferenceCorner getCorner(std::string str);
/// convert to coordinates on the root window
void translateXCoords(int &x, ReferenceCorner dir = LEFTTOP) const;
void translateYCoords(int &y, ReferenceCorner dir = LEFTTOP) const;
void translateCoords(int &x, int &y, ReferenceCorner dir = LEFTTOP) const;
/**

View file

@ -33,9 +33,9 @@
using namespace std;
using namespace FbTk;
void testStringtok() {
void testStringtok() {
vector<string> ls;
StringUtil::stringtok(ls, " arg1 arg2 \targ3\n arg4 arg5\t\t\t\targ6\n\n \n\n \t\t\narg7");
StringUtil::stringtok(ls, " arg1 arg2 \targ3\n arg4 arg5\t\t\t\targ6\n\n \n\n \t\t\narg7");
cerr<<"Size: "<<ls.size()<<". Should be: 7."<<endl;
for (vector<string>::const_iterator i = ls.begin();
i != ls.end(); ++i) {
@ -66,7 +66,7 @@ void testStrcasestr() {
cerr<<"ok."<<endl;
else
cerr<<"faild."<<endl;
cerr<<"test3 ";
if (StringUtil::strcasestr("TeSt", "abcTEStabc") == strcasestr("TeSt", "abcTEStabc"))
cerr<<"ok."<<endl;
@ -82,7 +82,7 @@ void testStrcasestr() {
}
void showError(int line, int pos, string& instr) {
cerr<<"Error on line: "<<line<<endl;
cerr<<instr<<endl;
for (int c=0; c<pos; c++) {
@ -91,8 +91,8 @@ void showError(int line, int pos, string& instr) {
else
cerr<<" ";
}
cerr<<"^ here"<<endl;
cerr<<"^ here"<<endl;
}
void testGetStringBetween() {
@ -101,7 +101,7 @@ void testGetStringBetween() {
stringlist.push_back(" \t\t\t \t[(in \\)\t haha )] \t\t ");
stringlist.push_back("(in\\)) {_ _ my_ _}");
stringlist.push_back("(in) {_ _ my_ _}");
stringlist.push_back("(in){_ _ my_ _}");
stringlist.push_back("(in){_ _ my_ _}");
stringlist.push_back("\t \t \t ( in ) {haha}");
stringlist.push_back("\t \t \t (( in \\) ) {haha}");
stringlist.push_back("\t \t \t (( in \\) ){hihi}");
@ -116,17 +116,18 @@ void testGetStringBetween() {
cerr<<"string="<<stringlist[i]<<endl;
cerr<<"pos="<<pos<<" ::"<<out;
total_pos += pos;
pos = StringUtil::getStringBetween(out, stringlist[i].c_str()+total_pos, '{', '}');
pos = StringUtil::getStringBetween(out, stringlist[i].c_str()+total_pos, '{', '}');
if (pos<=0) {
pos=-pos;
showError(i+1, total_pos+pos, stringlist[i]);
continue;
}
}
cerr<<"::"<<out<<"::"<<endl;
total_pos += pos;
}
}
int main() {
int main() {
try {
string replaceme = "something((((otherthanthis)could[be]changed";
@ -140,13 +141,10 @@ int main() {
} catch (std::exception & e) {
cerr<<"exception: "<<e.what()<<endl;
}
cerr<<"Testing stringtok."<<endl;
cerr<<"Testing stringtok."<<endl;
testStringtok();
cerr<<"Testing expandFilename."<<endl;
testExpandFilename();
cerr<<"Testing strcasestr."<<endl;
testStrcasestr();
}