Project

General

Profile

Actions

Bug #2328

closed

WNavigationBar popup menu doesn't disappear in git HEAD

Added by Velvet Jones over 10 years ago. Updated about 10 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
10/18/2013
Due date:
% Done:

0%

Estimated time:

Description

This code produces two drop-down menus, File1 and File2. If you select File1, a popup appears. If you then select File2, another popup appears, and the first popup doesn't disappear as it should.


Files

main.cpp (1.37 KB) main.cpp Velvet Jones, 10/18/2013 02:53 PM
main.cpp (1.91 KB) main.cpp Velvet Jones, 10/25/2013 01:57 AM
subMenus2.cpp (1.97 KB) subMenus2.cpp Koen Deforche, 10/25/2013 12:18 PM
main.cpp (2.07 KB) main.cpp Velvet Jones, 10/25/2013 03:04 PM
Actions #1

Updated by Koen Deforche over 10 years ago

  • Status changed from New to InProgress
  • Assignee set to Koen Deforche
  • Target version set to 3.3.1

Hey,

Indeed, and this is unfortunate as it slipped into 3.3.1.

The reason is a preventPropagation() that was added in WMenuItem::clicked() which also prevents this signal to be a trigger to close menus.

I will look into a possible workaround and/or patch to 3.3.1

Regards,

koen

Actions #2

Updated by Koen Deforche over 10 years ago

  • Status changed from InProgress to Resolved

Hey,

I've got a fix ready for git. Instead of preventing propagation on a menu item, we now do it (correctly) for popup widgets since these do not actually have a predictable DOM parent and whose event propagation can cause unexpected consequences.

A workaround is a bit more involved, I'm afraid. You need to call the following function on each item in a plain WMenu (i.e. not a WPopupMenu).

void fixItem(WMenuItem *item) {
  Wt::WAnchor *anchor = (Wt::WAnchor*)item->widget(0);
  if (anchor)
    anchor->clicked().preventPropagation(false);
}
Actions #3

Updated by Velvet Jones over 10 years ago

Not so interested in the workaround here, I'm not paying attention to the releases at all. Bleeding edge all the way. :)

When you check it in I'll verify that it fixes the problem.

- Bud

Actions #4

Updated by Koen Deforche over 10 years ago

Hey,

It's in. The workaround might still apply to those that believe in the dogmatic stability of a release :-)

koen

Actions #5

Updated by Velvet Jones over 10 years ago

Works beautifully with no code changes on my part. Thanks a ton!

Actions #6

Updated by Velvet Jones over 10 years ago

I may have spoken too soon.

I am seeing a very odd behavior where the contents stack displays the wrong widget. If I don't call setInternalPathEnabled() on the submenus it works correctly, but of course then I don't get navigation on sub-menu items (specifically, my anchors to menu items don't work).

I can't re-create this yet, but I can give you something that seems to behave in a similarly wrong way (do these steps in order):

1. Build and run this, then connect with your browser

  1. Choose Colors~~Bright~~>Red
  2. Then choose Colors->Black

Notice that the popup menu doesn't disappear when you choose "Black". I see this same behavior, but it also chooses the wrong widget from the widget stack. Maybe this little test will help, if not I will try to re-create the exact problem next week.

- Bud

Actions #7

Updated by Koen Deforche over 10 years ago

Hey,

Indeed something still wasn't quite right. I've fixed this now in git.

I could also reproduce the situation where the wrong item was displayed (the event simply wasn't processed properly).

Find attached a modified version of your test case: you need to specify the internal path at which you want to deploy a menu (the default is to take the current internal path which is most likely wrong).

Regards,

koen

Actions #8

Updated by Velvet Jones over 10 years ago

Thanks for the quick fix Koen. I'm testing it out here, but I find that partial internal paths versus fully qualified internal paths is a real headache.

I have been instantiating container widget and giving them a fully qualified path, which serves as a unique identifier that can be used when processing internal path changes. This seems the most straightforward way to allow the widgets to recognize themselves when the path changes, and to respond to the URL by changing state in some way.

For example, I have two different classes representing different kinds of policies. One is given the path "/lease/policy" and the other "/device/policy". This has worked well, and it ensures that the two widgets do not confuse themselves in the path, since both are named "policy" at the partial level.

When creating menu entries for these two items, however, I have to specify partial paths for each - i.e., both get path component "policy". Instead of having one moniker for each widget (the fully qualified path), I end up having to coordinate partial menu paths to fully qualified widget paths, and that can be a source of errors in maintenance.

Ideally, I would specify all menu path "components" as fully qualified paths, and never make a reference to the partial path anywhere.

Is this possible?

- Bud

Actions #9

Updated by Velvet Jones over 10 years ago

There is another bug in the attached file. I added a menu item before the popup, and it stays selected even when the popup is selected.

About paths, I have solved my problem by giving widgets a fully qualified internal path for identification, then building the path component on the fly by removing the menu's internal base path from the widget's fully qualified path. It's not ideal, but I cannot see a better approach.

This may sound convoluted, but when it comes to locating widgets it's important to not let these names propagate all over the place. In particular, if I have a widget that builds WAnchors to other widgets in my application, I should be able to declare a link to the other widget without having to have an instance of the widget - the way links are supposed work, after all.

In other words, I create a WAnchor that links to "/devices/leases/42", and the "leases" widget recognizes itself in the path change, then brings up lease 42. This name - "/devices/leases" - is kept in a central place so that any widget can build an anchor to any other widget without having to have an instance of the target widget.

I read somewhere online from you or Wim that the approach to internal paths was to not have a central url router, but to instead let each widget process its own path handling. I like that model, but I think it requires that you have well known names for widgets located somewhere centrally in your application. If you agree with that statement, then IMO it becomes clear that dealing with partial paths is not a great idea, especially when two widgets may have the same partial name, but be very different things.

Actions #10

Updated by Koen Deforche over 10 years ago

Hey,

I didn't notice these new (unrelated) comments. But if I understand correctly you don't like the pathComponent() approach of menus and would like to have (at least the option for) full internal paths for each item?

Regards,

koen

Actions #11

Updated by Velvet Jones over 10 years ago

Hi Koen:

Yes, that's right. If all views process path changes, then these views should know their fully qualified url in order to be able to verify that the path refers to their specific object instance. In my opinion, I should never have to deal with partial paths because they are ambiguous.

It's not a bug, just a subtle design suggestion.

- Bud

Actions #12

Updated by Koen Deforche over 10 years ago

Hey,

I've fixed the popup-menu item selected problem in my git copy, it'll be in git soon.

Regards,

koen

Actions #13

Updated by Velvet Jones over 10 years ago

Much appreciated!

- Bud

Actions #14

Updated by Koen Deforche about 10 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF