diff --git a/src/g_canvas.c b/src/g_canvas.c
index 36d3d3d64446d9d19e31903c5a708a7b60787b43..ffd6d1b3784f6b7f5311c7a7b1a5abcab8787d58 100644
--- a/src/g_canvas.c
+++ b/src/g_canvas.c
@@ -47,7 +47,7 @@ static void canvas_start_dsp(void);
 static void canvas_stop_dsp(void);
 static void canvas_drawlines(t_canvas *x);
 static void canvas_setbounds(t_canvas *x, int x1, int y1, int x2, int y2);
-static void canvas_reflecttitle(t_canvas *x);
+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);
@@ -682,144 +682,6 @@ void canvas_redraw(t_canvas *x)
     }
 }
 
-/* ----  editors -- perhaps this and "vis" should go to g_editor.c ------- */
-
-static t_editor *editor_new(t_glist *owner)
-{
-    char buf[40];
-    t_editor *x = (t_editor *)getbytes(sizeof(*x));
-    x->e_connectbuf = binbuf_new();
-    x->e_deleted = binbuf_new();
-    x->e_glist = owner;
-    sprintf(buf, ".x%lx", (t_int)owner);
-    x->e_guiconnect = guiconnect_new(&owner->gl_pd, gensym(buf));
-    return (x);
-}
-
-static void editor_free(t_editor *x, t_glist *y)
-{
-    glist_noselect(y);
-    guiconnect_notarget(x->e_guiconnect, 1000);
-    binbuf_free(x->e_connectbuf);
-    binbuf_free(x->e_deleted);
-    freebytes((void *)x, sizeof(*x));
-}
-
-    /* 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)
-{
-    t_gobj *y;
-    t_object *ob;
-    if (createit)
-    {
-        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);
-        }
-    }
-    else
-    {
-        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 (pd_class(&y->g_pd) == canvas_class &&
-            ((t_canvas *)y)->gl_isgraph && !((t_canvas *)y)->gl_havewindow)
-                canvas_create_editor((t_canvas *)y, createit);
-}
-
-    /* we call this when we want the window to become visible, mapped, and
-    in front of all windows; or with "f" zero, when we want to get rid of
-    the window. */
-void canvas_vis(t_canvas *x, t_floatarg f)
-{
-    char buf[30];
-    int flag = (f != 0);
-    if (flag)
-    {
-        /* post("havewindow %d, isgraph %d, isvisible %d  editor %d",
-            x->gl_havewindow, x->gl_isgraph, glist_isvisible(x),
-                (x->gl_editor != 0)); */
-            /* test if we're already visible and toplevel */
-        if (x->gl_editor)
-        {           /* just put us in front */
-#ifdef MSW
-            canvas_vis(x, 0);
-            canvas_vis(x, 1);
-#else
-            sys_vgui("raise .x%lx\n", x);
-            sys_vgui("focus .x%lx.c\n", x);
-            sys_vgui("wm deiconify .x%lx\n", x);  
-#endif
-        }
-        else
-        {
-            canvas_create_editor(x, 1);
-            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),
-                (int)(x->gl_screenx1), (int)(x->gl_screeny1),
-                x->gl_edit);
-            canvas_reflecttitle(x);
-            x->gl_havewindow = 1;
-            canvas_updatewindowlist();
-        }
-    }
-    else    /* make invisible */
-    {
-        int i;
-        t_canvas *x2;
-        if (!x->gl_havewindow)
-        {
-                /* bug workaround -- a graph in a visible patch gets "invised"
-                when the patch is closed, and must lose the editor here.  It's
-                probably not the natural place to do this.  Other cases like
-                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);
-            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);
-        sys_vgui("destroy .x%lx\n", x);
-        for (i = 1, x2 = x; x2; x2 = x2->gl_next, i++)
-            ;
-        sys_vgui(".mbar.find delete %d\n", i);
-            /* if we're a graph on our parent, and if the parent exists
-               and is visible, show ourselves on parent. */
-        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;
-            if (glist_isvisible(gl2))
-                gobj_vis(&x->gl_gobj, gl2, 1);
-        }
-        else x->gl_havewindow = 0;
-        canvas_updatewindowlist();
-    }
-}
 
     /* we call this on a non-toplevel glist to "open" it into its
     own window. */
diff --git a/src/g_editor.c b/src/g_editor.c
index 8f240f57b71e9266a8be5a856640776a644851bc..d56f3fbb0552c8fbce1722e13d63371bde0ad025 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -831,10 +831,153 @@ static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y)
         x, xpos, ypos, canprop, canopen);
 }
 
