diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index a05f8bd5104aba9179035d8f7edd54d7f8de5aea..d27f6a26911ea5a4de7d14007b0d85f2411a139f 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2170,13 +2170,57 @@ function gui_draw_coords(cid, tag, shape, points) {
     }
 }
 
+var gui_draw_drag_event = (function() {
+    var last_mousedown,
+        last_mouseup,
+        last_mousemove;
+    return function gui_draw_drag_event(cid, tag, scalar_sym,
+        drawcommand_sym, event_name, state) {
+        var last_x,
+            last_y,
+            item = get_item(cid, tag),
+            doc = patchwin[cid].window.document,
+            mousemove = function(e) {
+                var new_x = e.pageX,
+                    new_y = e.pageY;
+                pdsend(cid, "scalar_event", scalar_sym, drawcommand_sym,
+                    event_name, new_x - last_x, new_y - last_y);
+                last_x = new_x;
+                last_y = new_y;
+            },
+            mousedown = function(e) {
+                if (e.target === item) {
+                    last_x = e.pageX;
+                    last_y = e.pageY;
+                    doc.addEventListener("mousemove", mousemove, false);
+                }
+            },
+            mouseup = function(e) {
+                doc.removeEventListener("mousemove", mousemove, false);
+            }
+        ;
+        // Go ahead and remove any event listeners
+        doc.removeEventListener("mousedown", last_mousedown, false);
+        doc.removeEventListener("mouseup", last_mouseup, false);
+        doc.removeEventListener("mousemove", last_mousemove, false);
+
+        // Set mousedown and mouseup events to create our "drag" event
+        if (state === 1) {
+            doc.addEventListener("mousedown", mousedown, false);
+            doc.addEventListener("mouseup", mouseup, false);
+            last_mousemove = mousemove;
+            last_mouseup = mouseup;
+            last_mousedown = mousedown;
+        }
+    }
+}());
+
 function gui_draw_event(cid, tag, scalar_sym, drawcommand_sym, event_name,
     state) {
     var item = get_item(cid, tag),
         event_type = "on" + event_name; 
     if (state === 1) {
         item[event_type] = function(e) {
-//            gui_post("Entered! Tag is " + tag);
             pdsend(cid, "scalar_event", scalar_sym, drawcommand_sym, event_name,
                 e.pageX, e.pageY);
         };
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index d5b93ffd0220f164478e33f437bbd23b1b92394b..d881b906c0090374d324f5cf6810e6aa0f3507c0 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -733,7 +733,11 @@ void draw_notify(t_canvas *x, t_symbol *s, int argc, t_atom *argv);
 
 void canvas_scalar_event(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
 {
-    draw_notify(x, s, argc, argv);
+    /* These events only get sent when we're not in edit mode.  Once
+       we get editmode status sync'd in the GUI we can just prevent
+       sending any messages when in edit mode. */
+    if (!x->gl_edit)
+        draw_notify(x, s, argc, argv);
 }
 
 extern void canvas_check_nlet_highlights(t_canvas *x);
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index aec7ed311bb65479f113310a487656c43584181a..0ecb62ea59baad3588f2d33b9d36ef5d81e0b544 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -1095,7 +1095,8 @@ typedef struct _svg_event
                e_mouseup,
                e_mouseover,
                e_mousemove,
-               e_mouseout;
+               e_mouseout,
+               e_drag; /* not in the svg spec, but should have been */
 } t_svg_event;
 
 /* svg attributes */
@@ -1366,6 +1367,8 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv)
     x->x_events.e_mousemove.a_flag = 0;
     fielddesc_setfloat_const(&x->x_events.e_mouseout.a_attr, 0);
     x->x_events.e_mouseout.a_flag = 0;
+    fielddesc_setfloat_const(&x->x_events.e_drag.a_attr, 0);
+    x->x_events.e_drag.a_flag = 0;
 
     char buf[50];
     // Here we bind the parent object to the addy for
@@ -1710,6 +1713,13 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
             (int)fielddesc_getcoord(
                 &x->x_events.e_mousedown.a_attr, template, data, 1));
     }
+    else if (s == gensym("drag"))
+    {
+        gui_vmess("gui_draw_drag_event", "xsxxsi",
+            glist_getcanvas(c), tag, sc, x, "drag",
+            (int)fielddesc_getcoord(
+                &x->x_events.e_drag.a_attr, template, data, 1));
+    }
     else if (s == gensym("vis"))
     {
         gui_vmess("gui_draw_configure", "xsss",
@@ -1980,16 +1990,21 @@ void svg_register_events(t_gobj *z, t_canvas *c, t_scalar *sc,
             glist_getcanvas(c), tagbuf, sc, svg, "mousemove",
             (int)fielddesc_getcoord(&svg->x_events.e_mousemove.a_attr, template,
             data, 1));
-    if (svg->x_events.e_mousemove.a_flag)
+    if (svg->x_events.e_mousedown.a_flag)
         gui_vmess("gui_draw_event", "xsxxsi",
-            glist_getcanvas(c), tagbuf, sc, svg, "mousemove",
-            (int)fielddesc_getcoord(&svg->x_events.e_mousemove.a_attr, template,
+            glist_getcanvas(c), tagbuf, sc, svg, "mousedown",
+            (int)fielddesc_getcoord(&svg->x_events.e_mousedown.a_attr, template,
             data, 1));
     if (svg->x_events.e_mouseup.a_flag)
         gui_vmess("gui_draw_event", "xsxxsi",
             glist_getcanvas(c), tagbuf, sc, svg, "mouseup",
             (int)fielddesc_getcoord(&svg->x_events.e_mouseup.a_attr, template,
             data, 1));
+    if (svg->x_events.e_drag.a_flag)
+        gui_vmess("gui_draw_drag_event", "xsxxsi",
+            glist_getcanvas(c), tagbuf, sc, svg, "drag",
+            (int)fielddesc_getcoord(&svg->x_events.e_drag.a_attr, template,
+            data, 1));
 }
 
 void svg_setattr(t_svg *x, t_symbol *s, t_int argc, t_atom *argv)
@@ -2255,6 +2270,11 @@ void svg_event(t_svg *x, t_symbol *s, int argc, t_atom *argv)
             fielddesc_setfloatarg(&x->x_events.e_mouseout.a_attr, argc, argv);
             x->x_events.e_mouseout.a_flag = 1;
         }
+        else if (s == gensym("drag"))
+        {
+            fielddesc_setfloatarg(&x->x_events.e_drag.a_attr, argc, argv);
+            x->x_events.e_drag.a_flag = 1;
+        }
         svg_update(x, s);
     }
 }
@@ -4316,7 +4336,9 @@ static void draw_setup(void)
         gensym("cy"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_data,
         gensym("data"), A_GIMME, 0);
-    class_addmethod(svg_class, (t_method)svg_drag,
+//    class_addmethod(svg_class, (t_method)svg_drag,
+//        gensym("drag"), A_GIMME, 0);
+    class_addmethod(svg_class, (t_method)svg_event,
         gensym("drag"), A_GIMME, 0);
     class_addmethod(svg_class, (t_method)svg_fill,
         gensym("fill"), A_GIMME, 0);