Chrome/Edge issue with application-managed PopupMenus [message #1860622] |
Tue, 22 August 2023 11:00 |
Gunnar Adams Messages: 49 Registered: May 2016 |
Member |
|
|
Hi,
in our application, we have overridden the standard brower-managed context menus in order to present the user with options relevant to our application.
One of our customers discovered what I believe to be a bug in Eclipse RAP:
When an entry in the context menu, which is shown in response to either the right mousebutton click or the contextmenu key on the keyboard, is selected by using the mouse (keyboard activation does not cause the issue), the field on the shell, which previously had the input focus (document.activeElement pointed to the relevant <input>) will no longer show the cursor and document.activeElement has changed to the <body> element of the page.
Only by clicking somewhere on the shell or in the field, the focus will be restored.
The Java servlet does not notice that the focus has moved. Any attempt I made, including setFocus, forceFocus, using the DisplayManager to reset the focussed control or activeShell to null in order to force an update to the browser did not work. I tried to do this, when the poupmenu gets hidden. The JSON packet sent to the browser does not contain any focus or shell activation.
BTW: Firefox works fine and as expected. The error only occurs in the 2 other browsers tested: Chrome and Edge.
I tried to debug this in Chrome, I can see that document.activeElement changes somewhere between or within the mousedown and mouseup event handling on the MenuItem, but was not yet able to pinpoint the exact part of the code.
I believe, that the previously active shell is not restored when the PopupMenu widget is disposed.
My questions:
1. Is there already an Eclipse/RAP demo, which manages a popupmenu and might be used to reproduce the issue?
2. If not, we will try to create a small example app. If reproducable, would you be willing to accept this as a bug?
3. For a workaround: Can you think of a way to trick the Java servlet to sent an activation of the shell to the RWT toolkit?
Thank you very much for your help
Best regards
Gunnar Adams
|
|
|
|
|
|
|
Re: Chrome/Edge issue with application-managed PopupMenus [message #1860666 is a reply to message #1860634] |
Thu, 24 August 2023 13:59 |
Gunnar Adams Messages: 49 Registered: May 2016 |
Member |
|
|
Hi,
I just want to update you with the workaround I came up with:
The issue occurs when an item in the popup menu has been selected. In fact, this (document.activeElement reverts to <body>) seems to happen when mousedown event is handled and before mouseup is handled.
In order to work around this effect, and because this focus change goes unnoticed on the servlet side, I implemented a Javascript function which can be used to restore the focus to a control and call this with the id of the Control returned by Display.getCurrent().getFocusControl().
My code currently looks like this:
public void menuHidden(MenuEvent arg0) {
if (fMenu != null) {
fMenu.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
fMenu.dispose();
fMenu = null;
if (getFrame().getSessionManager().getBrowserType() != BrowserDetection.BROWSERTYPE_FIREFOX) {
if (Display.getCurrent().getFocusControl() != null) {
CustomBehaviors.restoreFocus(Display.getCurrent().getFocusControl());
}
}
}
});
}
}
with , in CustomBehaviors class
public static void restoreFocus(Widget widget) {
if (!widget.isDisposed()) {
exec("try {if (rap.getObject(\"" + WidgetUtil.getId(widget) + "\")) { window.restoreFocus(\"" + WidgetUtil.getId(widget) + "\");} } catch(e) {alert(e);}");
}
}
and the Javascript function
window.restoreFocus = function(id) {
var widget = rap.getObject(id);
if (widget.$input && widget.$input.get()[0]) {
widget.$input.get()[0].focus();
} else {
widget.$el.get()[0].focus();
}
}
This seeems to work reliably and I check the browser type determined from the useragent in order to exclude Firefox from this special handling.
But couldn't something similar be done on the Javascript side automatically, when the PopupMenu is disposed? Here the code could check, whether document.activeElement is the body element and then restore the focus to whatever control was active before. I assume, there is a function on the RWT side, which corresponds to Display.getFocusControl() ?
Even simpler, one could store document.activeElement when RWT displays a popup menu and focus that element again after the popup menu is closed?
Any ideas?
Thanks and best regards,
Gunnar
|
|
|
Powered by
FUDForum. Page generated in 0.03650 seconds