aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Tiefenbruck <mark@fluxbox.org>2008-08-27 17:05:49 (GMT)
committerMark Tiefenbruck <mark@fluxbox.org>2008-08-27 17:05:49 (GMT)
commit55fd49614bb1b9e37561147f18719b2ac277b64b (patch)
treec0f58db24f6fa3a457bca26393c00632dd630328
parent08c8c6431f88ff3d5012d800a8df689b7028fe98 (diff)
downloadfluxbox-55fd49614bb1b9e37561147f18719b2ac277b64b.zip
fluxbox-55fd49614bb1b9e37561147f18719b2ac277b64b.tar.bz2
move FbWinFrame::State class to a new file
-rw-r--r--src/CurrentWindowCmd.cc2
-rw-r--r--src/FbWinFrame.cc303
-rw-r--r--src/FbWinFrame.hh103
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Remember.cc40
-rw-r--r--src/WinClient.hh7
-rw-r--r--src/Window.cc92
-rw-r--r--src/Window.hh12
-rw-r--r--src/WindowState.cc266
-rw-r--r--src/WindowState.hh118
10 files changed, 486 insertions, 459 deletions
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 95f2933..59b0186 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -503,7 +503,7 @@ void SetTitleCmd::real_execute() {
503REGISTER_COMMAND_WITH_ARGS(setdecor, SetDecorCmd, void); 503REGISTER_COMMAND_WITH_ARGS(setdecor, SetDecorCmd, void);
504 504
505SetDecorCmd::SetDecorCmd(const std::string &args): 505SetDecorCmd::SetDecorCmd(const std::string &args):
506 m_mask(FbWinFrame::getDecoMaskFromString(args)) { } 506 m_mask(WindowState::getDecoMaskFromString(args)) { }
507 507
508void SetDecorCmd::real_execute() { 508void SetDecorCmd::real_execute() {
509 fbwindow().setDecorationMask(m_mask); 509 fbwindow().setDecorationMask(m_mask);
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index 9e7f613..1a98ff5 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -28,7 +28,6 @@
28#include "FbTk/Compose.hh" 28#include "FbTk/Compose.hh"
29#include "FbTk/Transparent.hh" 29#include "FbTk/Transparent.hh"
30#include "FbTk/CompareEqual.hh" 30#include "FbTk/CompareEqual.hh"
31#include "FbTk/StringUtil.hh"
32#include "FbTk/TextUtils.hh" 31#include "FbTk/TextUtils.hh"
33 32
34#include "FbWinFrameTheme.hh" 33#include "FbWinFrameTheme.hh"
@@ -194,7 +193,7 @@ void FbWinFrame::show() {
194 Toggle shade state, and resize window 193 Toggle shade state, and resize window
195 */ 194 */
196void FbWinFrame::shade() { 195void FbWinFrame::shade() {
197 if (!(m_state.deco_mask & DECORM_TITLEBAR)) 196 if (!(m_state.deco_mask & WindowState::DECORM_TITLEBAR))
198 return; 197 return;
199 198
200 // toggle shade 199 // toggle shade
@@ -254,7 +253,8 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
254 m_window.resize(width, height); 253 m_window.resize(width, height);
255 } 254 }
256 255
257 saveGeometry(); 256 m_state.saveGeometry(window().x(), window().y(),
257 window().width(), window().height());
258 258
259 if (move || (resize && m_screen.getTabPlacement() != TOPLEFT && 259 if (move || (resize && m_screen.getTabPlacement() != TOPLEFT &&
260 m_screen.getTabPlacement() != LEFTTOP)) 260 m_screen.getTabPlacement() != LEFTTOP))
@@ -283,7 +283,8 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
283void FbWinFrame::quietMoveResize(int x, int y, 283void FbWinFrame::quietMoveResize(int x, int y,
284 unsigned int width, unsigned int height) { 284 unsigned int width, unsigned int height) {
285 m_window.moveResize(x, y, width, height); 285 m_window.moveResize(x, y, width, height);
286 saveGeometry(); 286 m_state.saveGeometry(window().x(), window().y(),
287 window().width(), window().height());
287 if (m_tabmode == EXTERNAL) { 288 if (m_tabmode == EXTERNAL) {
288 289
289 switch(m_screen.getTabPlacement()) { 290 switch(m_screen.getTabPlacement()) {
@@ -534,21 +535,6 @@ void FbWinFrame::setMaximized(int value) {
534 applyState(); 535 applyState();
535} 536}
536 537
537void FbWinFrame::saveGeometry() {
538 if (m_state.fullscreen || m_state.maximized == MAX_FULL)
539 return;
540
541 if (!(m_state.maximized & MAX_HORZ)) {
542 m_state.x = x();
543 m_state.width = width();
544 }
545 if (!(m_state.maximized & MAX_VERT)) {
546 m_state.y = y();
547 if (!m_state.shaded)
548 m_state.height = height();
549 }
550}
551
552void FbWinFrame::applyState() { 538void FbWinFrame::applyState() {
553 applyDecorations(); 539 applyDecorations();
554 540
@@ -556,7 +542,7 @@ void FbWinFrame::applyState() {
556 int new_x = m_state.x, new_y = m_state.y; 542 int new_x = m_state.x, new_y = m_state.y;
557 unsigned int new_w = m_state.width, new_h = m_state.height; 543 unsigned int new_w = m_state.width, new_h = m_state.height;
558 544
559 if (m_state.maximized & MAX_VERT) { 545 if (m_state.maximized & WindowState::MAX_VERT) {
560 new_y = m_screen.maxTop(head); 546 new_y = m_screen.maxTop(head);
561 new_h = m_screen.maxBottom(head) - new_y - 2*window().borderWidth(); 547 new_h = m_screen.maxBottom(head) - new_y - 2*window().borderWidth();
562 if (!m_screen.getMaxOverTabs()) { 548 if (!m_screen.getMaxOverTabs()) {
@@ -564,7 +550,7 @@ void FbWinFrame::applyState() {
564 new_h -= heightOffset(); 550 new_h -= heightOffset();
565 } 551 }
566 } 552 }
567 if (m_state.maximized & MAX_HORZ) { 553 if (m_state.maximized & WindowState::MAX_HORZ) {
568 new_x = m_screen.maxLeft(head); 554 new_x = m_screen.maxLeft(head);
569 new_w = m_screen.maxRight(head) - new_x - 2*window().borderWidth(); 555 new_w = m_screen.maxRight(head) - new_x - 2*window().borderWidth();
570 if (!m_screen.getMaxOverTabs()) { 556 if (!m_screen.getMaxOverTabs()) {
@@ -1482,50 +1468,11 @@ void FbWinFrame::applyTabContainer() {
1482 } 1468 }
1483} 1469}
1484 1470
1485int FbWinFrame::getDecoMaskFromString(const string &str_label) {
1486 string label = FbTk::StringUtil::toLower(str_label);
1487 if (label == "none")
1488 return DECOR_NONE;
1489 if (label == "normal")
1490 return DECOR_NORMAL;
1491 if (label == "tiny")
1492 return DECOR_TINY;
1493 if (label == "tool")
1494 return DECOR_TOOL;
1495 if (label == "border")
1496 return DECOR_BORDER;
1497 if (label == "tab")
1498 return DECOR_TAB;
1499 int mask = -1;
1500 if ((str_label.size() > 1 && str_label[0] == '0' && str_label[1] == 'x') ||
1501 (str_label.size() > 0 && isdigit(str_label[0])))
1502 mask = strtol(str_label.c_str(), NULL, 0);
1503 return mask;
1504}
1505
1506bool FbWinFrame::useBorder() const {
1507 return !m_state.fullscreen && m_state.maximized != MAX_FULL &&
1508 (m_state.deco_mask & DECORM_BORDER);
1509}
1510
1511bool FbWinFrame::useTabs() const {
1512 return !m_state.fullscreen && m_state.deco_mask & DECORM_TAB;
1513}
1514
1515bool FbWinFrame::useTitlebar() const {
1516 return !m_state.fullscreen && m_state.deco_mask & DECORM_TITLEBAR;
1517}
1518
1519bool FbWinFrame::useHandle() const {
1520 return !m_state.fullscreen && !m_state.shaded &&
1521 m_state.deco_mask & DECORM_HANDLE;
1522}
1523
1524int FbWinFrame::getShape() const { 1471int FbWinFrame::getShape() const {
1525 int shape = theme()->shapePlace(); 1472 int shape = theme()->shapePlace();
1526 if (!useTitlebar()) 1473 if (!m_state.useTitlebar())
1527 shape &= ~(FbTk::Shape::TOPRIGHT|FbTk::Shape::TOPLEFT); 1474 shape &= ~(FbTk::Shape::TOPRIGHT|FbTk::Shape::TOPLEFT);
1528 if (!useHandle()) 1475 if (!m_state.useHandle())
1529 shape &= ~(FbTk::Shape::BOTTOMRIGHT|FbTk::Shape::BOTTOMLEFT); 1476 shape &= ~(FbTk::Shape::BOTTOMRIGHT|FbTk::Shape::BOTTOMLEFT);
1530 return shape; 1477 return shape;
1531} 1478}
@@ -1541,13 +1488,13 @@ void FbWinFrame::applyDecorations() {
1541 // tab deocration only affects if we're external 1488 // tab deocration only affects if we're external
1542 // must do before the setTabMode in case it goes 1489 // must do before the setTabMode in case it goes
1543 // to external and is meant to be hidden 1490 // to external and is meant to be hidden
1544 if (useTabs()) 1491 if (m_state.useTabs())
1545 client_move |= showTabs(); 1492 client_move |= showTabs();
1546 else 1493 else
1547 client_move |= hideTabs(); 1494 client_move |= hideTabs();
1548 1495
1549 // we rely on frame not doing anything if it is already shown/hidden 1496 // we rely on frame not doing anything if it is already shown/hidden
1550 if (useTitlebar()) { 1497 if (m_state.useTitlebar()) {
1551 client_move |= showTitlebar(); 1498 client_move |= showTitlebar();
1552 if (m_screen.getDefaultInternalTabs()) 1499 if (m_screen.getDefaultInternalTabs())
1553 client_move |= setTabMode(INTERNAL); 1500 client_move |= setTabMode(INTERNAL);
@@ -1555,11 +1502,11 @@ void FbWinFrame::applyDecorations() {
1555 client_move |= setTabMode(EXTERNAL); 1502 client_move |= setTabMode(EXTERNAL);
1556 } else { 1503 } else {
1557 client_move |= hideTitlebar(); 1504 client_move |= hideTitlebar();
1558 if (useTabs()) 1505 if (m_state.useTabs())
1559 client_move |= setTabMode(EXTERNAL); 1506 client_move |= setTabMode(EXTERNAL);
1560 } 1507 }
1561 1508
1562 if (useHandle()) 1509 if (m_state.useHandle())
1563 client_move |= showHandle(); 1510 client_move |= showHandle();
1564 else 1511 else
1565 client_move |= hideHandle(); 1512 client_move |= hideHandle();
@@ -1581,7 +1528,7 @@ void FbWinFrame::applyDecorations() {
1581 1528
1582bool FbWinFrame::setBorderWidth(bool do_move) { 1529bool FbWinFrame::setBorderWidth(bool do_move) {
1583 unsigned int border_width = theme()->border().width(); 1530 unsigned int border_width = theme()->border().width();
1584 unsigned int win_bw = useBorder() ? border_width : 0; 1531 unsigned int win_bw = m_state.useBorder() ? border_width : 0;
1585 1532
1586 if (border_width && 1533 if (border_width &&
1587 theme()->border().color().pixel() != window().borderColor()) { 1534 theme()->border().color().pixel() != window().borderColor()) {
@@ -1717,30 +1664,6 @@ void FbWinFrame::gravityTranslate(int &x, int &y,
1717 } 1664 }
1718} 1665}
1719 1666
1720int FbWinFrame::normalX() const {
1721 if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen)
1722 return m_state.x;
1723 return x();
1724}
1725
1726int FbWinFrame::normalY() const {
1727 if ((m_state.maximized & MAX_VERT) || m_state.fullscreen)
1728 return m_state.y;
1729 return y();
1730}
1731
1732unsigned int FbWinFrame::normalWidth() const {
1733 if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen)
1734 return m_state.width;
1735 return width();
1736}
1737
1738unsigned int FbWinFrame::normalHeight() const {
1739 if ((m_state.maximized & MAX_VERT) || m_state.fullscreen || m_state.shaded)
1740 return m_state.height;
1741 return height();
1742}
1743
1744int FbWinFrame::widthOffset() const { 1667int FbWinFrame::widthOffset() const {
1745 if (m_tabmode != EXTERNAL || !m_use_tabs) 1668 if (m_tabmode != EXTERNAL || !m_use_tabs)
1746 return 0; 1669 return 0;
@@ -1825,201 +1748,3 @@ void FbWinFrame::displaySize(unsigned int width, unsigned int height) const {
1825 width, height - titlebarHeight() - handleHeight()); 1748 width, height - titlebarHeight() - handleHeight());
1826 m_screen.showGeometry(i, j); 1749 m_screen.showGeometry(i, j);
1827} 1750}
1828
1829void FbWinFrame::SizeHints::reset(const XSizeHints &sizehint) {
1830 if (sizehint.flags & PMinSize) {
1831 min_width = sizehint.min_width;
1832 min_height = sizehint.min_height;
1833 } else
1834 min_width = min_height = 1;
1835
1836 if (sizehint.flags & PBaseSize) {
1837 base_width = sizehint.base_width;
1838 base_height = sizehint.base_height;
1839 if (!(sizehint.flags & PMinSize)) {
1840 min_width = base_width;
1841 min_height = base_height;
1842 }
1843 } else
1844 base_width = base_height = 0;
1845
1846 if (sizehint.flags & PMaxSize) {
1847 max_width = sizehint.max_width;
1848 max_height = sizehint.max_height;
1849 } else
1850 max_width = max_height = 0; // unbounded
1851
1852 if (sizehint.flags & PResizeInc) {
1853 width_inc = sizehint.width_inc;
1854 height_inc = sizehint.height_inc;
1855 } else
1856 width_inc = height_inc = 1;
1857
1858 if (sizehint.flags & PAspect) {
1859 min_aspect_x = sizehint.min_aspect.x;
1860 min_aspect_y = sizehint.min_aspect.y;
1861 max_aspect_x = sizehint.max_aspect.x;
1862 max_aspect_y = sizehint.max_aspect.y;
1863 } else {
1864 min_aspect_x = max_aspect_y = 0;
1865 min_aspect_y = max_aspect_x = 1;
1866 }
1867
1868 if (sizehint.flags & PWinGravity)
1869 win_gravity = sizehint.win_gravity;
1870 else
1871 win_gravity = NorthWestGravity;
1872
1873 // some sanity checks
1874 if (width_inc == 0)
1875 width_inc = 1;
1876 if (height_inc == 0)
1877 height_inc = 1;
1878
1879 if (base_width > min_width)
1880 min_width = base_width;
1881 if (base_height > min_height)
1882 min_height = base_height;
1883}
1884
1885/* For aspect ratios
1886 Note that its slightly simplified in that only the
1887 line gradient is given - this is because for aspect
1888 ratios, we always have the line going through the origin
1889
1890 * Based on this formula:
1891 http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
1892
1893 Note that a gradient from origin goes through ( grad , 1 )
1894 */
1895
1896void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y,
1897 unsigned int point_x, unsigned int point_y,
1898 unsigned int aspect_x, unsigned int aspect_y) {
1899 double u = static_cast<double>(point_x * aspect_x + point_y * aspect_y) /
1900 static_cast<double>(aspect_x * aspect_x + aspect_y * aspect_y);
1901
1902 ret_x = static_cast<unsigned int>(u * aspect_x);
1903 ret_y = static_cast<unsigned int>(u * aspect_y);
1904}
1905
1906unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
1907 return val % inc ? val + inc - (val % inc) : val;
1908}
1909
1910unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) {
1911 return val % inc ? val - (val % inc) : val;
1912}
1913
1914/**
1915 * Changes width and height to the nearest (lower) value
1916 * that conforms to it's size hints.
1917 *
1918 * display_* give the values that would be displayed
1919 * to the user when resizing.
1920 * We use pointers for display_* since they are optional.
1921 *
1922 * See ICCCM section 4.1.2.3
1923 */
1924void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height,
1925 bool make_fit) const {
1926
1927 /* aspect ratios are applied exclusive to the base size
1928 *
1929 * min_aspect_x width max_aspect_x
1930 * ------------ < ------- < ------------
1931 * min_aspect_y height max_aspect_y
1932 *
1933 * The trick is how to get back to the aspect ratio with minimal
1934 * change - do we modify x, y or both?
1935 * A: we minimise the distance between the current point, and
1936 * the target aspect ratio (consider them as x,y coordinates)
1937 * Consider that the aspect ratio is a line, and the current
1938 * w/h is a point, so we're just using the formula for
1939 * shortest distance from a point to a line!
1940 */
1941
1942 // make respective to base_size
1943 unsigned int w = width - base_width, h = height - base_height;
1944
1945 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) {
1946 closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y);
1947 // new w must be > old w, new h must be < old h
1948 w = increaseToMultiple(w, width_inc);
1949 h = decreaseToMultiple(h, height_inc);
1950 } else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) {
1951 closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y);
1952 // new w must be < old w, new h must be > old h
1953 w = decreaseToMultiple(w, width_inc);
1954 h = increaseToMultiple(h, height_inc);
1955 }
1956
1957 // Check minimum size
1958 if (w + base_width < min_width) {
1959 w = increaseToMultiple(min_width - base_width, width_inc);
1960 // need to check maximum aspect again
1961 if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
1962 h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc);
1963 }
1964
1965 if (h + base_height < min_height) {
1966 h = increaseToMultiple(min_height - base_height, height_inc);
1967 // need to check minimum aspect again
1968 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
1969 w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc);
1970 }
1971
1972 unsigned int max_w = make_fit && (width < max_width || max_width == 0) ?
1973 width : max_width;
1974 unsigned int max_h = make_fit && (height < max_height || max_height == 0) ?
1975 height : max_height;
1976
1977 // Check maximum size
1978 if (max_w > 0 && w + base_width > max_w)
1979 w = max_w - base_width;
1980
1981 if (max_h > 0 && h + base_height > max_h)
1982 h = max_h - base_height;
1983
1984 w = decreaseToMultiple(w, width_inc);
1985 h = decreaseToMultiple(h, height_inc);
1986
1987 // need to check aspects one more time
1988 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
1989 h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc);
1990
1991 if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
1992 w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc);
1993
1994 width = w + base_width;
1995 height = h + base_height;
1996}
1997
1998// check if the given width and height satisfy the size hints
1999bool FbWinFrame::SizeHints::valid(unsigned int w, unsigned int h) const {
2000 if (w < min_width || h < min_height)
2001 return false;
2002
2003 if (w > max_width || h > max_height)
2004 return false;
2005
2006 if ((w - base_width) % width_inc != 0)
2007 return false;
2008
2009 if ((h - base_height) % height_inc != 0)
2010 return false;
2011
2012 if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y)
2013 return false;
2014
2015 if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y)
2016 return false;
2017
2018 return true;
2019}
2020
2021void FbWinFrame::SizeHints::displaySize(unsigned int &i, unsigned int &j,
2022 unsigned int width, unsigned int height) const {
2023 i = (width - base_width) / width_inc;
2024 j = (height - base_height) / height_inc;
2025}
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh
index 55d47ed..4a33fec 100644
--- a/src/FbWinFrame.hh
+++ b/src/FbWinFrame.hh
@@ -33,6 +33,8 @@
33#include "FbTk/Container.hh" 33#include "FbTk/Container.hh"
34#include "FbTk/Shape.hh" 34#include "FbTk/Shape.hh"
35 35
36#include "WindowState.hh"
37
36#include <X11/Xutil.h> 38#include <X11/Xutil.h>
37 39
38#include <vector> 40#include <vector>
@@ -68,85 +70,6 @@ public:
68 RIGHTBOTTOM, RIGHT, RIGHTTOP 70 RIGHTBOTTOM, RIGHT, RIGHTTOP
69 }; 71 };
70 72
71 /**
72 * Types of maximization
73 */
74 enum MaximizeMode {
75 MAX_NONE = 0, ///< normal state
76 MAX_HORZ = 1, ///< maximize horizontal
77 MAX_VERT = 2, ///< maximize vertical
78 MAX_FULL = 3 ///< maximize full
79 };
80
81 /**
82 This enumeration represents individual decoration
83 attributes, they can be OR-d together to get a mask.
84 Useful for saving.
85 */
86 enum DecorationMask {
87 DECORM_TITLEBAR = (1<<0),
88 DECORM_HANDLE = (1<<1),
89 DECORM_BORDER = (1<<2),
90 DECORM_ICONIFY = (1<<3),
91 DECORM_MAXIMIZE = (1<<4),
92 DECORM_CLOSE = (1<<5),
93 DECORM_MENU = (1<<6),
94 DECORM_STICKY = (1<<7),
95 DECORM_SHADE = (1<<8),
96 DECORM_TAB = (1<<9),
97 DECORM_ENABLED = (1<<10),
98 DECORM_LAST = (1<<11) // useful for getting "All"
99 };
100
101 enum Decoration {
102 DECOR_NONE = 0,
103 DECOR_NORMAL = DECORM_LAST - 1,
104 DECOR_TINY = DECORM_TITLEBAR|DECORM_ICONIFY|DECORM_MENU|DECORM_TAB,
105 DECOR_TOOL = DECORM_TITLEBAR|DECORM_MENU,
106 DECOR_BORDER = DECORM_BORDER|DECORM_MENU,
107 DECOR_TAB = DECORM_BORDER|DECORM_MENU|DECORM_TAB
108 };
109
110 class SizeHints {
111 public:
112 SizeHints():
113 min_width(1), max_width(0), min_height(1), max_height(0),
114 width_inc(1), height_inc(1), base_width(0), base_height(0),
115 min_aspect_x(0), max_aspect_x(1),
116 min_aspect_y(1), max_aspect_y(0),
117 win_gravity(0) { }
118
119 void reset(const XSizeHints &sizehint);
120
121 void apply(unsigned int &w, unsigned int &h,
122 bool maximizing = false) const;
123 bool valid(unsigned int width, unsigned int height) const;
124 void displaySize(unsigned int &i, unsigned int &j,
125 unsigned int width, unsigned int height) const;
126
127 unsigned int min_width, max_width, min_height, max_height,
128 width_inc, height_inc, base_width, base_height,
129 min_aspect_x, max_aspect_x, min_aspect_y, max_aspect_y;
130 int win_gravity;
131 };
132
133 class State {
134 public:
135 State():
136 size_hints(),
137 deco_mask(DECOR_NORMAL),
138 focused(false),
139 shaded(false), fullscreen(false), maximized(0),
140 x(0), y(0), width(1), height(1) { }
141
142 SizeHints size_hints;
143 unsigned int deco_mask;
144 bool focused, shaded, fullscreen;
145 int maximized;
146 int x, y;
147 unsigned int width, height;
148 };
149
150 /// create a top level window 73 /// create a top level window
151 FbWinFrame(BScreen &screen, FocusableTheme<FbWinFrameTheme> &theme, 74 FbWinFrame(BScreen &screen, FocusableTheme<FbWinFrameTheme> &theme,
152 FbTk::ImageControl &imgctrl, 75 FbTk::ImageControl &imgctrl,
@@ -247,18 +170,9 @@ public:
247 bool maximizing = false) const; 170 bool maximizing = false) const;
248 void displaySize(unsigned int width, unsigned int height) const; 171 void displaySize(unsigned int width, unsigned int height) const;
249 172
250 static int getDecoMaskFromString(const std::string &str);
251 void setDecorationMask(unsigned int mask) { m_state.deco_mask = mask; } 173 void setDecorationMask(unsigned int mask) { m_state.deco_mask = mask; }
252 void applyDecorations(); 174 void applyDecorations();
253 void applyState(); 175 void applyState();
254 void saveGeometry();
255
256 /// determine if the given decoration should be shown in current state
257 bool useBorder() const;
258 bool useTabs() const;
259 bool useTitlebar() const;
260 bool useHandle() const;
261 int getShape() const;
262 176
263 // this function translates its arguments according to win_gravity 177 // this function translates its arguments according to win_gravity
264 // if win_gravity is negative, it does an inverse translation 178 // if win_gravity is negative, it does an inverse translation
@@ -287,10 +201,10 @@ public:
287 unsigned int width() const { return m_window.width(); } 201 unsigned int width() const { return m_window.width(); }
288 unsigned int height() const { return m_window.height(); } 202 unsigned int height() const { return m_window.height(); }
289 203
290 int normalX() const; 204 int normalX() const { return m_state.x; }
291 int normalY() const; 205 int normalY() const { return m_state.y; }
292 unsigned int normalWidth() const; 206 unsigned int normalWidth() const { return m_state.width; }
293 unsigned int normalHeight() const; 207 unsigned int normalHeight() const { return m_state.height; }
294 208
295 // extra bits for tabs 209 // extra bits for tabs
296 int xOffset() const; 210 int xOffset() const;
@@ -368,6 +282,9 @@ private:
368 bool showHandle(); 282 bool showHandle();
369 bool setBorderWidth(bool do_move = true); 283 bool setBorderWidth(bool do_move = true);
370 284
285 // check which corners should be rounded
286 int getShape() const;
287
371 /** 288 /**
372 @name apply pixmaps depending on focus 289 @name apply pixmaps depending on focus
373 */ 290 */
@@ -463,7 +380,7 @@ private:
463 TabMode m_tabmode; 380 TabMode m_tabmode;
464 381
465 unsigned int m_active_orig_client_bw; 382 unsigned int m_active_orig_client_bw;
466 State m_state; 383 WindowState m_state;
467 384
468 bool m_need_render; 385 bool m_need_render;
469 int m_button_size; ///< size for all titlebar buttons 386 int m_button_size; ///< size for all titlebar buttons
diff --git a/src/Makefile.am b/src/Makefile.am
index 448a781..923b2cc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -113,7 +113,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
113 Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \ 113 Slit.cc Slit.hh SlitTheme.hh SlitTheme.cc SlitClient.hh SlitClient.cc \
114 WinButton.hh WinButton.cc \ 114 WinButton.hh WinButton.cc \
115 WinButtonTheme.hh WinButtonTheme.cc \ 115 WinButtonTheme.hh WinButtonTheme.cc \
116 Window.cc Window.hh \ 116 Window.cc Window.hh WindowState.cc WindowState.hh\
117 Workspace.cc Workspace.hh \ 117 Workspace.cc Workspace.hh \
118 FbCommands.hh FbCommands.cc LayerMenu.hh LayerMenu.cc \ 118 FbCommands.hh FbCommands.cc LayerMenu.hh LayerMenu.cc \
119 Layer.hh \ 119 Layer.hh \
diff --git a/src/Remember.cc b/src/Remember.cc
index 1df5045..0ea8a6c 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -500,7 +500,7 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
500 app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); 500 app.rememberIconHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
501 app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0)); 501 app.rememberFocusHiddenstate((strcasecmp(str_label.c_str(), "yes") == 0));
502 } else if (str_key == "deco") { 502 } else if (str_key == "deco") {
503 int deco = FbWinFrame::getDecoMaskFromString(str_label); 503 int deco = WindowState::getDecoMaskFromString(str_label);
504 if (deco == -1) 504 if (deco == -1)
505 had_error = 1; 505 had_error = 1;
506 else 506 else
@@ -535,13 +535,13 @@ int parseApp(ifstream &file, Application &app, string *first_line = 0) {
535 app.rememberMinimizedstate((strcasecmp(str_label.c_str(), "yes") == 0)); 535 app.rememberMinimizedstate((strcasecmp(str_label.c_str(), "yes") == 0));
536 } else if (str_key == "maximized") { 536 } else if (str_key == "maximized") {
537 if (strcasecmp(str_label.c_str(), "yes") == 0) 537 if (strcasecmp(str_label.c_str(), "yes") == 0)
538 app.rememberMaximizedstate(FbWinFrame::MAX_FULL); 538 app.rememberMaximizedstate(WindowState::MAX_FULL);
539 else if (strcasecmp(str_label.c_str(), "horz") == 0) 539 else if (strcasecmp(str_label.c_str(), "horz") == 0)
540 app.rememberMaximizedstate(FbWinFrame::MAX_HORZ); 540 app.rememberMaximizedstate(WindowState::MAX_HORZ);
541 else if (strcasecmp(str_label.c_str(), "vert") == 0) 541 else if (strcasecmp(str_label.c_str(), "vert") == 0)
542 app.rememberMaximizedstate(FbWinFrame::MAX_VERT); 542 app.rememberMaximizedstate(WindowState::MAX_VERT);
543 else 543 else
544 app.rememberMaximizedstate(FbWinFrame::MAX_NONE); 544 app.rememberMaximizedstate(WindowState::MAX_NONE);
545 } else if (str_key == "fullscreen") { 545 } else if (str_key == "fullscreen") {
546 app.rememberFullscreenstate((strcasecmp(str_label.c_str(), "yes") == 0)); 546 app.rememberFullscreenstate((strcasecmp(str_label.c_str(), "yes") == 0));
547 } else if (str_key == "jump") { 547 } else if (str_key == "jump") {
@@ -953,25 +953,25 @@ void Remember::save() {
953 apps_file << " [Deco]\t{NONE}" << endl; 953 apps_file << " [Deco]\t{NONE}" << endl;
954 break; 954 break;
955 case (0xffffffff): 955 case (0xffffffff):
956 case (FbWinFrame::DECORM_LAST - 1): 956 case (WindowState::DECORM_LAST - 1):
957 apps_file << " [Deco]\t{NORMAL}" << endl; 957 apps_file << " [Deco]\t{NORMAL}" << endl;
958 break; 958 break;
959 case (FbWinFrame::DECORM_TITLEBAR 959 case (WindowState::DECORM_TITLEBAR
960 | FbWinFrame::DECORM_ICONIFY 960 | WindowState::DECORM_ICONIFY
961 | FbWinFrame::DECORM_MENU): 961 | WindowState::DECORM_MENU):
962 apps_file << " [Deco]\t{TOOL}" << endl; 962 apps_file << " [Deco]\t{TOOL}" << endl;
963 break; 963 break;
964 case (FbWinFrame::DECORM_TITLEBAR 964 case (WindowState::DECORM_TITLEBAR
965 | FbWinFrame::DECORM_MENU): 965 | WindowState::DECORM_MENU):
966 apps_file << " [Deco]\t{TINY}" << endl; 966 apps_file << " [Deco]\t{TINY}" << endl;
967 break; 967 break;
968 case (FbWinFrame::DECORM_BORDER 968 case (WindowState::DECORM_BORDER
969 | FbWinFrame::DECORM_MENU): 969 | WindowState::DECORM_MENU):
970 apps_file << " [Deco]\t{BORDER}" << endl; 970 apps_file << " [Deco]\t{BORDER}" << endl;
971 break; 971 break;
972 case (FbWinFrame::DECORM_BORDER 972 case (WindowState::DECORM_BORDER
973 | FbWinFrame::DECORM_MENU 973 | WindowState::DECORM_MENU
974 | FbWinFrame::DECORM_TAB): 974 | WindowState::DECORM_TAB):
975 apps_file << " [Deco]\t{TAB}" << endl; 975 apps_file << " [Deco]\t{TAB}" << endl;
976 break; 976 break;
977 default: 977 default:
@@ -999,16 +999,16 @@ void Remember::save() {
999 if (a.maximizedstate_remember) { 999 if (a.maximizedstate_remember) {
1000 apps_file << " [Maximized]\t{"; 1000 apps_file << " [Maximized]\t{";
1001 switch (a.maximizedstate) { 1001 switch (a.maximizedstate) {
1002 case FbWinFrame::MAX_FULL: 1002 case WindowState::MAX_FULL:
1003 apps_file << "yes" << "}" << endl; 1003 apps_file << "yes" << "}" << endl;
1004 break; 1004 break;
1005 case FbWinFrame::MAX_HORZ: 1005 case WindowState::MAX_HORZ:
1006 apps_file << "horz" << "}" << endl; 1006 apps_file << "horz" << "}" << endl;
1007 break; 1007 break;
1008 case FbWinFrame::MAX_VERT: 1008 case WindowState::MAX_VERT:
1009 apps_file << "vert" << "}" << endl; 1009 apps_file << "vert" << "}" << endl;
1010 break; 1010 break;
1011 case FbWinFrame::MAX_NONE: 1011 case WindowState::MAX_NONE:
1012 default: 1012 default:
1013 apps_file << "no" << "}" << endl; 1013 apps_file << "no" << "}" << endl;
1014 break; 1014 break;
diff --git a/src/WinClient.hh b/src/WinClient.hh
index 18c9b0b..1903040 100644
--- a/src/WinClient.hh
+++ b/src/WinClient.hh
@@ -22,8 +22,9 @@
22#ifndef WINCLIENT_HH 22#ifndef WINCLIENT_HH
23#define WINCLIENT_HH 23#define WINCLIENT_HH
24 24
25#include "FbWinFrame.hh"
26#include "Window.hh" 25#include "Window.hh"
26#include "WindowState.hh"
27
27#include "FbTk/FbWindow.hh" 28#include "FbTk/FbWindow.hh"
28#include "FbTk/FbString.hh" 29#include "FbTk/FbString.hh"
29 30
@@ -114,7 +115,7 @@ public:
114 Window getGroupLeftWindow() const; 115 Window getGroupLeftWindow() const;
115 116
116 const MwmHints *getMwmHint() const { return m_mwm_hint; } 117 const MwmHints *getMwmHint() const { return m_mwm_hint; }
117 const FbWinFrame::SizeHints &sizeHints() const { return m_size_hints; } 118 const SizeHints &sizeHints() const { return m_size_hints; }
118 119
119 unsigned int minWidth() const { return m_size_hints.min_width; } 120 unsigned int minWidth() const { return m_size_hints.min_width; }
120 unsigned int minHeight() const { return m_size_hints.min_height; } 121 unsigned int minHeight() const { return m_size_hints.min_height; }
@@ -157,7 +158,7 @@ private:
157 158
158 Focusable::WindowType m_window_type; 159 Focusable::WindowType m_window_type;
159 MwmHints *m_mwm_hint; 160 MwmHints *m_mwm_hint;
160 FbWinFrame::SizeHints m_size_hints; 161 SizeHints m_size_hints;
161 162
162 Strut *m_strut; 163 Strut *m_strut;
163 // map transient_for X window to winclient transient 164 // map transient_for X window to winclient transient
diff --git a/src/Window.cc b/src/Window.cc
index 4b77b95..25a6baf 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -271,7 +271,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer):
271 m_creation_time(0), 271 m_creation_time(0),
272 moving(false), resizing(false), shaded(false), iconic(false), 272 moving(false), resizing(false), shaded(false), iconic(false),
273 stuck(false), m_initialized(false), fullscreen(false), 273 stuck(false), m_initialized(false), fullscreen(false),
274 maximized(FbWinFrame::MAX_NONE), 274 maximized(WindowState::MAX_NONE),
275 m_attaching_tab(0), 275 m_attaching_tab(0),
276 display(FbTk::App::instance()->display()), 276 display(FbTk::App::instance()->display()),
277 m_button_grab_x(0), m_button_grab_y(0), 277 m_button_grab_x(0), m_button_grab_y(0),
@@ -423,7 +423,7 @@ void FluxboxWindow::init() {
423 m_workspace_number = m_screen.currentWorkspaceID(); 423 m_workspace_number = m_screen.currentWorkspaceID();
424 424
425 // set default decorations but don't apply them 425 // set default decorations but don't apply them
426 setDecorationMask(FbWinFrame::getDecoMaskFromString(screen().defaultDeco()), 426 setDecorationMask(WindowState::getDecoMaskFromString(screen().defaultDeco()),
427 false); 427 false);
428 428
429 functions.resize = functions.move = functions.iconify = functions.maximize 429 functions.resize = functions.move = functions.iconify = functions.maximize
@@ -559,7 +559,7 @@ void FluxboxWindow::init() {
559 559
560 if (maximized) { 560 if (maximized) {
561 int tmp = maximized; 561 int tmp = maximized;
562 maximized = FbWinFrame::MAX_NONE; 562 maximized = WindowState::MAX_NONE;
563 setMaximizedState(tmp); 563 setMaximizedState(tmp);
564 } 564 }
565 565
@@ -1045,7 +1045,7 @@ void FluxboxWindow::updateSizeHints() {
1045 if ((*it) == m_client) 1045 if ((*it) == m_client)
1046 continue; 1046 continue;
1047 1047
1048 const FbWinFrame::SizeHints &hint = (*it)->sizeHints(); 1048 const SizeHints &hint = (*it)->sizeHints();
1049 if (m_size_hint.min_width < hint.min_width) 1049 if (m_size_hint.min_width < hint.min_width)
1050 m_size_hint.min_width = hint.min_width; 1050 m_size_hint.min_width = hint.min_width;
1051 if (m_size_hint.max_width > hint.max_width) 1051 if (m_size_hint.max_width > hint.max_width)
@@ -1144,7 +1144,7 @@ void FluxboxWindow::updateMWMHintsFromClient(WinClient &client) {
1144 } 1144 }
1145 1145
1146 unsigned int mask = decorationMask(); 1146 unsigned int mask = decorationMask();
1147 mask &= FbWinFrame::getDecoMaskFromString(screen().defaultDeco()); 1147 mask &= WindowState::getDecoMaskFromString(screen().defaultDeco());
1148 setDecorationMask(mask, false); 1148 setDecorationMask(mask, false);
1149 1149
1150 // functions.tabable is ours, not special one 1150 // functions.tabable is ours, not special one
@@ -1503,7 +1503,7 @@ void FluxboxWindow::setFullscreenLayer() {
1503void FluxboxWindow::maximize(int type) { 1503void FluxboxWindow::maximize(int type) {
1504 1504
1505 // nothing to do 1505 // nothing to do
1506 if (type == FbWinFrame::MAX_NONE) 1506 if (type == WindowState::MAX_NONE)
1507 return; 1507 return;
1508 1508
1509 int new_max = maximized; 1509 int new_max = maximized;
@@ -1512,14 +1512,14 @@ void FluxboxWindow::maximize(int type) {
1512 // when _don't_ we want to toggle? 1512 // when _don't_ we want to toggle?
1513 // - type is horizontal maximise, or 1513 // - type is horizontal maximise, or
1514 // - type is full and we are not maximised horz but already vertically 1514 // - type is full and we are not maximised horz but already vertically
1515 if (type != FbWinFrame::MAX_HORZ && 1515 if (type != WindowState::MAX_HORZ &&
1516 (type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_VERT)) 1516 (type != WindowState::MAX_FULL || maximized != WindowState::MAX_VERT))
1517 new_max ^= FbWinFrame::MAX_VERT; 1517 new_max ^= WindowState::MAX_VERT;
1518 1518
1519 // maximize horizontally? 1519 // maximize horizontally?
1520 if (type != FbWinFrame::MAX_VERT && 1520 if (type != WindowState::MAX_VERT &&
1521 (type != FbWinFrame::MAX_FULL || maximized != FbWinFrame::MAX_HORZ)) 1521 (type != WindowState::MAX_FULL || maximized != WindowState::MAX_HORZ))
1522 new_max ^= FbWinFrame::MAX_HORZ; 1522 new_max ^= WindowState::MAX_HORZ;
1523 1523
1524 setMaximizedState(new_max); 1524 setMaximizedState(new_max);
1525} 1525}
@@ -1552,21 +1552,21 @@ void FluxboxWindow::setMaximizedState(int type) {
1552 * Maximize window horizontal 1552 * Maximize window horizontal
1553 */ 1553 */
1554void FluxboxWindow::maximizeHorizontal() { 1554void FluxboxWindow::maximizeHorizontal() {
1555 maximize(FbWinFrame::MAX_HORZ); 1555 maximize(WindowState::MAX_HORZ);
1556} 1556}
1557 1557
1558/** 1558/**
1559 * Maximize window vertical 1559 * Maximize window vertical
1560 */ 1560 */
1561void FluxboxWindow::maximizeVertical() { 1561void FluxboxWindow::maximizeVertical() {
1562 maximize(FbWinFrame::MAX_VERT); 1562 maximize(WindowState::MAX_VERT);
1563} 1563}
1564 1564
1565/** 1565/**
1566 * Maximize window fully 1566 * Maximize window fully
1567 */ 1567 */
1568void FluxboxWindow::maximizeFull() { 1568void FluxboxWindow::maximizeFull() {
1569 maximize(FbWinFrame::MAX_FULL); 1569 maximize(WindowState::MAX_FULL);
1570} 1570}
1571 1571
1572void FluxboxWindow::setWorkspace(int n) { 1572void FluxboxWindow::setWorkspace(int n) {
@@ -2807,9 +2807,9 @@ void FluxboxWindow::toggleDecoration() {
2807 if (m_toggled_decos) { 2807 if (m_toggled_decos) {
2808 m_old_decoration_mask = decorationMask(); 2808 m_old_decoration_mask = decorationMask();
2809 if (decorations.titlebar | decorations.tab) 2809 if (decorations.titlebar | decorations.tab)
2810 setDecorationMask(FbWinFrame::DECOR_NONE); 2810 setDecorationMask(WindowState::DECOR_NONE);
2811 else 2811 else
2812 setDecorationMask(FbWinFrame::DECOR_NORMAL); 2812 setDecorationMask(WindowState::DECOR_NORMAL);
2813 } else //revert back to old decoration 2813 } else //revert back to old decoration
2814 setDecorationMask(m_old_decoration_mask); 2814 setDecorationMask(m_old_decoration_mask);
2815 2815
@@ -2818,42 +2818,42 @@ void FluxboxWindow::toggleDecoration() {
2818unsigned int FluxboxWindow::decorationMask() const { 2818unsigned int FluxboxWindow::decorationMask() const {
2819 unsigned int ret = 0; 2819 unsigned int ret = 0;
2820 if (decorations.titlebar) 2820 if (decorations.titlebar)
2821 ret |= FbWinFrame::DECORM_TITLEBAR; 2821 ret |= WindowState::DECORM_TITLEBAR;
2822 if (decorations.handle) 2822 if (decorations.handle)
2823 ret |= FbWinFrame::DECORM_HANDLE; 2823 ret |= WindowState::DECORM_HANDLE;
2824 if (decorations.border) 2824 if (decorations.border)
2825 ret |= FbWinFrame::DECORM_BORDER; 2825 ret |= WindowState::DECORM_BORDER;
2826 if (decorations.iconify) 2826 if (decorations.iconify)
2827 ret |= FbWinFrame::DECORM_ICONIFY; 2827 ret |= WindowState::DECORM_ICONIFY;
2828 if (decorations.maximize) 2828 if (decorations.maximize)
2829 ret |= FbWinFrame::DECORM_MAXIMIZE; 2829 ret |= WindowState::DECORM_MAXIMIZE;
2830 if (decorations.close) 2830 if (decorations.close)
2831 ret |= FbWinFrame::DECORM_CLOSE; 2831 ret |= WindowState::DECORM_CLOSE;
2832 if (decorations.menu) 2832 if (decorations.menu)
2833 ret |= FbWinFrame::DECORM_MENU; 2833 ret |= WindowState::DECORM_MENU;
2834 if (decorations.sticky) 2834 if (decorations.sticky)
2835 ret |= FbWinFrame::DECORM_STICKY; 2835 ret |= WindowState::DECORM_STICKY;
2836 if (decorations.shade) 2836 if (decorations.shade)
2837 ret |= FbWinFrame::DECORM_SHADE; 2837 ret |= WindowState::DECORM_SHADE;
2838 if (decorations.tab) 2838 if (decorations.tab)
2839 ret |= FbWinFrame::DECORM_TAB; 2839 ret |= WindowState::DECORM_TAB;
2840 if (decorations.enabled) 2840 if (decorations.enabled)
2841 ret |= FbWinFrame::DECORM_ENABLED; 2841 ret |= WindowState::DECORM_ENABLED;
2842 return ret; 2842 return ret;
2843} 2843}
2844 2844
2845void FluxboxWindow::setDecorationMask(unsigned int mask, bool apply) { 2845void FluxboxWindow::setDecorationMask(unsigned int mask, bool apply) {
2846 decorations.titlebar = mask & FbWinFrame::DECORM_TITLEBAR; 2846 decorations.titlebar = mask & WindowState::DECORM_TITLEBAR;
2847 decorations.handle = mask & FbWinFrame::DECORM_HANDLE; 2847 decorations.handle = mask & WindowState::DECORM_HANDLE;
2848 decorations.border = mask & FbWinFrame::DECORM_BORDER; 2848 decorations.border = mask & WindowState::DECORM_BORDER;
2849 decorations.iconify = mask & FbWinFrame::DECORM_ICONIFY; 2849 decorations.iconify = mask & WindowState::DECORM_ICONIFY;
2850 decorations.maximize = mask & FbWinFrame::DECORM_MAXIMIZE; 2850 decorations.maximize = mask & WindowState::DECORM_MAXIMIZE;
2851 decorations.close = mask & FbWinFrame::DECORM_CLOSE; 2851 decorations.close = mask & WindowState::DECORM_CLOSE;
2852 decorations.menu = mask & FbWinFrame::DECORM_MENU; 2852 decorations.menu = mask & WindowState::DECORM_MENU;
2853 decorations.sticky = mask & FbWinFrame::DECORM_STICKY; 2853 decorations.sticky = mask & WindowState::DECORM_STICKY;
2854 decorations.shade = mask & FbWinFrame::DECORM_SHADE; 2854 decorations.shade = mask & WindowState::DECORM_SHADE;
2855 decorations.tab = mask & FbWinFrame::DECORM_TAB; 2855 decorations.tab = mask & WindowState::DECORM_TAB;
2856 decorations.enabled = mask & FbWinFrame::DECORM_ENABLED; 2856 decorations.enabled = mask & WindowState::DECORM_ENABLED;
2857 // we don't want to do this during initialization 2857 // we don't want to do this during initialization
2858 if (apply) 2858 if (apply)
2859 applyDecorations(); 2859 applyDecorations();
@@ -3024,7 +3024,7 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
3024 // we only care about the left/top etc that includes borders 3024 // we only care about the left/top etc that includes borders
3025 int borderW = 0; 3025 int borderW = 0;
3026 3026
3027 if (decorationMask() & (FbWinFrame::DECORM_BORDER|FbWinFrame::DECORM_HANDLE)) 3027 if (decorationMask() & (WindowState::DECORM_BORDER|WindowState::DECORM_HANDLE))
3028 borderW = frame().window().borderWidth(); 3028 borderW = frame().window().borderWidth();
3029 3029
3030 int top = orig_top; // orig include the borders 3030 int top = orig_top; // orig include the borders
@@ -3096,7 +3096,7 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
3096 if ((*it) == this) 3096 if ((*it) == this)
3097 continue; // skip myself 3097 continue; // skip myself
3098 3098
3099 bw = (*it)->decorationMask() & (FbWinFrame::DECORM_BORDER|FbWinFrame::DECORM_HANDLE) ? 3099 bw = (*it)->decorationMask() & (WindowState::DECORM_BORDER|WindowState::DECORM_HANDLE) ?
3100 (*it)->frame().window().borderWidth() : 0; 3100 (*it)->frame().window().borderWidth() : 0;
3101 3101
3102 snapToWindow(dx, dy, left, right, top, bottom, 3102 snapToWindow(dx, dy, left, right, top, bottom,
@@ -3175,7 +3175,7 @@ void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) {
3175 m_resize_corner = dir; 3175 m_resize_corner = dir;
3176 3176
3177 resizing = true; 3177 resizing = true;
3178 maximized = FbWinFrame::MAX_NONE; 3178 maximized = WindowState::MAX_NONE;
3179 frame().setMaximized(maximized); 3179 frame().setMaximized(maximized);
3180 3180
3181 const Cursor& cursor = (m_resize_corner == LEFTTOP) ? frame().theme()->upperLeftAngleCursor() : 3181 const Cursor& cursor = (m_resize_corner == LEFTTOP) ? frame().theme()->upperLeftAngleCursor() :
@@ -3862,7 +3862,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
3862 setFocusNew(false); 3862 setFocusNew(false);
3863 setMouseFocus(false); 3863 setMouseFocus(false);
3864 setClickFocus(false); 3864 setClickFocus(false);
3865 setDecorationMask(FbWinFrame::DECOR_NONE); 3865 setDecorationMask(WindowState::DECOR_NONE);
3866 moveToLayer(::Layer::DOCK); 3866 moveToLayer(::Layer::DOCK);
3867 break; 3867 break;
3868 case Focusable::TYPE_DESKTOP: 3868 case Focusable::TYPE_DESKTOP:
@@ -3877,7 +3877,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
3877 setFocusNew(false); 3877 setFocusNew(false);
3878 setMouseFocus(false); 3878 setMouseFocus(false);
3879 moveToLayer(::Layer::DESKTOP); 3879 moveToLayer(::Layer::DESKTOP);
3880 setDecorationMask(FbWinFrame::DECOR_NONE); 3880 setDecorationMask(WindowState::DECOR_NONE);
3881 setTabable(false); 3881 setTabable(false);
3882 setMovable(false); 3882 setMovable(false);
3883 setResizable(false); 3883 setResizable(false);
@@ -3889,7 +3889,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
3889 * window is a splash screen displayed as an application 3889 * window is a splash screen displayed as an application
3890 * is starting up. 3890 * is starting up.
3891 */ 3891 */
3892 setDecorationMask(FbWinFrame::DECOR_NONE); 3892 setDecorationMask(WindowState::DECOR_NONE);
3893 setFocusHidden(true); 3893 setFocusHidden(true);
3894 setIconHidden(true); 3894 setIconHidden(true);
3895 setFocusNew(false); 3895 setFocusNew(false);
@@ -3909,7 +3909,7 @@ void FluxboxWindow::setWindowType(Focusable::WindowType type) {
3909 * application). Windows of this type may set the 3909 * application). Windows of this type may set the
3910 * WM_TRANSIENT_FOR hint indicating the main application window. 3910 * WM_TRANSIENT_FOR hint indicating the main application window.
3911 */ 3911 */
3912 setDecorationMask(FbWinFrame::DECOR_TOOL); 3912 setDecorationMask(WindowState::DECOR_TOOL);
3913 setIconHidden(true); 3913 setIconHidden(true);
3914 moveToLayer(::Layer::ABOVE_DOCK); 3914 moveToLayer(::Layer::ABOVE_DOCK);
3915 break; 3915 break;
diff --git a/src/Window.hh b/src/Window.hh
index 89cbc69..2dbb816 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -31,6 +31,7 @@
31#include "FbTk/Observer.hh" 31#include "FbTk/Observer.hh"
32#include "FbTk/EventHandler.hh" 32#include "FbTk/EventHandler.hh"
33#include "FbTk/XLayerItem.hh" 33#include "FbTk/XLayerItem.hh"
34
34#include "FbWinFrame.hh" 35#include "FbWinFrame.hh"
35#include "Focusable.hh" 36#include "Focusable.hh"
36#include "FocusableTheme.hh" 37#include "FocusableTheme.hh"
@@ -45,7 +46,6 @@
45class WinClient; 46class WinClient;
46class FbWinFrameTheme; 47class FbWinFrameTheme;
47class BScreen; 48class BScreen;
48class FbWinFrame;
49class FocusControl; 49class FocusControl;
50class FbMenu; 50class FbMenu;
51 51
@@ -212,7 +212,7 @@ public:
212 /// set fullscreen 212 /// set fullscreen
213 void setFullscreen(bool flag); 213 void setFullscreen(bool flag);
214 /// toggle maximize 214 /// toggle maximize
215 void maximize(int type = FbWinFrame::MAX_FULL); 215 void maximize(int type = WindowState::MAX_FULL);
216 /// sets the maximized state 216 /// sets the maximized state
217 void setMaximizedState(int type); 217 void setMaximizedState(int type);
218 /// maximizes the window horizontal 218 /// maximizes the window horizontal
@@ -373,9 +373,9 @@ public:
373 bool isIconic() const { return iconic; } 373 bool isIconic() const { return iconic; }
374 bool isShaded() const { return shaded; } 374 bool isShaded() const { return shaded; }
375 bool isFullscreen() const { return fullscreen; } 375 bool isFullscreen() const { return fullscreen; }
376 bool isMaximized() const { return maximized == FbWinFrame::MAX_FULL; } 376 bool isMaximized() const { return maximized == WindowState::MAX_FULL; }
377 bool isMaximizedVert() const { return (bool)(maximized & FbWinFrame::MAX_VERT); } 377 bool isMaximizedVert() const { return (bool)(maximized & WindowState::MAX_VERT); }
378 bool isMaximizedHorz() const { return (bool)(maximized & FbWinFrame::MAX_HORZ); } 378 bool isMaximizedHorz() const { return (bool)(maximized & WindowState::MAX_HORZ); }
379 int maximizedState() const { return maximized; } 379 int maximizedState() const { return maximized; }
380 bool isIconifiable() const { return functions.iconify; } 380 bool isIconifiable() const { return functions.iconify; }
381 bool isMaximizable() const { return functions.maximize; } 381 bool isMaximizable() const { return functions.maximize; }
@@ -553,7 +553,7 @@ private:
553 typedef std::map<WinClient *, IconButton *> Client2ButtonMap; 553 typedef std::map<WinClient *, IconButton *> Client2ButtonMap;
554 Client2ButtonMap m_labelbuttons; 554 Client2ButtonMap m_labelbuttons;
555 555
556 FbWinFrame::SizeHints m_size_hint; 556 SizeHints m_size_hint;
557 struct _decorations { 557 struct _decorations {
558 bool titlebar, handle, border, iconify, 558 bool titlebar, handle, border, iconify,
559 maximize, close, menu, sticky, shade, tab, enabled; 559 maximize, close, menu, sticky, shade, tab, enabled;
diff --git a/src/WindowState.cc b/src/WindowState.cc
new file mode 100644
index 0000000..2f8fd4e
--- /dev/null
+++ b/src/WindowState.cc
@@ -0,0 +1,266 @@
1// WindowState.cc
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
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 "WindowState.hh"
23
24#include "FbTk/StringUtil.hh"
25
26#include <stdlib.h>
27
28bool WindowState::useBorder() const {
29 return !fullscreen && maximized != MAX_FULL && deco_mask & DECORM_BORDER;
30}
31
32bool WindowState::useHandle() const {
33 return !fullscreen && !shaded && deco_mask & DECORM_HANDLE;
34}
35
36bool WindowState::useTabs() const {
37 return !fullscreen && deco_mask & DECORM_TAB;
38}
39
40bool WindowState::useTitlebar() const {
41 return !fullscreen && deco_mask & DECORM_TITLEBAR;
42}
43
44void WindowState::saveGeometry(int new_x, int new_y,
45 unsigned int new_w, unsigned int new_h) {
46 if (fullscreen || maximized == MAX_FULL)
47 return;
48
49 if (!(maximized & MAX_HORZ)) {
50 x = new_x;
51 width = new_w;
52 }
53 if (!(maximized & MAX_VERT)) {
54 y = new_y;
55 if (!shaded)
56 height = new_h;
57 }
58}
59
60int WindowState::getDecoMaskFromString(const std::string &str_label) {
61 std::string label = FbTk::StringUtil::toLower(str_label);
62 if (label == "none")
63 return DECOR_NONE;
64 if (label == "normal")
65 return DECOR_NORMAL;
66 if (label == "tiny")
67 return DECOR_TINY;
68 if (label == "tool")
69 return DECOR_TOOL;
70 if (label == "border")
71 return DECOR_BORDER;
72 if (label == "tab")
73 return DECOR_TAB;
74 int mask = -1;
75 if ((str_label.size() > 1 && str_label[0] == '0' && str_label[1] == 'x') ||
76 (str_label.size() > 0 && isdigit(str_label[0])))
77 mask = strtol(str_label.c_str(), NULL, 0);
78 return mask;
79}
80
81void SizeHints::reset(const XSizeHints &sizehint) {
82 if (sizehint.flags & PMinSize) {
83 min_width = sizehint.min_width;
84 min_height = sizehint.min_height;
85 } else
86 min_width = min_height = 1;
87
88 if (sizehint.flags & PBaseSize) {
89 base_width = sizehint.base_width;
90 base_height = sizehint.base_height;
91 if (!(sizehint.flags & PMinSize)) {
92 min_width = base_width;
93 min_height = base_height;
94 }
95 } else
96 base_width = base_height = 0;
97
98 if (sizehint.flags & PMaxSize) {
99 max_width = sizehint.max_width;
100 max_height = sizehint.max_height;
101 } else
102 max_width = max_height = 0; // unbounded
103
104 if (sizehint.flags & PResizeInc) {
105 width_inc = sizehint.width_inc;
106 height_inc = sizehint.height_inc;
107 } else
108 width_inc = height_inc = 1;
109
110 if (sizehint.flags & PAspect) {
111 min_aspect_x = sizehint.min_aspect.x;
112 min_aspect_y = sizehint.min_aspect.y;
113 max_aspect_x = sizehint.max_aspect.x;
114 max_aspect_y = sizehint.max_aspect.y;
115 } else {
116 min_aspect_x = max_aspect_y = 0;
117 min_aspect_y = max_aspect_x = 1;
118 }
119
120 if (sizehint.flags & PWinGravity)
121 win_gravity = sizehint.win_gravity;
122 else
123 win_gravity = NorthWestGravity;
124
125 // some sanity checks
126 if (width_inc == 0)
127 width_inc = 1;
128 if (height_inc == 0)
129 height_inc = 1;
130
131 if (base_width > min_width)
132 min_width = base_width;
133 if (base_height > min_height)
134 min_height = base_height;
135}
136
137void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y,
138 unsigned int point_x, unsigned int point_y,
139 unsigned int aspect_x, unsigned int aspect_y) {
140 double u = static_cast<double>(point_x * aspect_x + point_y * aspect_y) /
141 static_cast<double>(aspect_x * aspect_x + aspect_y * aspect_y);
142
143 ret_x = static_cast<unsigned int>(u * aspect_x);
144 ret_y = static_cast<unsigned int>(u * aspect_y);
145}
146
147unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
148 return val % inc ? val + inc - (val % inc) : val;
149}
150
151unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) {
152 return val % inc ? val - (val % inc) : val;
153}
154
155/**
156 * Changes width and height to the nearest (lower) value
157 * that conforms to it's size hints.
158 *
159 * display_* give the values that would be displayed
160 * to the user when resizing.
161 * We use pointers for display_* since they are optional.
162 *
163 * See ICCCM section 4.1.2.3
164 */
165void SizeHints::apply(unsigned int &width, unsigned int &height,
166 bool make_fit) const {
167
168 /* aspect ratios are applied exclusive to the base size
169 *
170 * min_aspect_x width max_aspect_x
171 * ------------ < ------- < ------------
172 * min_aspect_y height max_aspect_y
173 *
174 * The trick is how to get back to the aspect ratio with minimal
175 * change - do we modify x, y or both?
176 * A: we minimise the distance between the current point, and
177 * the target aspect ratio (consider them as x,y coordinates)
178 * Consider that the aspect ratio is a line, and the current
179 * w/h is a point, so we're just using the formula for
180 * shortest distance from a point to a line!
181 */
182
183 // make respective to base_size
184 unsigned int w = width - base_width, h = height - base_height;
185
186 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) {
187 closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y);
188 // new w must be > old w, new h must be < old h
189 w = increaseToMultiple(w, width_inc);
190 h = decreaseToMultiple(h, height_inc);
191 } else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) {
192 closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y);
193 // new w must be < old w, new h must be > old h
194 w = decreaseToMultiple(w, width_inc);
195 h = increaseToMultiple(h, height_inc);
196 }
197
198 // Check minimum size
199 if (w + base_width < min_width) {
200 w = increaseToMultiple(min_width - base_width, width_inc);
201 // need to check maximum aspect again
202 if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
203 h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc);
204 }
205
206 if (h + base_height < min_height) {
207 h = increaseToMultiple(min_height - base_height, height_inc);
208 // need to check minimum aspect again
209 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
210 w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc);
211 }
212
213 unsigned int max_w = make_fit && (width < max_width || max_width == 0) ?
214 width : max_width;
215 unsigned int max_h = make_fit && (height < max_height || max_height == 0) ?
216 height : max_height;
217
218 // Check maximum size
219 if (max_w > 0 && w + base_width > max_w)
220 w = max_w - base_width;
221
222 if (max_h > 0 && h + base_height > max_h)
223 h = max_h - base_height;
224
225 w = decreaseToMultiple(w, width_inc);
226 h = decreaseToMultiple(h, height_inc);
227
228 // need to check aspects one more time
229 if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h)
230 h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc);
231
232 if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h)
233 w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc);
234
235 width = w + base_width;
236 height = h + base_height;
237}
238
239// check if the given width and height satisfy the size hints
240bool SizeHints::valid(unsigned int w, unsigned int h) const {
241 if (w < min_width || h < min_height)
242 return false;
243
244 if (w > max_width || h > max_height)
245 return false;
246
247 if ((w - base_width) % width_inc != 0)
248 return false;
249
250 if ((h - base_height) % height_inc != 0)
251 return false;
252
253 if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y)
254 return false;
255
256 if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y)
257 return false;
258
259 return true;
260}
261
262void SizeHints::displaySize(unsigned int &i, unsigned int &j,
263 unsigned int width, unsigned int height) const {
264 i = (width - base_width) / width_inc;
265 j = (height - base_height) / height_inc;
266}
diff --git a/src/WindowState.hh b/src/WindowState.hh
new file mode 100644
index 0000000..fa17eb6
--- /dev/null
+++ b/src/WindowState.hh
@@ -0,0 +1,118 @@
1// WindowState.hh
2// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
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 WINDOWSTATE_HH
23#define WINDOWSTATE_HH
24
25#include <X11/Xutil.h>
26
27#include <string>
28
29class SizeHints {
30public:
31 SizeHints():
32 min_width(1), max_width(0), min_height(1), max_height(0),
33 width_inc(1), height_inc(1), base_width(0), base_height(0),
34 min_aspect_x(0), max_aspect_x(1),
35 min_aspect_y(1), max_aspect_y(0),
36 win_gravity(0) { }
37
38 void reset(const XSizeHints &sizehint);
39
40 void apply(unsigned int &w, unsigned int &h,
41 bool maximizing = false) const;
42 bool valid(unsigned int width, unsigned int height) const;
43 void displaySize(unsigned int &i, unsigned int &j,
44 unsigned int width, unsigned int height) const;
45
46 unsigned int min_width, max_width, min_height, max_height,
47 width_inc, height_inc, base_width, base_height,
48 min_aspect_x, max_aspect_x, min_aspect_y, max_aspect_y;
49 int win_gravity;
50};
51
52class WindowState {
53public:
54
55 /**
56 * Types of maximization
57 */
58 enum MaximizeMode {
59 MAX_NONE = 0, ///< normal state
60 MAX_HORZ = 1, ///< maximize horizontal
61 MAX_VERT = 2, ///< maximize vertical
62 MAX_FULL = 3 ///< maximize full
63 };
64
65 /**
66 This enumeration represents individual decoration
67 attributes, they can be OR-d together to get a mask.
68 Useful for saving.
69 */
70 enum DecorationMask {
71 DECORM_TITLEBAR = (1<<0),
72 DECORM_HANDLE = (1<<1),
73 DECORM_BORDER = (1<<2),
74 DECORM_ICONIFY = (1<<3),
75 DECORM_MAXIMIZE = (1<<4),
76 DECORM_CLOSE = (1<<5),
77 DECORM_MENU = (1<<6),
78 DECORM_STICKY = (1<<7),
79 DECORM_SHADE = (1<<8),
80 DECORM_TAB = (1<<9),
81 DECORM_ENABLED = (1<<10),
82 DECORM_LAST = (1<<11) // useful for getting "All"
83 };
84
85 enum Decoration {
86 DECOR_NONE = 0,
87 DECOR_NORMAL = DECORM_LAST - 1,
88 DECOR_TINY = DECORM_TITLEBAR|DECORM_ICONIFY|DECORM_MENU|DECORM_TAB,
89 DECOR_TOOL = DECORM_TITLEBAR|DECORM_MENU,
90 DECOR_BORDER = DECORM_BORDER|DECORM_MENU,
91 DECOR_TAB = DECORM_BORDER|DECORM_MENU|DECORM_TAB
92 };
93
94 WindowState():
95 size_hints(),
96 deco_mask(DECOR_NORMAL),
97 focused(false),
98 shaded(false), fullscreen(false), maximized(0),
99 x(0), y(0), width(1), height(1) { }
100
101 void saveGeometry(int x, int y, unsigned int width, unsigned int height);
102
103 bool useBorder() const;
104 bool useHandle() const;
105 bool useTabs() const;
106 bool useTitlebar() const;
107
108 static int getDecoMaskFromString(const std::string &str);
109
110 SizeHints size_hints;
111 unsigned int deco_mask;
112 bool focused, shaded, fullscreen;
113 int maximized;
114 int x, y;
115 unsigned int width, height;
116};
117
118#endif // WINDOWSTATE_HH