Correct event / 'trigger when' to determine which tab is active after NPP start?
-
Two cases:
-
Click on another tab …
NPPN_BUFFERACTIVATED is the notification,
and i could determine the belonging file name(path now. This is correct? -
Start NPP with restoring e.g. 6 files / tabs.
When NPP starts, i’d like to be informed that all files have been opened and one tab is marked as selected.
By what event i can be sure i can determine the belonging file name/path now?
For this example - NPP starts, 6 files / tabs opened - i could trace the following event order:
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED <== this last one appears to be the relevant here
The first three ‘bufferactivated’ events obviously shouldn’t be processed without need.
But by which measure it’s normally achieved that now it’s the time i can begin … ?
Btw., NPPM_ACTIVATEDOC i hadn’t seen here at all.
-
-
Click on another tab …
yes, after changing tabs, NPPN_BUFFERACTIVATED is the indicator that it’s been activated.
When NPP starts, i’d like to be informed that all files have been opened …
By what event i can be sure i can determineHave you tried NPPN_READY ? I’ve never looked into the exact timing, but that’s supposed to be the indicator that N++ is ready after first being launched, so my guess would be that it would occur after all files have been opened. If my guess is right, you could probably process that notification, and then send the NPPM_GETFILENAME for getting the active file’s name.
-
@PeterJones Thanks Peter!
-> Have you tried NPPN_READY
Not yet, but i had already the rough idea, that, hm, there should be some notification that NPP had started, and so i’d need only to focus onto the last ‘bufferactivated’ before … i think that’s just something you pointed me to. I’ll try that, thank you! -
I got this (remembering sometimes i’d already seen ‘bufferactivated’ 4 times at the end):
…
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED
NPPN_READY
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATEDI think that should point to the right direction. Would only need to try out something meaningful with the last BufferIDs …
I’ll try to check, how. after NPPN_READY,- NPPM_GETFILENAME for getting the active file’s name
- resp. NPPM_GETCURRENTBUFFERID, NPPM_GETFULLPATHFROMBUFFERID etc. for the path
will behave.
-
Yep. works perfectly … NPPN_READY gave the solution …
-
@klaus101 said:
NPPN_READY gave the solution
So, klaus101 showed the sequence:
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED
NPPN_READY
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATEDWouldn’t it be better for NPPN_READY to be the first notification, and then this sequence happens:
NPPN_READY
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED
NPPN_FILEOPENED <- I added this one to balance with the number of buff-activated
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATED
NPPN_BUFFERACTIVATEDIn other words, shouldn’t Notepad++ buffer any notifications it wants to send until after it sends NPPN_READY?
The backstory:
I was trying to use NPPN_SNAPSHOTDIRTYFILELOADED and found I was not getting the notification (using PythonScript).
A few breakpoints in N++ source code showed me that NPPN_SNAPSHOTDIRTYFILELOADED is being sent to plugins before NPPN_READY. PythonScript is probably being a “good plugin” and not processing any messaging until it receives the ready signal (an assumption, but probably reasonable). Thus, using PythonScript, I can’t receive NPPN_SNAPSHOTDIRTYFILELOADED.
-
@Alan-Kilborn
That sounds reasonable. But i’d give to consider, a kindof ‘business rule’ should be identifiable for to determine which is the relevant activated buffer, representing the last active tab.
Which is it? Via the first NPPN_BUFFERACTIVATED? Or the last? If the last: how to determine, within a sequence of calls, that the last one is reached? Via timer? If yes: how long would it be expected to wait?Actually at least at me the sequence is as follow:
Scenario: 6 tabs open: Thir first tab helds an ‘abc.pas’, the fourth tab - which is the active tab - a file ‘xyz.pas’. At NPPN_READY i set a flag, and, if the flag ist true, let show each current file name for the following NPPN_BUFFERACTIVATED.
Restart NPP. I’d see:
‘xyz.pas’ // The file within the active tab
‘abc.pas’ // The file within the first tab
‘new 1’ // Obviously for provisorical internal use (there had been no ‘new 1’ open)So actually i can rely that the file name identifiable by the first NPPN_BUFFERACTIVATED after NPPN_READY is the relevant one that i’m waiting for.
Would such kind of rule be preserved? At least such kind of rule should exist. -
You make very good points.
-
@Alan-Kilborn
but i had not been quite precise either.
Had been a bit interested to see why at all it’s notifying about the first file:
is it about the first tab (of all tabs), or, if not all tabs might fit into the view and the view is scrolled to the right, is it maybe the left visible tab (first tab visible on the left side of a scrolled view)?
By that quick test i saw that those 3 files as from my example are debug-reported after having closed the session.When the session is still running, i see only exactly one file is debug-reported, and this is the file held in the active tab.
A perfect hook for to determine the active tab / file: exactly one NPPN_BUFFERACTIVATED after NPPN_READY …
Maybe that somebody who knows the internals of the NPP cpp-code might confirm - or disprove - that’s intentionally implemented in this way.
Btw, i had inspected with the 8.7.2 64bit portable. -
@klaus101 said :
exactly one NPPN_BUFFERACTIVATED after NPPN_READY
That seems acceptable to me, for my purposes, but I’m not sure to all.
Regardless, the original sequence (some number of buff-activateds, then “ready”, then more buff-activateds) definitely feels wrong.
I’d like some plugin authors to comment. Perhaps @Coises , @rdipardo , @Thomas-Knoefel, @Mark-Olson, others…?
-
Regarding @klaus101’s suggestion of having exactly one
NPPN_BUFFERACTIVATED
afterNPPN_READY
, that sounds pretty clever to me, and I would definitely endorse that.I have no idea how straightforward it would be to implement that, but hopefully not too hard… right?
-
Thanks for commenting.
The more I think about it, “one NPPN_BUFFERACTIVATED after NPPN_READY” may not even be necessary. When one gets the NPPN_READY, they can easily see which buffer is the active one (if needed).
The buffer really isn’t “activated” in the traditional sense here anyway. The traditional sense is the user activates a tab (or something else does in the normal flow). Notepad++ restoring a saved (default) session at startup seems artificial and possibly should be ignored. The “ready” signal should be enough in this case. (And, where’s “opened” notifications?)
Analogously, should plugins get the “closed” notification when N++ is shutting down? The tabs/files aren’t really being closed in a user sense (since they’ll be opened on the next run). Maybe this IS a bit different, as such a sequence also generates the save-this-file? query when a file is changed and N++ is not configured in “snapshot” mode.
It seems there are (or at least I have) a lot of questions regarding this. :-)
-
@Alan-Kilborn pinged me in chat, so I’ll chime in, even though, other than “it should be consistent, so plugins can rely on it”, I haven’t thought enough about that to really form a strong opinion.
At first glance, the many-NPPN_BUFFERACTIVATED as N++ loads, then NPPN_READY, then exactly one NPPN_BUFFERACTIVATED to set and indicate the actual active buffer makes sense to me.
Though as I was typing that, I had the additional thought: when there are two Views visible, would it make sense to have two NPPN_BUFFERACTIVATED after NPPN_READY? One to bring the right tab to the front on the inactive View, then the second to bring the right tab to the front on the active View. If that’s confusing: say N++ was closed with A, B, C open in View1 with B as the front tab; and X, Y, Z open in View2 with X as the front tab; with View1 as the active view (so B is the truly active tab); when N++ restarts, it could do up to 6 NPPN_BUFFERACTIVATED while loading the files, then NPPN_READY, then NPPN_BUFFERACTIVATED for View2.X to indicate the active on View2, then NPPN_BUFFERACTIVATED for View1.B, to indicate the active on View1 as the truly-active. But maybe that doesn’t make sense – I haven’t run any of the experiments or really thought about what would be truly meaningful to me, as none of my scripts have needed to use NPPN_READY, so the subtleties escape me.
-
@Alan-Kilborn said in Correct event / 'trigger when' to determine which tab is active after NPP start?:
@klaus101 said :
exactly one NPPN_BUFFERACTIVATED after NPPN_READY
That seems acceptable to me, for my purposes, but I’m not sure to all.
Regardless, the original sequence (some number of buff-activateds, then “ready”, then more buff-activateds) definitely feels wrong.
I’d like some plugin authors to comment. Perhaps @Coises , @rdipardo , @Thomas-Knoefel, @Mark-Olson, others…?
-
My first thought is that I’d want anyone suggesting changes to be sure they thoroughly understand what is happening now and why before proposing something different. (I’m not claiming such knowledge myself.)
-
My experience is that NPPN_BUFFERACTIVATED can occur at times you don’t expect it. Anything you do there should be “idempotent” (meaning unnecessary repetitions have no effect) and if it’s non-trivial you want to check to be sure it’s necessary.
-
I’ve not used sessions (and, now that I think of it, never tested my plugin with them), but I suppose you could have a session that opens both views. That might be one reason for multiple NPPN_BUFFERACTIVATED messages to occur after NPPN_READY. (But I wouldn’t assume that, either.)
-
-
Two points:
-
What is the true definition of
NPPN_READY
? Ready for what? Should notifications received beforeNPPN_READY
not be acted upon, or buffered by the plugin until NPPN_READY is received, and then acted upon? -
I can work with N++ the way it is, but I’m a scripter, and if PythonScript isn’t forwarding me notifications before it itself receives NPPN_READY, because someone judged that that’s what NPPN_READY means, then I can explore that via a PythonScript “issue”.
-
-
@Coises said in Correct event / 'trigger when' to determine which tab is active after NPP start?:
- My first thought is that I’d want anyone suggesting changes to be sure they thoroughly understand what is happening now and why before proposing something different. (I’m not claiming such knowledge myself.)
I completely agree with this and would rephrase it as follows.
I’m afraid we are looking for consistency where there truly is none. Let’s acknowledge that the plugin “API” is just a years-long accretion of ad hoc feature requests that seemed like good ideas at the time. It is the major reason (but far from the only one) that plugin development is so often an exhausting, error-prone chore.
There is no notification “protocol,” with a guaranteed, rational, documented order of events. There is only a massive
switch-case
in the aptly name NppBigSwitch source file.Anyone can debug the start-up process under the conditions of interest and see what gets called in what order. Do that enough times, under a suitably broad matrix of conditions, and you might discover something like a pattern. Like @Coises, I would suggest doing nothing until that investigative work is completed.
-
@Alan-Kilborn said in Correct event / 'trigger when' to determine which tab is active after NPP start?:
Two points:
- What is the true definition of
NPPN_READY
? Ready for what? Should notifications received beforeNPPN_READY
not be acted upon, or buffered by the plugin until NPPN_READY is received, and then acted upon?
I don’t think there is a “true” definition other than the code itself. In general, NPPN_READY is a place to do things you only want to do once, but after “most” of the Notepad++ environment is set up — for example, the menus are already built, the tool bars are set up (I think NPPN_TBMODIFICATION comes before NPPN_READY; and you noted that NPPN_SNAPSHOTDIRTYFILELOADED comes before NPPN_READY), I believe dockable panels are up —but the message loop hasn’t yet started and user interaction hasn’t yet become possible.
Looking over my own plugin, I recall that I ignore NPPN_BUFFERACTIVATED messages before NPPN_READY, but I did need to call my buffer activated process during NPPN_READY, because an NPPN_BUFFERACTIVATED message didn’t reliably come afterward.
- I can work with N++ the way it is, but I’m a scripter, and if PythonScript isn’t forwarding me notifications before it itself receives NPPN_READY, because someone judged that that’s what NPPN_READY means, then I can explore that via a PythonScript “issue”.
If plugins were never supposed to process messages before NPPN_READY, Notepad++ wouldn’t send them. I have no idea if PythonScript has its reasons for ignoring all messages before NPPN_READY — there might be one-time setup that it does in NPPN_READY that leaves it unable to function earlier — but there is no general expectation that plugins should do that.
- What is the true definition of