diff --git a/src/g_canvas.c b/src/g_canvas.c
index 6838832ec446cdbbac6a25f9be7e1ad670cb2647..d324fbd2c79294ce28c9ee876e21907acbf4062f 100644
--- a/src/g_canvas.c
+++ b/src/g_canvas.c
@@ -51,7 +51,6 @@ void canvas_reflecttitle(t_canvas *x);
 static void canvas_addtolist(t_canvas *x);
 static void canvas_takeofflist(t_canvas *x);
 static void canvas_pop(t_canvas *x, t_floatarg fvis);
-void canvas_create_editor(t_glist *x, int createit);
 
 /* --------- functions to handle the canvas environment ----------- */
 
@@ -513,8 +512,6 @@ t_glist *glist_addglist(t_glist *g, t_symbol *sym,
     if (!menu)
         pd_pushsym(&x->gl_pd);
     glist_add(g, &x->gl_gobj);
-    if (glist_isvisible(g))
-        canvas_create_editor(x, 1);
     return (x);
 }
 
@@ -613,7 +610,8 @@ void canvas_dirty(t_canvas *x, t_int n)
     if ((unsigned)n != x2->gl_dirty)
     {
         x2->gl_dirty = n;
-        canvas_reflecttitle(x2);
+        if (glist_isvisible(x2))
+            canvas_reflecttitle(x2);
     }
 }
 
@@ -663,15 +661,8 @@ void canvas_map(t_canvas *x, t_floatarg f)
     {
         if (glist_isvisible(x))
         {
-                /* just clear out the whole canvas... */
+                /* just clear out the whole canvas */
             sys_vgui(".x%lx.c delete all\n", x);
-#if 0
-                /* alternatively, we could have erased them one by one...
-            for (y = x->gl_list; y; y = y->g_next)
-                gobj_vis(y, x, 0);
-                    ... but we should go through and erase the lines as well
-                    if we do it that way. */
-#endif
             x->gl_mapped = 0;
         }
     }
@@ -702,7 +693,7 @@ void glist_menu_open(t_glist *x)
             gobj_vis(&x->gl_gobj, gl2, 0);
                     /* get rid of our editor (and subeditors) */
             if (x->gl_editor)
-                canvas_create_editor(x, 0);
+                canvas_destroy_editor(x);
             x->gl_havewindow = 1;
                     /* redraw ourself in parent window (blanked out this time) */
             gobj_vis(&x->gl_gobj, gl2, 1);
diff --git a/src/g_canvas.h b/src/g_canvas.h
index 784a590bdb0ed4d2df0927199e34e5204a2c20ea..d79510599146e892a2fbf4c5aa2c4b81c57776e9 100644
--- a/src/g_canvas.h
+++ b/src/g_canvas.h
@@ -401,7 +401,8 @@ EXTERN void glist_redraw(t_glist *x);
 EXTERN void glist_drawiofor(t_glist *glist, t_object *ob, int firsttime,
     char *tag, int x1, int y1, int x2, int y2);
 EXTERN void glist_eraseiofor(t_glist *glist, t_object *ob, char *tag);
-EXTERN void canvas_create_editor(t_glist *x, int createit);
+EXTERN void canvas_create_editor(t_glist *x);
+EXTERN void canvas_destroy_editor(t_glist *x);
 void canvas_deletelinesforio(t_canvas *x, t_text *text,
     t_inlet *inp, t_outlet *outp);
 extern int glist_amreloadingabstractions; /* stop GUI changes while reloading */ 
diff --git a/src/g_editor.c b/src/g_editor.c
index c4bfd4566b515f42e8f3a79e808fcfe96520e972..f8180d8a010ab4876fb746689483bbe9bd1496b2 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -862,39 +862,31 @@ static void editor_free(t_editor *x, t_glist *y)
 
     /* recursively create or destroy all editors of a glist and its 
     sub-glists, as long as they aren't toplevels. */
