[haiku-development] Re: Help regarding Dynamic Menu in Tracker

  • From: Hrishi Hiraskar <hrishihiraskar@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Thu, 26 Apr 2018 14:37:34 +0000

Thank you Stephen.

This does makes sense to me. It will be lot cleaner by doing so.

I'll try to implement this next...

Regards

On Thu, Apr 26, 2018 at 7:57 PM Stephan Aßmus <superstippi@xxxxxx> wrote:

Hi,

Am 26.04.2018 um 14:44 schrieb Adrien Destugues:
26 avril 2018 14:31 "Hrishi Hiraskar" <hrishihiraskar@xxxxxxxxx> a
écrit:
Hie

For my GSoC project, I'm experimenting with creating a Dymanic menu
which will be added to the
Tracker's Root Menu be an addon.
[...]
In both the cases, MessageReceived is not being called. I think I'm
missing something.

You don't need a "fake" window for receiving messages, you need a
BHandler, and possibly a BLooper (unless you can attach your handler to an
existing looper - usually the be_app, which is the main application looper.
[...]


I would like to propose the following solution: The idea is not to mess
with Tracker from inside add-on code by installing BHandlers or other
BLoopers which may be difficult to clean up. The dynamic menu building
may happen frequently and it could be messy for the add-on to figure out
what needs to be done. Also is the code of the add-on even kept loaded?
(I see that it used to be unloaded but that line is commented out in the
prototype...) Anyway, I would define a custom BMessage.what constant in
TrackerAddOn.h that all add-ons would use if they want to react to menu
items that they themselves installed. The add-on would also add a
message field with an add-on ID, by which Tracker then knows which
add-on should receive the message. Then I would add code in Tracker
which handles these special add-on messages, loads the add-on specified
by the id in the message and calls another new add-on hook method and
passes the message. In pseudo code:

In the add-on's code:

static void
populateMenu(..., BMenu* menu)
{
     ...

     BMessage* message = new BMessage(B_TRACKER_ADDON_MESSAGE);
     message->AddString("be:add-on-id", <file name of add-on?>);
     // Add more stuff which helps the add-on figure out what to do
     // with this message later on...
     message->Add...
     BMenuItem* item = new BMenuItem(..., message, ...);
     menu->AddItem(item);

     ...
}


And then in Tracker:

void
BContainerWindow::MessageReceived(BMessage* message)
{
     switch (message->what) {
         ...
         case B_TRACKER_ADDON_MESSAGE:
             _PassMessageToAddOn(message);
             break;
         ...
     }
}

void
BContainerWindow::_PassMessageToAddOn(BMessage* message)
{
     const char* addonID;
     if (message->FindString("be:add-on-id", &addonID) != B_OK)
         return;

     ... load the add-on via the id
     ... find the function symbol for to be defined "messageReceived"
         add-on function...
     ... call the function and pass it the message...

    (*messageReceived)(message);
}

The add-on-id could also be something that Tracker passes to the new
populateMenu() hook. Then it's solely Tracker's responsibility to map
ids to addons. It could just be the path that it used to load the add-on
in the first place in AddOnMenuGenerate().

Does that make sense?

Best regards,
-Stephan


Other related posts: