how best to use IgorStartOrNewHook

IgorStartOrNewHook allows Igor to do something after startup.

If the user starts Igor, the thing is done, all is fine.

But if the user starts Igor by double-clicking a pxp file, Igor starts, and runs the hook function before opening the experiment. Any non-modal thing I want to do is seemingly not possible.

It would be ideal to wait until the experiment is opened, and then run some code. But I can't see how to do that.

I could perhaps use IgorBeforeQuitHook to prevent the experiment being opened and allow the non-modal thing to happen. IgorStartOrNewHook sets a global variable with an expiry time, IgorBeforeQuitHook reads the variable, kills it, and returns 1 if the variable was recently set. But then the user is left without their experiment opened.

What am I missing? Is there some way to know that an experiment load is pending, and ideally to run some code after the experiment is reloaded?

Maybe there's a method using AfterCompiledHook and checking for uptime?

In reply to by aclight

Do I understand this sequence of events correctly:

user double-clicks an experiment file while igor is closed

1. igor is started

2. any IgorStartOrNewHook is called

3. the experiment is opened without calling any other hook (like IgorBeforeQuitHook)

4. any AfterFileOpenHook is called

The only pause between 2 and 3 is if the IgorStartOrNewHook activities leave igor in a modified state, in which case Igor offers to save changes to untitled.

The behaviour I'm looking for is: do stuff when Igor is started, but not if the stuff done is going to go unnoticed when 2 progresses to 3.

It looks like I have to use a modal solution.

> The only pause between 2 and 3 is if the IgorStartOrNewHook activities leave igor in a modified state, in which case Igor offers to save changes to untitled.

I would think that Igor should not be offering to save changes here. You have started with an unmodified experiment and modified it. But you are not quitting that modified experiment. So, why pause here to offer to save changes?

> The behaviour I'm looking for is: do stuff when Igor is started, but not if the stuff done is going to go unnoticed when 2 progresses to 3.

I am still puzzled by the sequence that you propose. Is this the issue:

* --> IgorStartOrNewHook: stuff is done
* (stuff done goes unnoticed)?????
* --> AfterFileOpenHook: FAILS because stuff went unnoticed

What then is meant by "goes unnoticed"?

If the hook function does something that Igor thinks is a modification (like creating a global variable or a wave, or even moving a window) then Igor will ask if you want to save. You can tell Igor to ignore your changes using ExperimentModified. Don't know if that helps you or not, as I didn't really follow what you're trying to do. Does Adam's suggestion help at all?

In reply to by jjweimer

jjweimer wrote:
I would think that Igor should not be offering to save changes here. You have started with an unmodified experiment and modified it. But you are not quitting that modified experiment. So, why pause here to offer to save changes?

I think that when you start Igor by double clicking an experiment, Igor first starts as if you had clicked on the Igor icon (creating an unmodified experiment called untitled), then runs IgorStartOrNewHook, then opens the experiment file. In the normal course of events the 'untitled' experiment is closed and the double-clicked experiment is opened. The hook activities make changes to the untitled experiment, NOT the experiment that's subsequently opened.

jjweimer wrote:
I am still puzzled by the sequence that you propose. Is this the issue:

* --> IgorStartOrNewHook: stuff is done
* (stuff done goes unnoticed)?????
* --> AfterFileOpenHook: FAILS because stuff went unnoticed

What then is meant by "goes unnoticed"?

I've been working on some potential improvements for the package management code that you recently and kindly evaluated for me. I wanted to try a new way to perform periodic checks to find out if updates are available for installed packages. If insufficient time has elapsed since the last check, I don't want to perform another check because it's slow and would be an annoyance. So the issue is that igor is started, a check is done, but unless I present a modal dialog I have no way to let the user know that an update is available (hence "goes unnoticed"). Repeating this process with the AfterFileOpenHook doesn't happen (rather than "fails") because the check is allowed to happen only periodically.

Maybe checking could be done in the background. In fact, yes, that's the answer: do it in the background with a delayed start. I just tested this and it works. Problem solved, I think. Even in the background the checking process locks up Igor for a while, but at least now double-clicking an experiment bypasses the check, which I can deal with.

In reply to by johnweeks

johnweeks wrote:

If the hook function does something that Igor thinks is a modification (like creating a global variable or a wave, or even moving a window) then Igor will ask if you want to save. You can tell Igor to ignore your changes using ExperimentModified. Don't know if that helps you or not, as I didn't really follow what you're trying to do. Does Adam's suggestion help at all?

Yes, I was using ExperimentModified to avoid the save dialog, I just couldn't find a way to anticipate whether or not an existing experiment file was going to be opened. The background task trick works fine, because the experiment is opened before the task fires (I delay by 60 ticks).

The same task is then fired by AfterFileOpenHook.