-void canvas_create_editor(t_glist *x, int createit)
+void canvas_create_editor(t_glist *x)
 {
     t_gobj *y;
     t_object *ob;
-    if (createit)
+    if (!x->gl_editor)
     {
-        if (x->gl_editor)
-            bug("canvas_create_editor");
-        else
-        {
-            x->gl_editor = editor_new(x);
-            for (y = x->gl_list; y; y = y->g_next)
-                if (ob = pd_checkobject(&y->g_pd))
-                    rtext_new(x, ob);
-        }
+        x->gl_editor = editor_new(x);
+        for (y = x->gl_list; y; y = y->g_next)
+            if (ob = pd_checkobject(&y->g_pd))
+                rtext_new(x, ob);
     }
-    else
+}
+
+void canvas_destroy_editor(t_glist *x)
+{
+    t_gobj *y;
+    t_object *ob;
+    if (x->gl_editor)
     {
-        if (!x->gl_editor)
-            bug("canvas_create_editor");
-        else
-        {
-            for (y = x->gl_list; y; y = y->g_next)
-                if (ob = pd_checkobject(&y->g_pd))
-                    rtext_free(glist_findrtext(x, ob));
-            editor_free(x->gl_editor, x);
-            x->gl_editor = 0;
-        }
+        for (y = x->gl_list; y; y = y->g_next)
+            if (ob = pd_checkobject(&y->g_pd))
+                rtext_free(glist_findrtext(x, ob));
+        editor_free(x->gl_editor, x);
+        x->gl_editor = 0;
     }
-    for (y = x->gl_list; y; y = y->g_next)
-        if (pd_class(&y->g_pd) == canvas_class &&
-            ((t_canvas *)y)->gl_isgraph && !((t_canvas *)y)->gl_havewindow)
-                canvas_create_editor((t_canvas *)y, createit);
 }
 
 void canvas_reflecttitle(t_canvas *x);
@@ -907,6 +899,8 @@ void canvas_vis(t_canvas *x, t_floatarg f)
 {
     char buf[30];
     int flag = (f != 0);
+    if (x != glist_getcanvas(x))
+        bug("canvas_vis");
     if (flag)
     {
         /* post("havewindow %d, isgraph %d, isvisible %d  editor %d",
@@ -926,7 +920,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
         }
         else
         {
-            canvas_create_editor(x, 1);
+            canvas_create_editor(x);
             sys_vgui("pdtk_canvas_new .x%lx %d %d +%d+%d %d\n", x,
                 (int)(x->gl_screenx2 - x->gl_screenx1),
                 (int)(x->gl_screeny2 - x->gl_screeny1),
@@ -949,14 +943,14 @@ void canvas_vis(t_canvas *x, t_floatarg f)
                 subpatches fall here too but don'd need the editor freed, so
                 we check if it exists. */
             if (x->gl_editor)
-                canvas_create_editor(x, 0);
+                canvas_destroy_editor(x);
             return;
         }
         sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
         glist_noselect(x);
         if (glist_isvisible(x))
             canvas_map(x, 0);
-        canvas_create_editor(x, 0);
+        canvas_destroy_editor(x);
         sys_vgui("destroy .x%lx\n", x);
         for (i = 1, x2 = x; x2; x2 = x2->gl_next, i++)
             ;
@@ -966,8 +960,6 @@ void canvas_vis(t_canvas *x, t_floatarg f)
         if (glist_isgraph(x) && x->gl_owner)
         {
             t_glist *gl2 = x->gl_owner;
-            if (!x->gl_owner->gl_isdeleting)
-                canvas_create_editor(x, 1);
             if (glist_isvisible(gl2))
                 gobj_vis(&x->gl_gobj, gl2, 0);
             x->gl_havewindow = 0;
@@ -987,7 +979,7 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
     {
         int hadeditor = (x->gl_editor != 0);
         if (hadeditor)
-            canvas_create_editor(x, 0);
+            canvas_destroy_editor(x);
         if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner))
             gobj_vis(&x->gl_gobj, x->gl_owner, 0);
         x->gl_isgraph = 0;
@@ -996,8 +988,6 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
             gobj_vis(&x->gl_gobj, x->gl_owner, 1);
             canvas_fixlinesfor(x->gl_owner, &x->gl_obj);
         }
-        if (hadeditor)
-            canvas_create_editor(x, 1);
     }
     else if (flag)
     {
@@ -1023,8 +1013,6 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
         }
         if (glist_isvisible(x) && x->gl_goprect)
             glist_redraw(x);
