diff options
author | Mark Tiefenbruck <mark@fluxbox.org> | 2008-08-27 17:05:49 (GMT) |
---|---|---|
committer | Mark Tiefenbruck <mark@fluxbox.org> | 2008-08-27 17:05:49 (GMT) |
commit | 55fd49614bb1b9e37561147f18719b2ac277b64b (patch) | |
tree | c0f58db24f6fa3a457bca26393c00632dd630328 | |
parent | 08c8c6431f88ff3d5012d800a8df689b7028fe98 (diff) | |
download | fluxbox_pavel-55fd49614bb1b9e37561147f18719b2ac277b64b.zip fluxbox_pavel-55fd49614bb1b9e37561147f18719b2ac277b64b.tar.bz2 |
move FbWinFrame::State class to a new file
-rw-r--r-- | src/CurrentWindowCmd.cc | 2 | ||||
-rw-r--r-- | src/FbWinFrame.cc | 303 | ||||
-rw-r--r-- | src/FbWinFrame.hh | 103 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Remember.cc | 40 | ||||
-rw-r--r-- | src/WinClient.hh | 7 | ||||
-rw-r--r-- | src/Window.cc | 92 | ||||
-rw-r--r-- | src/Window.hh | 12 | ||||
-rw-r--r-- | src/WindowState.cc | 266 | ||||
-rw-r--r-- | src/WindowState.hh | 118 |
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() { | |||
503 | REGISTER_COMMAND_WITH_ARGS(setdecor, SetDecorCmd, void); | 503 | REGISTER_COMMAND_WITH_ARGS(setdecor, SetDecorCmd, void); |
504 | 504 | ||
505 | SetDecorCmd::SetDecorCmd(const std::string &args): | 505 | SetDecorCmd::SetDecorCmd(const std::string &args): |
506 | m_mask(FbWinFrame::getDecoMaskFromString(args)) { } | 506 | m_mask(WindowState::getDecoMaskFromString(args)) { } |
507 | 507 | ||
508 | void SetDecorCmd::real_execute() { | 508 | void 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 | */ |
196 | void FbWinFrame::shade() { | 195 | void 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 | |||
283 | void FbWinFrame::quietMoveResize(int x, int y, | 283 | void 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 | ||
537 | void 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 | |||
552 | void FbWinFrame::applyState() { | 538 | void 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 | ||
1485 | int 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 | |||
1506 | bool FbWinFrame::useBorder() const { | ||
1507 | return !m_state.fullscreen && m_state.maximized != MAX_FULL && | ||
1508 | (m_state.deco_mask & DECORM_BORDER); | ||
1509 | } | ||
1510 | |||
1511 | bool FbWinFrame::useTabs() const { | ||
1512 | return !m_state.fullscreen && m_state.deco_mask & DECORM_TAB; | ||
1513 | } | ||
1514 | |||
1515 | bool FbWinFrame::useTitlebar() const { | ||
1516 | return !m_state.fullscreen && m_state.deco_mask & DECORM_TITLEBAR; | ||
1517 | } | ||
1518 | |||
1519 | bool FbWinFrame::useHandle() const { | ||
1520 | return !m_state.fullscreen && !m_state.shaded && | ||
1521 | m_state.deco_mask & DECORM_HANDLE; | ||
1522 | } | ||
1523 | |||
1524 | int FbWinFrame::getShape() const { | 1471 | int 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 | ||
1582 | bool FbWinFrame::setBorderWidth(bool do_move) { | 1529 | bool 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 | ||
1720 | int FbWinFrame::normalX() const { | ||
1721 | if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen) | ||
1722 | return m_state.x; | ||
1723 | return x(); | ||
1724 | } | ||
1725 | |||
1726 | int FbWinFrame::normalY() const { | ||
1727 | if ((m_state.maximized & MAX_VERT) || m_state.fullscreen) | ||
1728 | return m_state.y; | ||
1729 | return y(); | ||
1730 | } | ||
1731 | |||
1732 | unsigned int FbWinFrame::normalWidth() const { | ||
1733 | if ((m_state.maximized & MAX_HORZ) || m_state.fullscreen) | ||
1734 | return m_state.width; | ||
1735 | return width(); | ||
1736 | } | ||
1737 | |||
1738 | unsigned 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 | |||
1744 | int FbWinFrame::widthOffset() const { | 1667 | int 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 | |||
1829 | void 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 | |||
1896 | void 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 | |||
1906 | unsigned int increaseToMultiple(unsigned int val, unsigned int inc) { | ||
1907 | return val % inc ? val + inc - (val % inc) : val; | ||
1908 | } | ||
1909 | |||
1910 | unsigned 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 | */ | ||
1924 | void 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 | ||
1999 | bool 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 | |||
2021 | void 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() { | |||
1503 | void FluxboxWindow::maximize(int type) { | 1503 | void 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 | */ |
1554 | void FluxboxWindow::maximizeHorizontal() { | 1554 | void 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 | */ |
1561 | void FluxboxWindow::maximizeVertical() { | 1561 | void 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 | */ |
1568 | void FluxboxWindow::maximizeFull() { | 1568 | void FluxboxWindow::maximizeFull() { |
1569 | maximize(FbWinFrame::MAX_FULL); | 1569 | maximize(WindowState::MAX_FULL); |
1570 | } | 1570 | } |
1571 | 1571 | ||
1572 | void FluxboxWindow::setWorkspace(int n) { | 1572 | void 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() { | |||
2818 | unsigned int FluxboxWindow::decorationMask() const { | 2818 | unsigned 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 | ||
2845 | void FluxboxWindow::setDecorationMask(unsigned int mask, bool apply) { | 2845 | void 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 @@ | |||
45 | class WinClient; | 46 | class WinClient; |
46 | class FbWinFrameTheme; | 47 | class FbWinFrameTheme; |
47 | class BScreen; | 48 | class BScreen; |
48 | class FbWinFrame; | ||
49 | class FocusControl; | 49 | class FocusControl; |
50 | class FbMenu; | 50 | class 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 | |||
28 | bool WindowState::useBorder() const { | ||
29 | return !fullscreen && maximized != MAX_FULL && deco_mask & DECORM_BORDER; | ||
30 | } | ||
31 | |||
32 | bool WindowState::useHandle() const { | ||
33 | return !fullscreen && !shaded && deco_mask & DECORM_HANDLE; | ||
34 | } | ||
35 | |||
36 | bool WindowState::useTabs() const { | ||
37 | return !fullscreen && deco_mask & DECORM_TAB; | ||
38 | } | ||
39 | |||
40 | bool WindowState::useTitlebar() const { | ||
41 | return !fullscreen && deco_mask & DECORM_TITLEBAR; | ||
42 | } | ||
43 | |||
44 | void 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 | |||
60 | int 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 | |||
81 | void 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 | |||
137 | void 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 | |||
147 | unsigned int increaseToMultiple(unsigned int val, unsigned int inc) { | ||
148 | return val % inc ? val + inc - (val % inc) : val; | ||
149 | } | ||
150 | |||
151 | unsigned 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 | */ | ||
165 | void 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 | ||
240 | bool 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 | |||
262 | void 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 | |||
29 | class SizeHints { | ||
30 | public: | ||
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 | |||
52 | class WindowState { | ||
53 | public: | ||
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 | ||