aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLajos Koszti <ajnasz@ajnasz.hu>2012-04-06 12:10:24 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2012-04-06 12:11:16 (GMT)
commit7b6dc2ad72a4c4ecd20eddbfb6f1b4c3bd2a7024 (patch)
treec2a8f4aa658783c6454b7643ce2717acaa744101 /src
parent5d56046b68635cea2c187e59a9d8c514e2d6bdb2 (diff)
downloadfluxbox-7b6dc2ad72a4c4ecd20eddbfb6f1b4c3bd2a7024.zip
fluxbox-7b6dc2ad72a4c4ecd20eddbfb6f1b4c3bd2a7024.tar.bz2
Allow percentage values for some Window commands
Diffstat (limited to 'src')
-rw-r--r--src/CurrentWindowCmd.cc151
-rw-r--r--src/CurrentWindowCmd.hh20
-rw-r--r--src/FbTk/FbWindow.hh7
-rw-r--r--src/FbTk/Makefile.am1
-rw-r--r--src/FbTk/RelCalcHelper.cc38
-rw-r--r--src/FbTk/RelCalcHelper.hh43
-rw-r--r--src/Remember.cc104
-rw-r--r--src/Screen.cc49
-rw-r--r--src/Screen.hh17
-rw-r--r--src/Window.cc16
-rw-r--r--src/Window.hh2
-rw-r--r--src/tests/StringUtiltest.cc26
12 files changed, 386 insertions, 88 deletions
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 8d27a3a..4363d0d 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -36,6 +36,7 @@
36#include "FbTk/stringstream.hh" 36#include "FbTk/stringstream.hh"
37#include "FbTk/StringUtil.hh" 37#include "FbTk/StringUtil.hh"
38#include "FbTk/Util.hh" 38#include "FbTk/Util.hh"
39#include "FbTk/RelCalcHelper.hh"
39 40
40#ifdef HAVE_CONFIG_H 41#ifdef HAVE_CONFIG_H
41#include "config.h" 42#include "config.h"
@@ -47,7 +48,6 @@
47#include <stdlib.h> 48#include <stdlib.h>
48#endif 49#endif
49 50
50
51using FbTk::Command; 51using FbTk::Command;
52 52
53namespace { 53namespace {
@@ -477,21 +477,59 @@ void MoveCmd::real_execute() {
477 fbwindow().move(fbwindow().x() + m_step_size_x, fbwindow().y() + m_step_size_y); 477 fbwindow().move(fbwindow().x() + m_step_size_x, fbwindow().y() + m_step_size_y);
478} 478}
479 479
480namespace {
481 template <typename Container>
482 static void parseToken(Container &container, int &d, bool &is_relative, bool &ignore) {
483 if (container.size() < 1)
484 return;
485
486 d = 0;
487 is_relative = false;
488 ignore = false;
489 if (container[0] == '*') {
490 ignore = true;
491 } else if (container[container.size() - 1] == '%') {
492 // its a percent
493 is_relative = true;
494 d = atoi(container.substr(0, container.size() - 1).c_str());
495 } else {
496 d = atoi(container.c_str());
497 }
498 }
499}
500
480FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args, 501FbTk::Command<void> *ResizeCmd::parse(const string &command, const string &args,
481 bool trusted) { 502 bool trusted) {
482 FbTk_istringstream is(args.c_str()); 503
483 int dx = 0, dy = 0; 504 typedef std::vector<string> StringTokens;
484 is >> dx >> dy; 505 StringTokens tokens;
485 if (command == "resizehorizontal") 506 FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
507
508 if (tokens.size() < 1) {
509 return 0;
510 }
511
512 int dx, dy;
513 bool is_relative_x = false, is_relative_y = false, ignore_x = false, ignore_y = false;
514
515 if (command == "resizehorizontal") {
516 parseToken(tokens[0], dx, is_relative_x, ignore_x);
486 dy = 0; 517 dy = 0;
487 else if (command == "resizevertical") { 518 } else if (command == "resizevertical") {
488 dy = dx; 519 parseToken(tokens[0], dy, is_relative_y, ignore_y);
489 dx = 0; 520 dx = 0;
521 } else {
522 if (tokens.size() < 2) {
523 return 0;
524 }
525 parseToken(tokens[0], dx, is_relative_x, ignore_x);
526 parseToken(tokens[1], dy, is_relative_y, ignore_y);
490 } 527 }
491 528
492 if (command == "resizeto") 529 if (command == "resizeto") {
493 return new ResizeToCmd(dx, dy); 530 return new ResizeToCmd(dx, dy, is_relative_x, is_relative_y);
494 return new ResizeCmd(dx, dy); 531 }
532 return new ResizeCmd(dx, dy, is_relative_x, is_relative_y);
495} 533}
496 534
497REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse, void); 535REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse, void);
@@ -499,8 +537,8 @@ REGISTER_COMMAND_PARSER(resizeto, ResizeCmd::parse, void);
499REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse, void); 537REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse, void);
500REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse, void); 538REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse, void);
501 539
502ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) : 540ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y, bool is_relative_x, bool is_relative_y) :
503 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { } 541 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) { }
504 542
505void ResizeCmd::real_execute() { 543void ResizeCmd::real_execute() {
506 544
@@ -512,11 +550,27 @@ void ResizeCmd::real_execute() {
512 550
513 disableMaximizationIfNeeded(fbwindow()); 551 disableMaximizationIfNeeded(fbwindow());
514 552
515 int w = std::max<int>(static_cast<int>(fbwindow().width() + 553 int dx = m_step_size_x, dy = m_step_size_y;
516 m_step_size_x * fbwindow().winClient().widthInc()), 554 int windowWidth = fbwindow().width(), windowHeight = fbwindow().height();
555
556 unsigned int widthInc = fbwindow().winClient().widthInc(),
557 heightInc = fbwindow().winClient().heightInc();
558
559 if (m_is_relative_x) {
560 // dx = floor(windowWidth * m_step_size_x / 100 / widthInc + 0.5);
561 dx = static_cast<int>(FbTk::RelCalcHelper::calPercentageValueOf(windowWidth, m_step_size_x) / widthInc);
562 }
563
564 if (m_is_relative_y) {
565 // dy = floor(windowHeight * m_step_size_y / 100 / heightInc + 0.5);
566 dy = static_cast<int>(FbTk::RelCalcHelper::calPercentageValueOf(windowHeight, m_step_size_y) / heightInc);
567 }
568
569 int w = std::max<int>(static_cast<int>(windowWidth +
570 dx * widthInc),
517 fbwindow().frame().titlebarHeight() * 2 + 10); 571 fbwindow().frame().titlebarHeight() * 2 + 10);
518 int h = std::max<int>(static_cast<int>(fbwindow().height() + 572 int h = std::max<int>(static_cast<int>(windowHeight +
519 m_step_size_y * fbwindow().winClient().heightInc()), 573 dy * heightInc),
520 fbwindow().frame().titlebarHeight() + 10); 574 fbwindow().frame().titlebarHeight() + 10);
521 575
522 fbwindow().resize(w, h); 576 fbwindow().resize(w, h);
@@ -533,17 +587,10 @@ FbTk::Command<void> *MoveToCmd::parse(const string &cmd, const string &args,
533 587
534 FluxboxWindow::ReferenceCorner refc = FluxboxWindow::LEFTTOP; 588 FluxboxWindow::ReferenceCorner refc = FluxboxWindow::LEFTTOP;
535 int x = 0, y = 0; 589 int x = 0, y = 0;
536 bool ignore_x = false, ignore_y = false; 590 bool ignore_x = false, ignore_y = false, is_relative_x = false, is_relative_y = false;
537
538 if (tokens[0][0] == '*')
539 ignore_x = true;
540 else
541 x = atoi(tokens[0].c_str());
542 591
543 if (tokens[1][0] == '*' && !ignore_x) 592 parseToken(tokens[0], x, is_relative_x, ignore_x);
544 ignore_y = true; 593 parseToken(tokens[1], y, is_relative_y, ignore_y);
545 else
546 y = atoi(tokens[1].c_str());
547 594
548 if (tokens.size() >= 3) { 595 if (tokens.size() >= 3) {
549 refc = FluxboxWindow::getCorner(tokens[2]); 596 refc = FluxboxWindow::getCorner(tokens[2]);
@@ -551,7 +598,7 @@ FbTk::Command<void> *MoveToCmd::parse(const string &cmd, const string &args,
551 refc = FluxboxWindow::LEFTTOP; 598 refc = FluxboxWindow::LEFTTOP;
552 } 599 }
553 600
554 return new MoveToCmd(x, y, ignore_x, ignore_y, refc); 601 return new MoveToCmd(x, y, ignore_x, ignore_y, is_relative_x, is_relative_y, refc);
555} 602}
556 603
557REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse, void); 604REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse, void);
@@ -568,19 +615,31 @@ void MoveToCmd::real_execute() {
568 615
569 616
570 int x = m_pos_x, y = m_pos_y; 617 int x = m_pos_x, y = m_pos_y;
618 int head = fbwindow().getOnHead();
571 619
572 fbwindow().translateCoords(x, y, m_corner); 620 if (m_ignore_x) {
573 if (m_ignore_x)
574 x = fbwindow().x(); 621 x = fbwindow().x();
575 if (m_ignore_y) 622 } else {
623 if (m_is_relative_x) {
624 x = fbwindow().screen().calRelativeWidth(head, x);
625 }
626 fbwindow().translateXCoords(x, m_corner);
627 }
628 if (m_ignore_y) {
576 y = fbwindow().y(); 629 y = fbwindow().y();
630 } else {
631 if (m_is_relative_y) {
632 y = fbwindow().screen().calRelativeHeight(head, y);
633 }
634 fbwindow().translateYCoords(y, m_corner);
635 }
577 636
578 fbwindow().move(x, y); 637 fbwindow().move(x, y);
579} 638}
580 639
581 640
582ResizeToCmd::ResizeToCmd(const int step_size_x, const int step_size_y) : 641ResizeToCmd::ResizeToCmd(const int step_size_x, const int step_size_y, const bool is_relative_x, const bool is_relative_y) :
583 m_step_size_x(step_size_x), m_step_size_y(step_size_y) { } 642 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) { }
584 643
585void ResizeToCmd::real_execute() { 644void ResizeToCmd::real_execute() {
586 645
@@ -592,9 +651,31 @@ void ResizeToCmd::real_execute() {
592 651
593 disableMaximizationIfNeeded(fbwindow()); 652 disableMaximizationIfNeeded(fbwindow());
594 653
654 int dx = m_step_size_x, dy = m_step_size_y;
655 int head = fbwindow().getOnHead();
656
657 if (m_is_relative_x) {
658 dx = fbwindow().screen().calRelativeWidth(head, dx);
659 if(dx <= 0) {
660 dx = fbwindow().width();
661 }
662 }
663
664 if (m_is_relative_y) {
665 dy = fbwindow().screen().calRelativeHeight(head, dy);
666 if(dy <= 0) {
667 dy = fbwindow().height();
668 }
669 }
670
671 if (dx == 0) {
672 dx = fbwindow().width();
673 }
674 if (dy == 0) {
675 dy = fbwindow().height();
676 }
595 677
596 if (m_step_size_x > 0 && m_step_size_y > 0) 678 fbwindow().resize(dx, dy);
597 fbwindow().resize(m_step_size_x, m_step_size_y);
598} 679}
599 680
600REGISTER_COMMAND(fullscreen, FullscreenCmd, void); 681REGISTER_COMMAND(fullscreen, FullscreenCmd, void);
@@ -720,7 +801,7 @@ void SetAlphaCmd::real_execute() {
720 return; 801 return;
721 } 802 }
722 803
723 fbwindow().setFocusedAlpha(m_relative 804 fbwindow().setFocusedAlpha(m_relative
724 ? FbTk::Util::clamp(fbwindow().getFocusedAlpha() + m_focus, 0, 255) 805 ? FbTk::Util::clamp(fbwindow().getFocusedAlpha() + m_focus, 0, 255)
725 : m_focus); 806 : m_focus);
726 807
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh
index edf00fa..f406796 100644
--- a/src/CurrentWindowCmd.hh
+++ b/src/CurrentWindowCmd.hh
@@ -158,24 +158,26 @@ private:
158// resize cmd, relative size 158// resize cmd, relative size
159class ResizeCmd: public WindowHelperCmd{ 159class ResizeCmd: public WindowHelperCmd{
160public: 160public:
161 explicit ResizeCmd(int step_size_x, int step_size_y); 161 explicit ResizeCmd(int step_size_x, int step_size_y, bool is_relative_x, bool is_relative_y);
162 static FbTk::Command<void> *parse(const std::string &command, 162 static FbTk::Command<void> *parse(const std::string &command,
163 const std::string &args, bool trusted); 163 const std::string &args, bool trusted);
164protected: 164protected:
165 void real_execute(); 165 void real_execute();
166 166
167private: 167private:
168 168 const int m_step_size_x;
169 const int m_step_size_x; 169 const int m_step_size_y;
170 const int m_step_size_y; 170 const bool m_is_relative_x;
171 const bool m_is_relative_y;
171}; 172};
172 173
173class MoveToCmd: public WindowHelperCmd { 174class MoveToCmd: public WindowHelperCmd {
174public: 175public:
175 explicit MoveToCmd(int pos_x, int pos_y, bool ignore_x, bool ignore_y, 176 explicit MoveToCmd(int pos_x, int pos_y, bool ignore_x, bool ignore_y, bool is_relative_x, bool is_relative_y,
176 FluxboxWindow::ReferenceCorner refc): 177 FluxboxWindow::ReferenceCorner refc):
177 m_pos_x(pos_x), m_pos_y(pos_y), 178 m_pos_x(pos_x), m_pos_y(pos_y),
178 m_ignore_x(ignore_x), m_ignore_y(ignore_y), 179 m_ignore_x(ignore_x), m_ignore_y(ignore_y),
180 m_is_relative_x(is_relative_x), m_is_relative_y(is_relative_y),
179 m_corner(refc) { } 181 m_corner(refc) { }
180 182
181 static FbTk::Command<void> *parse(const std::string &command, 183 static FbTk::Command<void> *parse(const std::string &command,
@@ -185,19 +187,21 @@ protected:
185 187
186private: 188private:
187 int m_pos_x, m_pos_y; 189 int m_pos_x, m_pos_y;
188 bool m_ignore_x, m_ignore_y; 190 bool m_ignore_x, m_ignore_y, m_is_relative_x, m_is_relative_y;
189 FluxboxWindow::ReferenceCorner m_corner; 191 FluxboxWindow::ReferenceCorner m_corner;
190}; 192};
191 193
192// resize cmd 194// resize cmd
193class ResizeToCmd: public WindowHelperCmd{ 195class ResizeToCmd: public WindowHelperCmd{
194public: 196public:
195 explicit ResizeToCmd(int step_size_x, int step_size_y); 197 explicit ResizeToCmd(int step_size_x, int step_size_y, bool is_relative_x, bool is_relative_y);
196protected: 198protected:
197 void real_execute(); 199 void real_execute();
198private: 200private:
199 const int m_step_size_x; 201 const int m_step_size_x;
200 const int m_step_size_y; 202 const int m_step_size_y;
203 const bool m_is_relative_x;
204 const bool m_is_relative_y;
201}; 205};
202 206
203class FullscreenCmd: public WindowHelperCmd{ 207class FullscreenCmd: public WindowHelperCmd{
diff --git a/src/FbTk/FbWindow.hh b/src/FbTk/FbWindow.hh
index e03083c..9d335fa 100644
--- a/src/FbTk/FbWindow.hh
+++ b/src/FbTk/FbWindow.hh
@@ -28,6 +28,12 @@
28#include <string> 28#include <string>
29#include <set> 29#include <set>
30 30
31#ifdef HAVE_CMATH
32 #include <cmath>
33#else
34 #include <math.h>
35#endif
36
31namespace FbTk { 37namespace FbTk {
32 38
33class Color; 39class Color;
@@ -259,6 +265,7 @@ public:
259}; 265};
260 266
261 267
268
262} // end namespace FbTk 269} // end namespace FbTk
263 270
264#endif // FBTK_FBWINDOW_HH 271#endif // FBTK_FBWINDOW_HH
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index 4c38f84..171f27d 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -64,6 +64,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
64 CachedPixmap.hh CachedPixmap.cc \ 64 CachedPixmap.hh CachedPixmap.cc \
65 Slot.hh Signal.hh MemFun.hh SelectArg.hh \ 65 Slot.hh Signal.hh MemFun.hh SelectArg.hh \
66 Util.hh \ 66 Util.hh \
67 RelCalcHelper.hh RelCalcHelper.cc \
67 ${xpm_SOURCE} \ 68 ${xpm_SOURCE} \
68 ${xft_SOURCE} \ 69 ${xft_SOURCE} \
69 ${xmb_SOURCE} \ 70 ${xmb_SOURCE} \
diff --git a/src/FbTk/RelCalcHelper.cc b/src/FbTk/RelCalcHelper.cc
new file mode 100644
index 0000000..a537de4
--- /dev/null
+++ b/src/FbTk/RelCalcHelper.cc
@@ -0,0 +1,38 @@
1// RelCalcHelper.hh for Fluxbox - an X11 Window manager
2// Copyright (c) 2012 Lajos Koszti (ajnasz at ajnasz.hu)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#include "RelCalcHelper.hh"
23
24namespace FbTk {
25
26 namespace RelCalcHelper {
27
28 int calPercentageValueOf(int i, int j) {
29 return floor(i * j / 100 + 0.5);
30 }
31
32 int calPercentageOf(int i, int j) {
33 return floor((float) i / (float) j * 100 + 0.5);
34 }
35
36 }
37
38}
diff --git a/src/FbTk/RelCalcHelper.hh b/src/FbTk/RelCalcHelper.hh
new file mode 100644
index 0000000..67d85e9
--- /dev/null
+++ b/src/FbTk/RelCalcHelper.hh
@@ -0,0 +1,43 @@
1// RelCalcHelper.cc for Fluxbox - an X11 Window manager
2// Copyright (c) 2012 Lajos Koszti (ajnasz at ajnasz.hu)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22#ifndef FBTK_RELCALCHELPER_HH
23#define FBTK_RELCALCHELPER_HH
24
25#ifdef HAVE_CMATH
26 #include <cmath>
27#else
28 #include <math.h>
29#endif
30
31namespace FbTk {
32
33namespace RelCalcHelper {
34
35 int calPercentageOf(int i, int j);
36
37 int calPercentageValueOf(int i, int j);
38
39}
40
41}
42
43#endif // FBTK_RELCALCHELPER_HH
diff --git a/src/Remember.cc b/src/Remember.cc
index c4eeb25..626522c 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -54,7 +54,6 @@
54#define _GNU_SOURCE 54#define _GNU_SOURCE
55#endif // _GNU_SOURCE 55#endif // _GNU_SOURCE
56 56
57#include <iostream>
58#include <set> 57#include <set>
59 58
60 59
@@ -99,15 +98,24 @@ public:
99 { workspace = ws; workspace_remember = true; } 98 { workspace = ws; workspace_remember = true; }
100 void rememberHead(int h) 99 void rememberHead(int h)
101 { head = h; head_remember = true; } 100 { head = h; head_remember = true; }
102 void rememberDimensions(int width, int height) 101 void rememberDimensions(int width, int height, bool is_relative)
103 { w = width; h = height; dimensions_remember = true; } 102 {
103 dimension_is_relative = is_relative;
104 w = width; h = height;
105 dimensions_remember = true;
106 }
104 void rememberFocusHiddenstate(bool state) 107 void rememberFocusHiddenstate(bool state)
105 { focushiddenstate= state; focushiddenstate_remember= true; } 108 { focushiddenstate= state; focushiddenstate_remember= true; }
106 void rememberIconHiddenstate(bool state) 109 void rememberIconHiddenstate(bool state)
107 { iconhiddenstate= state; iconhiddenstate_remember= true; } 110 { iconhiddenstate= state; iconhiddenstate_remember= true; }
108 void rememberPosition(int posx, int posy, 111 void rememberPosition(int posx, int posy, bool is_relative,
109 FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP) 112 FluxboxWindow::ReferenceCorner rfc = FluxboxWindow::LEFTTOP)
110 { x = posx; y = posy; refc = rfc; position_remember = true; } 113 {
114 position_is_relative = is_relative;
115 x = posx; y = posy;
116 refc = rfc;
117 position_remember = true;
118 }
111 void rememberShadedstate(bool state) 119 void rememberShadedstate(bool state)
112 { shadedstate = state; shadedstate_remember = true; } 120 { shadedstate = state; shadedstate_remember = true; }
113 void rememberTabstate(bool state) 121 void rememberTabstate(bool state)
@@ -120,7 +128,7 @@ public:
120 { focusnewwindow = state; focusnewwindow_remember = true; } 128 { focusnewwindow = state; focusnewwindow_remember = true; }
121 void rememberJumpworkspace(bool state) 129 void rememberJumpworkspace(bool state)
122 { jumpworkspace = state; jumpworkspace_remember = true; } 130 { jumpworkspace = state; jumpworkspace_remember = true; }
123 void rememberLayer(int layernum) 131 void rememberLayer(int layernum)
124 { layer = layernum; layer_remember = true; } 132 { layer = layernum; layer_remember = true; }
125 void rememberSaveOnClose(bool state) 133 void rememberSaveOnClose(bool state)
126 { save_on_close = state; save_on_close_remember = true; } 134 { save_on_close = state; save_on_close_remember = true; }
@@ -141,9 +149,11 @@ public:
141 149
142 bool dimensions_remember; 150 bool dimensions_remember;
143 int w,h; // width, height 151 int w,h; // width, height
152 bool dimension_is_relative;
144 153
145 bool position_remember; 154 bool position_remember;
146 int x,y; 155 int x,y;
156 bool position_is_relative;
147 FluxboxWindow::ReferenceCorner refc; 157 FluxboxWindow::ReferenceCorner refc;
148 158
149 bool alpha_remember; 159 bool alpha_remember;
@@ -483,10 +493,13 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
483 app.rememberLayer(l); 493 app.rememberLayer(l);
484 } else if (str_key == "dimensions") { 494 } else if (str_key == "dimensions") {
485 unsigned int h,w; 495 unsigned int h,w;
486 if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2) 496 if (sscanf(str_label.c_str(), "%u %u", &w, &h) == 2) {
487 app.rememberDimensions(w, h); 497 app.rememberDimensions(w, h, false);
488 else 498 } else if(sscanf(str_label.c_str(), "%u%% %u%%", &w, &h) == 2) {
499 app.rememberDimensions(w, h, true);
500 } else {
489 had_error = true; 501 had_error = true;
502 }
490 } else if (str_key == "position") { 503 } else if (str_key == "position") {
491 FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP; 504 FluxboxWindow::ReferenceCorner r = FluxboxWindow::LEFTTOP;
492 int x = 0, y = 0; 505 int x = 0, y = 0;
@@ -497,10 +510,15 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
497 r = FluxboxWindow::getCorner(str_option); 510 r = FluxboxWindow::getCorner(str_option);
498 had_error = (r == FluxboxWindow::ERROR); 511 had_error = (r == FluxboxWindow::ERROR);
499 512
500 if (!had_error && sscanf(str_label.c_str(), "%d %d", &x, &y) == 2) 513 if (!had_error){
501 app.rememberPosition(x, y, r); 514 if(sscanf(str_label.c_str(), "%d %d", &x, &y) == 2) {
502 else 515 app.rememberPosition(x, y, false, r);
516 } else if (sscanf(str_label.c_str(), "%d%% %d%%", &x, &y) == 2){
517 app.rememberPosition(x, y, true, r);
518 }
519 } else {
503 had_error = true; 520 had_error = true;
521 }
504 } else if (str_key == "shaded") { 522 } else if (str_key == "shaded") {
505 app.rememberShadedstate((strcasecmp(str_label.c_str(), "yes") == 0)); 523 app.rememberShadedstate((strcasecmp(str_label.c_str(), "yes") == 0));
506 } else if (str_key == "tab") { 524 } else if (str_key == "tab") {
@@ -910,7 +928,11 @@ void Remember::save() {
910 apps_file << " [Head]\t{" << a.head << "}" << endl; 928 apps_file << " [Head]\t{" << a.head << "}" << endl;
911 } 929 }
912 if (a.dimensions_remember) { 930 if (a.dimensions_remember) {
913 apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl; 931 if(a.dimension_is_relative) {
932 apps_file << " [Dimensions]\t{" << a.w << "% " << a.h << "%}" << endl;
933 } else {
934 apps_file << " [Dimensions]\t{" << a.w << " " << a.h << "}" << endl;
935 }
914 } 936 }
915 if (a.position_remember) { 937 if (a.position_remember) {
916 apps_file << " [Position]\t("; 938 apps_file << " [Position]\t(";
@@ -942,7 +964,11 @@ void Remember::save() {
942 default: 964 default:
943 apps_file << "UPPERLEFT"; 965 apps_file << "UPPERLEFT";
944 } 966 }
945 apps_file << ")\t{" << a.x << " " << a.y << "}" << endl; 967 if(a.position_is_relative) {
968 apps_file << ")\t{" << a.x << "% " << a.y << "%}" << endl;
969 } else {
970 apps_file << ")\t{" << a.x << " " << a.y << "}" << endl;
971 }
946 } 972 }
947 if (a.shadedstate_remember) { 973 if (a.shadedstate_remember) {
948 apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl; 974 apps_file << " [Shaded]\t{" << ((a.shadedstate)?"yes":"no") << "}" << endl;
@@ -1029,7 +1055,7 @@ void Remember::save() {
1029 if (a.alpha_remember) { 1055 if (a.alpha_remember) {
1030 if (a.focused_alpha == a.unfocused_alpha) 1056 if (a.focused_alpha == a.unfocused_alpha)
1031 apps_file << " [Alpha]\t{" << a.focused_alpha << "}" << endl; 1057 apps_file << " [Alpha]\t{" << a.focused_alpha << "}" << endl;
1032 else 1058 else
1033 apps_file << " [Alpha]\t{" << a.focused_alpha << " " << a.unfocused_alpha << "}" << endl; 1059 apps_file << " [Alpha]\t{" << a.focused_alpha << " " << a.unfocused_alpha << "}" << endl;
1034 } 1060 }
1035 apps_file << "[end]" << endl; 1061 apps_file << "[end]" << endl;
@@ -1110,6 +1136,7 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
1110 app = add(winclient); 1136 app = add(winclient);
1111 if (!app) return; 1137 if (!app) return;
1112 } 1138 }
1139 int head, head_x, head_y, win_w, win_h, percx, percy;
1113 switch (attrib) { 1140 switch (attrib) {
1114 case REM_WORKSPACE: 1141 case REM_WORKSPACE:
1115 app->rememberWorkspace(win->workspaceNumber()); 1142 app->rememberWorkspace(win->workspaceNumber());
@@ -1117,16 +1144,18 @@ void Remember::rememberAttrib(WinClient &winclient, Attribute attrib) {
1117 case REM_HEAD: 1144 case REM_HEAD:
1118 app->rememberHead(win->screen().getHead(win->fbWindow())); 1145 app->rememberHead(win->screen().getHead(win->fbWindow()));
1119 break; 1146 break;
1120 case REM_DIMENSIONS: 1147 case REM_DIMENSIONS: {
1121 app->rememberDimensions(win->normalWidth(), 1148 head = win->screen().getHead(win->fbWindow());
1122 win->normalHeight()); 1149 int percx = win->screen().calRelativeDimensionWidth(head, win->normalWidth());
1150 int percy = win->screen().calRelativeDimensionHeight(head, win->normalHeight());
1151 app->rememberDimensions(percx, percy, true);
1123 break; 1152 break;
1153 }
1124 case REM_POSITION: { 1154 case REM_POSITION: {
1125 int head = win->screen().getHead(win->fbWindow()); 1155 head = win->screen().getHead(win->fbWindow());
1126 int head_x = win->screen().maxLeft(head); 1156 int percx = win->screen().calRelativePositionWidth(head, win->normalX());
1127 int head_y = win->screen().maxTop(head); 1157 int percy = win->screen().calRelativePositionHeight(head, win->normalY());
1128 app->rememberPosition(win->normalX() - head_x, 1158 app->rememberPosition(percx, percy, true);
1129 win->normalY() - head_y);
1130 break; 1159 break;
1131 } 1160 }
1132 case REM_FOCUSHIDDENSTATE: 1161 case REM_FOCUSHIDDENSTATE:
@@ -1288,13 +1317,32 @@ void Remember::setupFrame(FluxboxWindow &win) {
1288 win.setOnHead(app->head); 1317 win.setOnHead(app->head);
1289 } 1318 }
1290 1319
1291 if (app->dimensions_remember) 1320 if (app->dimensions_remember) {
1292 win.resize(app->w, app->h); 1321
1322 int win_w, win_h;
1323 if(app->dimension_is_relative) {
1324 int head = screen.getHead(win.fbWindow());
1325 int screen_y = screen.maxBottom(head) - screen.maxTop(head);
1326 win_w = screen.calRelativeWidth(head, app->w);
1327 win_h = screen.calRelativeHeight(head, app->h);
1328 } else {
1329 win_w = app->w;
1330 win_h = app->h;
1331 }
1332 win.resize(win_w, win_h);
1333 }
1293 1334
1294 if (app->position_remember) { 1335 if (app->position_remember) {
1295 int newx = app->x, newy = app->y; 1336 int newx, newy;
1296 win.translateCoords(newx, newy, app->refc); 1337 if(app->position_is_relative) {
1297 win.move(newx, newy); 1338 int head = screen.getHead(win.fbWindow());
1339 newx = screen.calRelativeWidth(head, app->x);
1340 newy = screen.calRelativeHeight(head, app->y);
1341 } else {
1342 newx = app->x, newy = app->y;
1343 }
1344 win.translateCoords(newx, newy, app->refc);
1345 win.move(newx, newy);
1298 } 1346 }
1299 1347
1300 if (app->shadedstate_remember) 1348 if (app->shadedstate_remember)
diff --git a/src/Screen.cc b/src/Screen.cc
index 4ea7afb..6757af0 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -1485,6 +1485,55 @@ void BScreen::addManagedResource(FbTk::Resource_base *resource) {
1485 m_managed_resources.push_back(resource); 1485 m_managed_resources.push_back(resource);
1486} 1486}
1487 1487
1488int BScreen::getGap(int head, const char type) {
1489 return type == 'w' ? getXGap(head) : getYGap(head);
1490}
1491
1492int BScreen::calRelativeSize(int head, int i, char type) {
1493 // return floor(i * getGap(head, type) / 100 + 0.5);
1494 return FbTk::RelCalcHelper::calPercentageValueOf(i, getGap(head, type));
1495}
1496int BScreen::calRelativeWidth(int head, int i) {
1497 return calRelativeSize(head, i, 'w');
1498}
1499int BScreen::calRelativeHeight(int head, int i) {
1500 return calRelativeSize(head, i, 'h');
1501}
1502
1503int BScreen::calRelativePosition(int head, int i, char type) {
1504 int max = type == 'w' ? maxLeft(head) : maxTop(head);
1505 // return floor((i - min) / getGap(head, type) * 100 + 0.5);
1506 return FbTk::RelCalcHelper::calPercentageOf((i - max), getGap(head, type));
1507}
1508// returns a pixel, which is relative to the width of the screen
1509// screen starts from 0, 1000 px width, if i is 10 then it should return 100
1510int BScreen::calRelativePositionWidth(int head, int i) {
1511 return calRelativePosition(head, i, 'w');
1512}
1513// returns a pixel, which is relative to the height of th escreen
1514// screen starts from 0, 1000 px height, if i is 10 then it should return 100
1515int BScreen::calRelativePositionHeight(int head, int i) {
1516 return calRelativePosition(head, i, 'h');
1517}
1518
1519int BScreen::calRelativeDimension(int head, int i, char type) {
1520 // return floor(i / getGap(head, type) * 100 + 0.5);
1521 return FbTk::RelCalcHelper::calPercentageOf(i, getGap(head, type));
1522 }
1523int BScreen::calRelativeDimensionWidth(int head, int i) {
1524 return calRelativeDimension(head, i, 'w');
1525}
1526int BScreen::calRelativeDimensionHeight(int head, int i) {
1527 return calRelativeDimension(head, i, 'h');
1528}
1529
1530float BScreen::getXGap(int head) {
1531 return maxRight(head) - maxLeft(head);
1532}
1533float BScreen::getYGap(int head) {
1534 return maxBottom(head) - maxTop(head);
1535}
1536
1488void BScreen::setupConfigmenu(FbTk::Menu &menu) { 1537void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1489 _FB_USES_NLS; 1538 _FB_USES_NLS;
1490 1539
diff --git a/src/Screen.hh b/src/Screen.hh
index de3a5a1..fe8d127 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -38,6 +38,7 @@
38#include "FbTk/MultLayers.hh" 38#include "FbTk/MultLayers.hh"
39#include "FbTk/NotCopyable.hh" 39#include "FbTk/NotCopyable.hh"
40#include "FbTk/Signal.hh" 40#include "FbTk/Signal.hh"
41#include "FbTk/RelCalcHelper.hh"
41 42
42#include "FocusControl.hh" 43#include "FocusControl.hh"
43 44
@@ -453,12 +454,28 @@ public:
453 /// when screen dies 454 /// when screen dies
454 void addManagedResource(FbTk::Resource_base *resource); 455 void addManagedResource(FbTk::Resource_base *resource);
455 456
457 int calRelativeSize(int head, int i, char type);
458 int calRelativeWidth(int head, int i);
459 int calRelativeHeight(int head, int i);
460
461 int calRelativePosition(int head, int i, char type);
462 int calRelativePositionWidth(int head, int i);
463 int calRelativePositionHeight(int head, int i);
464
465 int calRelativeDimension(int head, int i, char type);
466 int calRelativeDimensionWidth(int head, int i);
467 int calRelativeDimensionHeight(int head, int i);
468
456private: 469private:
457 void setupConfigmenu(FbTk::Menu &menu); 470 void setupConfigmenu(FbTk::Menu &menu);
458 void renderGeomWindow(); 471 void renderGeomWindow();
459 void renderPosWindow(); 472 void renderPosWindow();
460 void focusedWinFrameThemeReconfigured(); 473 void focusedWinFrameThemeReconfigured();
461 474
475 int getGap(int head, const char type);
476 float getXGap(int head);
477 float getYGap(int head);
478
462 const Strut* availableWorkspaceArea(int head) const; 479 const Strut* availableWorkspaceArea(int head) const;
463 480
464 FbTk::SignalTracker m_tracker; 481 FbTk::SignalTracker m_tracker;
diff --git a/src/Window.cc b/src/Window.cc
index a4eef44..f5a2fe2 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -3714,10 +3714,9 @@ FluxboxWindow::ReferenceCorner FluxboxWindow::getCorner(string str) {
3714 return ERROR; 3714 return ERROR;
3715} 3715}
3716 3716
3717void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const { 3717void FluxboxWindow::translateXCoords(int &x, ReferenceCorner dir) const {
3718 int head = getOnHead(), bw = 2 * frame().window().borderWidth(), 3718 int head = getOnHead(), bw = 2 * frame().window().borderWidth(),
3719 left = screen().maxLeft(head), right = screen().maxRight(head), 3719 left = screen().maxLeft(head), right = screen().maxRight(head);
3720 top = screen().maxTop(head), bottom = screen().maxBottom(head);
3721 3720
3722 if (dir == LEFTTOP || dir == LEFT || dir == LEFTBOTTOM) 3721 if (dir == LEFTTOP || dir == LEFT || dir == LEFTBOTTOM)
3723 x += left; 3722 x += left;
@@ -3725,6 +3724,12 @@ void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
3725 x = right - width() - bw - x; 3724 x = right - width() - bw - x;
3726 if (dir == TOP || dir == CENTER || dir == BOTTOM) 3725 if (dir == TOP || dir == CENTER || dir == BOTTOM)
3727 x += (left + right - width() - bw)/2; 3726 x += (left + right - width() - bw)/2;
3727}
3728
3729void FluxboxWindow::translateYCoords(int &y, ReferenceCorner dir) const {
3730 int head = getOnHead(), bw = 2 * frame().window().borderWidth(),
3731 top = screen().maxTop(head), bottom = screen().maxBottom(head);
3732
3728 if (dir == LEFTTOP || dir == TOP || dir == RIGHTTOP) 3733 if (dir == LEFTTOP || dir == TOP || dir == RIGHTTOP)
3729 y += top; 3734 y += top;
3730 if (dir == LEFTBOTTOM || dir == BOTTOM || dir == RIGHTBOTTOM) 3735 if (dir == LEFTBOTTOM || dir == BOTTOM || dir == RIGHTBOTTOM)
@@ -3733,6 +3738,11 @@ void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
3733 y += (top + bottom - height() - bw)/2; 3738 y += (top + bottom - height() - bw)/2;
3734} 3739}
3735 3740
3741void FluxboxWindow::translateCoords(int &x, int &y, ReferenceCorner dir) const {
3742 translateXCoords(x, dir);
3743 translateYCoords(y, dir);
3744}
3745
3736int FluxboxWindow::getOnHead() const { 3746int FluxboxWindow::getOnHead() const {
3737 return screen().getHead(fbWindow()); 3747 return screen().getHead(fbWindow());
3738} 3748}
diff --git a/src/Window.hh b/src/Window.hh
index a5bcb66..0d2cadd 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -350,6 +350,8 @@ public:
350 /// determine the reference corner from a string 350 /// determine the reference corner from a string
351 static ReferenceCorner getCorner(std::string str); 351 static ReferenceCorner getCorner(std::string str);
352 /// convert to coordinates on the root window 352 /// convert to coordinates on the root window
353 void translateXCoords(int &x, ReferenceCorner dir = LEFTTOP) const;
354 void translateYCoords(int &y, ReferenceCorner dir = LEFTTOP) const;
353 void translateCoords(int &x, int &y, ReferenceCorner dir = LEFTTOP) const; 355 void translateCoords(int &x, int &y, ReferenceCorner dir = LEFTTOP) const;
354 356
355 /** 357 /**
diff --git a/src/tests/StringUtiltest.cc b/src/tests/StringUtiltest.cc
index b723eef..e5e8419 100644
--- a/src/tests/StringUtiltest.cc
+++ b/src/tests/StringUtiltest.cc
@@ -33,9 +33,9 @@
33using namespace std; 33using namespace std;
34using namespace FbTk; 34using namespace FbTk;
35 35
36void testStringtok() { 36void testStringtok() {
37 vector<string> ls; 37 vector<string> ls;
38 StringUtil::stringtok(ls, " arg1 arg2 \targ3\n arg4 arg5\t\t\t\targ6\n\n \n\n \t\t\narg7"); 38 StringUtil::stringtok(ls, " arg1 arg2 \targ3\n arg4 arg5\t\t\t\targ6\n\n \n\n \t\t\narg7");
39 cerr<<"Size: "<<ls.size()<<". Should be: 7."<<endl; 39 cerr<<"Size: "<<ls.size()<<". Should be: 7."<<endl;
40 for (vector<string>::const_iterator i = ls.begin(); 40 for (vector<string>::const_iterator i = ls.begin();
41 i != ls.end(); ++i) { 41 i != ls.end(); ++i) {
@@ -66,7 +66,7 @@ void testStrcasestr() {
66 cerr<<"ok."<<endl; 66 cerr<<"ok."<<endl;
67 else 67 else
68 cerr<<"faild."<<endl; 68 cerr<<"faild."<<endl;
69 69
70 cerr<<"test3 "; 70 cerr<<"test3 ";
71 if (StringUtil::strcasestr("TeSt", "abcTEStabc") == strcasestr("TeSt", "abcTEStabc")) 71 if (StringUtil::strcasestr("TeSt", "abcTEStabc") == strcasestr("TeSt", "abcTEStabc"))
72 cerr<<"ok."<<endl; 72 cerr<<"ok."<<endl;
@@ -82,7 +82,7 @@ void testStrcasestr() {
82} 82}
83 83
84void showError(int line, int pos, string& instr) { 84void showError(int line, int pos, string& instr) {
85 85
86 cerr<<"Error on line: "<<line<<endl; 86 cerr<<"Error on line: "<<line<<endl;
87 cerr<<instr<<endl; 87 cerr<<instr<<endl;
88 for (int c=0; c<pos; c++) { 88 for (int c=0; c<pos; c++) {
@@ -91,8 +91,8 @@ void showError(int line, int pos, string& instr) {
91 else 91 else
92 cerr<<" "; 92 cerr<<" ";
93 } 93 }
94 cerr<<"^ here"<<endl; 94 cerr<<"^ here"<<endl;
95 95
96} 96}
97 97
98void testGetStringBetween() { 98void testGetStringBetween() {
@@ -101,7 +101,7 @@ void testGetStringBetween() {
101 stringlist.push_back(" \t\t\t \t[(in \\)\t haha )] \t\t "); 101 stringlist.push_back(" \t\t\t \t[(in \\)\t haha )] \t\t ");
102 stringlist.push_back("(in\\)) {_ _ my_ _}"); 102 stringlist.push_back("(in\\)) {_ _ my_ _}");
103 stringlist.push_back("(in) {_ _ my_ _}"); 103 stringlist.push_back("(in) {_ _ my_ _}");
104 stringlist.push_back("(in){_ _ my_ _}"); 104 stringlist.push_back("(in){_ _ my_ _}");
105 stringlist.push_back("\t \t \t ( in ) {haha}"); 105 stringlist.push_back("\t \t \t ( in ) {haha}");
106 stringlist.push_back("\t \t \t (( in \\) ) {haha}"); 106 stringlist.push_back("\t \t \t (( in \\) ) {haha}");
107 stringlist.push_back("\t \t \t (( in \\) ){hihi}"); 107 stringlist.push_back("\t \t \t (( in \\) ){hihi}");
@@ -116,17 +116,18 @@ void testGetStringBetween() {
116 cerr<<"string="<<stringlist[i]<<endl; 116 cerr<<"string="<<stringlist[i]<<endl;
117 cerr<<"pos="<<pos<<" ::"<<out; 117 cerr<<"pos="<<pos<<" ::"<<out;
118 total_pos += pos; 118 total_pos += pos;
119 pos = StringUtil::getStringBetween(out, stringlist[i].c_str()+total_pos, '{', '}'); 119 pos = StringUtil::getStringBetween(out, stringlist[i].c_str()+total_pos, '{', '}');
120 if (pos<=0) { 120 if (pos<=0) {
121 pos=-pos; 121 pos=-pos;
122 showError(i+1, total_pos+pos, stringlist[i]); 122 showError(i+1, total_pos+pos, stringlist[i]);
123 continue; 123 continue;
124 } 124 }
125 cerr<<"::"<<out<<"::"<<endl; 125 cerr<<"::"<<out<<"::"<<endl;
126 total_pos += pos; 126 total_pos += pos;
127 } 127 }
128} 128}
129int main() { 129
130int main() {
130 try { 131 try {
131 string replaceme = "something((((otherthanthis)could[be]changed"; 132 string replaceme = "something((((otherthanthis)could[be]changed";
132 133
@@ -140,13 +141,10 @@ int main() {
140 } catch (std::exception & e) { 141 } catch (std::exception & e) {
141 cerr<<"exception: "<<e.what()<<endl; 142 cerr<<"exception: "<<e.what()<<endl;
142 } 143 }
143 cerr<<"Testing stringtok."<<endl; 144 cerr<<"Testing stringtok."<<endl;
144 testStringtok(); 145 testStringtok();
145 cerr<<"Testing expandFilename."<<endl; 146 cerr<<"Testing expandFilename."<<endl;
146 testExpandFilename(); 147 testExpandFilename();
147 cerr<<"Testing strcasestr."<<endl; 148 cerr<<"Testing strcasestr."<<endl;
148 testStrcasestr(); 149 testStrcasestr();
149
150
151
152} 150}