diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/WinClient.cc | 82 |
2 files changed, 83 insertions, 8 deletions
@@ -1,12 +1,15 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.9: | 2 | Changes for 0.9.9: |
3 | *04/04/01: | ||
4 | * Support aspect ratio hints (Simon) | ||
5 | WinClient.cc | ||
3 | *04/03/31: | 6 | *04/03/31: |
4 | * Fixed _MOTIF_WM_HINTS decoration toggle bug (Henrik) | 7 | * Fixed _MOTIF_WM_HINTS decoration toggle bug (Henrik) |
5 | Window.cc | 8 | Window.cc |
6 | *04/03/30: | 9 | *04/03/30: |
7 | * Fixed optional decoration on transient windows (Thanks Scott Moser <ssmoser at us dot ibm dot com>) | 10 | * Fixed optional decoration on transient windows |
8 | 11 | (Thanks Scott Moser <ssmoser at us dot ibm dot com>) | |
9 | Screen.hh/cc, Window.cc, nls/C/Configmenu.m | 12 | Screen.hh/cc, Window.cc, nls/C/Configmenu.m |
10 | *04/03/28: | 13 | *04/03/28: |
11 | * Fixed window snaping to screen objects (Henrik) | 14 | * Fixed window snaping to screen objects (Henrik) |
12 | Window.cc | 15 | Window.cc |
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; |