Is there a way to detect if a browser window is closed? - gwt

Is there a way to detect if a browser window is closed using GWT. For example a window opened through GWT using this code:
Window.open("some_url", "__blank", null);
I need to detect wether this windows opened through gwt is closed. Is there a way to do that?

I think, it is a real problem making it cross-browser.
GWT has
Window.addCloseHandler(new CloseHandler<Window>() {
public void onClose(CloseEvent<Window> windowCloseEvent) {
}
});
Which handles the onunload event(occurs before the browser closes the document).
However it does not work for handling browser close event with all browsers, because when refreshing the page, this event is fired as well.
Since GWT also generates JavaScript see this article: Window Close Event of Browser
Here is conclusion of that article:
Conclusion
As we have already discussed that there is no 100% fool proof way to
detect the browser close event in a lot of cases, the above technique
can fail. For example if the user kills the browser's process from
task manager, there could be many more cases. Yet in a lot of cases,
this technique can be handy. Best of luck and happy programming.

Related

Open conversejs chat window after it has already been closed with initialize

I have an mobile web based application where I want the user to only use a chat window between them and another person.
I have javascript button that opens a chat window but it does it through the converse.initalize method with all the configuration variables pass to it. On the mobile view the user is only allowed to closed the chat window, there is no minimize option available.
Is there a way to open the chat window again from outside converse.js with out using the initialize method again? It seems a bit heavy since the chat window was open previously I can not see a public api for doing this and I can not see a way of doing this using a plugin since the button event is out side converse.
There is probably a better way of doing this but in case it helps...
I was trying to decipher the debug log on this and I think that, even though the chat window is closed in Converse, the connection to my ejabberd server isn't disconnected. I tried firing a disconnect when the window close event is fired.
this._converse.on('chatBoxClosed', function (chatbox) {
this._converse.connection.disconnect();
});
At this point Converse is clever and tried to reopen the window and rejoin the room if auto_reconnect is set to true so I had to turn it off.
window.converse.initialize({
auto_reconnect: true,
Is there a way to open the chat window again from outside converse.js with out using the initialize method again?
Not from outside converse.js, but you can register a plugin for converse.js and open the chat from within the plugin by calling _converse.api.chats.open().
The API is documented here:
https://conversejs.org/docs/html/developer_api.html#the-chats-grouping

Catching Input Events in WebGL build

When running a Unity project as a WebGL app is there way to catch the site's input events (e.g. keypress) once the application is running?
Currently once the Unity app launches it eats keyboard events so that I can't type in to my text boxes on the page. The best workaround I could come up with is to use jQuery to directly read the keypress event:
$('#input_message').keypress(function(evt){
event.preventDefault();
var code = evt.keyCode || evt.which;
var key=String.fromCharCode(code);
$('#input_message').val($('#input_message').val() + key);
});
};
This works for my immediate needs but I'm hoping there is a cleaner way through the Unity API.
Versions
Chrome v43
Unity 5.1.1f1
I would make this a comment if I had enough points but:
You could have your game send the inputs to your site via websockets. I've done similar things with Azure + SignalR
This question has no solution, so if someone comes up here, there is a short path:
By default, Unity WebGL will process all keyboard input send to the page, regardless of whether the WebGL canvas has focus or not. This is done so that a user can start playing a keyboard-based game right away without the need to click on the canvas to focus it first. However, this can cause problems when there are other HTML elements on the page which should receive keyboard input, such as text fields - as Unity will consume the input events before the rest of the page can get them. If you need to have other HTML elements receive keyboard input, you can change this behavior using the WebGLInput.captureAllKeyboardInput property.
This was taken from here.
The property you are looking for is WebGLInput.captureAllKeyboardInput.

Mono Form.Show from another form doesn't work

I am trying to port a WinForms app for use with Mono, and I've recently noted that calling Form.Show() from another form will either do nothing or cause the new form to flash and disappear. I read something about the new form needing a message pump, which is accomplished with Application.Run(), but that's already been called. Any idea why this doesn't work? I can't use ShowDialog because my program relies on events fired by completed async tasks, and I don't want to block a ton of extra threads that will be done right after the Show call.
Have you tried to hide your current form before showing/displaying your new one?
Seems to me like your form is indeed being displayed but for some strange reason it's being delegated to the background. Worth a shot.

Should WebSocket.onclose be triggered by user navigation or refresh?

Part 1: Expected behaviour?
I'm seeing some inconsistent browser behaviour between Firefox and Chrome in relation to the onclose handler being called.
It seems that Chrome does not trigger an onclose if it was caused by a user page navigation/refresh. However, Firefox does trigger the onclose.
It seems to me that Firefox may be behaving correctly here:
When the WebSocket connection is closed, possibly cleanly, the user agent must create an event that uses the CloseEvent interface, with the event name close, which does not bubble, is not cancelable, has no default action, whose wasClean attribute is set to true if the connection closed cleanly and false otherwise, whose code attribute is set to the WebSocket connection close code, and whose reason attribute is set to the WebSocket connection close reason; and queue a task to first change the readyState attribute's value to CLOSED (3), and then dispatch the event at the WebSocket object.
Source: http://www.w3.org/TR/2011/WD-websockets-20110419/#closeWebSocket
Even though it can lead to some sneaky code/unexpected behaviour.
Can anybody confirm the expected behaviour?
Part 2: How to implement auto-reconnect?
If you have a library that auto-reconnects for the user how do you know if you should try to reconnect? Do you check the CloseEvent.wasClean property? I'm having to assume that 'clean' means that the close was supposed to happen through either an API call to WebSocket.close() or the server sending a close frame? If a network error causes the close I'm guessing the wasClean would be false?
In the Pusher JavaScript library we assumed (onclose -> waiting -> connecting) that a close should trigger a reconnect unless we are in a closing state - the developer has chosen to close the connection. It would appear that the socket.io client library makes the same assumption.
Based on this the Firefox onclose event caused by user navigation/refresh triggers an unwanted reconnection because neither library check the CloseEvent.wasClean property.
Example and Video
Here's an example that you can use to demonstrate the inconsistency:
http://jsbin.com/awonod/7
Here's a video of me demonstrating the problem:
http://www.screenr.com/vHn8
(it's late, ignore the couple of slip-ups :))
One point to note is that my hitting the Escape key could also be causing the WebSocket connection to close. However, if you watch closely or try for yourself you will see the close event being logged just before the page refreshes.
The unexpected behavior is due to the way in which Firefox and Chrome handle the closing of a Websocket. When the page is refreshed, both browsers close the connection, however, Firefox will execute your onclose code, while chrome closes the connection and skips straight to re-loading the new page. So yes, I confirm this strange behavior.
Even stranger is the fact that, from my observations, calling websocket.close() in chrome will immediately close the connection and call the onclose function, while Firefox waits for a close message back from the server.
The wasClean property will be true if a close message was received from the server
If your library is auto-reconnecting without checking the wasClean property then this could cause a problem, as it tries to re-establish the connection as the page refreshes. You should consider not using the library for this and doing it manually, it should'nt be very hard, just call connect in the onclose function with an if statement making sure the onclean property is true. Or to be even more safe set a variable in onbeforeunload that prevents any new connection.
hope this helps!
This is amazingly still the current behavior in 2022. You can demonstrate this trivially by adding a console log in an onclose handler for a websocket, and click a link in Firefox vs in Chrome while watching the console (ensuring you preserve the console between webpages):
ws.onclose = function(e) {
printMsg('CLOSE')
// ... my other code ...
}
Firefox will show you a 'CLOSE' and Chrome will not.

Eclipse RAP - Firefox doesn't forget session

We've got an Eclipse RAP application that's behaving a bit strangely in Firefox - two distinct problems.
When you browse around, you can click on a button in one part of the system. This opens a popup window like so:
IWorkbenchBrowserSupport bs;
bs = PlatformUI.getWorkbench().getBrowserSupport();
int style = IWorkbenchBrowserSupport.AS_EXTERNAL;
IWebBrowser b = bs.createBrowser(style, getRandomID(), "Hello world", "");
b.openURL(new URL(...));
where the URL is another servlet in the application. This servlet is in the same runtime, but has nothing to do with RAP - it takes a binary blob from in-memory storage and dumps it in the output stream.
Problem 1: This causes the HTTP session to die in firefox, and shows the "session expired" RAP error page with a link to restart the session.
Problem 2: Now, when you click on the link to restart the session, it shows the application's dialog again, but the session expired error is shown again the moment you do anything. This prevents the user from using the system again, unless Firefox is closed down completely and restarted. A quick peek with FireBug reveals that the JSESSIONID passed by Firefox does not change.
Has anyone seen this before?
How long is the dumping of the stream to the output? May it cause a timeout? As RAP uses Javascript calls, it might be much shorter than the normal timeout time.
For problem 2: Firefox caches a lot of things; and if the Javascript execution hangs, it might cause such problems.
Are these problems present in other browsers? It might be a good idea to check with the internal browser (or any other browser with a different rendering engine).
It turns out that if a RAP application opens a popup window pointing to a servlet in the application itself, inside the current HTTP servlet context, the session is killed. Fixed by creating a dummy HTTP context for the servlet in question.
If you need to deliver content from within the same application, you should use a service handler instead. See this FAQ:
http://wiki.eclipse.org/RAP/FAQ#How_to_provide_download_link.3F