summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbWinFrame.cc94
-rw-r--r--src/WinClient.cc120
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
1692unsigned int increaseToMultiple(unsigned int val, unsigned int inc) {
1693 return val % inc ? val + inc - (val % inc) : val;
1694}
1695
1696unsigned 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 */
1702void FbWinFrame::SizeHints::apply(unsigned int &width, unsigned int &height, 1710void 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() {
471void WinClient::updateWMNormalHints() { 463void 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
543Window WinClient::getGroupLeftWindow() const { 527Window WinClient::getGroupLeftWindow() const {