PopupMenu wierdness


#1

I’ve noticed a couple strange things when using popup menus… I haven’t had time to debug the menu code yet, thought I’d ask first…

  1. I have a “right-click” menu with submenus… when I rollover a menu item which shows a submenu, a strange drawing anomaly occurs: Before the actual submenu appears there is a couple second delay, during which I can see the rect which is the width of the shadow and the height of the submenu redrawn, erased, and then the actual submenu is drawn. This does not happen on the Mac. It makes for a very sluggish menu. With dirty rects on I can see that nothing else is drawing at that time.

  2. I was noticing odd behavior with menus for which I used showAt(screenX, screenY, etc…). It appeared as if the menus were using the bottom right of the menu as the reference point, instead of top left… for example:

menu.showAt(myComponent->getScreenX(), myComponent->getScreenY());

…would draw the menu so that it’s bottom right corner (not top left) was at the given coordinates. Apparently:

avoids the problem altogether… but thought I’d mention it anyway.

As a side, does anyone have any suggestions for profiling their Juce app? I see Juce has a PerformanceCounter class… but I was looking for something a little more “robust”.

Thanks,
~D


#2

Well on windows, the shadows are drawn separately to the window, so you could see them appear separately. It’s nothing specific to menus though, and just depends on how long things take to draw, and how the os decides to process the window creation.

showAt doesn’t specify the menu’s top-left - the co-ords should be the position of the mouse or some object that the menu is attached to, and it finds the best spot for the menu based on that. I should probably improve the docs about this.


#3

Thanks, sorry, wasn’t clear to me what the behavior was, but I can see that apparently it is positioned based on where the coordinates are relative to the center of the screen, which I guess makes sense, but my assumption was that it would behave more like the latter where it would draw at the given coordinates and shift only when it hits the edges of the screen.

Perhaps there could be optional flags to specify an anchor and perhaps a “bounds” rect I could give it (relative to some component) within which to shift, scroll or use columns when it hits the edges? In this way, for example, I could confine menus to the main window. Make sense?

Re: 1) I’ll look into it when I have more time… certainly what I’m seeing can’t be normal, or maybe could be avoided somehow.


#4

well, I had a little time today to look at the popupmenu code and sure enuf, it is the shadow windows that are killing me. I thought it was very odd considering my dev machine has a lot of horsepower, and the menus are causing the CPU to spike considerably and slow enough that I get busy cursors.

At any rate I wrote a little wrapper class for the performance counter to time a function call (just creates and starts a pc in the constructor and stops it in destructor, so you just have one line at top of function that prints out time automatically when function returns) and put some in the popup and component classes… here’s the output for the showsubmenu call for submenu with two items:

