diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/WinClient.cc | 82 |
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 | |||
644 | void 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; |