diff --git a/pd/nw/index.js b/pd/nw/index.js
index 757f71fc9f24a5531036a7869e3b90521f524cd6..cda7a75235a55d3ae955823267af2878f6df7095 100644
--- a/pd/nw/index.js
+++ b/pd/nw/index.js
@@ -302,10 +302,12 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
     var my_file =
         type === "pd_canvas" ? "pd_canvas.html" : "dialog_" + type + ".html";
 
-    var new_win = gui.Window.open(my_file, {
+    var eval_string = "register_canvas_id(" +
+                      JSON.stringify(cid) + ", " +
+                      JSON.stringify(attr_array) + ");";
+    gui.Window.open(my_file, {
         title: my_title,
         position: "center",
-        toolbar: false,
         focus: true,
         width: width,
         // We add 23 as a kludge to account for the menubar at the top of
@@ -315,19 +317,17 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
         height: height + 23,
         x: xpos,
         y: ypos
+    }, function (new_win) {
+        pdgui.set_patchwin(cid, new_win);
+        new_win.on("loaded", function() {
+            new_win.eval(null, eval_string);
+        });
     });
     //pdgui.post("attr_array is " + attr_array);
-    var eval_string = "register_canvas_id(" +
-                      JSON.stringify(cid) + ", " +
-                      JSON.stringify(attr_array) + ");";
     //pdgui.post("eval string is " + eval_string);
     //if (attr_array !== null) {
     //    pdgui.post("attr_array is " + attr_array.toString());
     //}
-    new_win.on("loaded", function() {
-        new_win.eval(null, eval_string);
-    });
-    return new_win;
 }
 
 // Pd Window Menu Bar
diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js
index 608da223a163389bc09d4ad6577a26d1f6f84124..32d0b07438f37a7b5ef713479d45e4a56c68e599 100644
--- a/pd/nw/pd_canvas.js
+++ b/pd/nw/pd_canvas.js
@@ -451,6 +451,31 @@ var canvas_events = (function() {
         }, false
     );
 
+    // Whoa-- huge workaround!
+    // Right now we're getting the popup menu the way Pd Vanilla does it:
+    // 1) send a mouse(down) message to Pd
+    // 2) Pd checks whether it wants to send us a popup
+    // 3) Pd checks what popup menu items are available for this object/canvas
+    // 4) Pd sends GUI back a message with this info
+    // 5) GUI finally displays the popup
+    // 6) GUI keeps a _global_ _variable_ to remember where the popup coords
+    // 7) User clicks an option in the popup
+    // 8) GUI sends a message back to Pd with the popup index and coords
+    // 9) Pd walks the linked list of objects to look up the object
+    // 10) Pd asks that object if it reacts to popups, and if it reacts to the
+    //     selected item in the popup
+    // 11) Pd sends a message to the relevant object for the item in question
+    // nw.js has a nice little "contextmenu" event handler, but it's too
+    // difficult to use when we're passing between GUI and Pd (twice). In the
+    // future we should just do all the popup menu event handling in the GUI,
+    // and only pass a message to Pd when the user has clicked an item.
+    // For now, however, we just turn off its default behavior and control
+    // it with a bunch of complicated callbacks. :(
+    document.addEventListener("contextmenu", function(evt) {
+        console.log("got a context menu evt...");
+        evt.preventDefault();
+    });
+
     // The following is commented out because we have to set the
     // event listener inside nw_create_pd_window_menus due to a
     // bug with nwworkingdir
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 61bb986abfd757c9a35be766fc42cb586e556c8e..52a149b1129041a5186966a1e072618cd6cec18f 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -804,6 +804,10 @@ exports.get_patchwin = function(name) {
     return patchwin[name];
 }
 
+exports.set_patchwin = function(cid, win) {
+    patchwin[cid] = win;
+}
+
 exports.get_dialogwin = function(name) {
     return dialogwin[name];
 }
@@ -928,7 +932,7 @@ function gui_canvas_new(cid, width, height, geometry, editmode, name, dir, dirty
     last_loaded = cid;
     // Not sure why resize and topmost are here-- but we'll pass them on for
     // the time being...
-    patchwin[cid] = nw_create_window(cid, "pd_canvas", width, height,
+    nw_create_window(cid, "pd_canvas", width, height,
         xpos, ypos, {
             menu_flag: menu_flag,
             resize: resize[cid],
@@ -942,6 +946,7 @@ function gui_canvas_new(cid, width, height, geometry, editmode, name, dir, dirty
     });
     // initialize variable to reflect that this window has been opened
     loaded[cid] = 1;
+    // we call set_patchwin from the callback in pd_canvas
 }
 
 /* This gets sent to Pd to trigger each object on the canvas
@@ -2864,7 +2869,6 @@ function popup_action(cid, index) {
 
 exports.popup_action = popup_action;
 
-
 // Graphs and Arrays
 
 // Doesn't look like we needs this