Index: ChangeLog
===================================================================
RCS file: /export/cvs/gnome-2.0/libwnck/ChangeLog,v
retrieving revision 1.223
diff -p -u -5 -r1.223 ChangeLog
--- ChangeLog	2004/01/03 12:12:11	1.223
+++ ChangeLog	2004/01/05 13:53:46
@@ -1,5 +1,16 @@
+2004-01-05  Leena Gunda  <leena.gunda@wipro.com>
+
+	* libwnck/window-action-menu.c:
+	(wnck_create_window_action_menu): added the "Move to Workspace" 
+	submenu to the actions menu.
+	(get_workspace_name_with_accel): get workspace name with accel.
+	taken from metacity sources.
+	(item_activated_callback): implemented code to move the window to
+	specified workspace for MOVE_TO_WORKSPACE window action.
+	Fixes bug #96087.
+
 2004-01-03  Robert Sedak  <robert.sedak@sk.htnet.hr>
 
         * configure.in: Added "hr" in ALL_LINGUAS.
 
 2004-01-02  Padraig O'Briain  <padraigobriain@sun.com>
Index: libwnck/window-action-menu.c
===================================================================
RCS file: /export/cvs/gnome-2.0/libwnck/libwnck/window-action-menu.c,v
retrieving revision 1.10
diff -p -u -5 -r1.10 window-action-menu.c
--- libwnck/window-action-menu.c	2003/10/06 05:23:50	1.10
+++ libwnck/window-action-menu.c	2004/01/05 13:56:09
@@ -17,10 +17,13 @@
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
+#include <string.h>
+#include <stdio.h>
+
 #include "window-action-menu.h"
 #include "private.h"
 
 typedef enum
 {
@@ -28,11 +31,12 @@ typedef enum
   MINIMIZE,
   MAXIMIZE,
   SHADE,
   MOVE,
   RESIZE,
-  PIN
+  PIN,
+  MOVE_TO_WORKSPACE
 } WindowAction;
 
 typedef struct _ActionMenuData ActionMenuData;
 
 struct _ActionMenuData
@@ -44,10 +48,11 @@ struct _ActionMenuData
   GtkWidget *shade_item;
   GtkWidget *move_item;
   GtkWidget *resize_item;
   GtkWidget *close_item;
   GtkWidget *pin_item;
+  GtkWidget *workspace_item;
   guint idle_handler;
 };
 
 static void object_weak_notify (gpointer data,
                                 GObject *obj);
@@ -135,10 +140,20 @@ item_activated_callback (GtkWidget *menu
       if (wnck_window_is_pinned (amd->window))
         wnck_window_unpin (amd->window);
       else
         wnck_window_pin (amd->window);
       break;
+    case MOVE_TO_WORKSPACE: {
+        int workspace_index;
+
+        workspace_index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "workspace"));
+
+        wnck_window_move_to_workspace (amd->window,
+                                       wnck_screen_get_workspace (
+                                       wnck_window_get_screen (amd->window),
+                                       workspace_index));
+       }
     }
 }
 
 static void
 set_item_text (GtkWidget  *mi,
@@ -252,10 +267,14 @@ update_menu_state (ActionMenuData *amd)
   gtk_widget_set_sensitive (amd->move_item,
                             (actions & WNCK_WINDOW_ACTION_MOVE) != 0);
 
   gtk_widget_set_sensitive (amd->resize_item,
                             (actions & WNCK_WINDOW_ACTION_RESIZE) != 0);
+
+  gtk_widget_set_sensitive (amd->workspace_item,
+                            (actions & WNCK_WINDOW_ACTION_CHANGE_WORKSPACE) != 0);
+
   
   return FALSE;
 }
 
 static void
@@ -319,10 +338,89 @@ amd_free (ActionMenuData *amd)
     g_source_remove (amd->idle_handler);
 
   g_free (amd);
 }
 
