aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArkadiusz Bokowy <arkadiusz.bokowy@gmail.com>2016-02-11 19:35:10 (GMT)
committerArkadiusz Bokowy <arkadiusz.bokowy@gmail.com>2016-02-28 13:55:36 (GMT)
commit53de872163d61c87fa8128767ebbc218599f3835 (patch)
tree582749e335f9acfcbc29e3aa0887eb4960a32829
parent22866c4d30f5b289c429c5ca88d800200db4fc4f (diff)
downloadfluxbox-53de872163d61c87fa8128767ebbc218599f3835.zip
fluxbox-53de872163d61c87fa8128767ebbc218599f3835.tar.bz2
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>
-rw-r--r--src/CurrentWindowCmd.cc33
-rw-r--r--src/FbTk/StringUtil.hh35
-rw-r--r--src/Remember.cc114
3 files changed, 98 insertions, 84 deletions
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index dd43d43..44556f5 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -500,27 +500,6 @@ void MoveCmd::real_execute() {
500 fbwindow().move(fbwindow().x() + m_step_size_x, fbwindow().y() + m_step_size_y); 500 fbwindow().move(fbwindow().x() + m_step_size_x, fbwindow().y() + m_step_size_y);
501} 501}
502 502
503namespace {
504 template <typename Container>
505 static void parseToken(Container &container, int &d, bool &is_relative, bool &ignore) {
506 if (container.size() < 1)
507 return;
508
509 d = 0;
510 is_relative = false;
511 ignore = false;
512 if (container[0] == '*') {
513 ignore = true;
514 } else if (container[container.size() - 1] == '%') {
515 // its a percent
516 is_relative = true;
517 d = atoi(container.substr(0, container.size() - 1).c_str());
518 } else {
519 d = atoi(container.c_str());
520 }
521 }
522}
523
524FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args, 503FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args,
525 bool trusted) { 504 bool trusted) {
526 505
@@ -536,15 +515,15 @@ FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args,
536 bool is_relative_x = false, is_relative_y = false, ignore_x = false, ignore_y = false; 515 bool is_relative_x = false, is_relative_y = false, ignore_x = false, ignore_y = false;
537 516
538 if (command == "resizehorizontal") { 517 if (command == "resizehorizontal") {
539 parseToken(tokens[0], dx, is_relative_x, ignore_x); 518 dx = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x);
540 } else if (command == "resizevertical") { 519 } else if (command == "resizevertical") {
541 parseToken(tokens[0], dy, is_relative_y, ignore_y); 520 dy = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_y, ignore_y);
542 } else { 521 } else {
543 if (tokens.size() < 2) { 522 if (tokens.size() < 2) {
544 return 0; 523 return 0;
545 } 524 }
546 parseToken(tokens[0], dx, is_relative_x, ignore_x); 525 dx = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x);
547 parseToken(tokens[1], dy, is_relative_y, ignore_y); 526 dy = FbTk::StringUtil::parseSizeToken(tokens[1], is_relative_y, ignore_y);
548 } 527 }
549 528
550 if (command == "resizeto") { 529 if (command == "resizeto") {
@@ -610,8 +589,8 @@ FbTk::Command<void> *MoveToCmd::parse(const string &cmd, const string &args,
610 int x = 0, y = 0; 589 int x = 0, y = 0;
611 bool ignore_x = false, ignore_y = false, is_relative_x = false, is_relative_y = false; 590 bool ignore_x = false, ignore_y = false, is_relative_x = false, is_relative_y = false;
612 591
613 parseToken(tokens[0], x, is_relative_x, ignore_x); 592 x = FbTk::StringUtil::parseSizeToken(tokens[0], is_relative_x, ignore_x);
614 parseToken(tokens[1], y, is_relative_y, ignore_y); 593 y = FbTk::StringUtil::parseSizeToken(tokens[1], is_relative_y, ignore_y);
615 594
616 if (tokens.size() >= 3) { 595 if (tokens.size() >= 3) {
617 refc = FluxboxWindow::getCorner(tokens[2]); 596 refc = FluxboxWindow::getCorner(tokens[2]);
diff --git a/src/FbTk/StringUtil.hh b/src/FbTk/StringUtil.hh
index 2f7c6fc..bfa3a5c 100644
--- a/src/FbTk/StringUtil.hh
+++ b/src/FbTk/StringUtil.hh
@@ -24,6 +24,12 @@
24 24
25#include <string> 25#include <string>
26 26
27#ifdef HAVE_CSTDLIB
28#include <cstdlib>
29#else
30#include <stdlib.h>
31#endif
32
27namespace FbTk { 33namespace FbTk {
28 34
29namespace StringUtil { 35namespace StringUtil {
@@ -61,12 +67,12 @@ std::string findExtension(const std::string &filename);
61/// @param found - position of found char in alphabet (optional) 67/// @param found - position of found char in alphabet (optional)
62/// @return position of trigger if found 68/// @return position of trigger if found
63/// @return std::string::npos if nothing found 69/// @return std::string::npos if nothing found
64std::string::size_type findCharFromAlphabetAfterTrigger(const std::string& in, 70std::string::size_type findCharFromAlphabetAfterTrigger(const std::string& in,
65 char trigger, 71 char trigger,
66 const char alphabet[], size_t len_alphabet, size_t* found); 72 const char alphabet[], size_t len_alphabet, size_t* found);
67 73
68/// @return copy of original with find_string replaced with "replace" 74/// @return copy of original with find_string replaced with "replace"
69std::string replaceString(const std::string &original, 75std::string replaceString(const std::string &original,
70 const char *find_string, 76 const char *find_string,
71 const char *replace); 77 const char *replace);
72 78
@@ -143,6 +149,31 @@ stringtok (Container &container, std::string const &in,
143 } 149 }
144} 150}
145 151
152/// Parse token, which might be in formats as follows: <int>, <int>% or *.
153/// @param relative - parsed relative value (percentage suffix)
154/// @param ignore - this token should be ignored (asterisk)
155/// @return parsed integer value or 0 if not applicable
156template <typename Container>
157static int
158parseSizeToken(Container &container, bool &relative, bool &ignore) {
159
160 if (container.empty())
161 return 0;
162
163 relative = false;
164 ignore = false;
165
166 if (container[0] == '*') {
167 ignore = true;
168 return 0;
169 }
170
171 if (container[container.size() - 1] == '%')
172 relative = true;
173
174 return atoi(container.c_str());
175}
176
146} // end namespace StringUtil 177} // end namespace StringUtil
147 178
148} // end namespace FbTk 179} // end namespace FbTk
diff --git a/src/Remember.cc b/src/Remember.cc
index 7163dec..6dcd378 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -110,9 +110,10 @@ public:
110 { workspace = ws; workspace_remember = true; } 110 { workspace = ws; workspace_remember = true; }
111 void rememberHead(int h) 111 void rememberHead(int h)
112 { head = h; head_remember = true; } 112 { head = h; head_remember = true; }
113 void rememberDimensions(int width, int height, bool is_relative) 113 void rememberDimensions(int width, int height, bool is_w_relative, bool is_h_relative)
114 { 114 {
115 dimension_is_relative = is_relative; 115 dimension_is_w_relative = is_w_relative;
116 dimension_is_h_relative = is_h_relative;
116 w = width; h = height; 117 w = width; h = height;
117 dimensions_remember = true; 118 dimensions_remember = true;
118 } 119 }
@@ -120,10 +121,11 @@ public:
120 { focushiddenstate= state; focushiddenstate_remember= true; } 121 { focushiddenstate= state; focushiddenstate_remember= true; }
121 void rememberIconHiddenstate(bool state) 122 void rememberIconHiddenstate(bool state)
122 { iconhiddenstate= state; iconhiddenstate_remember= true; } 123 { iconhiddenstate= state; iconhiddenstate_remember= true; }
123 void rememberPosition(int posx, int posy, bool is_relative, 124 void rememberPosition(int posx, int posy, bool is_x_relative, bool is_y_relative,
124 FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP) 125 FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP)
125 { 126 {
126 position_is_relative = is_relative; 127 position_is_x_relative = is_x_relative;
128 position_is_y_relative = is_y_relative;
127 x = posx; y = posy; 129 x = posx; y = posy;
128 refc = rfc; 130 refc = rfc;
129 position_remember = true; 131 position_remember = true;
@@ -161,11 +163,13 @@ public:
161 163
162 bool dimensions_remember; 164 bool dimensions_remember;
163 int w,h; // width, height 165 int w,h; // width, height
164 bool dimension_is_relative; 166 bool dimension_is_w_relative;
167 bool dimension_is_h_relative;
165 168
166 bool position_remember; 169 bool position_remember;
167 int x,y; 170 int x,y;
168 bool position_is_relative; 171 bool position_is_x_relative;
172 bool position_is_y_relative;
169 FluxboxWindow::ReferenceCorner refc; 173 FluxboxWindow::ReferenceCorner refc;
170 174
171 bool alpha_remember; 175 bool alpha_remember;
@@ -481,32 +485,34 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
481 if (!had_error) 485 if (!had_error)
482 app.rememberLayer(l); 486 app.rememberLayer(l);
483 } else if (str_key == "dimensions") { 487 } else if (str_key == "dimensions") {
484 unsigned int h, w; 488 std::vector<string> tokens;
485 if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2) { 489 FbTk::StringUtil::stringtok<std::vector<string> >(tokens, str_label);
486 app.rememberDimensions(w, h, false); 490 if (tokens.size() == 2) {
487 } else if(sscanf(str_label.c_str(), "%u%% %u%%", &w, &h) == 2) { 491 unsigned int h, w;
488 app.rememberDimensions(w, h, true); 492 bool h_relative, w_relative, ignore;
489 } else { 493 w = FbTk::StringUtil::parseSizeToken(tokens[0], w_relative, ignore);
494 h = FbTk::StringUtil::parseSizeToken(tokens[1], h_relative, ignore);
495 app.rememberDimensions(w, h, w_relative, h_relative);
496 } else
490 had_error = true; 497 had_error = true;
491 }
492 } else if (str_key == "position") { 498 } else if (str_key == "position") {
493 FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP; 499 FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP;
494 int x = 0, y = 0;
495 // more info about the parameter 500 // more info about the parameter
496 // in ::rememberPosition 501 // in ::rememberPosition
497 502
498 if (str_option.length()) 503 if (str_option.length())
499 r = FluxboxWindow::getCorner(str_option); 504 r = FluxboxWindow::getCorner(str_option);
500 had_error = (r == FluxboxWindow::ERROR); 505 if (!(had_error = (r == FluxboxWindow::ERROR))) {
501 506 std::vector<string> tokens;
502 if (!had_error){ 507 FbTk::StringUtil::stringtok<std::vector<string> >(tokens, str_label);
503 if(sscanf(str_label.c_str(), "%d %d", &x, &y) == 2) { 508 if (tokens.size() == 2) {
504 app.rememberPosition(x, y, false, r); 509 int x, y;
505 } else if (sscanf(str_label.c_str(), "%d%% %d%%", &x, &y) == 2){ 510 bool x_relative, y_relative, ignore;
506 app.rememberPosition(x, y, true, r); 511 x = FbTk::StringUtil::parseSizeToken(tokens[0], x_relative, ignore);
507 } 512 y = FbTk::StringUtil::parseSizeToken(tokens[1], y_relative, ignore);
508 } else { 513 app.rememberPosition(x, y, x_relative, y_relative, r);
509 had_error = true; 514 } else
515 had_error = true;
510 } 516 }
511 } else if (str_key == "shaded") { 517 } else if (str_key == "shaded") {
512 app.rememberShadedstate(str_label == "yes"); 518 app.rememberShadedstate(str_label == "yes");
@@ -916,11 +922,9 @@ void Remember::save() {
916 apps_file << " [Head]\t{" << a.head << "}" << endl; 922 apps_file << " [Head]\t{" << a.head << "}" << endl;
917 } 923 }
918 if (a.dimensions_remember) { 924 if (a.dimensions_remember) {
919 if(a.dimension_is_relative) { 925 apps_file << " [Dimensions]\t{" <<
920 apps_file << " [Dimensions]\t{" << a.w << "% " << a.h << "%}" << endl; 926 a.w << (a.dimension_is_w_relative ? "% " : " ") <<
921 } else { 927 a.h << (a.dimension_is_h_relative ? "%}" : "}") << endl;
922 apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl;
923 }
924 } 928 }
925 if (a.position_remember) { 929 if (a.position_remember) {
926 apps_file << " [Position]\t("; 930 apps_file << " [Position]\t(";
@@ -952,11 +956,9 @@ void Remember::save() {
952 default: 956 default:
953 apps_file << "UPPERLEFT"; 957 apps_file << "UPPERLEFT";
954 } 958 }
955 if(a.position_is_relative) { 959 apps_file << ")\t{" <<
956 apps_file << ")\t{" << a.x << "% " << a.y << "%}" << endl; 960 a.x << (a.position_is_x_relative ? "% " : " ") <<
957 } else { 961 a.y << (a.position_is_y_relative ? "%}" : "}") << endl;
958 apps_file << ")\t{" << a.x << " " << a.y << "}" << endl;
959 }
960 } 962 }
961 if (a.shadedstate_remember) { 963 if (a.shadedstate_remember) {
962 apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl; 964 apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl;
@@ -1136,14 +1138,14 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
1136 head = win->screen().getHead(win->fbWindow()); 1138 head = win->screen().getHead(win->fbWindow());
1137 percx = win->screen().calRelativeDimensionWidth(head, win->normalWidth()); 1139 percx = win->screen().calRelativeDimensionWidth(head, win->normalWidth());
1138 percy = win->screen().calRelativeDimensionHeight(head, win->normalHeight()); 1140 percy = win->screen().calRelativeDimensionHeight(head, win->normalHeight());
1139 app->rememberDimensions(percx, percy, true); 1141 app->rememberDimensions(percx, percy, true, true);
1140 break; 1142 break;
1141 } 1143 }
1142 case REM_POSITION: { 1144 case REM_POSITION: {
1143 head = win->screen().getHead(win->fbWindow()); 1145 head = win->screen().getHead(win->fbWindow());
1144 percx = win->screen().calRelativePositionWidth(head, win->normalX()); 1146 percx = win->screen().calRelativePositionWidth(head, win->normalX());
1145 percy = win->screen().calRelativePositionHeight(head, win->normalY()); 1147 percy = win->screen().calRelativePositionHeight(head, win->normalY());
1146 app->rememberPosition(percx, percy, true); 1148 app->rememberPosition(percx, percy, true, true);
1147 break; 1149 break;
1148 } 1150 }
1149 case REM_FOCUSHIDDENSTATE: 1151 case REM_FOCUSHIDDENSTATE:
@@ -1307,28 +1309,30 @@ void Remember::setupFrame(FluxboxWindow &win) {
1307 1309
1308 if (app->dimensions_remember) { 1310 if (app->dimensions_remember) {
1309 1311
1310 int win_w, win_h; 1312 int win_w = app->w;
1311 if(app->dimension_is_relative) { 1313 int win_h = app->h;
1312 int head = screen.getHead(win.fbWindow()); 1314 int head = screen.getHead(win.fbWindow());
1313 win_w = screen.calRelativeWidth(head, app->w); 1315 int border_w = win.frame().window().borderWidth();
1314 win_h = screen.calRelativeHeight(head, app->h); 1316
1315 } else { 1317 if (app->dimension_is_w_relative)
1316 win_w = app->w; 1318 win_w = screen.calRelativeWidth(head, win_w);
1317 win_h = app->h; 1319 if (app->dimension_is_h_relative)
1318 } 1320 win_h = screen.calRelativeHeight(head, win_h);
1319 win.resize(win_w, win_h); 1321
1322 win.resize(win_w - 2 * border_w, win_h - 2 * border_w);
1320 } 1323 }
1321 1324
1322 if (app->position_remember) { 1325 if (app->position_remember) {
1323 int newx, newy; 1326
1324 if(app->position_is_relative) { 1327 int newx = app->x;
1325 int head = screen.getHead(win.fbWindow()); 1328 int newy = app->y;
1326 newx = screen.calRelativeWidth(head, app->x); 1329 int head = screen.getHead(win.fbWindow());
1327 newy = screen.calRelativeHeight(head, app->y); 1330
1328 } else { 1331 if (app->position_is_x_relative)
1329 newx = app->x; 1332 newx = screen.calRelativeWidth(head, newx);
1330 newy = app->y; 1333 if (app->position_is_y_relative)
1331 } 1334 newy = screen.calRelativeHeight(head, newy);
1335
1332 win.translateCoords(newx, newy, app->refc); 1336 win.translateCoords(newx, newy, app->refc);
1333 win.move(newx, newy); 1337 win.move(newx, newy);
1334 } 1338 }