Help with MouseDown()

I can’t get a context menu pop up from a deskbar replcant, i don’t know what i am doing wrong? i have the following implementation in the Deskbar (archivable) class but the code doesn’t do anything?
Here is the code:

void Deskbar::MouseDown(BPoint where)
{
	int32 buttons;

	Window()->CurrentMessage()->FindInt32("buttons", &buttons);

	if ((buttons & B_PRIMARY_MOUSE_BUTTON)) {
		LeftClick(ConvertToScreen(where));
	} else if ((buttons & B_SECONDARY_MOUSE_BUTTON)) {
		RightClick(ConvertToScreen(where));
	}

}


void Deskbar::LeftClick(BPoint where)
{
		BPopUpMenu *popup = new BPopUpMenu("popup", false, false);
		popup->AddItem(new BMenuItem("Pause",
		new BMessage(M_Pause)));
		popup->AddItem(new BMenuItem("Resume",
		new BMessage(M_Resume)));

		popup->AddSeparatorItem();

		popup->AddItem(new BMenuItem("Previous",
		new BMessage(M_Previous)));
		popup->AddItem(new BMenuItem("Next",
		new BMessage(M_Next)));
		
		popup->SetTargetForItems(this);
		
		ConvertToScreen(&where);
		popup->Go(where, true, true, true);

}


void Deskbar::RightClick(BPoint where)
{
		BPopUpMenu *popup = new BPopUpMenu("popup", false, false);
		popup->AddItem(new BMenuItem("Settins",
		new BMessage(M_Settings)));
		popup->AddItem(new BMenuItem("About",
		new BMessage(M_About)));

		popup->AddSeparatorItem();

		popup->AddItem(new BMenuItem("Quit",
		new BMessage(M_Quit)));
		
		popup->SetTargetForItems(this);

}

What am i missing?

Might need to add this to the RightClick action to get the menu to show:

Also you may be calling ConvertToScreen twice, which will move the coordinates too far.

Well i had done that before posting this thread, it didn’t work.

It could indeed very well be a coordinates issue, i wish the bebook was more helpfull.

Thanks for trying to help.

You can attach debugger to the deskbar (or for simpler testing, use another replicant host such as SHelfer) and set some breakpoints in your code to see if functions are called.

You can also capture stdout and stderr in Debugger in that case, so good old printf-based debugging would also work (you could for example print the coordinates of your BPoints and see if they are where you expect them).

That’s sounds like a good trick, could you care to elaborate on how to use “printf/fprintf” to debug in this case? my debugging knowledge with these functions is very limited.

printf("Point coordinates: %f,%f\n", point.x, point.y);

For a normal application launched from Terminal, you would then see the coordinates in the Terminal. However this would not be the case for a deskbar replicant (because Deskbar is not run from Terminal and has nowhere to send the output to).

As I mentioned you have two options to capture this output:

  • Attach Debugger to Deskbar and use the bottom part of the window to see the messages
  • Or use SHelfer, which is a small tool that acts as a target for replicants. So you can run it from Terminal, then put your replicant inside it. Then the output will get to Terminal.

@Pulkomandy, where can i find this SHelfer tool? i looked in the repo, haikuports and haikuarchives i couldn’t find it.

BTW, i tried with the debugger, it didn’t output anything.

I finaly got it to show the menus, i replaced the following:

Window()->CurrentMessage()->FindInt32(“buttons”, (int32)&buttons);

with :

BPoint location;
uint32 buttons;

GetMouse(&location, &buttons);

That did the trick, i still have 2 questions though.

  1. Do i need to delete the BPopUpMenu objects? if so, do i need to do it in both functions? LeftClick()/Rightclick().

  2. when i compile the app with gcc5 on a hybrid system the replicant doesn’t show up in the Deskbar and there is no output in the terminal, even though i set a check in the code which works when compiled with gcc2.

Here is my final Deskbar.cpp file:
https://pastebin.com/C84iQBfm

You may or may not need to delete the BPopUpMenu, it depends on how you use it. Docs at The Haiku Book: BPopUpMenu Class Reference and The Be Book - Classes And Methods - The Interface Kit say you should delete it after calling Go(), or you can tell it to self destruct once it closes:

Once Go() returns the BPopUpMenu object should be destroyed. You can call SetAsyncAutoDestruct() passing true to destroy the object automatically when it returns. This is not advisable if the deliversMessage parameter of Go() is set false because you’ll want to examine the return value before destroying the BPopUpMenu object.

Since your Go() call is passing in true for the async flag, it would be easiest to also call SetAsyncAutoDestruct(true) before doing the Go(). Then you don’t need to worry about keeping track of and then deleting the BPopUpMenu.

You cannot use a gcc5 replicant inside a gcc2 DeskBar. This is one of the reasons we still ship the gcc2 compiler by default, so people can use it to build their replicants and other add-ons (screensavers, …)

Yes i suspected so much, but the reason i asked this is because at some point in the development it did show up before i added the MouseDown() code, but i guess it’s normal behaviour?

Thanks for the “SetAsyncAutoDestruc” tip i totally overlooked it when i read the bebook.