+static char *
+get_workspace_name_with_accel (WnckWindow *window,
+			       int index)
+{
+  const char *name;
+  int number;
+ 
+  name = wnck_workspace_get_name (wnck_screen_get_workspace (
+				  wnck_window_get_screen (window),
+				  index));
+
+  g_assert (name != NULL);
+
+  /*
+   * If the name is of the form "Workspace x" where x is an unsigned
+   * integer, insert a '_' before the number if it is less than 10 and
+   * return it
+   */
+  number = 0;
+
+  if (sscanf (name, _("Workspace %d"), &number) == 1)
+    {
+      char *new_name;
+
+      /*
+       * Above name is a pointer into the Workspace struct. Here we make
+       * a copy copy so we can have our wicked way with it.
+       */
+      if (number == 10)
+        new_name = g_strdup_printf (_("Workspace 1_0"));
+      else
+        new_name = g_strdup_printf (_("Workspace %s%d"),
+                                    number < 10 ? "_" : "",
+                                    number);
+      return new_name;
+    }
+  else
+    {
+      /*
+       * Otherwise this is just a normal name. Escape any _ characters so that
+       * the user's workspace names do not get mangled.  If the number is less
+       * than 10 we provide an accelerator.
+       */
+      char *new_name;
+      const char *source;
+      char *dest;
+
+      /*
+       * Assume the worst case, that every character is a _.  We also
+       * provide memory for " (_#)"
+       */
+      new_name = g_malloc0 (strlen (name) * 2 + 6 + 1);
+
+      /*
+       * Now iterate down the strings, adding '_' to escape as we go
+       */
+      dest = new_name;
+      source = name;
+      while (*source != '\0')
+        {
+          if (*source == '_')
+            *dest++ = '_';
+          *dest++ = *source++;
+        }
+
+      /* People don't start at workstation 0, but workstation 1 */
+      if (index < 9)
+        {
+          g_snprintf (dest, 6, " (_%d)", index + 1);
+        }
+      else if (index == 9)
+        {
+          g_snprintf (dest, 6, " (_0)");
+        }
+
+      return new_name;
+    }
+}
+
 /**
  * wnck_create_window_action_menu:
  * @window: a #WnckWindow
  * 
  * Creates a menu of window operations for @window.
@@ -330,14 +428,15 @@ amd_free (ActionMenuData *amd)
  * Return value: a new menu of window operations
  **/
 GtkWidget*
 wnck_create_window_action_menu (WnckWindow *window)
 {
-  GtkWidget *menu;
+  GtkWidget *menu, *submenu;
   ActionMenuData *amd;
   GtkWidget *separator;
-  
+  int num_workspaces, present_workspace, i;
+ 
   _wnck_stock_icons_init ();
   
   amd = g_new0 (ActionMenuData, 1);
   amd->window = window;
   
@@ -403,10 +502,43 @@ wnck_create_window_action_menu (WnckWind
   amd->pin_item = make_menu_item (amd, PIN);
   gtk_menu_shell_append (GTK_MENU_SHELL (menu),
                          amd->pin_item);
   set_item_stock (amd->pin_item, NULL);
   
+  amd->workspace_item = gtk_menu_item_new_with_mnemonic (_("Move to Another _Workspace")); 
+  gtk_widget_show (amd->workspace_item);
+
+  submenu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (amd->workspace_item), 
+			     submenu);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+                         amd->workspace_item);
+
+  num_workspaces = wnck_screen_get_workspace_count (wnck_window_get_screen (
+						    amd->window));
+  present_workspace = wnck_workspace_get_number (wnck_window_get_workspace (
+						 amd->window));
+ 
+  for (i = 0; i < num_workspaces; i++) {
+    char *name,*label;
+    GtkWidget *mi;
+	
+    name = get_workspace_name_with_accel (amd->window,i);
+    label = g_strdup_printf (_("%s"), name);
+
+    mi = make_menu_item (amd, MOVE_TO_WORKSPACE);
+    g_object_set_data (G_OBJECT (mi), "workspace", GINT_TO_POINTER (i));
+
+    if (i == present_workspace)
+	gtk_widget_set_sensitive (mi, FALSE);
+
+    gtk_menu_shell_append (GTK_MENU_SHELL (submenu), mi);
+    set_item_text (mi, label);
+    set_item_stock (mi, NULL);
+  }	
+		 
   g_signal_connect_object (G_OBJECT (amd->window), 
                            "state_changed",
                            G_CALLBACK (state_changed_callback),
                            G_OBJECT (menu),
                            0);