PROFILER // PopupMenuWindow::showSubMenuFor (4077) - Start : 481562.69966 PROFILER // PopupMenuWindow::create (4078) - Start : 481562.70036 ... PROFILER \\ PopupMenuWindow::create (4078) - Stop : 481562.75482 - Time : 0.05446 seconds PROFILER // Component::setVisible (4100) - Start : 481562.75581 PROFILER // Component::sendVisibilityChangeMessage (4101) - Start : 481562.75713 PROFILER // DropShadower::componentVisibilityChanged (4102) - Start : 481562.75767 PROFILER // DropShadower::updateShadows (4103) - Start : 481562.75836 PROFILER // DropShadower::setShadowImage (4104) - Start : 481562.81649 PROFILER \\ DropShadower::setShadowImage (4104) - Stop : 481562.81775 - Time : 0.00126 seconds ... PROFILER // DropShadower::componentBroughtToFront (4120) - Start : 481562.95111 PROFILER // DropShadower::bringShadowWindowsToFront (4121) - Start : 481562.95234 PROFILER // DropShadower::updateShadows (4122) - Start : 481562.95353 PROFILER \\ DropShadower::updateShadows (4122) - Stop : 481562.95442 - Time : 0.00088 seconds PROFILER \\ DropShadower::bringShadowWindowsToFront (4121) - Stop : 481562.99262 - Time : 0.04028 seconds PROFILER \\ DropShadower::componentBroughtToFront (4120) - Stop : 481562.99418 - Time : 0.04307 seconds ... PROFILER // Component::setVisible (4124) - Start : 481562.99728 PROFILER // Component::sendVisibilityChangeMessage (4125) - Start : 481562.99929 PROFILER \\ Component::sendVisibilityChangeMessage (4125) - Stop : 481563.00026 - Time : 0.00097 seconds PROFILER // DropShadower::componentBroughtToFront (4126) - Start : 481563.00168 PROFILER // DropShadower::bringShadowWindowsToFront (4127) - Start : 481563.00275 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4127) - Stop : 481563.04367 - Time : 0.04092 seconds PROFILER \\ DropShadower::componentBroughtToFront (4126) - Stop : 481563.04542 - Time : 0.04374 seconds PROFILER \\ Component::setVisible (4124) - Stop : 481563.06065 - Time : 0.06337 seconds ... PROFILER // DropShadower::componentBroughtToFront (4130) - Start : 481563.07972 PROFILER // DropShadower::bringShadowWindowsToFront (4131) - Start : 481563.08087 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4131) - Stop : 481563.12141 - Time : 0.04054 seconds PROFILER \\ DropShadower::componentBroughtToFront (4130) - Stop : 481563.12306 - Time : 0.04334 seconds ... PROFILER // Component::setVisible (4134) - Start : 481563.12684 ... PROFILER // DropShadower::componentBroughtToFront (4136) - Start : 481563.13089 ... PROFILER \\ DropShadower::componentBroughtToFront (4136) - Stop : 481563.17868 - Time : 0.04779 seconds ... PROFILER \\ Component::setVisible (4134) - Stop : 481563.19208 - Time : 0.06524 seconds ... PROFILER // DropShadower::componentBroughtToFront (4140) - Start : 481563.21209 ... PROFILER \\ DropShadower::componentBroughtToFront (4140) - Stop : 481563.26009 - Time : 0.04800 seconds ... PROFILER // Component::setVisible (4144) - Start : 481563.26721 ... PROFILER // DropShadower::componentBroughtToFront (4146) - Start : 481563.27502 ... PROFILER \\ DropShadower::componentBroughtToFront (4146) - Stop : 481563.34567 - Time : 0.07065 seconds ... PROFILER \\ Component::setVisible (4144) - Stop : 481563.36038 - Time : 0.09317 seconds ... PROFILER // DropShadower::componentBroughtToFront (4150) - Start : 481563.37942 ... PROFILER \\ DropShadower::componentBroughtToFront (4150) - Stop : 481563.42621 - Time : 0.04679 seconds ... PROFILER // Component::setVisible (4154) - Start : 481563.43039 ... PROFILER // DropShadower::componentBroughtToFront (4156) - Start : 481563.43493 ... PROFILER \\ DropShadower::componentBroughtToFront (4156) - Stop : 481563.47856 - Time : 0.04363 seconds ... PROFILER \\ Component::setVisible (4154) - Stop : 481563.49224 - Time : 0.06185 seconds ... PROFILER // DropShadower::bringShadowWindowsToFront (4160) - Start : 481563.53101 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4160) - Stop : 481563.57433 - Time : 0.04332 seconds PROFILER \\ DropShadower::updateShadows (4103) - Stop : 481563.57610 - Time : 0.81774 seconds PROFILER \\ DropShadower::componentVisibilityChanged (4102) - Stop : 481563.57854 - Time : 0.82087 seconds PROFILER \\ Component::sendVisibilityChangeMessage (4101) - Stop : 481563.57993 - Time : 0.82279 seconds PROFILER // DropShadower::componentBroughtToFront (4162) - Start : 481563.58110 PROFILER // DropShadower::bringShadowWindowsToFront (4163) - Start : 481563.58218 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4163) - Stop : 481563.62288 - Time : 0.04070 seconds PROFILER \\ DropShadower::componentBroughtToFront (4162) - Stop : 481563.62493 - Time : 0.04383 seconds PROFILER // DropShadower::componentBroughtToFront (4165) - Start : 481563.62670 PROFILER // DropShadower::bringShadowWindowsToFront (4166) - Start : 481563.62785 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4166) - Stop : 481563.67028 - Time : 0.04243 seconds PROFILER \\ DropShadower::componentBroughtToFront (4165) - Stop : 481563.67224 - Time : 0.04555 seconds PROFILER // Component::internalHierarchyChanged (4168) - Start : 481563.68302 PROFILER // DropShadower::componentParentHierarchyChanged (4169) - Start : 481563.68399 PROFILER // DropShadower::deleteShadowWindows (4170) - Start : 481563.68482 PROFILER \\ DropShadower::deleteShadowWindows (4170) - Stop : 481563.72639 - Time : 0.04157 seconds PROFILER // DropShadower::updateShadows (4171) - Start : 481563.72762 ... PROFILER // DropShadower::componentBroughtToFront (4188) - Start : 481563.84914 PROFILER // DropShadower::bringShadowWindowsToFront (4189) - Start : 481563.85033 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4189) - Stop : 481563.89163 - Time : 0.04130 seconds PROFILER \\ DropShadower::componentBroughtToFront (4188) - Stop : 481563.89294 - Time : 0.04380 seconds ... PROFILER // Component::setVisible (4192) - Start : 481563.89525 PROFILER // Component::sendVisibilityChangeMessage (4193) - Start : 481563.89709 PROFILER \\ Component::sendVisibilityChangeMessage (4193) - Stop : 481563.89772 - Time : 0.00063 seconds PROFILER // DropShadower::componentBroughtToFront (4194) - Start : 481563.89874 PROFILER // DropShadower::bringShadowWindowsToFront (4195) - Start : 481563.89938 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4195) - Stop : 481563.93995 - Time : 0.04056 seconds PROFILER \\ DropShadower::componentBroughtToFront (4194) - Stop : 481563.94149 - Time : 0.04275 seconds ... PROFILER \\ Component::setVisible (4192) - Stop : 481563.95468 - Time : 0.05943 seconds ... PROFILER // DropShadower::componentBroughtToFront (4198) - Start : 481563.97337 ... PROFILER \\ DropShadower::componentBroughtToFront (4198) - Stop : 481564.01588 - Time : 0.04251 seconds ... PROFILER // Component::setVisible (4202) - Start : 481564.01887 PROFILER // DropShadower::componentBroughtToFront (4208) - Start : 481564.09707 ... PROFILER \\ DropShadower::componentBroughtToFront (4208) - Stop : 481564.14157 - Time : 0.04450 seconds PROFILER \\ Component::setVisible (4202) - Stop : 481564.07800 - Time : 0.05913 seconds ... PROFILER // DropShadower::componentBroughtToFront (4208) - Start : 481564.09707 ... PROFILER \\ DropShadower::componentBroughtToFront (4208) - Stop : 481564.14157 - Time : 0.04450 seconds ... PROFILER // Component::setVisible (4212) - Start : 481564.14477 ... PROFILER // DropShadower::componentBroughtToFront (4214) - Start : 481564.14839 ... PROFILER \\ DropShadower::componentBroughtToFront (4214) - Stop : 481564.19003 - Time : 0.04163 seconds ... PROFILER \\ Component::setVisible (4212) - Stop : 481564.20226 - Time : 0.05749 seconds ... PROFILER // DropShadower::componentBroughtToFront (4218) - Start : 481564.22111 ... PROFILER \\ DropShadower::componentBroughtToFront (4218) - Stop : 481564.26468 - Time : 0.04357 seconds ... PROFILER // Component::setVisible (4222) - Start : 481564.26803 ... PROFILER // DropShadower::componentBroughtToFront (4224) - Start : 481564.27129 ... PROFILER \\ DropShadower::componentBroughtToFront (4224) - Stop : 481564.31381 - Time : 0.04253 seconds ... PROFILER \\ Component::setVisible (4222) - Stop : 481564.32686 - Time : 0.05883 seconds PROFILER // DropShadower::bringShadowWindowsToFront (4228) - Start : 481564.36912 ... PROFILER \\ DropShadower::bringShadowWindowsToFront (4228) - Stop : 481564.40824 - Time : 0.03912 seconds ... PROFILER \\ DropShadower::updateShadows (4171) - Stop : 481564.40935 - Time : 0.68173 seconds PROFILER \\ DropShadower::componentParentHierarchyChanged (4169) - Stop : 481564.41051 - Time : 0.72652 seconds PROFILER \\ Component::internalHierarchyChanged (4168) - Stop : 481564.41400 - Time : 0.73098 seconds ... PROFILER \\ Component::setVisible (4100) - Stop : 481564.41465 - Time : 1.65883 seconds PROFILER // DropShadower::componentBroughtToFront (4232) - Start : 481564.42618 ... PROFILER \\ DropShadower::componentBroughtToFront (4232) - Stop : 481564.47497 - Time : 0.04878 seconds PROFILER \\ PopupMenuWindow::showSubMenuFor (4077) - Stop : 481564.47574 - Time : 1.77608 seconds

…unfortunately I’m not familiar enough with the code to recognize if there’s much redundancy here… it’s not clear to me why toFront should be called so often… but I can live without the shadows for now.

Thanks for 1.46 btw :slight_smile: I’ve been using the trunk anyway, but nice to know it’s been through your testing now.