diff options
author | Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com> | 2016-02-11 19:35:10 (GMT) |
---|---|---|
committer | Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com> | 2016-02-28 13:55:36 (GMT) |
commit | 53de872163d61c87fa8128767ebbc218599f3835 (patch) | |
tree | 582749e335f9acfcbc29e3aa0887eb4960a32829 /src | |
parent | 22866c4d30f5b289c429c5ca88d800200db4fc4f (diff) | |
download | fluxbox-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/CurrentWindowCmd.cc | 33 | ||||
-rw-r--r-- | src/FbTk/StringUtil.hh | 35 | ||||
-rw-r--r-- | src/Remember.cc | 114 |
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 | ||
503 | namespace { | ||
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 | |||
524 | FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args, | 503 | FbTk::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 | |||
27 | namespace FbTk { | 33 | namespace FbTk { |
28 | 34 | ||
29 | namespace StringUtil { | 35 | namespace 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 |
64 | std::string::size_type findCharFromAlphabetAfterTrigger(const std::string& in, | 70 | std::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" |
69 | std::string replaceString(const std::string &original, | 75 | std::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 | ||
156 | template <typename Container> | ||
157 | static int | ||
158 | parseSizeToken(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 | } |