? libwnck/wnck-tasklist.diff
Index: libwnck/tasklist.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/tasklist.c,v
retrieving revision 1.109
diff -u -p -r1.109 tasklist.c
--- libwnck/tasklist.c	2 Dec 2006 11:47:25 -0000	1.109
+++ libwnck/tasklist.c	28 Dec 2006 22:37:32 -0000
@@ -3007,6 +3007,7 @@ wnck_task_drag_leave (GtkWidget         
       g_source_remove (task->button_activate);
       task->button_activate = 0;
     }
+    gtk_drag_unhighlight (widget);
 }
 
 static gboolean
@@ -3017,13 +3018,21 @@ wnck_task_drag_motion (GtkWidget        
 		       guint               time,
 		       WnckTask            *task)
 {
-  task->dnd_timestamp = time;
-  if (task->button_activate == 0 && task->type == WNCK_TASK_WINDOW)
-      task->button_activate = g_timeout_add (WNCK_ACTIVATE_TIMEOUT,
-                                             wnck_task_motion_timeout,
-                                             task);
-  gdk_drag_status (context,0,time);
-
+  if (gtk_drag_dest_find_target (widget, context, NULL))
+    {
+       gtk_drag_highlight (widget);
+       gdk_drag_status (context, context->suggested_action, time);
+    }
+  else
+    {
+       task->dnd_timestamp = time;
+ 
+       if (task->button_activate == 0 && task->type == WNCK_TASK_WINDOW)
+           task->button_activate = g_timeout_add (WNCK_ACTIVATE_TIMEOUT,
+                                                  wnck_task_motion_timeout,
+                                                  task);
+       gdk_drag_status (context, 0, time);
+    }
   return TRUE;
 }
 
@@ -3051,6 +3060,69 @@ wnck_task_drag_data_get (GtkWidget      
 			  8, (guchar *)&xid, sizeof (gulong));
 }
 
