Copy link to clipboard
Copied
Is there a supported way to remove an app event handler?
Sample snippet:
f = function(event){
if(event.object instanceof Document && event.type == 'loaded'){
//do stuff
}
return {handled:false};
}
app.eventHandlers.push({handler:f});
So this works great, I have a floating palette and want to force a display refresh when the user changes folders in the Bridge browser window. I tried registering the click event in the palette (where the event handler can be removed) but window events don't work right or even the same cross-platform.
My problem is that after closing the palette, the app event handler and function f() remain active and continue to fire. So every time the browser loads, f() is executed.
I tried a window.onClose() event but can't figure out how to remove the handler (beyond deleting app.eventHandlers[0] which risks deleting an event handler from a different script.) Redefining the function f() doesn't work. Adobe's documentation only talks about setting this handler and that its a simple array entry, not how to remove it. No listing of methods and nothing in Event Model Viewer.
Any ideas?
With closing palette you use, additional code can be triggered, that wlll set environmental variable to true. And vice versa, when you open palette again, that variable will be set to false. This way when you close palette, handler won't work untill you open it again. I assume you saved your handler code inside Bridge Scripts folder, right? while palette script is separate code (in Bridge Scripts of Common Files that are in Program Files folder). At least it's how it should be done that worked.
H
...Copy link to clipboard
Copied
With closing palette you use, additional code can be triggered, that wlll set environmental variable to true. And vice versa, when you open palette again, that variable will be set to false. This way when you close palette, handler won't work untill you open it again. I assume you saved your handler code inside Bridge Scripts folder, right? while palette script is separate code (in Bridge Scripts of Common Files that are in Program Files folder). At least it's how it should be done that worked.
Here you have example - two scripts: Handler and Switch. Study them to use your way in your codes (with get / set env):
f = function(event) {
if (!$.getenv('h') && event.type == 'loaded'
&& event.object instanceof Document) {
alert('Hello!')
}
return {handled:false}
}
app.eventHandlers.push({handler:f})
#target bridge
onoff = new MenuElement('command',
'onoff', 'at the end of Thumbnail')
onoff.onSelect = function() {
if ($.getenv('h')) {
$.setenv('h', '')
}
else {
$.setenv('h', ' ')
}
}
The only thing I don't understand why Handler is executed twice (you'll see it in my example when 'Hello!' pops up 2 times). Maybe there is double refreshment like first normal, and then another when current folder gets selection? - I have no idea!)
Copy link to clipboard
Copied
Yeah it looks like a variable is the best bet. I can use array.pop() or delete to remove the array entry but I would risk deleting another script's handler. I tried walking the array but can't figure out how to match the elements.
I'm trying to show a confirm dialog when the user selects a Collection, to choose an export folder. Once the palette is closed, I don't want a dialog popping up.
Copy link to clipboard
Copied
I never worked in Bridge with handlers, as I even didn't know they are part of. I played with them only in Photoshop, but never met similar problem like this you came with. That was interesting challange for me. Like I said closing palette sets variable to true, so handler won't work untill your user call palette again what will trigger handler as well and so on. This action won't affect other handlers, at least there's no visible risk Test it and tell me how that worked, so I'll use it too...
Copy link to clipboard
Copied
Using $.setenv and $.getenv would be also my suggestion, as @Kukurikus wrote.
The only thing I don't understand why Handler is executed twice (you'll see it in my example when 'Hello!' pops up 2 times). Maybe there is double refreshment like first normal, and then another when current folder gets selection? - I have no idea!)
The fact that it triggers twice, it depends only on this: when you select a new folder that already has a bridge cache memory built.
When you select a folder for the first time (or if the cache was deleted before) it triggers only once.
If the folder has already registry in the cache, it triggers before the cache is verified and after the cache is verified.
All the other triggers are running only once each and are related to this:
- when Bridge has focus (when you move to other app and return to Bridge);
- when you rebuild cache in a folder;
- when you refresh (F5);
- when you create or delete a thumbnail (file or folder)
- when you re-order the thumbnails the first time in a folder (in fact, is due to the creation of a invisible xml file called .BridgeSort that contains de new annual order. If you you remove manual order to other order, the files remains and do not trigger any more, unless you delete the invisible file by script)
- when you label or rate a folder (it creates - like above - an invisible xml file called .BridgeLabelsAndRatings and the trigger runs only the first time this file it is created)
To trigger only once when each start of Bridge, use this simple solution.
$.setenv("onlyOnce", false);
//
var loadedEvent = function(event) {
if (event.type == 'loaded' && event.object instanceof Document) {
if ($.getenv("onlyOnce").toString() == "false") {
// YOUR CODE HERE TO RUN ONLY ONCE
//
$.setenv("onlyOnce", true);
}
}
return {handled:false}
}
app.eventHandlers.push({handler:loadedEvent})
Hope it helps.
Copy link to clipboard
Copied
Wow, very professional advices! I didn't know your knowledge covers also Bridge! Not many people post here while Br has potential Normally I would've used eval(!$.getenv("onlyOnce")), but it is because I didn't think up other way to do it
Copy link to clipboard
Copied
Yes, Bridge is so so powerful and there is an huge lack of information on what people can do with it.
Copy link to clipboard
Copied
If I do it this way I can not get it to return back to false it stays true.
Copy link to clipboard
Copied
It is running multiple times for me as well. I tried the $.setenv("onlyOnce", false); solution but it did not work. It either stays true or runs multiple times.
Copy link to clipboard
Copied
Are you talking about the loaded event? Adobe recommends using this before you do other operations but then has very little documentation on exactly how it works. :sigh:
I'm seeing the same thing with the document select event, which isn't even listed in the SDK pdfs. I have a script that swaps out iconbutton images if the user changes color theme.
Copy link to clipboard
Copied
Yes I am.
var mylib = new ExternalObject("lib:" + externalObjectName);
function eventHandler() {
$.setenv("onlyOnce", false);
app.eventHandlers.push({ handler: createSelectionHandler });
function createSelectionHandler(event) {
if (event.object instanceof Document && event.type === 'loaded') {
// $.writeln($.getenv("onlyOnce").toString())
// if ($.getenv("onlyOnce").toString() == "false") {
$.writeln(event.type)
$.writeln(event.object)
$.writeln(app.document.id)
// $.writeln(pth)
var newPth = app.document.presentationPath;
$.writeln(newPth)
$.setenv("onlyOnce", true);
// }
// var eventObj = new CSXSEvent();
// eventObj.type = "update";
// eventObj.data = "page changed"
// eventObj.dispatch();
}
return { handled: false }
}
}
bt = new BridgeTalk();
bt.target = "bridge";
bt.body = "eventHandler();" + eventHandler.toString();
bt.onError = function (btErr) { result = btErr.body; alert(result) };
bt.onResult = function (btRes) { result = btRes.body };
bt.send(8);
Copy link to clipboard
Copied
Cached folders cause this event to fire twice but I don't know how to get around.
Copy link to clipboard
Copied
I have a bug filed where event handlers aren't removed from the array when I use pop.