+/* ----  editors -- perhaps this and "vis" should go to g_editor.c ------- */
+
+static t_editor *editor_new(t_glist *owner)
+{
+    char buf[40];
+    t_editor *x = (t_editor *)getbytes(sizeof(*x));
+    x->e_connectbuf = binbuf_new();
+    x->e_deleted = binbuf_new();
+    x->e_glist = owner;
+    sprintf(buf, ".x%lx", (t_int)owner);
+    x->e_guiconnect = guiconnect_new(&owner->gl_pd, gensym(buf));
+    return (x);
+}
+
+static void editor_free(t_editor *x, t_glist *y)
+{
+    glist_noselect(y);
+    guiconnect_notarget(x->e_guiconnect, 1000);
+    binbuf_free(x->e_connectbuf);
+    binbuf_free(x->e_deleted);
+    freebytes((void *)x, sizeof(*x));
+}
+
+    /* 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)
+{
+    t_gobj *y;
+    t_object *ob;
+    if (createit)
+    {
+        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);
+        }
+    }
+    else
+    {
+        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 (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);
+void canvas_map(t_canvas *x, t_floatarg f);
+
+    /* we call this when we want the window to become visible, mapped, and
+    in front of all windows; or with "f" zero, when we want to get rid of
+    the window. */
+void canvas_vis(t_canvas *x, t_floatarg f)
+{
+    char buf[30];
+    int flag = (f != 0);
+    if (flag)
+    {
+        /* post("havewindow %d, isgraph %d, isvisible %d  editor %d",
+            x->gl_havewindow, x->gl_isgraph, glist_isvisible(x),
+                (x->gl_editor != 0)); */
+            /* test if we're already visible and toplevel */
+        if (x->gl_editor)
+        {           /* just put us in front */
+#ifdef MSW
+            canvas_vis(x, 0);
+            canvas_vis(x, 1);
+#else
+            sys_vgui("raise .x%lx\n", x);
+            sys_vgui("focus .x%lx.c\n", x);
+            sys_vgui("wm deiconify .x%lx\n", x);  
+#endif
+        }
+        else
+        {
+            canvas_create_editor(x, 1);
+            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),
+                (int)(x->gl_screenx1), (int)(x->gl_screeny1),
+                x->gl_edit);
+            canvas_reflecttitle(x);
+            x->gl_havewindow = 1;
+            canvas_updatewindowlist();
+        }
+    }
+    else    /* make invisible */
+    {
+        int i;
+        t_canvas *x2;
+        if (!x->gl_havewindow)
+        {
+                /* bug workaround -- a graph in a visible patch gets "invised"
+                when the patch is closed, and must lose the editor here.  It's
+                probably not the natural place to do this.  Other cases like
+                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);
+            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);
+        sys_vgui("destroy .x%lx\n", x);
+        for (i = 1, x2 = x; x2; x2 = x2->gl_next, i++)
+            ;
+        sys_vgui(".mbar.find delete %d\n", i);
+            /* if we're a graph on our parent, and if the parent exists
+               and is visible, show ourselves on parent. */
+        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;
+            if (glist_isvisible(gl2))
+                gobj_vis(&x->gl_gobj, gl2, 1);
+        }
+        else x->gl_havewindow = 0;
+        canvas_updatewindowlist();
+    }
+}
+
     /* set a canvas up as a graph-on-parent.  Set reasonable defaults for
     any missing paramters and redraw things if necessary. */
 void canvas_setgraph(t_glist *x, int flag, int nogoprect)
 {
+    editor_free(x->gl_editor, x);
     if (!flag && glist_isgraph(x))
     {
         if (x->gl_owner && !x->gl_loading && glist_isvisible(x->gl_owner))
@@ -878,6 +1021,7 @@ void canvas_setgraph(t_glist *x, int flag, int nogoprect)
             canvas_fixlinesfor(x->gl_owner, &x->gl_obj);
         }
     }
+    editor_new(x);
 }
 
 void garray_properties(t_garray *x);
diff --git a/src/g_graph.c b/src/g_graph.c
index ce5580c2e43004f0d2bdde5c0b734ef11ae0cf49..7af4213fc7a9be1866d26ff75bb6c8fda3393968 100644
--- a/src/g_graph.c
+++ b/src/g_graph.c
@@ -176,8 +176,9 @@ void glist_grab(t_glist *x, t_gobj *y, t_glistmotionfn motionfn,
 
 t_canvas *glist_getcanvas(t_glist *x)
 {
-    while (x->gl_owner && !x->gl_havewindow && x->gl_isgraph)
-        x = x->gl_owner;
+    while (x->gl_owner && !x->gl_havewindow && x->gl_isgraph &&
+        gobj_shouldvis(&x->gl_gobj, x->gl_owner))
+            x = x->gl_owner;
     return((t_canvas *)x);
 }