Index: constraints.c
===================================================================
RCS file: /cvs/gnome/metacity/src/constraints.c,v
retrieving revision 1.13
diff -p -u -r1.13 constraints.c
--- constraints.c	28 Jul 2003 02:09:19 -0000	1.13
+++ constraints.c	2 Aug 2003 17:38:59 -0000
@@ -119,6 +119,7 @@ typedef struct
   MetaRectangle work_area_xinerama;
   MetaRectangle work_area_screen;
   int nw_x, nw_y, se_x, se_y; /* these are whole-screen not xinerama */
+  int x_delta, y_delta, x_move_delta, y_move_delta;
 } ConstraintInfo;
 
 /* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
@@ -351,15 +352,17 @@ get_outermost_onscreen_positions (MetaWi
                                   const MetaRectangle  *orig,
                                   int                  delta_x,
                                   int                  delta_y,
-                                  int                  *leftmost_x,
-                                  int                  *rightmost_x,
-                                  int                  *topmost_y,
-                                  int                  *bottommost_y)
+                                  int                  *leftmost_x_p,
+                                  int                  *rightmost_x_p,
+                                  int                  *topmost_y_p,
+                                  int                  *bottommost_y_p,
+                                  int                  is_move)
 {
   GList *workspaces;
   GList *tmp;
   GSList *stmp;
   MetaRectangle current;
+  int bottommost_y;
 
   /* to handle struts, we get the list of workspaces for the window
    * and traverse all the struts in each of the cached strut lists for
@@ -375,9 +378,9 @@ get_outermost_onscreen_positions (MetaWi
   workspaces = meta_window_get_workspaces (window);
   tmp = workspaces;
 
-  if (leftmost_x)
+  if (leftmost_x_p)
     {
-      *leftmost_x = info->nw_x;
+      *leftmost_x_p = info->nw_x;
       while (tmp)
         {
           stmp = ((MetaWorkspace*) tmp->data)->left_struts;
@@ -392,7 +395,7 @@ get_outermost_onscreen_positions (MetaWi
                   ((current.y >= rect->y) &&
                    (current.y <= rect->y + rect->height)))
                 {
-                  *leftmost_x = MAX (*leftmost_x, rect->width);
+                  *leftmost_x_p = MAX (*leftmost_x_p, rect->width);
                 }
               
               stmp = stmp->next;
@@ -401,14 +404,14 @@ get_outermost_onscreen_positions (MetaWi
           tmp = tmp->next;
         }
       
-      *leftmost_x = *leftmost_x - current.width + 
+      *leftmost_x_p = *leftmost_x_p - current.width + 
         MIN (TITLEBAR_LENGTH_ONSCREEN, current.width);
     }
   
   tmp = workspaces;
-  if (rightmost_x)
+  if (rightmost_x_p)
     {
-      *rightmost_x = info->se_x;
+      *rightmost_x_p = info->se_x;
       while (tmp)
         {
           stmp = ((MetaWorkspace*) tmp->data)->right_struts;
@@ -423,7 +426,7 @@ get_outermost_onscreen_positions (MetaWi
                   ((current.y >= rect->y) &&
                    (current.y <= rect->y + rect->height)))
                 {
-                  *rightmost_x = MIN (*rightmost_x, rect->x);
+                  *rightmost_x_p = MIN (*rightmost_x_p, rect->x);
                 }
               
               stmp = stmp->next;
@@ -432,14 +435,14 @@ get_outermost_onscreen_positions (MetaWi
           tmp = tmp->next;
         }
       
-      *rightmost_x = *rightmost_x - 
+      *rightmost_x_p = *rightmost_x_p - 
         MIN (TITLEBAR_LENGTH_ONSCREEN, current.width);
     }
 
   tmp = workspaces;
-  if (topmost_y)
+  if (topmost_y_p)
     {
-      *topmost_y = info->nw_y;
+      *topmost_y_p = info->nw_y;
       while (tmp)
         {
           stmp = ((MetaWorkspace*) tmp->data)->top_struts;
@@ -449,10 +452,10 @@ get_outermost_onscreen_positions (MetaWi
               /* here the strut matters if the titlebar is overlapping
                * the window horizontally
                */
-	      if ((current.x <= rect->x + rect->width) &&
-		  (current.x + current.width >= rect->x))
+              if ((current.x <= rect->x + rect->width) &&
+                  (current.x + current.width >= rect->x))
                 {
-                  *topmost_y = MAX (*topmost_y, rect->height);
+                  *topmost_y_p = MAX (*topmost_y_p, rect->height);
                 }
               
               stmp = stmp->next;
@@ -461,13 +464,14 @@ get_outermost_onscreen_positions (MetaWi
           tmp = tmp->next;
         }
       
-      *topmost_y = *topmost_y + info->fgeom.top_height;
+      *topmost_y_p = *topmost_y_p + info->fgeom.top_height;
     }
 
   tmp = workspaces;