I'm not following how you use the background task. Is it started by StartOrNewHook? and it fires after the experiment file is opened? Seems like we shouldn't allow that :)

No, you don't allow that!

I use it to delay the start of the stuff that I would normally do with StartOrNewHook, so that the experiment is opened before it has a chance to run. So yes, started by StartOrNewHook, but with a 1 s delay to allow for an experiment to be opened instead.

It's like a conditional StartOrNewHook that doesn't run if the Untitled experiment is going to be closed as soon as the hook code would have finished running.

Ah, I get it. So you *count* on us cleaning up the background task if an experiment is being opened by double-click! Your usual clever programming.

Seems like we ought to be able to put a flag in the StartOrNewHook if Igor is about to open an experiment file. But that's just speculation. We depend on an event early in the process that tells us that the user started Igor by double-clicking an experiment file. Ah... and we store that name for later. On Windows, the file name is part of the command that starts Igor. On Macintosh, it's an Apple Event. I'm not sure if the event comes in early enough on Macintosh to do the job.

> I've been working on some potential improvements for the package management code that you recently and kindly evaluated for me. 

Thanks Tony. Your recent improvements are greatly appreciated. I truly love the new look, and I am honored to have been somewhere inspiring behind the changes.

Might I now recommend something again based on what I think that I hear that you are trying to do?

The TeXLive package manager was the motivator for my previous suggestions for how I might envision the UI for an Igor Pro package manager. The TeXLive package manager does not do anything to update packages *automatically*. It only serves to gather the information for the TeX install and present the user with the data and option to update. The user must always click a button to update a package individually or to update all packages.

I am in awe of your interest now to have the Igor Pro package manager also do automatic updates. While I can grasp at the concept and outline the practice, the endeavor itself is well beyond my programming skill level. I can reasonably guess that, implementing the plan you have may be more trouble than it is worth. I can also reasonably guess that the automatic update feature will go un-appreciated by most users or, even worse, it will lead to more headaches down the road than you might be able to plan against now. To put the former in perspective, you need only look at the number of users who are following the development of the package manager against the number of users who are just able by comparison to "play around with" Igor Pro. By specific example, I am not even yet sure how to bring my graduate students up to speed about installing some of the packages that I think are worthwhile let alone about how to start now also using the package manager.

So, in summary: Would you be put off when I would suggest, from my perspective, the best approach is to purposely and systematically avoid designing the package manager such that it invokes automatic updates?

In reply to by jjweimer

jjweimer wrote:
So, in summary: Would you be put off when I would suggest, from my perspective, the best approach is to purposely and systematically avoid designing the package manager such that it invokes automatic updates?

The UI that you saw recently is a control panel with a tab for installing packages, and a tab for updates. The updates tab gathers information about installed packages and presents their status, so that the user can click on 'update' when a newer release is available.

What I am trying to do is to make a periodic check to find out whether any installed package has an update available, ie. to run the same code that builds the list that appears in the updates tab. Only when an update is available is the user alerted: "an update is available, would you like to view updates?". Clicking yes invokes the UI with the updates tab open. That's it.

So it's more of a periodic check for updates rather than automated updating.

The updater project has always provided a way to install packages, to check for updates and to install updates, but it was done in a convoluted way and demanded that project releases were compliant with updater. In the old way, each installed package would request during startup that a check be made for updates. If a recent check had been made or when no updates are found this was unobtrusive.

The thing I am playing with is to allow updater to make periodic checks for updates to any* installed package, not just those that are built to be compliant. An update can be requested whether or not the package is currently loaded.

* this is only true for relatively simple packages, and update checking doesn't happen for anything that doesn't contain at least one ipf. For packages that require things like OS-specific XOPs installation is still possible, but requires some developer input.

 

 

 

How do you track that sufficient time has passed between two update checks? Are you using Package settings? We are using package settings for the window position in the codebrowser, see https://github.com/byte-physics/igor-code-browser/blob/master/procedure…. Nowadays I'm using JSON for package settings.

I might be special but I'm opening and closing Igor a billion times a day so just doing it always on startup seems like overkill for me. URLRequest is also threadsafe so you could also push that out into a preemptive thread.

In reply to by thomas_braun

@thomas_braun

Yes, I use a preferences file.

In fact, the current release uses a separate small prefs file for each project that it tracks, just to hold the last check time.

The method I'm working on will not use multiple prefs files, but it will store a last check time (and desired check frequency) in prefs.

So the check for sufficient time should be fast enough not to be noticeable: load prefs, check datetime against last check time, return. The actual check against remote version numbers would happen only weekly or monthly or something like that.

thomas_braun wrote:
URLRequest is also threadsafe so you could also push that out into a preemptive thread.
A-ha, I didn't expect it to be threadsafe. That's great.