Index: src/dragdrop.js
===================================================================
--- src/dragdrop.js	(revision 4380)
+++ src/dragdrop.js	(working copy)
@@ -147,6 +147,9 @@
   activate: function(draggable) {
     window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
     this.activeDraggable = draggable;
+	 if (draggable.options.delay)
+		 this.deactivateDelay();
+	 this.notify('onActivate', draggable);
   },
   
   deactivate: function() {
@@ -156,6 +159,12 @@
   updateDrag: function(event) {
     if(!this.activeDraggable) return;
     var pointer = [Event.pointerX(event), Event.pointerY(event)];
+    if(this.activeDraggable.options.ignorePositionX) {
+       pointer[0] = this.activeDraggable._cachedPositionX = this.activeDraggable._cachedPositionX ? this.activeDraggable._cachedPositionX : Position.cumulativeOffset(this.activeDraggable.element)[0];
+    }
+    else if(this.activeDraggable.options.ignorePositionY) {
+       pointer[1] = this.activeDraggable._cachedPositionY = this.activeDraggable._cachedPositionY ? this.activeDraggable._cachedPositionY : Position.cumulativeOffset(this.activeDraggable.element)[1];
+    }
     // Mozilla-based browsers fire successive mousemove events with
     // the same coordinates, prevent needless redrawing (moz bug?)
     if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
@@ -185,15 +194,25 @@
     this._cacheObserverCallbacks();
   },
   
-  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
+  notify: function(eventName, draggable, event) {  // 'onActivate, 'onStart', 'onEnd', 'onDrag'
     if(this[eventName+'Count'] > 0)
       this.observers.each( function(o) {
         if(o[eventName]) o[eventName](eventName, draggable, event);
       });
+  },  
+  
+  deactivateDelay: function() {
+	 if (this.delayInterval) this.delayInterval = window.clearInterval( this.delayInterval );
+	 
+	 if (this.initDraggable) {
+		 Event.stopObserving( this.initDraggable.element.id, "mouseout", this.eventDeactivateDelay );
+		 Event.stopObserving( document, "mouseup", Draggables.eventDeactivateDelay );
+		 this.initDraggable = null;
+	 }
   },
   
   _cacheObserverCallbacks: function() {
-    ['onStart','onEnd','onDrag'].each( function(eventName) {
+    ['onActivate','onStart','onEnd','onDrag'].each( function(eventName) {
       Draggables[eventName+'Count'] = Draggables.observers.select(
         function(o) { return o[eventName]; }
       ).length;
@@ -282,8 +301,19 @@
       var pointer = [Event.pointerX(event), Event.pointerY(event)];
       var pos     = Position.cumulativeOffset(this.element);
       this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
-      
-      Draggables.activate(this);
+      // start a timer if they want a delay for mousedown
+		if (this.options.delay) {
+			Draggables.initDraggable = this;
+			Draggables.delayInterval = window.setTimeout( Draggables.activate.bind( Draggables, this ), this.options.delay );
+			
+			Draggables.eventDeactivateDelay = Draggables.deactivateDelay.bindAsEventListener(Draggables);
+			
+			Event.observe(document, "mouseup", Draggables.eventDeactivateDelay);
+			Event.observe(this.element.id, "mouseout", Draggables.eventDeactivateDelay);
+		}
+		else { 
+         Draggables.activate(this);
+      }
       Event.stop(event);
     }
   },
@@ -604,7 +634,15 @@
 
     if(options.zindex)
       options_for_draggable.zindex = options.zindex;
+  
+    if(options.delay)
+      options_for_draggable.delay = options.delay;
 
+    if (options.ignorePositionX)
+      options_for_draggable.ignorePositionX = options.ignorePositionX;
+    else if (options.ignorePositionY)
+      options_for_draggable.ignorePositionY = options.ignorePositionY;
+   
     // build options for the droppables  
     var options_for_droppable = {
       overlap:     options.overlap,