-  if (bottommost_y)
+  bottommost_y = G_MAXUSHORT;
+  if (bottommost_y_p || topmost_y_p)
     {
-      *bottommost_y = info->se_y;
+      bottommost_y = info->se_y;
       while (tmp)
         {
           stmp = ((MetaWorkspace*) tmp->data)->bottom_struts;
@@ -477,10 +481,10 @@ get_outermost_onscreen_positions (MetaWi
               /* here the strut matters if the titlebar is overlapping
                * the window horizontally
                */
-	      if ((current.x <= rect->x + rect->width) &&
-		  (current.x + current.width >= rect->x))
+              if ((current.x <= rect->x + rect->width) &&
+                  (current.x + current.width >= rect->x))
                 {
-                  *bottommost_y = MIN (*bottommost_y, rect->y);
+                  bottommost_y = MIN (bottommost_y, rect->y);
                 }
               
               stmp = stmp->next;
@@ -488,14 +492,55 @@ get_outermost_onscreen_positions (MetaWi
           
           tmp = tmp->next;
         }
-      
+    }
+
+  if (bottommost_y_p)
+    {
+      *bottommost_y_p = bottommost_y;
+
       /* If no frame, keep random TITLEBAR_LENGTH_ONSCREEN pixels on the
        * screen.
        */
       if (!window->frame)
-        *bottommost_y = *bottommost_y -
+        *bottommost_y_p = *bottommost_y_p -
           MIN (TITLEBAR_LENGTH_ONSCREEN, current.height);
     }
+
+  /* if the window has a minimum size too big for the "effective" work
+   * area let it "cheat" a little by allowing a user to move it up so
+   * that you can see the bottom of the window.
+   */
+  if (topmost_y_p && is_move)
+    {
+      int minheight;
+      
+      if (window->frame)
+        {
+          /* this is the "normal" case of, e.g. a dialog that's
+           * just too big for the work area
+           */
+          minheight = window->frame->bottom_height +
+            window->size_hints.min_height;
+        }
+      else
+        {
+          /* let frameless windows move offscreen if their "proposed"
+           * height is too large for the effective work area.  This
+           * may include windows that try to make themselves full
+           * screen by removing the decorations and repositioning
+           * themselves.
+           *
+           * Note we have to use the proposed height since such
+           * windows will typically move/resize themselves in one
+           * configure event, and we do moving before resizing in such
+           * cases.
+           */
+          minheight = window->rect.height + info->y_delta;
+        }
+      
+      if (minheight > (bottommost_y - *topmost_y_p))
+          *topmost_y_p = bottommost_y - minheight;
+    }
 }
 
 static void
@@ -508,7 +553,7 @@ constraint_onscreen_top_func     (MetaWi
   int topmost_y;
 
   get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
-                                    NULL, NULL, &topmost_y, NULL);
+                                    NULL, NULL, &topmost_y, NULL, FALSE);
 
   min_dy = topmost_y - orig->y;
 
@@ -526,7 +571,7 @@ constraint_onscreen_bottom_func  (MetaWi
   int bottommost_y;
 
   get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
-                                    NULL, NULL, NULL, &bottommost_y);
+                                    NULL, NULL, NULL, &bottommost_y, FALSE);
 
   max_dy = bottommost_y - orig->y;
 
@@ -544,7 +589,7 @@ constraint_onscreen_vcenter_func (MetaWi
   int topmost_y;
 
   get_outermost_onscreen_positions (window, info, orig, 0, *y_delta,
-                                    NULL, NULL, &topmost_y, NULL);
+                                    NULL, NULL, &topmost_y, NULL, FALSE);
 
   max_dy = orig->y - topmost_y;
 
@@ -562,7 +607,7 @@ constraint_onscreen_left_func    (MetaWi
   int leftmost_x;
 
   get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
-                                    &leftmost_x, NULL, NULL, NULL);
+                                    &leftmost_x, NULL, NULL, NULL, FALSE);
 
   min_dx = leftmost_x - orig->x;
 
@@ -580,7 +625,7 @@ constraint_onscreen_right_func   (MetaWi
   int rightmost_x;
 
   get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
-                                    NULL, &rightmost_x, NULL, NULL);
+                                    NULL, &rightmost_x, NULL, NULL, FALSE);
 
   max_dx = rightmost_x - orig->x;
 
@@ -598,7 +643,7 @@ constraint_onscreen_hcenter_func (MetaWi
   int leftmost_x;
   
   get_outermost_onscreen_positions (window, info, orig, *x_delta, 0,
-                                    &leftmost_x, NULL, NULL, NULL);
+                                    &leftmost_x, NULL, NULL, NULL, FALSE);
 
   max_dx = orig->x - leftmost_x;
 
@@ -619,7 +664,7 @@ constraint_onscreen_move_func    (MetaWi
 
   get_outermost_onscreen_positions (window, info, orig, *x_delta, *y_delta,
                                     &leftmost_x, &rightmost_x,
-                                    &topmost_y, &bottommost_y);
+                                    &topmost_y, &bottommost_y, TRUE);
 
   min_delta = topmost_y - orig->y;
   max_delta = bottommost_y - orig->y;
@@ -1261,6 +1306,10 @@ meta_window_constrain (MetaWindow       
   info.window = window;
   info.xinerama = meta_screen_get_xinerama_for_window (window->screen,
                                                        window);
+  info.x_delta = x_delta;
+  info.y_delta = y_delta;
+  info.x_move_delta = x_move_delta;
+  info.y_move_delta = y_move_delta;
 
   /* Init info->nw_x etc. */
   update_position_limits (window, &info);
Index: tools/metacity-window-demo.c
===================================================================
RCS file: /cvs/gnome/metacity/src/tools/metacity-window-demo.c,v
retrieving revision 1.16
diff -p -u -r1.16 metacity-window-demo.c
--- tools/metacity-window-demo.c	28 Jul 2003 02:09:20 -0000	1.16
+++ tools/metacity-window-demo.c	2 Aug 2003 17:39:02 -0000
@@ -723,12 +723,15 @@ toggle_aspect_ratio (GtkWidget *button,
 
   aspect_on = !aspect_on;
 
+  geom.min_height = 900;
+  geom.min_width = 1;
+
   window = gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW);
   if (window)
     gtk_window_set_geometry_hints (GTK_WINDOW (window),
 				   GTK_WIDGET (data),
 				   &geom,
-				   GDK_HINT_ASPECT);
+				   GDK_HINT_ASPECT | GDK_HINT_MIN_SIZE);
 				   
 }
 
