Index: ChangeLog
===================================================================
RCS file: /export/cvs/head/gtk+/ChangeLog,v
retrieving revision 1.6777
diff -p -u -5 -r1.6777 ChangeLog
--- ChangeLog	28 Jun 2005 06:25:17 -0000	1.6777
+++ ChangeLog	7 Jul 2005 05:12:00 -0000
@@ -1,5 +1,13 @@
+2005-07-07  Leena Gunda  <leena.gunda@wipro.com>
+
+	* gtk/gtkwindow.c (gtk_window_constrain_position):
+	Constrain the popup window within the workarea if a11y 
+	is enabled.
+	(get_atom_net_workarea): Get atom _NET_WORKAREA.
+	Fixes bug #161972.
+
 2005-06-28  Matthias Clasen  <mclasen@redhat.com>
 
 	* gtk/gtkiconview.c (gtk_icon_view_calculate_item_size2): 
 	Make sure that cell boxes are always completely inside
 	the item area. 
Index: gtk/gtkwindow.c
===================================================================
RCS file: /export/cvs/head/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.294
diff -p -u -5 -r1.294 gtkwindow.c
--- gtk/gtkwindow.c	20 Jun 2005 18:19:33 -0000	1.294
+++ gtk/gtkwindow.c	7 Jul 2005 05:12:00 -0000
@@ -42,10 +42,11 @@
 #include "gtkicontheme.h"
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtkplug.h"
 #include "gtkalias.h"
+#include "gtkaccessible.h"
 
 #ifdef GDK_WINDOWING_X11
 #include "x11/gdkx.h"
 #endif
 
@@ -245,12 +246,12 @@ static void     gtk_window_constrain_siz
                                                       gint          width,
                                                       gint          height,
                                                       gint         *new_width,
                                                       gint         *new_height);
 static void     gtk_window_constrain_position        (GtkWindow    *window,
-                                                      gint          new_width,
-                                                      gint          new_height,
+                                                      gint         *new_width,
+                                                      gint         *new_height,
                                                       gint         *x,
                                                       gint         *y);
 static void     gtk_window_compute_hints             (GtkWindow    *window,
                                                       GdkGeometry  *new_geometry,
                                                       guint        *new_flags);
@@ -3578,12 +3579,12 @@ gtk_window_move (GtkWindow *window,
        * what position the user set before then.
        * i.e. if you do a move() then turn off POS_CENTER
        * then show the window, your move() will work.
        */
       gtk_window_constrain_position (window,
-                                     widget->allocation.width,
-                                     widget->allocation.height,
+                                     &widget->allocation.width,
+                                     &widget->allocation.height,
                                      &x, &y);
       
       /* Note that this request doesn't go through our standard request
        * framework, e.g. doesn't increment configure_request_count,
        * doesn't set info->last, etc.; that's because
@@ -5225,11 +5226,11 @@ gtk_window_compute_configure_request (Gt
   if (window->need_default_position &&
       info->initial_pos_set)
     {
       x = info->initial_x;
       y = info->initial_y;
-      gtk_window_constrain_position (window, w, h, &x, &y);
+      gtk_window_constrain_position (window, &w, &h, &x, &y);
     }
   
   request->x = x;
   request->y = y;
   request->width = w;
@@ -5239,29 +5240,117 @@ gtk_window_compute_configure_request (Gt
     *geometry = new_geometry;
   if (flags)
     *flags = new_flags;
 }
 
+static gboolean
+get_atom_net_workarea (gint *x,
+                       gint *y,
+                       gint *width,
+                       gint *height)
+{
+  gboolean result;
+  GdkAtom net_workarea;
+  GdkAtom return_type;
+  gint format;
+  gint length;
+  unsigned char *data;
+  gint *area;
+
+  net_workarea = gdk_atom_intern ("_NET_WORKAREA", TRUE);
+
+  if (net_workarea == GDK_NONE)
+      return FALSE;
+
+  result = gdk_property_get (NULL, net_workarea, GDK_NONE, 0, 4 * 32, FALSE,
+                             &return_type, &format, &length, &data);
+
+  if (!result || !data)
+    return FALSE;
+
+  area = (gint *) data;
+
+  *x = area[0];
+  *y = area[1];
+  *width = area[2];
+  *height = area[3];
+
+  return TRUE;
+}
+
 static void
 gtk_window_constrain_position (GtkWindow    *window,
-                               gint          new_width,
-                               gint          new_height,
+                               gint         *new_width,
+                               gint         *new_height,
                                gint         *x,
                                gint         *y)
 {
   /* See long comments in gtk_window_move_resize()
    * on when it's safe to call this function.
    */
   if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
     {
       gint center_x, center_y;
 
-      center_window_on_monitor (window, new_width, new_height, &center_x, &center_y);
+      center_window_on_monitor (window, *new_width, *new_height, &center_x, &center_y);
       
       *x = center_x;
       *y = center_y;
     }
+
+  if (window->type == GTK_WINDOW_POPUP &&
+      GTK_IS_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (window))))
+    {
+      gint workarea_x, workarea_y, workarea_width, workarea_height;
+
+      if (get_atom_net_workarea (&workarea_x, &workarea_y, &workarea_width, &workarea_height))
+        {
+          if (*x < workarea_x)
+            *x = workarea_x;
+
+          if (*y < workarea_y)
+            *y = workarea_y;
+
+          if ((*x + *new_width) > workarea_width)
+            {
+              gint delta_x;
+
+              delta_x = *x + *new_width - workarea_x - workarea_width;
+              *x -=  delta_x;
+
+              if (*x < workarea_x)
+                *x = workarea_x;
+            }
+
+          if ((*y + *new_height) > workarea_height)
+            {
+              gint delta_y;
+
+              delta_y = *y + *new_height - workarea_y - workarea_height;
+              *y -= delta_y;
+
+              if (*y < workarea_y)
+                *y = workarea_y;
+            }
+
+          if ((*x + *new_width) > workarea_width)
+            {
+              gint delta_w;
+
+              delta_w = *x + *new_width - workarea_x - workarea_width;
+              *new_width -= delta_w;
+            }
+
+          if ((*y + *new_height) > workarea_height)
+            {
+              gint delta_h;
+
+              delta_h = *y + *new_height - workarea_y - workarea_height;
+              *new_height -= delta_h;
+            }
+        }
+    }
 }
 
 static void
 gtk_window_move_resize (GtkWindow *window)
 {
@@ -5389,12 +5478,12 @@ gtk_window_move_resize (GtkWindow *windo
        *  - we're changing the size anyway
        *  - set_position() was called to toggle CENTER_ALWAYS on
        */
 
       gtk_window_constrain_position (window,
-                                     new_request.width,
-                                     new_request.height,
+                                     &new_request.width,
+                                     &new_request.height,
                                      &new_request.x,
                                      &new_request.y);
       
       /* Update whether we need to request a move */
       if (info->last.configure_request.x != new_request.x ||
