Description
Hi niceguys,
my native mode window ignores its settings when spawning it through an executable script.
Say we take the example from the website and installed it in a venv:
# main.py
from nicegui import app, ui
app.native.window_args['resizable'] = False
app.native.start_args['debug'] = True
app.native.settings['ALLOW_DOWNLOADS'] = True
ui.label('app running in native mode')
ui.button('enlarge', on_click=lambda: app.native.main_window.resize(1000, 700))
ui.run(native=True, window_size=(400, 300), fullscreen=False)
By "settings" I mean these values like "resizable"
.
Now I made this a "script" where script means the pip/distlib .exe that is created in .venv\Scripts
when you pip install
a project that has a [project.scripts]
section in its pyproject.toml. Such script endpoints specify a callable from a module, which should be imported and called without args on launch of the script. Here this can be done by adding an empty dummy function at the bottom of the file, as long as the rest of the code runs on import, this is sufficient to spawn the native window.
Now though, the app.native
settings don't get applied, i.e. no debug window shows, and the window is resizable.
Turns out for these settings to get applied, the multiprocessing.Process
that runs the pywebview window has to import and run these lines of code again. This is the case when running as __main__
, where mp runs the module again as __mp_main__
(some sort of special behavior there I guess), but not if it was imported like it is when running a script.exe. Here, only the parent process runs the module, but not the subprocess, i.e. no __mp_main__
will appear if you print __name__
at the start of the file. As a result, any settings done to app.native
are basically irrelevant, since they're not seen by or transferred to the mp subprocess, which is the one that needs them as it spawns the window from its app context.
Another effect is that even if you run this as __main__
, any modification to app.native
that you do under a __main__
guard, say for example taking the value for the debug setting from a --debug
flag from the command line, will not do anything. You will have to do the exact same argparsing again in an __mp_main__
guard of the subprocess to setup any window related flags in app.native
there.
I finally found a workaround for this, which is
- Launching through runpy:
# __init__.py
def run_main_from_script():
runpy.run_module(f"{__name__}.main", run_name="__main__", alter_sys=True)
- Sending all settings for
app.native
through env vars down to the subprocess, i.e.
- run cli / argparse if
__main__
- somehow encode all relevant data into
os.environ
- if
__mp_main__
, read settings fromos.environ
and apply toapp.native
.
This way, argparsing gets done only once, and all settings are applied correctly.
But that's quite tedious. Am I missing something here?
❓Would it make sense if NiceGUI somehow sent the app.native
settings down to the mp.Process when creating it (as args or such), instead of relying on that it will read them itself by running the code again? Or would that conflict with something else?
Sorry for the long text, but I wanted to make it clear. ^^