+void  
+wnck_task_drag_data_received (GtkWidget          *widget,
+			    GdkDragContext     *context,
+ 			    gint                x,
+ 			    gint                y,
+ 			    GtkSelectionData   *data,
+ 			    guint               info,
+ 			    guint               time,
+ 			    WnckTask           *target_task)
+{
+  WnckTasklist *tasklist = target_task->tasklist;
+ 
+  if ((data->length == sizeof (gulong)) && (data->format == 8))
+    {
+       GList *l, *windows;
+       WnckWindow *window;
+       gulong *xid = (gulong *)data->data;
+       guint new_order, old_order, order;
+       WnckWindow *found_window = NULL;
+
+       windows = wnck_screen_get_windows (tasklist->priv->screen);
+       for (l = windows; l; l = l->next)
+         {
+	     window = WNCK_WINDOW (l->data);
+    	     if (wnck_window_get_xid (window) == *xid) 
+              {
+ 	          old_order = wnck_window_get_sort_order (window);
+                 new_order = wnck_window_get_sort_order (target_task->window); 
+ 	          if (old_order < new_order) 
+ 	   	    new_order++;
+	          found_window = window;
+ 	          break;
+ 	       }
+         }
+ 
+       if (found_window) 
+         {	
+            for (l = windows; l; l = l->next)
+              {
+  	          window = WNCK_WINDOW (l->data);
+ 	          order = wnck_window_get_sort_order (window);
+ 	          if (order >= new_order)
+ 		  wnck_window_set_sort_order (window, order + 1);
+ 	       } 
+            wnck_window_set_sort_order (found_window, new_order);
+ 	   
+ 	     if (!tasklist->priv->include_all_workspaces)
+ 	       {
+ 	          WnckWorkspace *active_space;
+ 	          active_space = wnck_screen_get_active_workspace (tasklist->priv->screen);
+                 wnck_window_move_to_workspace (found_window, active_space);
+ 	       }
+ 
+ 	     gtk_widget_queue_resize (GTK_WIDGET (tasklist));
+ 	  }
+ 
+         gtk_drag_finish (context, TRUE, FALSE, time); 
+         return;
+    }   
+  gtk_drag_finish (context, FALSE, FALSE, time);
+}
+ 
+
 static gboolean
 wnck_task_button_press_event (GtkWidget	      *widget,
 			      GdkEventButton  *event,
@@ -3151,15 +3223,16 @@ wnck_task_create_widgets (WnckTask *task
   gtk_widget_set_name (task->button,
 		       "tasklist-button");
 
-  gtk_drag_dest_set (GTK_WIDGET(task->button), 0, NULL, 0, 0);
-
   if (task->type == WNCK_TASK_WINDOW)
     {
-      gtk_drag_source_set (GTK_WIDGET (task->button),
-		           GDK_BUTTON1_MASK,
-		           targets, 1,
-		           GDK_ACTION_MOVE);
+      gtk_drag_source_set (GTK_WIDGET (task->button),
+   		            GDK_BUTTON1_MASK,
+ 		            targets, 1,
+ 		            GDK_ACTION_MOVE);
+      gtk_drag_dest_set (GTK_WIDGET(task->button), GTK_DEST_DEFAULT_DROP, targets, 1, GDK_ACTION_MOVE);
     }
+  else
+    gtk_drag_dest_set (GTK_WIDGET(task->button), 0, NULL, 0, GDK_ACTION_DEFAULT);
 
   hbox = gtk_hbox_new (FALSE, 0);
 
@@ -3217,6 +3290,20 @@ wnck_task_create_widgets (WnckTask *task
                            G_CALLBACK (wnck_task_drag_motion),
                            G_OBJECT (task),
                            0); 
+
+  if (task->type == WNCK_TASK_WINDOW) 
+    {
+      g_signal_connect_object (G_OBJECT(task->button), "drag_data_get",
+                               G_CALLBACK (wnck_task_drag_data_get),
+                               G_OBJECT (task),
+                               0); 
+
+      g_signal_connect_object (G_OBJECT(task->button), "drag_data_received",
+                               G_CALLBACK (wnck_task_drag_data_received),
+                               G_OBJECT (task),
+                               0); 
+
+    }
 
   g_signal_connect_object (G_OBJECT(task->button), "drag_leave",
                            G_CALLBACK (wnck_task_drag_leave),
Index: libwnck/window.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/window.c,v
retrieving revision 1.71
diff -u -p -r1.71 window.c
--- libwnck/window.c	2 Dec 2006 11:47:25 -0000	1.71
+++ libwnck/window.c	28 Dec 2006 22:37:35 -0000
@@ -646,7 +646,7 @@ wnck_window_get_pid (WnckWindow *window)
  * @window: a #WnckWindow
  *
  * Gets the sort order of @window; used for ordering of the window in
- * the tasklist.  This is defined when the window is created.
+ * the tasklist. 
  *
  * Return value: sort order of @window, or G_MAXINT if none available
  **/
@@ -656,6 +656,24 @@ wnck_window_get_sort_order (WnckWindow *
   g_return_val_if_fail (WNCK_IS_WINDOW (window), G_MAXINT);
 
   return window->priv->sort_order;
+}
+
+/**
+ * wnck_window_set_sort_order:
+ * @window: a #WnckWindow
+ * @order: new order
+ *
+ * Sets the sort order of @window; used for ordering of the window in
+ * the tasklist. 
+ *
+ **/
+void        wnck_window_set_sort_order        (WnckWindow *window, 
+					       gint order)
+{ 
+  g_return_if_fail (WNCK_IS_WINDOW (window));
+  
+  window->priv->sort_order = order;
+  return;
 }
 
 /**
Index: libwnck/window.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/window.h,v
retrieving revision 1.38
diff -u -p -r1.38 window.h
--- libwnck/window.h	20 Jul 2006 17:45:44 -0000	1.38
+++ libwnck/window.h	28 Dec 2006 22:37:35 -0000
@@ -173,6 +173,8 @@ const char* wnck_window_get_session_id  
 const char* wnck_window_get_session_id_utf8   (WnckWindow *window);
 int         wnck_window_get_pid               (WnckWindow *window);
 gint        wnck_window_get_sort_order        (WnckWindow *window);
+void        wnck_window_set_sort_order        (WnckWindow *window, 
+						gint order);
 
 WnckWindowType wnck_window_get_window_type    (WnckWindow *window);
 void           wnck_window_set_window_type    (WnckWindow *window,