-        if (x->gl_loading && x->gl_owner && glist_isvisible(x->gl_owner))
-            canvas_create_editor(x, 1);
         if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner))
         {
             gobj_vis(&x->gl_gobj, x->gl_owner, 1);
diff --git a/src/g_rtext.c b/src/g_rtext.c
index 948ebcb4c280ac863ebb89888c086dc1d1db4db0..63a7485bf9f0be7acdfa9cc5ab1ee664823b4c97 100644
--- a/src/g_rtext.c
+++ b/src/g_rtext.c
@@ -342,8 +342,11 @@ void rtext_retext(t_rtext *x)
 /* find the rtext that goes with a text item */
 t_rtext *glist_findrtext(t_glist *gl, t_text *who)
 {
-    t_rtext *x = gl->gl_editor->e_rtext;
-    while (x && x->x_text != who) x = x->x_next;
+    t_rtext *x;
+    if (!gl->gl_editor)
+        canvas_create_editor(gl);
+    for (x = gl->gl_editor->e_rtext; x && x->x_text != who; x = x->x_next)
+        ;
     if (!x) bug("glist_findrtext");
     return (x);
 }
diff --git a/src/m_glob.c b/src/m_glob.c
index c3a70e53e6c4a25666edb7c5508f6f5ecc53b010..e3b49249d9fe53608eecc1215157fcd53e0b9c36 100644
--- a/src/m_glob.c
+++ b/src/m_glob.c
@@ -128,3 +128,16 @@ void glob_init(void)
     class_addanything(glob_pdobject, max_default);
     pd_bind(&glob_pdobject, gensym("pd"));
 }
+
+    /* function to return version number at run time.  Any of the
+    calling pointers may be zero in case you don't need all of them. */
+void sys_getversion(int *major, int *minor, int *bugfix)
+{
+    if (major)
+        *major = PD_MAJOR_VERSION;
+    if (minor)
+        *minor = PD_MINOR_VERSION;
+    if (bugfix)
+        *bugfix = PD_BUGFIX_VERSION;
+}
+
diff --git a/src/m_pd.h b/src/m_pd.h
index 3e686aa192f0322d52fe916da29f0cb820338891..26f1126f323f9a0436e54786e47a084c173e1718 100644
--- a/src/m_pd.h
+++ b/src/m_pd.h
@@ -11,7 +11,7 @@ extern "C" {
 #define PD_MAJOR_VERSION 0
 #define PD_MINOR_VERSION 42
 #define PD_BUGFIX_VERSION 0
-#define PD_TEST_VERSION "test6"
+#define PD_TEST_VERSION "test7"
 
 /* old name for "MSW" flag -- we have to take it for the sake of many old
 "nmakefiles" for externs, which will define NT and not MSW */
@@ -642,6 +642,9 @@ defined, there is a "te_xpix" field in objects, not a "te_xpos" as before: */
 #define PD_BIGORSMALL(f) 0
 #endif
 
+    /* get version number at run time */
+EXTERN void sys_getversion(int *major, int *minor, int *bugfix);
+
 #if defined(_LANGUAGE_C_PLUS_PLUS) || defined(__cplusplus)
 }
 #endif
diff --git a/src/s_loader.c b/src/s_loader.c
index bc637dcef436d79d26b7a5fb055c8847c8eb7702..6cc497c4b6f15738184a79842bea957842d10ce5 100644
--- a/src/s_loader.c
+++ b/src/s_loader.c
@@ -203,8 +203,6 @@ gotone:
     return (1);
 }
 
-/* callback type definition */
-typedef int (*loader_t)(t_canvas *canvas, char *classname);
 
 /* linked list of loaders */
 typedef struct loader_queue {
diff --git a/src/s_stuff.h b/src/s_stuff.h
index f85fb6cb05b6e88120e660dd890fd37ddd34d26e..0fb2497ebd945c5dca5d39596cb90c2575bb5edd 100644
--- a/src/s_stuff.h
+++ b/src/s_stuff.h
@@ -52,7 +52,10 @@ extern t_symbol *sys_libdir;    /* library directory for auxilliary files */
 extern t_symbol *sys_guidir;    /* directory holding pd_gui, u_pdsend, etc */
 
 /* s_loader.c */
-int sys_load_lib(t_canvas *canvas, char *filename);
+
+typedef int (*loader_t)(t_canvas *canvas, char *classname); /* callback type */
+EXTERN int sys_load_lib(t_canvas *canvas, char *filename);
+EXTERN void sys_register_loader(loader_t loader);
 
 /* s_audio.c */