Here's another approach that works better for modal windows with focusable controls.
Once you open a modal window in Vaadin, the UI does not receive any click events, but the Window does. However, the the client does not send glass clicks to the server.
You need to extend the Window to received clicks on the glass. When the glass is clicked, you then close the window.
Beware: We make assumptions on how Vaadin creates the Window element to get to the Glass element. There are most likely better ways. In a nutshell, we wait for the window to attach, then wait 100ms for the glass to attach, then install a click handler on the glass.
The Click Handler
public interface ClickHandler extends ServerRpc {
void onClick(String elementId);
}
The Extender - server side
public class GlassClickExtender extends AbstractExtension {
public GlassClickExtender(Window window, ClickHandler clickHandler) {
extend((AbstractClientConnector) window);
registerRpc(clickHandler);
}
}
The Extender - GlassClickExtenderClient
@Connect(GlassClickExtender.class)
public class GlassClickExtenderClient extends AbstractExtensionConnector {
private ClickHandler clickHandler;
@Override
protected void init() {
clickHandler = getRpcProxy(ClickHandler.class);
super.init();
}
@Override
protected void extend(ServerConnector serverConnector) {
try {
final Widget widget = ((ComponentConnector) serverConnector).getWidget();
widget.addAttachHandler(new AttachEvent.Handler() {
@Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
new Timer() {
@Override
public void run() {
Element windowElement = widget.getElement();
final Element glass = (Element) windowElement.getPreviousSibling();
if (glass == null || !glass.getClassName().contains("v-window-modalitycurtain")) {
return;
}
Event.sinkEvents(glass, Event.ONCLICK);
Event.setEventListener(glass, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
if (Event.ONCLICK == event.getTypeInt()) {
clickHandler.onClick(glass.getId());
}
}
});
}
}.schedule(100);
}
;
}
;
});
} catch (Exception e) {
System.out.print(e.getMessage());
}
}
}
Now, extend the window and listen for the click
new GlassClickExtender(window, elementId -> {
close();
});