-
Notifications
You must be signed in to change notification settings - Fork 82
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
Add callback mechanism for GUI mode #301
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #301 +/- ##
==========================================
- Coverage 77.81% 77.48% -0.33%
==========================================
Files 16 17 +1
Lines 2010 2034 +24
==========================================
+ Hits 1564 1576 +12
- Misses 446 458 +12 ☔ View full report in Codecov by Sentry. |
15e8366
to
dbb930c
Compare
884c7df
to
3f0188b
Compare
Edit: This is no longer an issue with labeling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I'm excited about these changes @elevans!
I'm a bit wary about that new override
parameter on the initialization function, though - let's discuss below.
Otherwise, there is no way to access it from other threads. This may be useful for scenarios like napari-imagej, where access to Python scripting is available from threads other than the blocked one.
This is an internal variable, not intended as public API.
It doesn't need to be "ij_wrapper" or "ij_fixture". It's OK to be ij!
This test checks that functions registered via when_imagej_starts get called as part of imagej.init.
This commit adds section 5.2 to the "Convenience methods of PyImageJ" that describes how to use the when_image_starts callback mechanism.
This commit introduces a check to determine if the current running thread is the main thread. If True, then we continue to block interactive mode on macOS (it is not possible to share the main thread with GUI event loop needed for the ImageJ GUI). If False, then the current thread is *not* the main thread (e.g. a jaunched session) and interactive mode for macOS can proceed.
fda4992
to
d0eed46
Compare
Thanks @gselzer for your review! It made it sooo much better! I addressed all your comments. Ready to merge? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love the new changes!
...unfortunately, I requested a couple new things 😅
Use a more descriptive attribute name and value for when_imagej_starts() test.
This commit adds the pthread library loading exception to the logger and assumes that the current thread is the main thread if no pthread library is found.
The default here should be None, not True, otherwise this test does not actually test for the `_testing` attribute value.
This commit improves how we clean up the gateway once the UI is closed in gui mode. Although it is highly unlikely, it is possible for a user to run into a NameError when deleting the gateway if a user enters gui mode but is NOT on macos and successfully exits the gui without crashing the session (see next below, this requires some playing around). This is resolved by assigning the gateway to None, ensuring there is *something* to delete if no gateway object is assigned. This commit also adds an additional check for a running JVM instance when in gui mode on non-macos systems. This prevents a `jpype._core.JVMNotRunning: Java Virtual Machine is not running` error that is produced when the imagej ui visbility is polled but is no longer available because the JVM has been shut down via gui interactions.
Update
Update I wanted to preserve the original text (below) for this PR as its relevant to the goals (i.e. create a better experience for macOS users). With the awesome work that @ctrueden has done with
jaunch
we now have a way to actually supportinteractive
mode on macOS. This PR introduces the following new elements and also paves the way for interactive mode on macOS viajaunch
.This PR adds:
when_imagej_starts()
. This can enable some GUI related workflows on macOS (a kind of limited psuedo-interactive mode). See notebook 5 section5.2
for the relevant documentation. This callback mechanism is not compatible with napari.override
flag to the maininit
method. This flag will enable users/developers to bypass initialization checks/blocks we've put in place to stop unsupported/application breaking behavior -- mainlyinteractive
mode on macOS. To test interactive mode on macOS:jaunch
'sfiji.py
file. Add theoverride=True
flag toij = imagej.init(app_dir, mode="interactive")
on line 72../fiji-macos-universal -i --python
.Some other relevant information: Based on what I now understand about Python's threading system and some experimentation on macOS/Linux with
jaunch
, Python will always think its in a main thread. There is no way (from what I gather) to know if a particular Python instance was started with/in apthread
. Instead, threads that are spawned from an already running instance, say in a function that creates threads, are identified as "non-main" thread. This is obvious, but it would have been cool if there was a way to know about how the current instance was started.Original text
Until we can find a true interactive mode for macOS (see #298) this callback mechanism gives macOS users the ability to run their desired Python functions before the REPL is locked by the
AppHelper.runConsoleEventLoop()
.Here's how you register a callback with PyImageJ:
Unfortunately this callback strategy doesn't work with
napari
. Registering the callbacklambda: napari.Viewer()
results in this segfault: