From e320ba418fa7c4dfe0640935150f66ef55bfd653 Mon Sep 17 00:00:00 2001 From: Sonny Piers <sonny@fastmail.net> Date: Sat, 16 Dec 2023 17:43:58 +0100 Subject: [PATCH 1/3] previewer: Simplify preview flow --- src/Library/demos | 2 +- src/Previewer/DBusPreviewer.js | 17 ++++-- src/Previewer/External.js | 10 ++-- src/Previewer/Previewer.js | 95 +++++++++++++++++++--------------- src/langs/rust/Compiler.js | 12 +++-- src/window.blp | 77 ++++++++++++++++----------- src/window.js | 10 ++-- 7 files changed, 134 insertions(+), 89 deletions(-) diff --git a/src/Library/demos b/src/Library/demos index 34987fa26..a9d31b520 160000 --- a/src/Library/demos +++ b/src/Library/demos @@ -1 +1 @@ -Subproject commit 34987fa26e351ee2c3fb105a48f797fd83479ea3 +Subproject commit a9d31b520b1a418cf70ca3abc4467e90627b0eff diff --git a/src/Previewer/DBusPreviewer.js b/src/Previewer/DBusPreviewer.js index d56e9f891..a1e96a77b 100644 --- a/src/Previewer/DBusPreviewer.js +++ b/src/Previewer/DBusPreviewer.js @@ -42,6 +42,11 @@ async function startProcess(type) { [executable_name, server.get_client_address()], Gio.SubprocessFlags.NONE, ); + + current_sub_process.wait_async(null).then(() => { + dbus_previewer.onStop?.(); + }); + current_type = type; const connection = await new Promise((resolve) => { @@ -83,12 +88,15 @@ async function startProcess(type) { null, ); - proxy.connectSignal("CssParserError", (_proxy, _name_owner, ...args) => { + proxy.connectSignal("CssParserError", (_self, _name_owner, ...args) => { dbus_previewer.onCssParserError?.(...args); }); - proxy.connectSignal("WindowOpen", (_proxy, _name_owner, ...args) => { - dbus_previewer.onWindowOpen?.(...args); + proxy.connectSignal("WindowOpen", (_self, _name_owner, [open]) => { + if (!open) { + dbus_previewer.stop().catch(console.error); + } + // dbus_previewer.onWindowOpen?.(open); }); return proxy; @@ -96,7 +104,8 @@ async function startProcess(type) { const dbus_previewer = { onCssParserError: null, // set in External.js - onWindowOpen: null, // set in External.js + // onWindowOpen: null, // set in External.js + onStop: null, async getProxy(type) { if (current_type !== type) { await this.stop(); diff --git a/src/Previewer/External.js b/src/Previewer/External.js index a85b9618b..0075b608d 100644 --- a/src/Previewer/External.js +++ b/src/Previewer/External.js @@ -1,13 +1,15 @@ import Adw from "gi://Adw"; import dbus_previewer from "./DBusPreviewer.js"; -export default function External({ output, builder, onWindowChange }) { +export default function External({ output, builder, onWindowChange, onStop }) { const stack = builder.get_object("stack_preview"); let dbus_proxy; - dbus_previewer.onWindowOpen = ([open]) => { - onWindowChange(open); - }; + // dbus_previewer.onWindowOpen = (open) => { + // onWindowChange(open); + // }; + + dbus_previewer.onStop = onStop; dbus_previewer.onCssParserError = (error) => { builder diff --git a/src/Previewer/Previewer.js b/src/Previewer/Previewer.js index 992012e72..4d7dfec5f 100644 --- a/src/Previewer/Previewer.js +++ b/src/Previewer/Previewer.js @@ -51,14 +51,14 @@ export default function Previewer({ makeDropdownFlat(dropdown_preview_align); const internal = Internal({ - onWindowChange(open) { - if (current !== internal) return; - if (open) { - stack.set_visible_child_name("close_window"); - } else { - stack.set_visible_child_name("open_window"); - } - }, + // onWindowChange(open) { + // if (current !== internal) return; + // if (open) { + // stack.set_visible_child_name("close_window"); + // } else { + // stack.set_visible_child_name("open_window"); + // } + // }, output, builder, window, @@ -67,16 +67,25 @@ export default function Previewer({ panel_ui, session, }); + + const stack_start_stop = builder.get_object("stack_start_stop"); + const button_run = builder.get_object("button_run"); + // const button_stop = builder.get_object("button_stop"); + const external = External({ - onWindowChange(open) { - if (current !== external) return; - if (open) { - stack.set_visible_child_name("close_window"); - } else { - stack.set_visible_child_name("open_window"); - useInternal().catch(console.error); - } + onStop() { + stack_start_stop.visible_child = button_run; + useInternal().catch(console.error); }, + // onWindowChange(open) { + // if (current !== external) return; + // if (open) { + // stack.set_visible_child_name("close_window"); + // } else { + // stack.set_visible_child_name("open_window"); + // useInternal().catch(console.error); + // } + // }, output, builder, panel_ui, @@ -87,12 +96,12 @@ export default function Previewer({ let handler_id_ui = null; let handler_id_css = null; - let handler_id_button_open; - let handler_id_button_close; + // let handler_id_button_open; + // let handler_id_button_close; const stack = builder.get_object("stack_preview"); - const button_open = builder.get_object("button_open_preview_window"); - const button_close = builder.get_object("button_close_preview_window"); + // const button_open = builder.get_object("button_open_preview_window"); + // const button_close = builder.get_object("button_close_preview_window"); settings.bind( "preview-align", @@ -255,12 +264,12 @@ export default function Previewer({ } async function setPreviewer(previewer, language) { - if (handler_id_button_open) { - button_open.disconnect(handler_id_button_open); - } - if (handler_id_button_close) { - button_close.disconnect(handler_id_button_close); - } + // if (handler_id_button_open) { + // button_open.disconnect(handler_id_button_open); + // } + // if (handler_id_button_close) { + // button_close.disconnect(handler_id_button_close); + // } try { await current?.closeInspector(); @@ -276,23 +285,23 @@ export default function Previewer({ current = previewer; - handler_id_button_open = button_open.connect("clicked", async () => { - try { - await current.open(); - stack.set_visible_child_name("close_window"); - } catch (err) { - console.error(err); - } - }); - - handler_id_button_close = button_close.connect("clicked", async () => { - try { - await current.close(); - stack.set_visible_child_name("open_window"); - } catch (err) { - console.error(err); - } - }); + // handler_id_button_open = button_open.connect("clicked", async () => { + // try { + // await current.open(); + // stack.set_visible_child_name("close_window"); + // } catch (err) { + // console.error(err); + // } + // }); + + // handler_id_button_close = button_close.connect("clicked", async () => { + // try { + // await current.close(); + // stack.set_visible_child_name("open_window"); + // } catch (err) { + // console.error(err); + // } + // }); try { await current.start(language); diff --git a/src/langs/rust/Compiler.js b/src/langs/rust/Compiler.js index 4f479b414..3b7c0449e 100644 --- a/src/langs/rust/Compiler.js +++ b/src/langs/rust/Compiler.js @@ -41,15 +41,21 @@ export default function Compiler({ session }) { } async function run() { + let proxy; + try { - const proxy = await dbus_previewer.getProxy("vala"); // rust uses the Vala previewer. - const sharedLibrary = `${targetPath}/debug/libdemo.so`; - await proxy.RunAsync(sharedLibrary, session.file.get_uri()); + proxy = await dbus_previewer.getProxy("vala"); // rust uses the Vala previewer. + await proxy.RunAsync( + `${targetPath}/debug/libdemo.so`, + session.file.get_uri(), + ); } catch (err) { console.error(err); return false; } + console.log(proxy); + return true; } diff --git a/src/window.blp b/src/window.blp index 79cacde91..5f0b22c54 100644 --- a/src/window.blp +++ b/src/window.blp @@ -121,19 +121,36 @@ Adw.ApplicationWindow window { } [end] - Button button_run { - child: Adw.ButtonContent { - icon-name: "media-playback-start-symbolic"; - label: _("_Run"); - use-underline: true; - }; + Stack stack_start_stop { + Button button_run { + child: Adw.ButtonContent { + icon-name: "media-playback-start-symbolic"; + label: _("_Run"); + use-underline: true; + }; - action-name: "win.run"; - tooltip-text: _("Run (Ctrl+⏎)"); + action-name: "win.run"; + tooltip-text: _("Run (Ctrl+⏎)"); - styles [ - "suggested-action" - ] + styles [ + "suggested-action" + ] + } + + Button button_stop { + child: Adw.ButtonContent { + icon-name: "media-playback-stop-symbolic"; + label: _("_Stop"); + use-underline: true; + }; + + action-name: "win.stop"; + // tooltip-text: _("Stop"); + + styles [ + "suggested-action" + ] + } } } @@ -418,18 +435,18 @@ Adw.ApplicationWindow window { description: _("This interface can only be previewed as a separate window.\nWe recommend using “Always on Top”."); icon-name: "multitasking-windows-symbolic"; - Box { - halign: center; + // Box { + // halign: center; - Button button_open_preview_window { - label: _("Show Preview Window"); + // Button button_open_preview_window { + // label: _("Show Preview Window"); - styles [ - "pill", - "suggested-action" - ] - } - } + // styles [ + // "pill", + // "suggested-action" + // ] + // } + // } }; } @@ -441,17 +458,17 @@ Adw.ApplicationWindow window { description: _("This interface can only be previewed as a separate window.\nWe recommend using “Always on Top”."); icon-name: "multitasking-windows-symbolic"; - Box { - halign: center; + // Box { + // halign: center; - Button button_close_preview_window { - label: _("Close Preview Window"); + // Button button_close_preview_window { + // label: _("Close Preview Window"); - styles [ - "pill" - ] - } - } + // styles [ + // "pill" + // ] + // } + // } }; } } diff --git a/src/window.js b/src/window.js index 2e78f463d..17ddecd52 100644 --- a/src/window.js +++ b/src/window.js @@ -159,7 +159,9 @@ export default function Window({ application, session }) { previewer.setPanelCode(panel_code); + const stack_start_stop = builder.get_object("stack_start_stop"); const button_run = builder.get_object("button_run"); + const button_stop = builder.get_object("button_stop"); const button_preview = builder.get_object("button_preview"); const button_inspector = builder.get_object("button_inspector"); @@ -318,7 +320,7 @@ export default function Window({ application, session }) { let builder_python = null; async function runCode({ format }) { - button_run.set_sensitive(false); + stack_start_stop.visible_child = button_stop; term_console.clear(); previewer.stop(); @@ -331,7 +333,7 @@ export default function Window({ application, session }) { await formatCode(); } - await compile(); + await start(); } catch (err) { // prettier xml errors are not instances of Error if (err instanceof Error || err instanceof GLib.Error) { @@ -344,11 +346,11 @@ export default function Window({ application, session }) { previewer.start(); panel_ui.start(); - button_run.set_sensitive(true); + // stack_start_stop.visible_child = button_run; term_console.scrollToEnd(); } - async function compile() { + async function start() { const { language } = panel_code; const lang = langs[language.toLowerCase()]; From 8bba9bfaf944f59a0cde90ec8c3df64ef79cac0b Mon Sep 17 00:00:00 2001 From: Sonny Piers <sonny@fastmail.net> Date: Sat, 16 Dec 2023 18:39:40 +0100 Subject: [PATCH 2/3] Implement start/stop behaviour --- src/Previewer/External.js | 13 +----- src/Previewer/Internal.js | 10 ++--- src/Previewer/Previewer.js | 82 ++++++++++---------------------------- src/window.blp | 9 ----- src/window.js | 11 +++-- 5 files changed, 33 insertions(+), 92 deletions(-) diff --git a/src/Previewer/External.js b/src/Previewer/External.js index 0075b608d..6f124e16e 100644 --- a/src/Previewer/External.js +++ b/src/Previewer/External.js @@ -1,14 +1,10 @@ import Adw from "gi://Adw"; import dbus_previewer from "./DBusPreviewer.js"; -export default function External({ output, builder, onWindowChange, onStop }) { +export default function External({ output, builder, onStop }) { const stack = builder.get_object("stack_preview"); let dbus_proxy; - // dbus_previewer.onWindowOpen = (open) => { - // onWindowChange(open); - // }; - dbus_previewer.onStop = onStop; dbus_previewer.onCssParserError = (error) => { @@ -48,15 +44,10 @@ export default function External({ output, builder, onWindowChange, onStop }) { console.debug(err); return; } - stack.set_visible_child_name("open_window"); } function stop() { - close() - .then(() => { - return dbus_previewer.stop(); - }) - .catch(console.error); + close().then(() => dbus_previewer.stop()); } async function updateXML({ xml, target_id, original_id }) { diff --git a/src/Previewer/Internal.js b/src/Previewer/Internal.js index faedf2e90..0964eb0ff 100644 --- a/src/Previewer/Internal.js +++ b/src/Previewer/Internal.js @@ -19,6 +19,7 @@ export default function Internal({ dropdown_preview_align, panel_ui, session, + onStop, }) { const inline_css_scope_target = output.get_parent(); inline_css_scope_target.name = `workbench_output-${session.id}`; @@ -51,12 +52,9 @@ export default function Internal({ onWindowChange(true); } - async function close() { - object_root?.close(); - } - function stop() { - close(); + console.log("stop"); + object_root?.close(); if (css_provider) { Gtk.StyleContext.remove_provider_for_display( output.get_display(), @@ -66,6 +64,7 @@ export default function Internal({ } object_root?.destroy(); object_root = null; + onStop(); } function preview(object) { @@ -230,7 +229,6 @@ export default function Internal({ return { async start(_language) {}, open, - close, stop, updateXML, updateCSS, diff --git a/src/Previewer/Previewer.js b/src/Previewer/Previewer.js index 4d7dfec5f..3dbeb124e 100644 --- a/src/Previewer/Previewer.js +++ b/src/Previewer/Previewer.js @@ -51,14 +51,11 @@ export default function Previewer({ makeDropdownFlat(dropdown_preview_align); const internal = Internal({ - // onWindowChange(open) { - // if (current !== internal) return; - // if (open) { - // stack.set_visible_child_name("close_window"); - // } else { - // stack.set_visible_child_name("open_window"); - // } - // }, + onStop() { + console.log("on stop internal"); + stack_start_stop.visible_child = button_run; + update(true); + }, output, builder, window, @@ -74,18 +71,10 @@ export default function Previewer({ const external = External({ onStop() { + console.log("on stop external"); stack_start_stop.visible_child = button_run; useInternal().catch(console.error); }, - // onWindowChange(open) { - // if (current !== external) return; - // if (open) { - // stack.set_visible_child_name("close_window"); - // } else { - // stack.set_visible_child_name("open_window"); - // useInternal().catch(console.error); - // } - // }, output, builder, panel_ui, @@ -96,12 +85,6 @@ export default function Previewer({ let handler_id_ui = null; let handler_id_css = null; - // let handler_id_button_open; - // let handler_id_button_close; - - const stack = builder.get_object("stack_preview"); - // const button_open = builder.get_object("button_open_preview_window"); - // const button_close = builder.get_object("button_close_preview_window"); settings.bind( "preview-align", @@ -118,8 +101,19 @@ export default function Previewer({ } setPreviewAlign(); + function clean() { + if (handler_id_ui) { + panel_ui.disconnect(handler_id_ui); + handler_id_ui = null; + } + if (handler_id_css) { + code_view_css.disconnect(handler_id_css); + handler_id_css = null; + } + } + function start() { - stop(); + clean(); if (handler_id_ui === null) { handler_id_ui = panel_ui.connect("updated", () => schedule_update()); } @@ -131,14 +125,8 @@ export default function Previewer({ } function stop() { - if (handler_id_ui) { - panel_ui.disconnect(handler_id_ui); - handler_id_ui = null; - } - if (handler_id_css) { - code_view_css.disconnect(handler_id_css); - handler_id_css = null; - } + clean(); + current?.stop?.(); } // Using this custom scope we make sure that previewing UI definitions @@ -252,7 +240,6 @@ export default function Previewer({ await setPreviewer(external, language); } current_external_language = language; - stack.set_visible_child_name("close_window"); await update(true); } @@ -264,13 +251,6 @@ export default function Previewer({ } async function setPreviewer(previewer, language) { - // if (handler_id_button_open) { - // button_open.disconnect(handler_id_button_open); - // } - // if (handler_id_button_close) { - // button_close.disconnect(handler_id_button_close); - // } - try { await current?.closeInspector(); } catch { @@ -284,25 +264,6 @@ export default function Previewer({ } current = previewer; - - // handler_id_button_open = button_open.connect("clicked", async () => { - // try { - // await current.open(); - // stack.set_visible_child_name("close_window"); - // } catch (err) { - // console.error(err); - // } - // }); - - // handler_id_button_close = button_close.connect("clicked", async () => { - // try { - // await current.close(); - // stack.set_visible_child_name("open_window"); - // } catch (err) { - // console.error(err); - // } - // }); - try { await current.start(language); } catch (err) { @@ -324,9 +285,6 @@ export default function Previewer({ open() { return current.open(); }, - close() { - return current.close(); - }, openInspector() { return current.openInspector(); }, diff --git a/src/window.blp b/src/window.blp index 5f0b22c54..2bbdac4ee 100644 --- a/src/window.blp +++ b/src/window.blp @@ -144,9 +144,6 @@ Adw.ApplicationWindow window { use-underline: true; }; - action-name: "win.stop"; - // tooltip-text: _("Stop"); - styles [ "suggested-action" ] @@ -434,13 +431,10 @@ Adw.ApplicationWindow window { title: _("Windowed Preview"); description: _("This interface can only be previewed as a separate window.\nWe recommend using “Always on Top”."); icon-name: "multitasking-windows-symbolic"; - // Box { // halign: center; - // Button button_open_preview_window { // label: _("Show Preview Window"); - // styles [ // "pill", // "suggested-action" @@ -457,13 +451,10 @@ Adw.ApplicationWindow window { title: _("Windowed Preview"); description: _("This interface can only be previewed as a separate window.\nWe recommend using “Always on Top”."); icon-name: "multitasking-windows-symbolic"; - // Box { // halign: center; - // Button button_close_preview_window { // label: _("Close Preview Window"); - // styles [ // "pill" // ] diff --git a/src/window.js b/src/window.js index 17ddecd52..fda0d43b9 100644 --- a/src/window.js +++ b/src/window.js @@ -160,7 +160,7 @@ export default function Window({ application, session }) { previewer.setPanelCode(panel_code); const stack_start_stop = builder.get_object("stack_start_stop"); - const button_run = builder.get_object("button_run"); + // const button_run = builder.get_object("button_run"); const button_stop = builder.get_object("button_stop"); const button_preview = builder.get_object("button_preview"); const button_inspector = builder.get_object("button_inspector"); @@ -320,8 +320,6 @@ export default function Window({ application, session }) { let builder_python = null; async function runCode({ format }) { - stack_start_stop.visible_child = button_stop; - term_console.clear(); previewer.stop(); panel_ui.stop(); @@ -346,7 +344,6 @@ export default function Window({ application, session }) { previewer.start(); panel_ui.start(); - // stack_start_stop.visible_child = button_run; term_console.scrollToEnd(); } @@ -360,6 +357,8 @@ export default function Window({ application, session }) { return; } + stack_start_stop.visible_child = button_stop; + if (language === "JavaScript") { await previewer.update(true); @@ -440,6 +439,10 @@ export default function Window({ application, session }) { window.add_action(action_run); application.set_accels_for_action("win.run", ["<Control>Return"]); + button_stop.connect("clicked", () => { + previewer.stop(); + }); + const action_format = new Gio.SimpleAction({ name: "format", }); From c7135a6b656a76b342621a576c9b955c66207539 Mon Sep 17 00:00:00 2001 From: Sonny Piers <sonny@fastmail.net> Date: Wed, 20 Dec 2023 21:12:21 +0100 Subject: [PATCH 3/3] cleanup --- data/app.metainfo.xml | 1 + src/Library/demos | 2 +- src/Previewer/DBusPreviewer.js | 2 -- src/Previewer/Internal.js | 1 - src/Previewer/Previewer.js | 5 +++-- src/langs/rust/Compiler.js | 6 +----- src/window.js | 4 ++++ 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/data/app.metainfo.xml b/data/app.metainfo.xml index 7e1be2d8e..7ba149085 100644 --- a/data/app.metainfo.xml +++ b/data/app.metainfo.xml @@ -54,6 +54,7 @@ <li>Update gst-plugin-gtk4 to 0.11.2</li> <li>Add "Copy" to Console</li> <li>Add "Select All" to Console</li> + <li>Format JavaScript code with Biome instead of Prettier</li> <li>Library: Port "Accessibility" entry to Python</li> <li>Library: Port "Account" entry to Python</li> <li>Library: Port "Email" entry to Python</li> diff --git a/src/Library/demos b/src/Library/demos index a9d31b520..34987fa26 160000 --- a/src/Library/demos +++ b/src/Library/demos @@ -1 +1 @@ -Subproject commit a9d31b520b1a418cf70ca3abc4467e90627b0eff +Subproject commit 34987fa26e351ee2c3fb105a48f797fd83479ea3 diff --git a/src/Previewer/DBusPreviewer.js b/src/Previewer/DBusPreviewer.js index a1e96a77b..cf2e35d41 100644 --- a/src/Previewer/DBusPreviewer.js +++ b/src/Previewer/DBusPreviewer.js @@ -96,7 +96,6 @@ async function startProcess(type) { if (!open) { dbus_previewer.stop().catch(console.error); } - // dbus_previewer.onWindowOpen?.(open); }); return proxy; @@ -104,7 +103,6 @@ async function startProcess(type) { const dbus_previewer = { onCssParserError: null, // set in External.js - // onWindowOpen: null, // set in External.js onStop: null, async getProxy(type) { if (current_type !== type) { diff --git a/src/Previewer/Internal.js b/src/Previewer/Internal.js index 0964eb0ff..ca5faef04 100644 --- a/src/Previewer/Internal.js +++ b/src/Previewer/Internal.js @@ -53,7 +53,6 @@ export default function Internal({ } function stop() { - console.log("stop"); object_root?.close(); if (css_provider) { Gtk.StyleContext.remove_provider_for_display( diff --git a/src/Previewer/Previewer.js b/src/Previewer/Previewer.js index 3dbeb124e..b909f5661 100644 --- a/src/Previewer/Previewer.js +++ b/src/Previewer/Previewer.js @@ -52,7 +52,7 @@ export default function Previewer({ const internal = Internal({ onStop() { - console.log("on stop internal"); + console.log("stopping ouin ouin internal"); stack_start_stop.visible_child = button_run; update(true); }, @@ -71,7 +71,7 @@ export default function Previewer({ const external = External({ onStop() { - console.log("on stop external"); + console.log("stoping ouin ouin external"); stack_start_stop.visible_child = button_run; useInternal().catch(console.error); }, @@ -125,6 +125,7 @@ export default function Previewer({ } function stop() { + console.log("previewer stop"); clean(); current?.stop?.(); } diff --git a/src/langs/rust/Compiler.js b/src/langs/rust/Compiler.js index 3b7c0449e..103c5ce8b 100644 --- a/src/langs/rust/Compiler.js +++ b/src/langs/rust/Compiler.js @@ -41,10 +41,8 @@ export default function Compiler({ session }) { } async function run() { - let proxy; - try { - proxy = await dbus_previewer.getProxy("vala"); // rust uses the Vala previewer. + const proxy = await dbus_previewer.getProxy("vala"); // rust uses the Vala previewer. await proxy.RunAsync( `${targetPath}/debug/libdemo.so`, session.file.get_uri(), @@ -54,8 +52,6 @@ export default function Compiler({ session }) { return false; } - console.log(proxy); - return true; } diff --git a/src/window.js b/src/window.js index 637eb529f..e26a42037 100644 --- a/src/window.js +++ b/src/window.js @@ -306,10 +306,14 @@ export default function Window({ application, session }) { compiler_vala = compiler_vala || ValaCompiler({ session }); const success = await compiler_vala.compile(); if (success) { + console.log("use external"); await previewer.useExternal("vala"); + console.log("run"); if (await compiler_vala.run()) { + console.log("open"); await previewer.open(); } else { + console.log("use internal"); await previewer.useInternal(); } }