Index: constraints.c
===================================================================
RCS file: /cvs/gnome/metacity/src/constraints.c,v
retrieving revision 1.4
diff -u -p -r1.4 constraints.c
--- constraints.c	6 Aug 2002 04:11:23 -0000	1.4
+++ constraints.c	12 Jan 2003 05:53:02 -0000
@@ -788,12 +788,12 @@ update_position_limits (MetaWindow      
   int se_x, se_y;
   int offscreen_w, offscreen_h;
   
-  nw_x = info->work_area_screen.x;
-  nw_y = info->work_area_screen.y;
+  nw_x = info->work_area_xinerama.x;
+  nw_y = info->work_area_xinerama.y;
   
   /* find bottom-right corner of workarea */
-  se_x = info->work_area_screen.x + info->work_area_screen.width;
-  se_y = info->work_area_screen.y + info->work_area_screen.height;
+  se_x = info->work_area_xinerama.x + info->work_area_xinerama.width;
+  se_y = info->work_area_xinerama.y + info->work_area_xinerama.height;
   
   /* If we have a micro-screen or huge frames maybe nw/se got
    * swapped
Index: place.c
===================================================================
RCS file: /cvs/gnome/metacity/src/place.c,v
retrieving revision 1.29
diff -u -p -r1.29 place.c
--- place.c	2 Oct 2002 02:42:24 -0000	1.29
+++ place.c	12 Jan 2003 05:53:04 -0000
@@ -121,12 +121,8 @@ find_next_cascade (MetaWindow *window,
    * of NW corner of window frame.
    */
   
-  /* FIXME this is bogus because we get the current xinerama
-   * for the window based on its position, but we haven't
-   * placed it yet.
-   */
-  meta_window_get_work_area (window, TRUE, &work_area);
-  
+  meta_window_get_work_area_for_xinerama (window, TRUE, 0, &work_area);
+
   cascade_x = MAX (0, work_area.x);
   cascade_y = MAX (0, work_area.y);
   
@@ -283,13 +279,13 @@ rectangle_overlaps_some_window (MetaRect
 
       switch (other->type)
         {
-        case META_WINDOW_DOCK:
         case META_WINDOW_SPLASHSCREEN:
         case META_WINDOW_DESKTOP:
         case META_WINDOW_DIALOG:
         case META_WINDOW_MODAL_DIALOG:
           break;
 
+        case META_WINDOW_DOCK:
         case META_WINDOW_NORMAL:
         case META_WINDOW_UTILITY:
         case META_WINDOW_TOOLBAR:
@@ -364,12 +360,16 @@ topmost_cmp (gconstpointer a, gconstpoin
 }
 
 static gboolean
-fit_rect_in_xinerama (MetaScreen    *screen,
+fit_rect_in_xinerama (MetaWindow *window,
                       MetaRectangle *rect)
 {
   int i;
   int best_index;
   int best_overlap;
+  int fluff;
+  gboolean ret;
+  MetaScreen *screen = window->screen;
+  MetaRectangle work_area;
   const MetaXineramaScreenInfo *xsi;
   
   /* Find xinerama with best fit, then
@@ -409,17 +409,22 @@ fit_rect_in_xinerama (MetaScreen    *scr
   /* some overlap had to be better than -1 */
   g_assert (best_index >= 0);
 
-  xsi = &screen->xinerama_infos[best_index];
+  meta_window_get_work_area_for_xinerama(window, TRUE, best_index, &work_area);
   
-  if (rect->x < xsi->x_origin)
-    rect->x = xsi->x_origin;
-  if (rect->y < xsi->y_origin)
-    rect->y = xsi->y_origin;
+  if ((rect->x < work_area.x) || (rect->y < work_area.y))
+    {
+      fluff = (work_area.width % rect->width) / 2;
+      rect->x = work_area.x+fluff;
+      fluff = (work_area.height % rect->height) / 4;
+      rect->y = work_area.y+fluff;
+    }
 
   /* Now return whether we are entirely within the xinerama screen */
-  return
-    ((rect->x + rect->width) < (xsi->x_origin + xsi->width)) &&
-    ((rect->y + rect->height) < (xsi->y_origin + xsi->height));
+  ret = 
+    ((rect->x + rect->width) < (work_area.x + work_area.width)) &&
+    ((rect->y + rect->height) < (work_area.y + work_area.height));
+
+  return ret;
 }
 
 /* Find the leftmost, then topmost, empty area on the workspace
@@ -449,9 +454,11 @@ find_first_fit (MetaWindow *window,
    */
   
   int retval;
+  int fluff;
   GList *sorted;
   GList *tmp;
   MetaRectangle rect;
+  MetaRectangle work_area;
   int i;
   
   retval = FALSE;
@@ -467,10 +474,13 @@ find_first_fit (MetaWindow *window,
     }
 
   /* Try origin of first Xinerama */
-  rect.x = window->screen->xinerama_infos[0].x_origin;
-  rect.y = window->screen->xinerama_infos[0].y_origin;
+  meta_window_get_work_area_for_xinerama(window, TRUE, 0, &work_area);
+  fluff = (work_area.width % rect.width) / 2;
+  rect.x = work_area.x + fluff;
+  fluff = (work_area.height % rect.height) / 4;
+  rect.y = work_area.y + fluff;
 
-  if (fit_rect_in_xinerama (window->screen, &rect) &&
+  if (fit_rect_in_xinerama (window, &rect) &&
       !rectangle_overlaps_some_window (&rect, windows))
     {
       *new_x = rect.x;
@@ -496,28 +506,32 @@ find_first_fit (MetaWindow *window,
   while (tmp != NULL)
     {
       MetaWindow *w = tmp->data;
-      MetaRectangle outer_rect;
-      
-      meta_window_get_outer_rect (w, &outer_rect);
-
-      rect.x = outer_rect.x;
-      rect.y = outer_rect.y + outer_rect.height;
-      
-      if (fit_rect_in_xinerama (window->screen, &rect) &&
-          !rectangle_overlaps_some_window (&rect, sorted))
-        {
-          *new_x = rect.x;
-          *new_y = rect.y;
-          if (fgeom)
-            {
-              *new_x += fgeom->left_width;
-              *new_y += fgeom->top_height;
-            }
 
-          retval = TRUE;
+      if (META_WINDOW_DOCK != w->type)
+	{
+	  MetaRectangle outer_rect;
+	  
+	  meta_window_get_outer_rect (w, &outer_rect);
+	  
+	  rect.x = outer_rect.x;
+	  rect.y = outer_rect.y + outer_rect.height;
+	  
+	  if (fit_rect_in_xinerama (window, &rect) &&
+	      !rectangle_overlaps_some_window (&rect, sorted))
+	    {
+	      *new_x = rect.x;
+	      *new_y = rect.y;
+	      if (fgeom)
+		{
+		  *new_x += fgeom->left_width;
+		  *new_y += fgeom->top_height;
+		}
+	      
+	      retval = TRUE;
 
-          goto out;
-        }
+	      goto out;
+	    }
+	}
       
       tmp = tmp->next;
     }
@@ -530,29 +544,32 @@ find_first_fit (MetaWindow *window,
   while (tmp != NULL)
     {
       MetaWindow *w = tmp->data;
-      MetaRectangle outer_rect;
-      
-      meta_window_get_outer_rect (w, &outer_rect);
 
-      rect.x = outer_rect.x + outer_rect.width;
-      rect.y = outer_rect.y;
+      if (META_WINDOW_DOCK != w->type)
+	{
+	  MetaRectangle outer_rect;
       
-      if (fit_rect_in_xinerama (window->screen, &rect) &&
-          !rectangle_overlaps_some_window (&rect, sorted))
-        {
-          *new_x = rect.x;
-          *new_y = rect.y;
-          if (fgeom)
-            {
-              *new_x += fgeom->left_width;
-              *new_y += fgeom->top_height;
-            }
-
-          retval = TRUE;
+	  meta_window_get_outer_rect (w, &outer_rect);
 
-          goto out;
-        }      
+	  rect.x = outer_rect.x + outer_rect.width;
+	  rect.y = outer_rect.y;
       
+	  if (fit_rect_in_xinerama (window, &rect) &&
+	      !rectangle_overlaps_some_window (&rect, sorted))
+	    {
+	      *new_x = rect.x;
+	      *new_y = rect.y;
+	      if (fgeom)
+		{
+		  *new_x += fgeom->left_width;
+		  *new_y += fgeom->top_height;
+		}
+
+	      retval = TRUE;
+
+	      goto out;
+	    }      
+	}
       tmp = tmp->next;
     }  
 
@@ -560,10 +577,14 @@ find_first_fit (MetaWindow *window,
   i = 1;
   while (i < window->screen->n_xinerama_infos)
     {
-      rect.x = window->screen->xinerama_infos[i].x_origin;
-      rect.y = window->screen->xinerama_infos[i].y_origin;
+
+      meta_window_get_work_area_for_xinerama(window, TRUE, i, &work_area);
+      fluff = (work_area.width % rect.width) / 2;
+      rect.x = work_area.x + fluff;
+      fluff = (work_area.height % rect.height) / 4;
+      rect.y = work_area.y + fluff;
       
-      if (fit_rect_in_xinerama (window->screen, &rect) &&
+      if (fit_rect_in_xinerama (window, &rect) &&
           !rectangle_overlaps_some_window (&rect, windows))
         {
           *new_x = rect.x;
@@ -609,10 +630,11 @@ constrain_placement (MetaWindow        *
    * for the window based on its position, but we haven't
    * placed it yet.
    */
-  meta_window_get_work_area (window, TRUE, &work_area);
+  meta_window_get_work_area_for_xinerama (window, TRUE, 0, &work_area);
 
   nw_x = work_area.x;
   nw_y = work_area.y;
+
   if (window->frame)
     {
       nw_x += fgeom->left_width;
Index: screen.c
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.c,v
retrieving revision 1.98
diff -u -p -r1.98 screen.c
--- screen.c	8 Jan 2003 04:23:18 -0000	1.98
+++ screen.c	12 Jan 2003 05:53:07 -0000
@@ -1261,6 +1261,32 @@ meta_screen_get_xinerama_for_window (Met
   return &screen->xinerama_infos[best_xinerama];
 }
 
+gboolean
+meta_screen_window_on_xinerama (MetaScreen *screen,
+				MetaWindow *window,
+				gint which_xinerama)
+{
+  MetaRectangle window_rect;
+  MetaRectangle dest, screen_info;
+  
+  meta_window_get_outer_rect (window, &window_rect);
+  
+  screen_info.x = screen->xinerama_infos[which_xinerama].x_origin;
+  screen_info.y = screen->xinerama_infos[which_xinerama].y_origin;
+  screen_info.width = screen->xinerama_infos[which_xinerama].width;
+  screen_info.height = screen->xinerama_infos[which_xinerama].height;
+  
+  if (meta_rectangle_intersect (&screen_info, &window_rect, &dest))
+    {
+      if (dest.width * dest.height > 0)
+	{
+	  return TRUE;
+	}
+    }
+
+  return FALSE;
+}
+
 const MetaXineramaScreenInfo*
 meta_screen_get_current_xinerama (MetaScreen *screen)
 {
@@ -1532,7 +1558,7 @@ set_work_area_hint (MetaScreen *screen)
 
       if (workspace->screen == screen)
         {
-          meta_workspace_get_work_area (workspace, &area);
+          meta_workspace_get_work_area (workspace, &area, -1);
           tmp[0] = area.x;
           tmp[1] = area.y;
           tmp[2] = area.width;
Index: screen.h
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.h,v
retrieving revision 1.44
diff -u -p -r1.44 screen.h
--- screen.h	5 Jan 2003 18:36:01 -0000	1.44
+++ screen.h	12 Jan 2003 05:53:07 -0000
@@ -130,6 +130,9 @@ void          meta_screen_focus_top_wind
 const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
 const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
 								   MetaWindow *window);
+gboolean meta_screen_window_on_xinerama (MetaScreen *screen, 
+					 MetaWindow *window,
+					 gint which_xinerama);
 
 void          meta_screen_update_workspace_layout (MetaScreen             *screen);
 void          meta_screen_update_workspace_names  (MetaScreen             *screen);
