]> Dogcows Code - chaz/openbox/commitdiff
support the aspect ratio hints in the WMNormalHints
authorDana Jansens <danakj@orodu.net>
Tue, 28 Jan 2003 00:26:54 +0000 (00:26 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 28 Jan 2003 00:26:54 +0000 (00:26 +0000)
src/client.cc
src/client.hh

index eeb09a374981a4fe5cfe9dc30d3f6386c6faa980..572c383aecb15d5f2410164c834f877f0349454e 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
 #define _(str) gettext(str)
 }
 
+#include <algorithm>
+
 namespace ob {
 
 Client::Client(int screen, Window window)
@@ -198,6 +200,11 @@ void Client::setupDecorAndFunctions()
     _decorations |= Decor_Close;
     _functions |= Func_Close;
   }
+
+  if (_min_size.x() > _max_size.x() || _min_size.y() > _max_size.y()) {
+    _decorations &= ~Decor_Maximize;
+    _functions &= ~(Func_Resize | Func_Maximize);
+  }
   
   switch (_type) {
   case Type_Normal:
@@ -418,6 +425,8 @@ void Client::updateNormalHints()
   int oldgravity = _gravity;
 
   // defaults
+  _min_ratio = 0.0;
+  _max_ratio = 0.0;
   _size_inc.setPoint(1, 1);
   _base_size.setPoint(0, 0);
   _min_size.setPoint(0, 0);
@@ -443,6 +452,11 @@ void Client::updateNormalHints()
       }
     }
 
+    if (size.flags & PAspect) {
+      if (size.min_aspect.y) _min_ratio = size.min_aspect.x/size.min_aspect.y;
+      if (size.max_aspect.y) _max_ratio = size.max_aspect.x/size.max_aspect.y;
+    }
+
     if (size.flags & PMinSize)
       _min_size.setPoint(size.min_width, size.min_height);
     
@@ -497,7 +511,7 @@ void Client::updateWMHints(bool initstate)
 #endif
     // fire the urgent callback if we're mapped, otherwise, wait until after
     // we're mapped
-    if (_urgent && frame)
+    if (frame)
       fireUrgent();
   }
 }
@@ -634,9 +648,10 @@ void Client::propertyHandler(const XPropertyEvent &e)
     }
   }
 
-  if (e.atom == XA_WM_NORMAL_HINTS)
+  if (e.atom == XA_WM_NORMAL_HINTS) {
     updateNormalHints();
-  else if (e.atom == XA_WM_HINTS)
+    setupDecorAndFunctions(); // normal hints can make a window non-resizable
+  } else if (e.atom == XA_WM_HINTS)
     updateWMHints();
   else if (e.atom == XA_WM_TRANSIENT_FOR) {
     updateTransientFor();
@@ -980,7 +995,8 @@ void Client::resize(Corner anchor, int w, int h)
 }
 
 
-void Client::internal_resize(Corner anchor, int w, int h, int x, int y)
+void Client::internal_resize(Corner anchor, int w, int h, bool user,
+                             int x, int y)
 {
   w -= _base_size.x(); 
   h -= _base_size.y();
@@ -990,14 +1006,21 @@ void Client::internal_resize(Corner anchor, int w, int h, int x, int y)
   w += _size_inc.x() / 2;
   h += _size_inc.y() / 2;
 
-  // is the window resizable? if it is not, then don't check its sizes, the
-  // client can do what it wants and the user can't change it anyhow
-  if (_min_size.x() <= _max_size.x() && _min_size.y() <= _max_size.y()) {
+  if (user) {
+    // if this is a user-requested resize, then check against min/max sizes
+    // and aspect ratios
+
     // smaller than min size or bigger than max size?
     if (w < _min_size.x()) w = _min_size.x();
     else if (w > _max_size.x()) w = _max_size.x();
     if (h < _min_size.y()) h = _min_size.y();
     else if (h > _max_size.y()) h = _max_size.y();
+
+    // adjust the height ot match the width for the aspect ratios
+    if (_min_ratio)
+      if (h * _min_ratio > w) h = static_cast<int>(w / _min_ratio);
+    if (_max_ratio)
+      if (h * _max_ratio < w) h = static_cast<int>(w / _max_ratio);
   }
 
   // keep to the increments
@@ -1404,9 +1427,9 @@ void Client::configureRequestHandler(const XConfigureRequestEvent &e)
     if (e.value_mask & (CWX | CWY)) {
       int x = (e.value_mask & CWX) ? e.x : _area.x();
       int y = (e.value_mask & CWY) ? e.y : _area.y();
-      internal_resize(corner, w, h, x, y);
+      internal_resize(corner, w, h, false, x, y);
     } else // if JUST resizing...
-      internal_resize(corner, w, h);
+      internal_resize(corner, w, h, false);
   } else if (e.value_mask & (CWX | CWY)) { // if JUST moving...
     int x = (e.value_mask & CWX) ? e.x : _area.x();
     int y = (e.value_mask & CWY) ? e.y : _area.y();
index c8110a3f70e75661926412e374a7f3ce0dac998a..0d8465482313398ebb91b38c68ff3a0f6b6d64f3 100644 (file)
@@ -236,6 +236,17 @@ private:
   */
   int _border_width;
 
+  //! The minimum aspect ratio the client window can be sized to.
+  /*!
+    A value of 0 means this is ignored.
+  */
+  float _min_ratio;
+  //! The maximum aspect ratio the client window can be sized to.
+  /*!
+    A value of 0 means this is ignored.
+  */
+  float _max_ratio;
+  
   //! The minimum size of the client window
   /*!
     If the min is > the max, then the window is not resizable
@@ -429,6 +440,8 @@ private:
     @param anchor The corner to keep in the same position when resizing.
     @param w The width component of the new size for the client.
     @param h The height component of the new size for the client.
+    @param user Specifies whether this is a user-requested change or a
+                program requested change.
     @param x An optional X coordinate to which the window will be moved
              after resizing.
     @param y An optional Y coordinate to which the window will be moved
@@ -436,7 +449,7 @@ private:
     The x and y coordinates must both be sepcified together, or they will have
     no effect. When they are specified, the anchor is ignored.
   */
-  void internal_resize(Corner anchor, int w, int h,
+  void internal_resize(Corner anchor, int w, int h, bool user = true,
                        int x = INT_MIN, int y = INT_MIN);
 
 public:
This page took 0.027101 seconds and 4 git commands to generate.