all repos — fluxbox @ 7b6dc2ad72a4c4ecd20eddbfb6f1b4c3bd2a7024

custom fork of the fluxbox windowmanager

Allow percentage values for some Window commands
Lajos Koszti ajnasz@ajnasz.hu
commit

7b6dc2ad72a4c4ecd20eddbfb6f1b4c3bd2a7024

parent

5d56046b68635cea2c187e59a9d8c514e2d6bdb2

M .gitignore.gitignore

@@ -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
M doc/asciidoc/fluxbox-apps.txtdoc/asciidoc/fluxbox-apps.txt

@@ -114,14 +114,17 @@ Specify the layer to open the window on (by number). Each layer has a

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*
M doc/asciidoc/fluxbox-keys.txtdoc/asciidoc/fluxbox-keys.txt

@@ -259,17 +259,22 @@

*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.
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -36,6 +36,7 @@ #include "FbTk/I18n.hh"

#include "FbTk/stringstream.hh" #include "FbTk/StringUtil.hh" #include "FbTk/Util.hh" +#include "FbTk/RelCalcHelper.hh" #ifdef HAVE_CONFIG_H #include "config.h"

@@ -46,7 +47,6 @@ #include <cstdlib>

#else #include <stdlib.h> #endif - using FbTk::Command;

@@ -477,21 +477,59 @@

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") + + typedef std::vector<string> StringTokens; + StringTokens tokens; + FbTk::StringUtil::stringtok<StringTokens>(tokens, args); + + if (tokens.size() < 1) { + return 0; + } + + 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") { - dy = dx; + } 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); - return new ResizeCmd(dx, dy); + 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 @@ }

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 @@ return 0;

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 @@ if (refc == FluxboxWindow::ERROR)

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

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

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

return; } - fbwindow().setFocusedAlpha(m_relative + fbwindow().setFocusedAlpha(m_relative ? FbTk::Util::clamp(fbwindow().getFocusedAlpha() + m_focus, 0, 255) : m_focus);
M src/CurrentWindowCmd.hhsrc/CurrentWindowCmd.hh

@@ -158,24 +158,26 @@

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

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{
M src/FbTk/FbWindow.hhsrc/FbTk/FbWindow.hh

@@ -28,6 +28,12 @@ #include <memory>

#include <string> #include <set> +#ifdef HAVE_CMATH + #include <cmath> +#else + #include <math.h> +#endif + namespace FbTk { class Color;

@@ -257,6 +263,7 @@ public:

virtual void renderForeground(FbWindow &win, FbDrawable &drawable) = 0; virtual ~FbWindowRenderer() { } }; + } // end namespace FbTk
M src/FbTk/Makefile.amsrc/FbTk/Makefile.am

@@ -64,6 +64,7 @@ Select2nd.hh STLUtil.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} \
A src/FbTk/RelCalcHelper.cc

@@ -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); + } + + } + +}
A src/FbTk/RelCalcHelper.hh

@@ -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
M src/Remember.ccsrc/Remember.cc

@@ -54,7 +54,6 @@ #ifndef _GNU_SOURCE

#define _GNU_SOURCE #endif // _GNU_SOURCE -#include <iostream> #include <set>

@@ -99,15 +98,24 @@ void rememberWorkspace(int ws)

{ 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 @@ void rememberFocusNewWindow(bool state)

{ 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 @@ int head;

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 @@ if (!had_error)

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 @@ if (str_option.length())

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 @@ if (a.head_remember) {

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

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

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 @@ if (!app) {

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

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 @@ if (app->head_remember) {

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)
M src/Screen.ccsrc/Screen.cc

@@ -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;
M src/Screen.hhsrc/Screen.hh

@@ -38,6 +38,7 @@ #include "FbTk/Resource.hh"

#include "FbTk/MultLayers.hh" #include "FbTk/NotCopyable.hh" #include "FbTk/Signal.hh" +#include "FbTk/RelCalcHelper.hh" #include "FocusControl.hh"

@@ -453,11 +454,27 @@ /// This resource is now owned by Screen and will be destroyed

/// 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;
M src/Window.ccsrc/Window.cc

@@ -3714,10 +3714,9 @@ return RIGHTBOTTOM;

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,12 +3724,23 @@ 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; +} + +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) y = bottom - height() - bw - y; if (dir == LEFT || dir == CENTER || dir == RIGHT) 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 {
M src/Window.hhsrc/Window.hh

@@ -350,6 +350,8 @@

/// 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; /**
M src/tests/StringUtiltest.ccsrc/tests/StringUtiltest.cc

@@ -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 @@ if (StringUtil::strcasestr("Test", "ESTabc") == strcasestr("Test", "ESTabc"))

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 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 @@ cerr<<'\t';

else cerr<<" "; } - cerr<<"^ here"<<endl; - + cerr<<"^ here"<<endl; + } void testGetStringBetween() {

@@ -101,7 +101,7 @@ vector<string> stringlist;

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

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 @@ cerr<<"newstr = "<<newstr<<endl;

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