From 821906971cfd50aba25f95fa5c75b8b1d387edd7 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Mon, 19 Dec 2016 20:04:26 -0500 Subject: [PATCH] fix #194: saving a loaded abstraction gives errors. Cleaned up dangling reference to closed nw window, and protect against out-of-order messages that come before the canvas is mapped --- pd/nw/index.js | 21 ++++++++++++++++++++- pd/nw/pdgui.js | 45 ++++++++++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/pd/nw/index.js b/pd/nw/index.js index d734d47f3..2436ef49c 100644 --- a/pd/nw/index.js +++ b/pd/nw/index.js @@ -374,7 +374,6 @@ function nw_close_window(window) { window.close(true); } -// Way too many arguments here-- rethink this interface function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) { // todo: make a separate way to format the title for OSX var my_title; @@ -412,6 +411,7 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) { pdgui.set_dialogwin(cid, new_win); } new_win.on("loaded", function() { + // Off to the races... :( // We need to check here if we're still the window pointed to // by the GUI's array of toplevel windows. It can easily happen // that we're not-- for example the user could send a stream @@ -424,12 +424,31 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) { // as a loaded canvas. If not, we assume it got closed before // we were able to finish loading the browser window (e.g., // with a [vis 1, vis 0( message). In that case we kill the window. + + // Still, this is pretty fortuitous-- we have two levels of + // asynchronicity-- creating the nw window and loading it. There + // may still be an edge case where a race between those two causes + // unpredictable behavior. if ((new_win === pdgui.get_patchwin(cid) || new_win === pdgui.get_dialogwin(cid)) && pdgui.window_is_loading(cid)) { // initialize the window new_win.eval(null, eval_string); + // flag the window as loaded. We may want to wait until the + // DOM window has finished loading for this. + pdgui.set_finished_loading(cid); } else { + // If the window is no longer loading, we need to go ahead + // and remove the reference to it in the patchwin array. + // Otherwise we get dangling references to closed windows + // and other bugs... + if (!pdgui.window_is_loading(cid)) { + if (type === "pd_canvas") { + pdgui.set_patchwin(cid, undefined); + } else { + pdgui.set_dialogwin(cid, undefined); + } + } new_win.close(true); } }); diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index e92043279..b318f1045 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -1247,6 +1247,12 @@ function window_is_loading(cid) { exports.window_is_loading = window_is_loading; +function set_window_finished_loading(cid) { + loading[cid] = null; +} + +exports.set_window_finished_loading = set_window_finished_loading; + // wrapper for nw_create_window function create_window(cid, type, width, height, xpos, ypos, attr_array) { nw_create_window(cid, type, width, height, xpos, ypos, attr_array); @@ -1924,11 +1930,14 @@ function gui_canvas_deselect_line(cid, tag) { // rename to erase_line (or at least standardize with gobj_erase) function gui_canvas_delete_line(cid, tag) { - var line = get_item(cid, tag); - if (line !== null) { - line.parentNode.removeChild(line); - } else { - //post("canvas_delete_line: error: the line doesn't exist"); + var line; + if (patchwin[cid]) { + line = get_item(cid, tag); + if (line !== null) { + line.parentNode.removeChild(line); + } else { + //post("canvas_delete_line: error: the line doesn't exist"); + } } } @@ -2167,11 +2176,14 @@ function gui_gobj_select(cid, tag) { } function gui_gobj_deselect(cid, tag) { - var gobj = get_gobj(cid, tag) - if (gobj !== null) { - gobj.classList.remove("selected"); - } else { - console.log("text_deselect: something wrong with tag: " + tag + "gobj"); + var gobj; + if (patchwin[cid]) { + gobj = get_gobj(cid, tag); + if (gobj !== null) { + gobj.classList.remove("selected"); + } else { + console.log("text_deselect: error with tag: " + tag + "gobj"); + } } } @@ -2809,11 +2821,14 @@ function gui_iemgui_label_color(cid, tag, color) { } function gui_iemgui_label_select(cid, tag, is_selected) { - var svg_text = get_item(cid, tag + "label"); - if (is_selected) { - svg_text.classList.add("iemgui_label_selected"); - } else { - svg_text.classList.remove("iemgui_label_selected"); + var svg_text; + if (patchwin[cid]) { + svg_text = get_item(cid, tag + "label"); + if (is_selected) { + svg_text.classList.add("iemgui_label_selected"); + } else { + svg_text.classList.remove("iemgui_label_selected"); + } } } -- GitLab