diff --git a/src/Previewer/Internal.js b/src/Previewer/Internal.js index 0125581cf..25eaa67c1 100644 --- a/src/Previewer/Internal.js +++ b/src/Previewer/Internal.js @@ -250,8 +250,7 @@ export default function Internal({ // it would be great to keep the ast around and pass that to prettier // so there is no need to re-parse but that's not supported yet // https://github.com/prettier/prettier/issues/9114 -// We are not using https://github.com/pazams/postcss-scopify -// because it's not compatible with postcss 8 +// TODO: Consider using https://github.com/pazams/postcss-scopify instead function scopeStylesheet(style, id) { const ast = postcss.parse(style); for (const node of ast.nodes) { diff --git a/src/Previewer/Previewer.js b/src/Previewer/Previewer.js index b9c1235e2..d4b6a39c4 100644 --- a/src/Previewer/Previewer.js +++ b/src/Previewer/Previewer.js @@ -189,9 +189,13 @@ export default function Previewer({ if (settings.get_boolean("safe-mode")) { // console.time("detectCrash"); - const crashed = await detectCrash(text, target_id); - if (crashed) return; + const crashed = await detectCrash({ + xml: text, + css: code_view_css.buffer.text, + object_id: target_id, + }); // console.timeEnd("detectCrash"); + if (crashed) return; } const builder = new Gtk.Builder(); diff --git a/src/Previewer/crasher.vala b/src/Previewer/crasher.vala index 63f0e0e8e..8b515600e 100644 --- a/src/Previewer/crasher.vala +++ b/src/Previewer/crasher.vala @@ -3,12 +3,33 @@ public void main (string[] args) { var builder = new Gtk.Builder (); var output = new Gtk.Window (); + var provider = new Gtk.CssProvider (); try { builder.add_from_string (args[1], -1); - var object = builder.get_object (args[2]) as Gtk.Widget; + print("1\n"); + provider.load_from_string (args[2]); + print("2\n"); + Gtk.StyleContext.add_provider_for_display ( + output.get_display(), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ); + print("3\n"); + var object = builder.get_object (args[3]) as Gtk.Widget; output.set_child (object); } catch (Error e) { GLib.error (e.message); } + + //output.opacity = 0; + output.present(); + + // run pending work so CSS/style errors surface + var ctx = MainContext.default (); + while (ctx.pending ()) { + ctx.iteration (false); + } + + output.destroy(); } diff --git a/src/Previewer/utils.js b/src/Previewer/utils.js index 2f12a760f..4672c4e7d 100644 --- a/src/Previewer/utils.js +++ b/src/Previewer/utils.js @@ -151,11 +151,29 @@ function assertObjectBuildable(el_object, is_root) { } } -export async function detectCrash(str, object_id) { - // const flags = - // Gio.SubprocessFlags.STDOUT_SILENCE | Gio.SubprocessFlags.STDERR_SILENCE; - const flags = Gio.SubprocessFlags.NONE; - const proc = Gio.Subprocess.new(["workbench-crasher", str, object_id], flags); +const BROADWAY_DISPLAY = ":5"; +let broadwayd = null; + +function ensureBroadway() { + if (broadwayd) return; + // GTK4's daemon is gtk4-broadwayd (broadwayd is the GTK3 one) + broadwayd = Gio.Subprocess.new( + ["gtk4-broadwayd", BROADWAY_DISPLAY], + Gio.SubprocessFlags.STDOUT_SILENCE | Gio.SubprocessFlags.STDERR_SILENCE, + ); +} + +export async function detectCrash({ xml, css, object_id }) { + ensureBroadway(); + + const launcher = new Gio.SubprocessLauncher({ + flags: Gio.SubprocessFlags.NONE, + }); + launcher.setenv("GDK_BACKEND", "broadway", true); + launcher.setenv("BROADWAY_DISPLAY", BROADWAY_DISPLAY, true); + launcher.setenv("G_DEBUG", "fatal-criticals", true); // optional: make criticals fail + + const proc = launcher.spawnv(["workbench-crasher", xml, css, object_id]); const success = await proc.wait_check_async(null).catch((_err) => { return false;