all repos — fluxbox @ 53de872163d61c87fa8128767ebbc218599f3835

custom fork of the fluxbox windowmanager

Mixed relative and absolute values for apps

Allow setting relative value for x and y or width and height separately in
the apps configuration file. This makes these settings compatible with ones
available in the keys file.

Previous buggy behavior:
If someone has specified, e.g. "[Dimensions] {50% 100}" it was parsed as
"{50% 100%}" not as "{50% 100px}" which was inconsistent with the "keys"
configuration file.

From now on it is possible to write something like this:
[app]
  [Position] (RIGHT) {50% 0}
  [Dimensions] {300 100%}
[end]

Signed-off-by: Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com>
Arkadiusz Bokowy arkadiusz.bokowy@gmail.com
commit

53de872163d61c87fa8128767ebbc218599f3835

parent

22866c4d30f5b289c429c5ca88d800200db4fc4f

3 files changed, 98 insertions(+), 84 deletions(-)

jump to
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -500,27 +500,6 @@

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

@@ -536,15 +515,15 @@ int dx = 0, dy = 0;

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); + dx = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x); } else if (command == "resizevertical") { - parseToken(tokens[0], dy, is_relative_y, ignore_y); + dy = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_y, ignore_y); } 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); + dx = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x); + dy = FbTk::StringUtil::parseSizeToken(tokens[1], is_relative_y, ignore_y); } if (command == "resizeto") {

@@ -610,8 +589,8 @@ FluxboxWindow::ReferenceCorner refc = FluxboxWindow::LEFTTOP;

int x = 0, y = 0; bool ignore_x = false, ignore_y = false, is_relative_x = false, is_relative_y = false; - parseToken(tokens[0], x, is_relative_x, ignore_x); - parseToken(tokens[1], y, is_relative_y, ignore_y); + x = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x); + y = FbTk::StringUtil::parseSizeToken(tokens[1], is_relative_y, ignore_y); if (tokens.size() >= 3) { refc = FluxboxWindow::getCorner(tokens[2]);
M src/FbTk/StringUtil.hhsrc/FbTk/StringUtil.hh

@@ -24,6 +24,12 @@ #define FBTK_STRINGUTIL_HH

#include <string> +#ifdef HAVE_CSTDLIB +#include <cstdlib> +#else +#include <stdlib.h> +#endif + namespace FbTk { namespace StringUtil {

@@ -61,12 +67,12 @@ /// @param len_alphabet - length of alphabet

/// @param found - position of found char in alphabet (optional) /// @return position of trigger if found /// @return std::string::npos if nothing found -std::string::size_type findCharFromAlphabetAfterTrigger(const std::string& in, +std::string::size_type findCharFromAlphabetAfterTrigger(const std::string& in, char trigger, const char alphabet[], size_t len_alphabet, size_t* found); /// @return copy of original with find_string replaced with "replace" -std::string replaceString(const std::string &original, +std::string replaceString(const std::string &original, const char *find_string, const char *replace);

@@ -141,6 +147,31 @@

// set up for next loop i = j + 1; } +} + +/// Parse token, which might be in formats as follows: <int>, <int>% or *. +/// @param relative - parsed relative value (percentage suffix) +/// @param ignore - this token should be ignored (asterisk) +/// @return parsed integer value or 0 if not applicable +template <typename Container> +static int +parseSizeToken(Container &container, bool &relative, bool &ignore) { + + if (container.empty()) + return 0; + + relative = false; + ignore = false; + + if (container[0] == '*') { + ignore = true; + return 0; + } + + if (container[container.size() - 1] == '%') + relative = true; + + return atoi(container.c_str()); } } // end namespace StringUtil
M src/Remember.ccsrc/Remember.cc

@@ -110,9 +110,10 @@ void rememberWorkspace(int ws)

{ workspace = ws; workspace_remember = true; } void rememberHead(int h) { head = h; head_remember = true; } - void rememberDimensions(int width, int height, bool is_relative) + void rememberDimensions(int width, int height, bool is_w_relative, bool is_h_relative) { - dimension_is_relative = is_relative; + dimension_is_w_relative = is_w_relative; + dimension_is_h_relative = is_h_relative; w = width; h = height; dimensions_remember = true; }

@@ -120,10 +121,11 @@ void rememberFocusHiddenstate(bool state)

{ focushiddenstate= state; focushiddenstate_remember= true; } void rememberIconHiddenstate(bool state) { iconhiddenstate= state; iconhiddenstate_remember= true; } - void rememberPosition(int posx, int posy, bool is_relative, + void rememberPosition(int posx, int posy, bool is_x_relative, bool is_y_relative, FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP) { - position_is_relative = is_relative; + position_is_x_relative = is_x_relative; + position_is_y_relative = is_y_relative; x = posx; y = posy; refc = rfc; position_remember = true;

@@ -161,11 +163,13 @@ int head;

bool dimensions_remember; int w,h; // width, height - bool dimension_is_relative; + bool dimension_is_w_relative; + bool dimension_is_h_relative; bool position_remember; int x,y; - bool position_is_relative; + bool position_is_x_relative; + bool position_is_y_relative; FluxboxWindow::ReferenceCorner refc; bool alpha_remember;

@@ -481,32 +485,34 @@ had_error = (l == -1);

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, false); - } else if(sscanf(str_label.c_str(), "%u%% %u%%", &w, &h) == 2) { - app.rememberDimensions(w, h, true); - } else { + std::vector<string> tokens; + FbTk::StringUtil::stringtok<std::vector<string> >(tokens, str_label); + if (tokens.size() == 2) { + unsigned int h, w; + bool h_relative, w_relative, ignore; + w = FbTk::StringUtil::parseSizeToken(tokens[0], w_relative, ignore); + h = FbTk::StringUtil::parseSizeToken(tokens[1], h_relative, ignore); + app.rememberDimensions(w, h, w_relative, h_relative); + } else had_error = true; - } } else if (str_key == "position") { FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP; - int x = 0, y = 0; // more info about the parameter // in ::rememberPosition if (str_option.length()) r = FluxboxWindow::getCorner(str_option); - had_error = (r == FluxboxWindow::ERROR); - - 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; + if (!(had_error = (r == FluxboxWindow::ERROR))) { + std::vector<string> tokens; + FbTk::StringUtil::stringtok<std::vector<string> >(tokens, str_label); + if (tokens.size() == 2) { + int x, y; + bool x_relative, y_relative, ignore; + x = FbTk::StringUtil::parseSizeToken(tokens[0], x_relative, ignore); + y = FbTk::StringUtil::parseSizeToken(tokens[1], y_relative, ignore); + app.rememberPosition(x, y, x_relative, y_relative, r); + } else + had_error = true; } } else if (str_key == "shaded") { app.rememberShadedstate(str_label == "yes");

@@ -916,11 +922,9 @@ if (a.head_remember) {

apps_file << " [Head]\t{" << a.head << "}" << endl; } if (a.dimensions_remember) { - if(a.dimension_is_relative) { - apps_file << " [Dimensions]\t{" << a.w << "% " << a.h << "%}" << endl; - } else { - apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl; - } + apps_file << " [Dimensions]\t{" << + a.w << (a.dimension_is_w_relative ? "% " : " ") << + a.h << (a.dimension_is_h_relative ? "%}" : "}") << endl; } if (a.position_remember) { apps_file << " [Position]\t(";

@@ -952,11 +956,9 @@ break;

default: apps_file << "UPPERLEFT"; } - if(a.position_is_relative) { - apps_file << ")\t{" << a.x << "% " << a.y << "%}" << endl; - } else { - apps_file << ")\t{" << a.x << " " << a.y << "}" << endl; - } + apps_file << ")\t{" << + a.x << (a.position_is_x_relative ? "% " : " ") << + a.y << (a.position_is_y_relative ? "%}" : "}") << endl; } if (a.shadedstate_remember) { apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl;

@@ -1136,14 +1138,14 @@ case REM_DIMENSIONS: {

head = win->screen().getHead(win->fbWindow()); percx = win->screen().calRelativeDimensionWidth(head, win->normalWidth()); percy = win->screen().calRelativeDimensionHeight(head, win->normalHeight()); - app->rememberDimensions(percx, percy, true); + app->rememberDimensions(percx, percy, true, true); break; } case REM_POSITION: { head = win->screen().getHead(win->fbWindow()); percx = win->screen().calRelativePositionWidth(head, win->normalX()); percy = win->screen().calRelativePositionHeight(head, win->normalY()); - app->rememberPosition(percx, percy, true); + app->rememberPosition(percx, percy, true, true); break; } case REM_FOCUSHIDDENSTATE:

@@ -1307,28 +1309,30 @@ }

if (app->dimensions_remember) { - int win_w, win_h; - if(app->dimension_is_relative) { - int head = screen.getHead(win.fbWindow()); - 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); + int win_w = app->w; + int win_h = app->h; + int head = screen.getHead(win.fbWindow()); + int border_w = win.frame().window().borderWidth(); + + if (app->dimension_is_w_relative) + win_w = screen.calRelativeWidth(head, win_w); + if (app->dimension_is_h_relative) + win_h = screen.calRelativeHeight(head, win_h); + + win.resize(win_w - 2 * border_w, win_h - 2 * border_w); } if (app->position_remember) { - 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; - } + + int newx = app->x; + int newy = app->y; + int head = screen.getHead(win.fbWindow()); + + if (app->position_is_x_relative) + newx = screen.calRelativeWidth(head, newx); + if (app->position_is_y_relative) + newy = screen.calRelativeHeight(head, newy); + win.translateCoords(newx, newy, app->refc); win.move(newx, newy); }