Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't build GUI-optional (CLI mode) app because of qode. #986

Open
dzek69 opened this issue Jan 6, 2023 · 6 comments
Open

Can't build GUI-optional (CLI mode) app because of qode. #986

dzek69 opened this issue Jan 6, 2023 · 6 comments

Comments

@dzek69
Copy link

dzek69 commented Jan 6, 2023

Describe the bug
I want to create an app that can work with gui by default but optionally allow to pass some cli flags to skip the GUI.

But qode injects stuff into node.js event loop, causing simple console.log(123); app to run forever (until I forcibly quit it with ctrl+c or process.exit() in the code).

Creating a "starter script", that will try to decide if I should run the app with node or qode (and replace static imports with dynamic imports of nodegui) is no perfect, because sometimes I want to do cli only background job, but sometimes I want to popup a window to let user decide about something.

Adding process.exit(0) at the end of my script isn't too perfect again, because I'd have to keep track of all started background tasks somehow, to be sure if that's the right moment to call process.exit();

Is there a way to rework qode that it will only start to inject event loop stuff on demand, when a first QT stuff is created?

This way node can close the app automatically when all the background stuff ends.

To Reproduce
Steps to reproduce the behavior:

  1. Use this code in the starter repo:
const action = process.argv[2];

if (action === "--cli") {
  console.log("doing stuff via cli");
}
else {
  (async () => {
    const { QMainWindow, QLabel } = await import("@nodegui/nodegui")
    const win = new QMainWindow();
    win.setWindowTitle("Hello World");

    const label = new QLabel();
    label.setText("Do stuff via GUI");
    win.setCentralWidget(label);
    win.show();

    (global as any).win = win;
  })();
}

Run node dist --cli - this is how node is behaving - it will quit the app after console log
Run qode dist --cli - qode will keep app running forever, even if no nodegui stuff is ever used (you can even remove the else)

Expected behavior
With above code app should quit automatically with qode when run with --cli flag. It should not without the flag of course to let GUI live.

Screenshots
no screenshots

Desktop (please complete the following information):

  • OS: Linux
  • NodeGUI version: 0.58.0-rc2
  • OS Version: Mint 21.1 Cinnamon

Additional context
It's all written in the top.

@J-Cake
Copy link

J-Cake commented Aug 21, 2023

Can't you decide which executable to call based on the presence/absence of the flag? In theory, if you're running in CLI mode, the standard Node binary has the behaviour you want, while GUI requires Qode, so why not wrap your program in a script which swaps the binary?

Something like this may do the job:

#!node
import cp from 'node:child_process';

const cli_flag = process.argv.indexOf('--cli');

if (cli_flag >= -1)
    cp.spawn('node', process.argv.slice(1), { stdio: 'inherit' });
else
    cp.spawn('qode', [...process.argv.slice(1, cli_flag), ...process.argv.slice(cli_flag)], { stdio: 'iherit' });

Please don't use that script as-is as I've just written it up without testing it, but in principle this might be an approach.

@dzek69
Copy link
Author

dzek69 commented Aug 21, 2023

@J-Cake I already considered this one, quoting myself:

Creating a "starter script", that will try to decide if I should run the app with node or qode (and replace static imports with dynamic imports of nodegui) is no perfect, because sometimes I want to do cli only background job, but sometimes I want to popup a window to let user decide about something.

I mean I run something that takes time and I don't know know in advance if GUI will be needed. So by default I choose node and then I'd have to take parts out my app out to let it run with qode and then maybe continue node script, etc.

I know it's ultimately possible, but adds a lot of complexity.

Having something like that, quoting again:

Is there a way to rework qode that it will only start to inject event loop stuff on demand, when a first QT stuff is created?

Would save a lot of trouble.

@J-Cake
Copy link

J-Cake commented Aug 21, 2023

It's not superb, but there's always process.exit().

export default async function main(argv: string[]) -> Promise<boolean> {
    // Do shit here. Can also be Qt stuff
}

await main(process.argv.slice(2))
    .then(function(success) {
        if (!did_launch_gui) process.exit(success ? 0 : 1);
    });

@dzek69
Copy link
Author

dzek69 commented Aug 21, 2023

Yeah, if I remember well that's what I was doing. I paused the project, so I don't remember well. Thanks for your suggestions.

@J-Cake
Copy link

J-Cake commented Aug 21, 2023

Ah I see. Well I remember encountering something like this. You wanna know what I did? I switched to writing it in C++ 😆

@dzek69
Copy link
Author

dzek69 commented Aug 21, 2023

It's tempting but I don't have time to learn all the details about c++. So many ideas, so little time to implement them. So I just hope this project can improve a little :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants