diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index fde6149189e12d1885b851cff6c73aa902f316a7..6152c5f1972ad78425deae6e8a3acff2bd1b0041 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -803,7 +803,7 @@ void canvas_map(t_canvas *x, t_floatarg f)
         canvas_drawlines(x);
         if (x->gl_isgraph && x->gl_goprect)
             canvas_drawredrect(x, 1);
-        sys_vgui("pdtk_canvas_force_getscroll .x%lx.c\n", x);
+        sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
         //}
     }
     else
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 8958bd4ca185833f00c042ab97134021d8deba74..1315e166d868c32f1d2f39960ae3e66428956558 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -2069,6 +2069,8 @@ t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
     /* right-clicking on a canvas object pops up a menu. */
 static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y_sel)
 {
+	//fprintf(stderr,"e_onmotion=%d\n",x->gl_editor->e_onmotion);
+	if (x->gl_editor->e_onmotion != MA_NONE) return;
     int canprop, canopen, isobject;
 	t_gobj *y = NULL;
 	int x1, y1, x2, y2;
@@ -2805,8 +2807,10 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
         	sys_vgui(".x%lx.c raise all_cords\n", x);
 			sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
 		}
-        x->gl_editor->e_grab = 0;
-        x->gl_editor->e_onmotion = MA_NONE;
+		if (x->gl_editor->e_onmotion != MA_SCROLL) {
+	        x->gl_editor->e_grab = 0;
+	        x->gl_editor->e_onmotion = MA_NONE;
+	    }
     }
     //post("click %d %d %d %d", xpos, ypos, which, mod);
     
@@ -4511,6 +4515,7 @@ void canvas_motion(t_canvas *x, t_floatarg xpos, t_floatarg ypos,
     t_floatarg fmod)
 { 
     //fprintf(stderr,"motion %d %d %d %d\n", (int)xpos, (int)ypos, (int)fmod, canvas_last_glist_mod);
+    //fprintf(stderr,"canvas_motion=%d\n",x->gl_editor->e_onmotion);
     int mod = fmod;
     if (!x->gl_editor)
     {
@@ -6297,7 +6302,7 @@ void glob_pastetext(void *dummy, t_symbol *s, int ac, t_atom *av)
 	canvas_key(canvas_editing, s, ac-1, av+1);
 	if ((int)atom_getfloat(av) == 1) {
 		//fprintf(stderr,"force getscroll\n");
-		sys_vgui("pdtk_canvas_force_getscroll .x%lx.c\n", canvas_editing);
+		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", canvas_editing);
 	}
 }
 
diff --git a/pd/src/g_text.c b/pd/src/g_text.c
index 005d91bff04c03505321efcfc0073be257b14927..2ae760b5794b13e4713502a9f521c235b20dfd3d 100644
--- a/pd/src/g_text.c
+++ b/pd/src/g_text.c
@@ -244,7 +244,7 @@ void canvas_howputnew(t_canvas *x, int *connectp, int *xpixp, int *ypixp,
                 indx = nobj-1;
         }
 		x->gl_editor->e_onmotion = MA_NONE;
-		sys_vgui("after 100 pdtk_canvas_force_getscroll .x%lx.c\n", x);
+		sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
     }
     else
     {
diff --git a/pd/src/pd.tk b/pd/src/pd.tk
index 891f6537e8e0443f6a13290d039888e1218000a9..252ffd0d2a172b6bd9eca6a6ad6b34fc36ea3ce5 100644
--- a/pd/src/pd.tk
+++ b/pd/src/pd.tk
@@ -2357,7 +2357,7 @@ proc pdtk_k12_show_sound_icons {name} {
 	}
 }
 
-package require tkpath
+package require tkpath 0.3.3
 
 ############# pdtk_canvas_new -- create a new canvas ###############
 proc pdtk_canvas_new {name width height geometry editable} {
@@ -2414,6 +2414,9 @@ proc pdtk_canvas_new {name width height geometry editable} {
 	if {![info exists ::font($name)]} {
 		set ::font($name) 10
 	}
+	if {![info exists ::doscroll($name)]} {
+		set ::doscroll($name) 0
+	}
 
 	if {$::menu($name) == 1} {
     	toplevel $name -menu $name.m -class [winfo class .]
@@ -3830,7 +3833,7 @@ proc pdtk_canvas_toggle_scrollbars {rootname x} {
     }
 	if {[info exists ::loaded($rootname)]} {
 		#puts stderr getscroll
-		pdtk_canvas_force_getscroll $rootname.c
+		pdtk_canvas_getscroll $rootname.c
 	}
 }
 
@@ -4094,12 +4097,17 @@ proc pdtk_find_highest_widget_withtag {canvas name} {
 	#puts stderr "final_highest=$tag"
 }
 
-proc pdtk_canvas_force_getscroll {name} {
-	set ::update_tick([winfo parent $name]) 0
-	pdtk_canvas_getscroll $name
-}
+#proc pdtk_canvas_force_getscroll {name} {
+#	set ::update_tick([winfo parent $name]) 0
+#	after idle [concat pdtk_canvas_getscroll $name]
+#}
 
 proc pdtk_canvas_getscroll {name} {
+	catch { after cancel $::doscroll($name) }
+	set ::doscroll($name) [after idle [concat pdtk_canvas_do_getscroll $name]]
+}
+
+proc pdtk_canvas_do_getscroll {name} {
 	global pd_nt
     global pdtk_canvas_mouseup_name
     global pdtk_canvas_mouseup_xminval
@@ -4113,26 +4121,9 @@ proc pdtk_canvas_getscroll {name} {
     # kludge since this gets called sometimes after a canvas is destroyed
     if {![winfo exists $name]} {return}
 
-	if {$::update_tick([winfo parent $name]) == 1} {return}
-
-	#set ::update_tick([winfo parent $name]) 1
-
-	after 100 set ::update_tick([winfo parent $name]) 0
-
-	# waiting for refresh
-	#if {$::update_tick([winfo parent $name]) == 2} {return}
-
-	# init
-	#if {$::update_tick([winfo parent $name]) == 0} {
-	# 	set ::update_tick([winfo parent $name]) 1
-	#	pdtk_canvas_getscroll_ping $name		
-	#}
-
-	# update
-	#if {$::update_tick([winfo parent $name]) == 1} {
-	#	set ::update_tick([winfo parent $name]) 2
-	#	return
-	#}
+    # for use with tick mechanism
+	#if {$::update_tick([winfo parent $name]) == 1} {return}
+	#after 100 set ::update_tick([winfo parent $name]) 0
 
 	#puts stderr getscroll
 
@@ -4329,7 +4320,7 @@ proc pdtk_canvas_getscroll {name} {
 			set ::yscrollable($parentname) 0
 		}
 	}
-	set ::update_tick([winfo parent $name]) 1
+	#set ::update_tick([winfo parent $name]) 1
     pdtk_canvas_checkgeometry [canvastosym $name]
 	pdtk_canvas_draw_scrollbars $name
 	pdtk_canvas_update_sticky_tip $name