aboutsummaryrefslogtreecommitdiff
path: root/src/WinClient.cc
diff options
context:
space:
mode:
authorrathnor <rathnor>2004-04-01 14:06:42 (GMT)
committerrathnor <rathnor>2004-04-01 14:06:42 (GMT)
commitab6e83e9356bea6006aaf524681797f0ef6cb18e (patch)
tree237d5e88e7af25af581c5f97a7d3161682aed157 /src/WinClient.cc
parentcb3aeaf378c7af9cbea6059f9533fc65bcf9ef46 (diff)
downloadfluxbox-ab6e83e9356bea6006aaf524681797f0ef6cb18e.zip
fluxbox-ab6e83e9356bea6006aaf524681797f0ef6cb18e.tar.bz2
honour aspect ratio hints
Diffstat (limited to 'src/WinClient.cc')
-rw-r--r--src/WinClient.cc82
1 files changed, 77 insertions, 5 deletions
diff --git a/src/WinClient.cc b/src/WinClient.cc
index 2524106..2265f2f 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -19,7 +19,7 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: WinClient.cc,v 1.37 2003/12/30 20:56:41 fluxgen Exp $ 22// $Id: WinClient.cc,v 1.38 2004/04/01 14:06:42 rathnor Exp $
23 23
24#include "WinClient.hh" 24#include "WinClient.hh"
25 25
@@ -45,8 +45,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
45 min_width(1), min_height(1), 45 min_width(1), min_height(1),
46 max_width(0), max_height(0), 46 max_width(0), max_height(0),
47 width_inc(1), height_inc(1), 47 width_inc(1), height_inc(1),
48 min_aspect_x(1), min_aspect_y(1), 48 min_aspect_x(0), min_aspect_y(0),
49 max_aspect_x(1), max_aspect_y(1), 49 max_aspect_x(0), max_aspect_y(0),
50 base_width(1), base_height(1), 50 base_width(1), base_height(1),
51 initial_state(0), 51 initial_state(0),
52 normal_hint_flags(0), 52 normal_hint_flags(0),
@@ -441,7 +441,7 @@ void WinClient::updateWMNormalHints() {
441 max_width = 0; // unbounded 441 max_width = 0; // unbounded
442 max_height = 0; 442 max_height = 0;
443 min_aspect_x = min_aspect_y = 443 min_aspect_x = min_aspect_y =
444 max_aspect_x = max_aspect_y = 1; 444 max_aspect_x = max_aspect_y = 0;
445 m_win_gravity = NorthWestGravity; 445 m_win_gravity = NorthWestGravity;
446 } else { 446 } else {
447 normal_hint_flags = sizehint.flags; 447 normal_hint_flags = sizehint.flags;
@@ -488,7 +488,7 @@ void WinClient::updateWMNormalHints() {
488 max_aspect_y = sizehint.max_aspect.y; 488 max_aspect_y = sizehint.max_aspect.y;
489 } else 489 } else
490 min_aspect_x = min_aspect_y = 490 min_aspect_x = min_aspect_y =
491 max_aspect_x = max_aspect_y = 1; 491 max_aspect_x = max_aspect_y = 0;
492 492
493 if (sizehint.flags & PWinGravity) 493 if (sizehint.flags & PWinGravity)
494 m_win_gravity = sizehint.win_gravity; 494 m_win_gravity = sizehint.win_gravity;
@@ -630,6 +630,26 @@ void WinClient::updateWMProtocols() {
630 630
631} 631}
632 632
633/* For aspect ratios
634 Note that its slightly simplified in that only the
635 line gradient is given - this is because for aspect
636 ratios, we always have the line going through the origin
637
638 * Based on this formula:
639 http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
640
641 Note that a gradient from origin goes through ( grad , 1 )
642 */
643
644void closestPointToLine(double &ret_x, double &ret_y,
645 double point_x, double point_y,
646 double gradient) {
647 double u = (point_x * gradient + point_y) /
648 (gradient*gradient + 1);
649
650 ret_x = u*gradient;
651 ret_y = u;
652}
633 653
634/** 654/**
635 * Changes width and height to the nearest (lower) value 655 * Changes width and height to the nearest (lower) value
@@ -660,6 +680,58 @@ void WinClient::applySizeHints(int &width, int &height,
660 if (max_height > 0 && height > static_cast<signed>(max_height)) 680 if (max_height > 0 && height > static_cast<signed>(max_height))
661 height = max_height; 681 height = max_height;
662 682
683 // we apply aspect ratios before incrementals
684 // Too difficult to exactly satisfy both incremental+aspect
685 // in most situations
686 // (they really shouldn't happen at the same time anyway).
687
688 /* aspect ratios are applied exclusive to the base_width
689 *
690 * min_aspect_x width max_aspect_x
691 * ------------ < ------- < ------------
692 * min_aspect_y height max_aspect_y
693 *
694 * beware of integer maximum (so I'll use doubles instead and divide)
695 *
696 * The trick is how to get back to the aspect ratio with minimal
697 * change - do we modify x, y or both?
698 * A: we minimise the distance between the current point, and
699 * the target aspect ratio (consider them as x,y coordinates)
700 * Consider that the aspect ratio is a line, and the current
701 * w/h is a point, so we're just using the formula for
702 * shortest distance from a point to a line!
703 */
704
705 if (min_aspect_y > 0 && max_aspect_y > 0 &&
706 (height - base_height) > 0) {
707 double widthd = static_cast<double>(width - base_width);
708 double heightd = static_cast<double>(height - base_height);
709
710 double min = static_cast<double>(min_aspect_x) /
711 static_cast<double>(min_aspect_y);
712
713 double max = static_cast<double>(max_aspect_x) /
714 static_cast<double>(max_aspect_y);
715
716 double actual = widthd / heightd;
717
718 if (max > 0 && min > 0 && actual > 0) { // don't even try otherwise
719 bool changed = false;
720 if (actual < min) {
721 changed = true;
722 closestPointToLine(widthd, heightd, widthd, heightd, min);
723 } else if (actual > max) {
724 changed = true;
725 closestPointToLine(widthd, heightd, widthd, heightd, max);
726 }
727
728 if (changed) {
729 width = static_cast<int>(widthd) + base_width;
730 height = static_cast<int>(heightd) + base_height;
731 }
732 }
733 }
734
663 // enforce incremental size limits, wrt base size 735 // enforce incremental size limits, wrt base size
664 // only calculate this if we really need to 736 // only calculate this if we really need to
665 i = (width - base_width) / width_inc; 737 i = (width - base_width) / width_inc;