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 | |
parent | 6053ecc1b573e437dd0d1752670748c5c3679669 (diff) | |
download | fluxbox-1dab657708cd8246c2ce5a6aaa05cc5733e09c54.zip fluxbox-1dab657708cd8246c2ce5a6aaa05cc5733e09c54.tar.bz2 |
aspect ratios should take base size into account, fix size hint initialization
-rw-r--r-- | src/FbWinFrame.cc | 94 | ||||
-rw-r--r-- | src/WinClient.cc | 120 |
2 files changed, 109 insertions, 105 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; |
diff --git a/src/WinClient.cc b/src/WinClient.cc index f421013..2c9cdc6 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc | |||
@@ -82,14 +82,6 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin): | |||
82 | m_mwm_hint(0), | 82 | m_mwm_hint(0), |
83 | m_strut(0) { | 83 | m_strut(0) { |
84 | 84 | ||
85 | m_size_hints.min_width = m_size_hints.min_height = | ||
86 | m_size_hints.width_inc = m_size_hints.height_inc = | ||
87 | m_size_hints.base_width = m_size_hints.base_height = 1; | ||
88 | |||
89 | m_size_hints.max_width = m_size_hints.max_height = | ||
90 | m_size_hints.min_aspect_x = m_size_hints.min_aspect_y = | ||
91 | m_size_hints.max_aspect_x = m_size_hints.max_aspect_y = 0; | ||
92 | |||
93 | updateWMProtocols(); | 85 | updateWMProtocols(); |
94 | updateMWMHints(); | 86 | updateMWMHints(); |
95 | updateWMHints(); | 87 | updateWMHints(); |
@@ -471,73 +463,65 @@ void WinClient::updateWMHints() { | |||
471 | void WinClient::updateWMNormalHints() { | 463 | void WinClient::updateWMNormalHints() { |
472 | long icccm_mask; | 464 | long icccm_mask; |
473 | XSizeHints sizehint; | 465 | XSizeHints sizehint; |
474 | if (! XGetWMNormalHints(display(), window(), &sizehint, &icccm_mask)) { | 466 | if (!XGetWMNormalHints(display(), window(), &sizehint, &icccm_mask)) |
475 | m_size_hints.min_width = m_size_hints.min_height = | 467 | sizehint.flags = 0; |
476 | m_size_hints.base_width = m_size_hints.base_height = | 468 | |
477 | m_size_hints.width_inc = m_size_hints.height_inc = 1; | 469 | normal_hint_flags = sizehint.flags; |
470 | |||
471 | if (sizehint.flags & PMinSize) { | ||
472 | m_size_hints.min_width = sizehint.min_width; | ||
473 | m_size_hints.min_height = sizehint.min_height; | ||
474 | } else | ||
475 | m_size_hints.min_width = m_size_hints.min_height = 1; | ||
476 | |||
477 | if (sizehint.flags & PBaseSize) { | ||
478 | m_size_hints.base_width = sizehint.base_width; | ||
479 | m_size_hints.base_height = sizehint.base_height; | ||
480 | if (!(sizehint.flags & PMinSize)) { | ||
481 | m_size_hints.min_width = m_size_hints.base_width; | ||
482 | m_size_hints.min_height = m_size_hints.base_height; | ||
483 | } | ||
484 | } else | ||
485 | m_size_hints.base_width = m_size_hints.base_height = 0; | ||
486 | |||
487 | if (sizehint.flags & PMaxSize) { | ||
488 | m_size_hints.max_width = sizehint.max_width; | ||
489 | m_size_hints.max_height = sizehint.max_height; | ||
490 | } else { | ||
478 | m_size_hints.max_width = 0; // unbounded | 491 | m_size_hints.max_width = 0; // unbounded |
479 | m_size_hints.max_height = 0; | 492 | m_size_hints.max_height = 0; |
493 | } | ||
494 | |||
495 | if (sizehint.flags & PResizeInc) { | ||
496 | m_size_hints.width_inc = sizehint.width_inc; | ||
497 | m_size_hints.height_inc = sizehint.height_inc; | ||
498 | } else | ||
499 | m_size_hints.width_inc = m_size_hints.height_inc = 1; | ||
500 | |||
501 | if (sizehint.flags & PAspect) { | ||
502 | m_size_hints.min_aspect_x = sizehint.min_aspect.x; | ||
503 | m_size_hints.min_aspect_y = sizehint.min_aspect.y; | ||
504 | m_size_hints.max_aspect_x = sizehint.max_aspect.x; | ||
505 | m_size_hints.max_aspect_y = sizehint.max_aspect.y; | ||
506 | } else | ||
480 | m_size_hints.min_aspect_x = m_size_hints.min_aspect_y = | 507 | m_size_hints.min_aspect_x = m_size_hints.min_aspect_y = |
481 | m_size_hints.max_aspect_x = m_size_hints.max_aspect_y = 0; | 508 | m_size_hints.max_aspect_x = m_size_hints.max_aspect_y = 0; |
482 | m_win_gravity = NorthWestGravity; | ||
483 | } else { | ||
484 | normal_hint_flags = sizehint.flags; | ||
485 | |||
486 | if (sizehint.flags & PMinSize) { | ||
487 | m_size_hints.min_width = sizehint.min_width; | ||
488 | m_size_hints.min_height = sizehint.min_height; | ||
489 | if (!(sizehint.flags & PBaseSize)) { | ||
490 | m_size_hints.base_width = m_size_hints.min_width; | ||
491 | m_size_hints.base_height = m_size_hints.min_height; | ||
492 | } | ||
493 | } else { | ||
494 | m_size_hints.min_width = m_size_hints.min_height = 1; | ||
495 | m_size_hints.base_width = m_size_hints.base_height = 0; | ||
496 | } | ||
497 | |||
498 | if (sizehint.flags & PBaseSize) { | ||
499 | m_size_hints.base_width = sizehint.base_width; | ||
500 | m_size_hints.base_height = sizehint.base_height; | ||
501 | if (!(sizehint.flags & PMinSize)) { | ||
502 | m_size_hints.min_width = m_size_hints.base_width; | ||
503 | m_size_hints.min_height = m_size_hints.base_height; | ||
504 | } | ||
505 | } // default set in PMinSize | ||
506 | |||
507 | if (sizehint.flags & PMaxSize) { | ||
508 | m_size_hints.max_width = sizehint.max_width; | ||
509 | m_size_hints.max_height = sizehint.max_height; | ||
510 | } else { | ||
511 | m_size_hints.max_width = 0; // unbounded | ||
512 | m_size_hints.max_height = 0; | ||
513 | } | ||
514 | 509 | ||
515 | if (sizehint.flags & PResizeInc) { | 510 | if (sizehint.flags & PWinGravity) |
516 | m_size_hints.width_inc = sizehint.width_inc; | 511 | m_win_gravity = sizehint.win_gravity; |
517 | m_size_hints.height_inc = sizehint.height_inc; | 512 | else |
518 | } else | 513 | m_win_gravity = NorthWestGravity; |
519 | m_size_hints.width_inc = m_size_hints.height_inc = 1; | ||
520 | |||
521 | if (m_size_hints.width_inc == 0) | ||
522 | m_size_hints.width_inc = 1; | ||
523 | if (m_size_hints.height_inc == 0) | ||
524 | m_size_hints.height_inc = 1; | ||
525 | |||
526 | if (sizehint.flags & PAspect) { | ||
527 | m_size_hints.min_aspect_x = sizehint.min_aspect.x; | ||
528 | m_size_hints.min_aspect_y = sizehint.min_aspect.y; | ||
529 | m_size_hints.max_aspect_x = sizehint.max_aspect.x; | ||
530 | m_size_hints.max_aspect_y = sizehint.max_aspect.y; | ||
531 | } else | ||
532 | m_size_hints.min_aspect_x = m_size_hints.min_aspect_y = | ||
533 | m_size_hints.max_aspect_x = m_size_hints.max_aspect_y = 0; | ||
534 | 514 | ||
535 | if (sizehint.flags & PWinGravity) | 515 | // some sanity checks |
536 | m_win_gravity = sizehint.win_gravity; | 516 | if (m_size_hints.width_inc == 0) |
537 | else | 517 | m_size_hints.width_inc = 1; |
538 | m_win_gravity = NorthWestGravity; | 518 | if (m_size_hints.height_inc == 0) |
519 | m_size_hints.height_inc = 1; | ||
539 | 520 | ||
540 | } | 521 | if (m_size_hints.base_width > m_size_hints.min_width) |
522 | m_size_hints.min_width = m_size_hints.base_width; | ||
523 | if (m_size_hints.base_height > m_size_hints.min_height) | ||
524 | m_size_hints.min_height = m_size_hints.base_height; | ||
541 | } | 525 | } |
542 | 526 | ||
543 | Window WinClient::getGroupLeftWindow() const { | 527 | Window WinClient::getGroupLeftWindow() const { |