cboulanger / eventrecorder

A qooxdoo package that allows to record user interaction for replay in testing or presentations
https://cboulanger.github.io/eventrecorder/eventrecorder/
1 stars 5 forks source link

qx.ui.tree.Tree events not being recorded #9

Closed jaminfine closed 4 years ago

jaminfine commented 5 years ago

To demonstrate this issue, start with the widget browser demo application, and add the following lines to widgetbrowser/pages/Tree.js In the constructor starting at line 47.

    let menu = new qx.ui.menu.Menu();
    this.setContextMenu(menu);
    let button = new qx.ui.menu.Button(this.tr("contextmenu button"));
    menu.add(button);

The issue technically still exists without adding these lines, but it isn't as clear to see.

Under the tree tab of the widgetbrowser, when the tree area under the nodes is right-clicked, the contextmenu event should be recorded, but it isn't. Other events are also not being recorded. The context menu appears on right-click if it exists, and then its menu button can be used. When repaying the test, the context menu is not opened. Related, the tooltipid of the tree is not present.

Strangely, if you hover your mouse on the very right side of the tree area (only a few pixels of leeway here), you will see the tooltipid and the events will be recorded. This may not be possible in other apps, where the tree is inside of a splitpane, for example.

cboulanger commented 5 years ago

This should be fixed by https://github.com/cboulanger/eventrecorder/commit/a41baa2a234c5cae7a5d4ea03c4bb7fcc78ca778 , can you check?

cboulanger commented 5 years ago

Reopening, since replaying the "contextmenu" event does not work when there is no "real" handler.

cboulanger commented 5 years ago

Firing a contextmenu event programmatically is surprisingly difficult. This is what it seems to require:

let tgt = qx.core.Id.getQxObject("${id}").getContentElement().getDomElement(); 
let r = tgt.getBoundingClientRect(), 
  clientX=parseInt((r.right+r.left)/2), 
  clientY=parseInt((r.bottom+r.top)/2); 
qx.event.Registration.fireEvent(tgt, "contextmenu", qx.event.type.Mouse, [new MouseEvent("contextmenu", {clientX,clientY}),tgt,null,true,true]);

Please test if this solves your problem.

jaminfine commented 4 years ago

This did solve the issue - sort of. In ObjectIdGenerator.js:141 I saw that under the case qx.ui.tree.Tree, the child control "pane" of the tree is added to the otherChildRoots. In my app, I have created a new class, guestnic.tree.Tree, which extends qx.ui.tree.Tree. So the needed case is not hit due to the difference in class name. Adding another case for my custom class name solves the issue, but a more general solution would be much better.

Is there a way to check the base class name of the extended class? Maybe it makes sense to recursively check down the classes until you find one that begins with "qx.ui" or find the base-most class. Although I wonder if that would considerably slow down the application.

cboulanger commented 4 years ago

Good point - I should use instanceof instead and the whole thing needs to be made extensible, too, so that you could subclass the object id generator and add your own widgets.

cboulanger commented 4 years ago

@jaminfine https://github.com/cboulanger/eventrecorder/commit/2065e08d33f331fcf476295289258c712e0d0451 is an attempt to solve your issue - can you test the current master if it works for you?

jaminfine commented 4 years ago

Yes! I can now get the events for my custom class. Thank you

cboulanger commented 4 years ago

Great, thanks for testing it right away.