summaryrefslogtreecommitdiff
path: root/src/FbWinFrame.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbWinFrame.cc')
-rw-r--r--src/FbWinFrame.cc303
1 files changed, 14 insertions, 289 deletions
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}