From c37a91e1504fa73da233cc59fe67ead56dbd3083 Mon Sep 17 00:00:00 2001
From: Mark Tiefenbruck <mark@fluxbox.org>
Date: Fri, 22 Aug 2008 10:16:33 -0700
Subject: be a little smarter about size hints in tabbed windows

---
 src/FbWinFrame.cc |  6 +++--
 src/FbWinFrame.hh |  4 ++--
 src/Window.cc     | 69 ++++++++++++++++++++++++++++++++++---------------------
 src/Window.hh     |  2 ++
 4 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index f6f591e..bac06d2 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -1860,8 +1860,10 @@ void FbWinFrame::SizeHints::reset(const XSizeHints &sizehint) {
         min_aspect_y = sizehint.min_aspect.y;
         max_aspect_x = sizehint.max_aspect.x;
         max_aspect_y = sizehint.max_aspect.y;
-    } else
-        min_aspect_x = min_aspect_y = max_aspect_x = max_aspect_y = 0;
+    } else {
+        min_aspect_x = max_aspect_y = 0;
+        min_aspect_y = max_aspect_x = 1;
+    }
 
     if (sizehint.flags & PWinGravity)
         win_gravity = sizehint.win_gravity;
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh
index d2f7a1f..7f08175 100644
--- a/src/FbWinFrame.hh
+++ b/src/FbWinFrame.hh
@@ -112,8 +112,8 @@ public:
         SizeHints():
             min_width(1), max_width(0), min_height(1), max_height(0),
             width_inc(1), height_inc(1), base_width(0), base_height(0),
-            min_aspect_x(0), max_aspect_x(0),
-            min_aspect_y(0), max_aspect_y(0),
+            min_aspect_x(0), max_aspect_x(1),
+            min_aspect_y(1), max_aspect_y(0),
             win_gravity(0) { }
 
         void reset(const XSizeHints &sizehint);
diff --git a/src/Window.cc b/src/Window.cc
index 7dc268f..52672c0 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -1016,7 +1016,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
     // frame focused doesn't necessarily mean input focused
     frame().setLabelButtonFocus(*button);
     frame().setShapingClient(&client, false);
-    frame().setSizeHints(client.sizeHints());
     return ret;
 }
 
@@ -1033,10 +1032,50 @@ void FluxboxWindow::associateClientWindow() {
                                 m_client->width(), m_client->height(),
                                 m_client->gravity(), m_client->old_bw);
 
-    frame().setSizeHints(m_client->sizeHints());
+    updateSizeHints();
     frame().setClientWindow(*m_client);
 }
 
+void FluxboxWindow::updateSizeHints() {
+    m_size_hint = m_client->sizeHints();
+
+    ClientList::const_iterator it = clientList().begin();
+    ClientList::const_iterator it_end = clientList().end();
+    for (; it != it_end; ++it) {
+        if ((*it) == m_client)
+            continue;
+
+        const FbWinFrame::SizeHints &hint = (*it)->sizeHints();
+        if (m_size_hint.min_width < hint.min_width)
+            m_size_hint.min_width = hint.min_width;
+        if (m_size_hint.max_width > hint.max_width)
+            m_size_hint.max_width = hint.max_width;
+        if (m_size_hint.min_height < hint.min_height)
+            m_size_hint.min_height = hint.min_height;
+        if (m_size_hint.max_height > hint.max_height)
+            m_size_hint.max_height = hint.max_height;
+        // lcm could end up a bit silly, and the situation is bad no matter what
+        if (m_size_hint.width_inc < hint.width_inc)
+            m_size_hint.width_inc = hint.width_inc;
+        if (m_size_hint.height_inc < hint.height_inc)
+            m_size_hint.height_inc = hint.height_inc;
+        if (m_size_hint.base_width < hint.base_width)
+            m_size_hint.base_width = hint.base_width;
+        if (m_size_hint.base_height < hint.base_height)
+            m_size_hint.base_height = hint.base_height;
+        if (m_size_hint.min_aspect_x * hint.min_aspect_y >
+            m_size_hint.min_aspect_y * hint.min_aspect_x) {
+            m_size_hint.min_aspect_x = hint.min_aspect_x;
+            m_size_hint.min_aspect_y = hint.min_aspect_y;
+        }
+        if (m_size_hint.max_aspect_x * hint.max_aspect_y >
+            m_size_hint.max_aspect_y * hint.max_aspect_x) {
+            m_size_hint.max_aspect_x = hint.max_aspect_x;
+            m_size_hint.max_aspect_y = hint.max_aspect_y;
+        }
+    }
+    frame().setSizeHints(m_size_hint);
+}
 
 void FluxboxWindow::grabButtons() {
 
@@ -1208,32 +1247,10 @@ void FluxboxWindow::moveResizeForClient(int new_x, int new_y,
 }
 
 void FluxboxWindow::getMaxSize(unsigned int* width, unsigned int* height) const {
-
-    if (!width || !height)
-        return;
-
-    ClientList::const_iterator it = clientList().begin();
-    ClientList::const_iterator it_end = clientList().end();
-
-    unsigned int w;
-    unsigned int h;
-
-    w = h = 0; // unlimited
-
-    for (; it != it_end; ++it) {
-        // special case for max height/width == 0
-        // 0 indicates unlimited size, so we skip them
-        if (!h || ((*it)->maxHeight() && h > (*it)->maxHeight()))
-            h = (*it)->maxHeight();
-        if (!w || ((*it)->maxWidth() && w > (*it)->maxWidth()))
-            w = (*it)->maxWidth();
-    }
-
     if (width)
-        *width = w;
-
+        *width = m_size_hint.max_width;
     if (height)
-        *height = h;
+        *height = m_size_hint.max_height;
 }
 
 // returns whether the focus was "set" to this window
diff --git a/src/Window.hh b/src/Window.hh
index 16d5bc9..89cbc69 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -491,6 +491,7 @@ private:
 
     bool getState();
     void updateMWMHintsFromClient(WinClient &client);
+    void updateSizeHints();
     void associateClientWindow();
 
     void setState(unsigned long stateval, bool setting_up);
@@ -552,6 +553,7 @@ private:
     typedef std::map<WinClient *, IconButton *> Client2ButtonMap;
     Client2ButtonMap m_labelbuttons;
 
+    FbWinFrame::SizeHints m_size_hint;
     struct _decorations {
         bool titlebar, handle, border, iconify,
             maximize, close, menu, sticky, shade, tab, enabled;
-- 
cgit v0.11.2