diff options
author | Mark Tiefenbruck <mark@fluxbox.org> | 2008-08-15 11:16:30 (GMT) |
---|---|---|
committer | Mark Tiefenbruck <mark@fluxbox.org> | 2008-08-15 11:16:30 (GMT) |
commit | 1dab657708cd8246c2ce5a6aaa05cc5733e09c54 (patch) | |
tree | bd5a647d38f847dce1902536441a3c8ad6222881 /src/FbWinFrame.cc | |
parent | 6053ecc1b573e437dd0d1752670748c5c3679669 (diff) | |
download | fluxbox-1dab657708cd8246c2ce5a6aaa05cc5733e09c54.zip fluxbox-1dab657708cd8246c2ce5a6aaa05cc5733e09c54.tar.bz2 |
aspect ratios should take base size into account, fix size hint initialization
Diffstat (limited to 'src/FbWinFrame.cc')
-rw-r--r-- | src/FbWinFrame.cc | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index d044dd7..eb8510e 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc | |||
@@ -1689,6 +1689,14 @@ void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y, | |||
1689 | ret_y = static_cast<unsigned int>(u * aspect_y); | 1689 | ret_y = static_cast<unsigned int>(u * aspect_y); |
1690 | } | 1690 | } |
1691 | 1691 | ||
1692 | unsigned int increaseToMultiple(unsigned int val, unsigned int inc) { | ||
1693 | return val % inc ? val + inc - (val % inc) : val; | ||
1694 | } | ||
1695 | |||
1696 | unsigned int decreaseToMultiple(unsigned int val, unsigned int inc) { | ||
1697 | return val % inc ? val - (val % inc) : val; | ||
1698 | } | ||
1699 | |||
1692 | /** | 1700 | /** |
1693 | * Changes width and height to the nearest (lower) value | 1701 | * Changes width and height to the nearest (lower) value |
1694 | * that conforms to it's size hints. | 1702 | * that conforms to it's size hints. |
@@ -1700,12 +1708,7 @@ void closestPointToAspect(unsigned int &ret_x, unsigned int &ret_y, | |||
1700 | * See ICCCM section 4.1.2.3 | 1708 | * See ICCCM section 4.1.2.3 |
1701 | */ | 1709 | */ |
1702 | void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height, | 1710 | void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height, |
1703 | bool maximizing) const { | 1711 | bool make_fit) const { |
1704 | |||
1705 | // we apply aspect ratios before incrementals | ||
1706 | // Too difficult to exactly satisfy both incremental+aspect | ||
1707 | // in most situations | ||
1708 | // (they really shouldn't happen at the same time anyway). | ||
1709 | 1712 | ||
1710 | /* aspect ratios are applied exclusive to the base size | 1713 | /* aspect ratios are applied exclusive to the base size |
1711 | * | 1714 | * |
@@ -1713,8 +1716,6 @@ void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height, | |||
1713 | * ------------ < ------- < ------------ | 1716 | * ------------ < ------- < ------------ |
1714 | * min_aspect_y height max_aspect_y | 1717 | * min_aspect_y height max_aspect_y |
1715 | * | 1718 | * |
1716 | * beware of integer maximum (so I'll use doubles instead and divide) | ||
1717 | * | ||
1718 | * The trick is how to get back to the aspect ratio with minimal | 1719 | * The trick is how to get back to the aspect ratio with minimal |
1719 | * change - do we modify x, y or both? | 1720 | * change - do we modify x, y or both? |
1720 | * A: we minimise the distance between the current point, and | 1721 | * A: we minimise the distance between the current point, and |
@@ -1722,43 +1723,62 @@ void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height, | |||
1722 | * Consider that the aspect ratio is a line, and the current | 1723 | * Consider that the aspect ratio is a line, and the current |
1723 | * w/h is a point, so we're just using the formula for | 1724 | * w/h is a point, so we're just using the formula for |
1724 | * shortest distance from a point to a line! | 1725 | * shortest distance from a point to a line! |
1725 | * | ||
1726 | * When maximizing, we must not increase any of the sizes, because we | ||
1727 | * would end up with the window partly off a screen, so a simpler formula | ||
1728 | * is used in that case. | ||
1729 | */ | 1726 | */ |
1730 | 1727 | ||
1731 | if (min_aspect_y > 0 && width*min_aspect_y < min_aspect_x*height) { | 1728 | // make respective to base_size |
1732 | if (maximizing) | 1729 | unsigned int w = width - base_width, h = height - base_height; |
1733 | height = width * min_aspect_y / min_aspect_x; | 1730 | |
1734 | else | 1731 | if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) { |
1735 | closestPointToAspect(width, height, width, height, | 1732 | closestPointToAspect(w, h, w, h, min_aspect_x, min_aspect_y); |
1736 | min_aspect_x, min_aspect_y); | 1733 | // new w must be > old w, new h must be < old h |
1737 | } else if (max_aspect_x > 0 && width*max_aspect_y > max_aspect_x*height) { | 1734 | w = increaseToMultiple(w, width_inc); |
1738 | if (maximizing) | 1735 | h = decreaseToMultiple(h, height_inc); |
1739 | width = height * max_aspect_x / max_aspect_y; | 1736 | } else if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) { |
1740 | else | 1737 | closestPointToAspect(w, h, w, h, max_aspect_x, max_aspect_y); |
1741 | closestPointToAspect(width, height, width, height, | 1738 | // new w must be < old w, new h must be > old h |
1742 | max_aspect_x, max_aspect_y); | 1739 | w = decreaseToMultiple(w, width_inc); |
1740 | h = increaseToMultiple(h, height_inc); | ||
1743 | } | 1741 | } |
1744 | 1742 | ||
1745 | // Check minimum size | 1743 | // Check minimum size |
1746 | if (width < min_width) | 1744 | if (w + base_width < min_width) { |
1747 | width = min_width; | 1745 | w = increaseToMultiple(min_width - base_width, width_inc); |
1746 | // need to check maximum aspect again | ||
1747 | if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) | ||
1748 | h = increaseToMultiple(w * max_aspect_y / max_aspect_x, height_inc); | ||
1749 | } | ||
1750 | |||
1751 | if (h + base_height < min_height) { | ||
1752 | h = increaseToMultiple(min_height - base_height, height_inc); | ||
1753 | // need to check minimum aspect again | ||
1754 | if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) | ||
1755 | w = increaseToMultiple(h * min_aspect_x / min_aspect_y, width_inc); | ||
1756 | } | ||
1748 | 1757 | ||
1749 | if (height < min_height) | 1758 | unsigned int max_w = make_fit && (width < max_width || max_width == 0) ? |
1750 | height = min_height; | 1759 | width : max_width; |
1760 | unsigned int max_h = make_fit && (height < max_height || max_height == 0) ? | ||
1761 | height : max_height; | ||
1751 | 1762 | ||
1752 | // Check maximum size | 1763 | // Check maximum size |
1753 | if (max_width > 0 && width > max_width) | 1764 | if (max_w > 0 && w + base_width > max_w) |
1754 | width = max_width; | 1765 | w = max_w - base_width; |
1766 | |||
1767 | if (max_h > 0 && h + base_height > max_h) | ||
1768 | h = max_h - base_height; | ||
1769 | |||
1770 | w = decreaseToMultiple(w, width_inc); | ||
1771 | h = decreaseToMultiple(h, height_inc); | ||
1772 | |||
1773 | // need to check aspects one more time | ||
1774 | if (min_aspect_y > 0 && w * min_aspect_y < min_aspect_x * h) | ||
1775 | h = decreaseToMultiple(w * min_aspect_y / min_aspect_x, height_inc); | ||
1755 | 1776 | ||
1756 | if (max_height > 0 && height > max_height) | 1777 | if (max_aspect_x > 0 && w * max_aspect_y > max_aspect_x * h) |
1757 | height = max_height; | 1778 | w = decreaseToMultiple(h * max_aspect_x / max_aspect_y, width_inc); |
1758 | 1779 | ||
1759 | // enforce incremental size limits, wrt base size | 1780 | width = w + base_width; |
1760 | width -= (width - base_width) % width_inc; | 1781 | height = h + base_height; |
1761 | height -= (height - base_height) % height_inc; | ||
1762 | } | 1782 | } |
1763 | 1783 | ||
1764 | // check if the given width and height satisfy the size hints | 1784 | // check if the given width and height satisfy the size hints |
@@ -1775,10 +1795,10 @@ bool FbWinFrame::SizeHints::valid(unsigned int w, unsigned int h) const { | |||
1775 | if ((h - base_height) % height_inc != 0) | 1795 | if ((h - base_height) % height_inc != 0) |
1776 | return false; | 1796 | return false; |
1777 | 1797 | ||
1778 | if (min_aspect_x * h > w * min_aspect_y) | 1798 | if (min_aspect_x * (h - base_height) > (w - base_width) * min_aspect_y) |
1779 | return false; | 1799 | return false; |
1780 | 1800 | ||
1781 | if (max_aspect_x * h < w * max_aspect_y) | 1801 | if (max_aspect_x * (h - base_height) < (w - base_width) * max_aspect_y) |
1782 | return false; | 1802 | return false; |
1783 | 1803 | ||
1784 | return true; | 1804 | return true; |