diff --git a/pd/nw/index.html b/pd/nw/index.html
index 806fa3f5080255e161a9a5b2ae30a919d1afaaa7..0a51f10d54003da1c586e0c8ee6ee29a5bbb93ee 100644
--- a/pd/nw/index.html
+++ b/pd/nw/index.html
@@ -11,6 +11,9 @@
       <input style="display:none;" id="fileDialog" type="file"
              nwworkingdir multiple />
     </span>
+    <input style="display:none;" id="openpanel_dialog" type="file" />
+    <input style="display:none;" id="savepanel_dialog" type="file"
+           nwsaveas nwworkingdir />
     <div id="console_controls" class="noselect">
       <div id="control_frame">
         <label class="dsp_toggle">DSP
diff --git a/pd/nw/index.js b/pd/nw/index.js
index 9d69b385ec05affde6bd427127b3f994faa7e094..e0b0039d03a5a8de8b00d99b19dd692f32943cf4 100644
--- a/pd/nw/index.js
+++ b/pd/nw/index.js
@@ -341,6 +341,26 @@ function add_events() {
     document.getElementById("fileDialog").setAttribute("accept",
         Object.keys(pdgui.pd_filetypes).toString());
 
+    // [openpanel] and [savepanel] callbacks
+    document.querySelector("#openpanel_dialog").addEventListener("change",
+        function(evt) {
+            var file_string = evt.target.value;
+            // reset value so that we can open the same file twice
+            evt.target.value = null;
+            pdgui.file_dialog_callback(file_string);
+            console.log("tried to openpanel something");
+        }, false
+    );
+    document.querySelector("#savepanel_dialog").addEventListener("change",
+        function(evt) {
+            var file_string = evt.target.value;
+            // reset value so that we can open the same file twice
+            evt.target.value = null;
+            pdgui.file_dialog_callback(file_string);
+            console.log("tried to savepanel something");
+        }, false
+    );
+
     // disable drag and drop for the time being
     window.addEventListener("dragover", function (evt) {
         evt.preventDefault();
diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js
index 936c99cd3edd7b3a2f7f676b47fe90327cfe3655..d0a4e8c6e2ebdd78a27523b6504fd517a4011918 100644
--- a/pd/nw/pd_canvas.js
+++ b/pd/nw/pd_canvas.js
@@ -119,7 +119,8 @@ function permission_to_paste_from_external_clipboard() {
     return global.confirm(l("canvas.paste_clipboard_prompt"));
 }
 
-function nw_window_focus_callback() {
+function nw_window_focus_callback(name) {
+    pdgui.set_focused_patchwin(name);
     // on OSX, update the menu on focus
     if (process.platform === "darwin") {
         nw_create_patch_window_menus(gui, window, canvas_events.get_id());
@@ -592,7 +593,7 @@ var canvas_events = (function() {
         pdgui.gui_canvas_get_scroll(name);
     });
     gui.Window.get().on("focus", function() {
-        nw_window_focus_callback();
+        nw_window_focus_callback(name);
     });
     gui.Window.get().on("blur", function() {
         nw_window_blur_callback(name);
@@ -757,7 +758,7 @@ function register_window_id(cid, attr_array) {
     canvas_events.register(cid);
     translate_form();
     // Trigger a "focus" event so that OSX updates the menu for this window
-    nw_window_focus_callback();
+    nw_window_focus_callback(cid);
     canvas_events.normal();
     pdgui.canvas_map(cid); // side-effect: triggers gui_canvas_get_scroll
     set_editmode_checkbox(attr_array.editmode !== 0 ? true : false);
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index a5e15e5747a4f885a1256bf05c5ea5e090416e25..8fc382dc3d2143a2930262c08df9b3602966fc8f 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -66,6 +66,10 @@ function gui_set_gui_preset(name) {
     skin.set(name);
 }
 
+exports.set_focused_patchwin = function(cid) {
+    last_focused = cid;
+}
+
 // Modules
 
 var fs = require("fs");     // for fs.existsSync
@@ -1110,7 +1114,8 @@ var scroll = {},
     redo = {},
     font = {},
     doscroll = {},
-    last_loaded,
+    last_loaded, // last loaded canvas
+    last_focused, // last focused canvas (doesn't include Pd window or dialogs)
     loading = {},
     title_queue= {}, // ugly kluge to work around an ugly race condition
     popup_menu = {};
@@ -4127,9 +4132,17 @@ function file_dialog(cid, type, target, path) {
     file_dialog_target = target;
     var query_string = (type === "open" ?
                         "openpanel_dialog" : "savepanel_dialog"),
-        d = patchwin[cid].window.document.querySelector("#" + query_string);
-    d.setAttribute("nwworkingdir", path);
-    d.click();
+        input_elem,
+        win;
+        // We try opening the dialog in the last focused window. There's an
+        // edge case where [loadbang]--[openpanel] will trigger before the
+        // window has finished loading. In that case we just trigger the
+        // dialog in the main Pd window.
+        win = last_focused && patchwin[last_focused] ? patchwin[last_focused] :
+            pd_window;
+        input_elem = win.window.document.querySelector("#" + query_string);
+    input_elem.setAttribute("nwworkingdir", path);
+    input_elem.click();
 }
 
 function gui_openpanel(cid, target, path) {