webglcontextrestored event not firing after context lost - webgl

I'm writing a webgl application and am trying to recover a webgl context after it has been lost, but the context restored event does not seem to be firing.
I'm running the following code, and expecting both "context lost" and "context restored" to be logged, based on the WebGL specification and the documentation on the WebGL wiki. When I run the code below in jsfiddle in both Chrome (50.0.2661.102 m) and Firefox (46.0.1) I see "context lost" logged but not "context restored", and I'm seeing the same behaviour in my electron application.
var canvas = document.createElement( 'canvas' )
var gl = canvas.getContext("webgl");
var WEBGL_lose_context = gl.getExtension('WEBGL_lose_context');
canvas.addEventListener("webglcontextlost", function(e) {
log("context lost");
e.preventDefault();
}, false);
canvas.addEventListener("webglcontextrestored", function() {
log("context restored");
}, false);
WEBGL_lose_context.loseContext();
function log(msg) {
var div = document.createElement("pre");
div.appendChild(document.createTextNode(msg));
document.body.appendChild(div);
}
Do I need to do anything extra to get the context restored event to fire? Have I misunderstood the WebGL specification?

In the case of using WEBGL_lose_context you have to call WEBGL_lose_context.restoreContext(). WEBGL_lose_context is for testing only. In the normal case it's up to the browser to decide when to restore the context. For example if you're tab is not the front tab and another tab needs all the WebGL memory your tab might get a lost context event. Later when you're tab is made the active tab you'll finally get a restore context event.
See conformance test here

Related

Electron framework window management for refresh not working

i've created a program in electron where:
When i a button in one window sends a ipc to the main window and check if the window exist and refresh the window, but its not working.
Maybe i missed something in the documentation but i don't find anything about how to check if a window is null or undefined (Already tried to check if is null and others none values).
Thanks for the attention.
Code
Error
I think this is a scope issue. Please ensure the window variable is reachable by your code. Something like this should work:
var mywindow = null; //global def
app.once("ready", function() {
mywindow = new BrowserWindow({...});
mywindow.loadURL(...);
});
ipc.on('something_refresh', function(evt) {
mywindow.reload(); //this works for me
});

Suppress the “are you sure you want to leave this page” popup in the Delphi TWebbrowser control

I have an Delphi application that uses TWebbrowser component to automate navigation to another web application we have.
My problem is that sometimes IE shows the infamous 'Are you sure you want to leave this page' message and when this happens, my app can't navigate to another pages unless an user clicks on 'Leave this page' button. I can't edit the website code to remove this warning, unfortunately.
This message is plaguing my app for weeks, and I could not reach to a proper solution anymore. What I did is to keep a background process do manually send a keystroke when this window is show, but this is not a good solution because nobody can use the computer while my app is working.
I saw possible solution for C# in the topic below but I need a Delphi code instead.
Supress the "are you sure you want to leave this page" popup in the .NET webbrowser control
Any help is very, very appreciated.
Thanks :)
This message is shown by the underlying MSHTML engine if the web page handles window.onbeforeunload event. Usually, it's there for a reason, to let the user know his/her input hasn't been saved or submitted yet. The prompt suppression script from the answer you linked doesn't work for cases when the page uses addEventListener("beforeonload", handler) or attachEvent("onbeforeunload", handler). I don't think there's a reliable way of doing this, without resorting to low-level Windows hooks.
[UPDATE] The following script (look for "Inject this script") is a hack which aggressively suppresses the page's own handlers for onbeforeunload event, via setInterval. It should work in 99% of cases, but it still leaves a gap for the page to override onbeforeonload right before navigating away.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script type="text/javascript">
window.attachEvent("onbeforeunload", function (ev) {
window.event.returnValue = "onbeforeunload via window.attachEvent()";
});
window.addEventListener("beforeunload", function (ev) {
window.event.returnValue = "onbeforeunload via window.addEventListener()";
});
window.onbeforeunload = function (ev) {
window.event.returnValue = "onbeforeunload via window.onbeforeunload";
};
</script>
<script type="text/javascript">
//
// Inject this script
//
(function () {
var onbeforeunloadHandler = function (ev) {
if (ev) {
if (ev.stopPropagation)
ev.stopPropagation();
if (ev.stopImmediatePropagation)
ev.stopImmediatePropagation();
ev.returnValue = undefined;
}
window.event.returnValue = undefined;
}
var handler = null;
var intervalHandler = function () {
if (handler)
window.detachEvent("onbeforeunload", handler);
// window.attachEvent works best
handler = window.attachEvent("onbeforeunload", onbeforeunloadHandler);
// handler = window.addEventListener("beforeunload", onbeforeunloadHandler);
// handler = window.onload = onbeforeunloadHandler;
};
window.setInterval(intervalHandler, 500);
intervalHandler();
})();
</script>
</head>
<body>
Go away
</body>
</html>
To inject this script with Delphi, you'd probably need to resort to low-level WebBrowser/MSHTML COM interfaces, like IWebBrowser2, IHTMLDocument2, IHTMLScriptElement, in a very similar way it's done in the linked answer. With some more efforts, the same can also be done via late binding, using IDispatch::GetIDsOfNames and IDispatch::Invoke only. If you're asking for exact Delphi code, I don't have one.
The other answer you link to handles the browser's Navigated event. In it, it injects a script element into the page and into each frame on the page. That script assigns a new value to window.alert so that when other code on the page calls it, it does nothing.
This code resets the event handler:
var
WrkIHTMLWindow2: IHTMLWindow2;
WrkIHTMLWindow2Disp: IHTMLWindow2Disp;
begin
WrkIHTMLWindow2 := IHTMLDocument2Disp(WrkIWebBrowser2.Document).parentWindow;
if WrkIHTMLWindow2.QueryInterface(IHTMLWindow2Disp, WrkIHTMLWindow2Disp) = S_OK then
if not VarIsNull(WrkIHTMLWindow2Disp.onbeforeunload) then
WrkIHTMLWindow2Disp.onbeforeunload := NULL;
end;

Getting error on $.mobile.changePage(): Uncaught TypeError: Cannot call method 'trigger' of undefined

I have a JQM apps and I am incorporating Backbone.
Since my initial javascript code is huge, I am only extracting what I believe is problematic.
I am following the advices and calls steps cited here:
jqm-config.js from http://coenraets.org/blog/2012/03/using-backbone-js-with-jquery-mobile/
http://jquerymobile.com/test/docs/pages/backbone-require.html
I have a major problem, and this is the behaviour, the problem comes from this code:
var r = Backbone.Router.extend
router: ...
"page": "pageDisplay"
...
pageDisplay: function(){
c = new AView(); // Backbone.View ...fetch() data...
$(c.el).page(); // Call to JQM to add its extra stuff; seems done correctly
$.mobile.changePage( "#" + c.id, {changeHash: false}); // line 50
}
When following the links of <a href="#page" >, I come as expected to the
page "#page" properly processed. But once there, if I click a refresh, which is indirectly reprocessed by the same router rule, I end up with the following error:
Uncaught TypeError: Cannot call method 'trigger' of undefined
I downloaded the jquery mobile development code and observed this:
// JQM1.1.2 - Line #3772 Show a specific page in the page container.
$.mobile.changePage = function( toPage, options ) {
if ( isPageTransitioning ) {
pageTransitionQueue.unshift(arguments );
return;
}
var settings = $.extend( {}, $.mobile.changePage.defaults, options);
// Make sure we have a pageContainer to work with.
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;
// Make sure we have a fromPage.
settings.fromPage = settings.fromPage || $.mobile.activePage;
// Line #3788
var mpc = settings.pageContainer, // Line #3789
pbcEvent = new $.Event("pagebeforechange" ),
triggerData = { toPage: toPage, options: settings };
// Let listeners know we're about to change the current page.
mpc.trigger( pbcEvent, triggerData ); // Line #3794
The Uncaught TypeError is caused by Line #3794, because mpc is undefined.
So, from JQM, In the Chrome inspector, I can see also that settings.fromPage is undefined and settings.pageContainer is undefined. I kind of imagine, that JQM cannot make an assumption on the fromPage, and therefore, cannot proceed on my refresh. All the options I have tried on the $mobile.changePage() have not succeed. I am out of ideas.
UPDATE/ Online site with the minimum to reproduce the problem:
apartindex, access the website with the bug
Any help will be appreciated.
The dextoInit function that calls the router code is called in $(document).ready() which does not guarantee that the jQuery mobile page has actually been set up successfully. But the router code calls $.mobile.changePage which depends on jQuery Mobile being initialized.
Putting it into mobileinit or pageinit should work.
(Unfortunately I can't modify the code and test it easily.)
Although, this fix it for the moment, it does have drawbacks. See below.
$(document).bind("pageinit", function(){
console.log('bindtomobileinit: event pageinit received');
if ( !window.AppNode.router ){
window.AppNode.router = new AppNode.singletons.router();
console.log("mobileRouter.js: Starting b history");
console.log('mobileRouter.js: About to launch Backbone history');
Backbone.history.start();
}
});
Registering to pageinit has a weird effect of being fired twice. I see that 2 nodes have been added to the Dom: the default "loading" jquery mobile div (related to pageinit:1), and my data-role page (pageinit:2). So on a "refresh browser click", my situation leaves me waiting for a first pageinit, creating an unexpected jquery mobile dom element (a default page created to display the waiting JQM circle animation), which trigger the router creation, and allows the Backbone.history call which then deal with my "" home page. The second pageinit do not interfere with the settings since I execute it only once.
I am really disappointed by this setup. I will leave this question for now, since it does sort of work.
I've found the source of the problem to be jquery-mobile version 1.3.0. When I fall back to either JSM 1.2.0 or 1.2.1, the "Uncaught TypeError: Cannot call method 'trigger' of undefined" problem goes away.
BTW, I am not using Backbone.
I had fixed this problem by using method append(), but not html()
$('body').append(view.render().$el);
I was able to resolve this issue by changing the page data property from "data-role" to "data-mobile-page" as what is referenced in line 4042 of jqm 1.3.2
fromPage.data( "mobile-page" )._trigger( "beforehide", null, { nextPage: toPage } );
Setting
$.mobile.autoInitializePage = true;
In your jquery mobile config file, some place like:
$(document).on("mobileinit", function () {...});
May help.

SelectControl doesn't work in OpenLayers using IE8

I'm trying to display an alert message when a user clicks on one of the vectors is in the vector layer. This works fine in all browser, except IE8.
map = new OpenLayers.Map(id, {
theme: null
});
vectorLayer = new OpenLayers.Layer.Vector("Vector Layer");
map.addLayer(vectorLayer);
selectControl = new OpenLayers.Control.SelectFeature(vectorLayer);
vectorLayer.events.on({
'featureselected': onPopupFeatureSelect,
'featureunselected': onPopupFeatureUnselect
});
map.addControl(selectControl);
selectControl.activate();
// ...
function onPopupFeatureSelect(feature) {
alert("OK");
} // <-- Exceptions are thrown here
Whenever the onPopupFeatureSelect function is finished (at {) the IE8 debugger somehow falls into the JQuery code and throws exceptions there.
Am I using the select feature correctly?
Update: The crash occurs when I click anywhere in the map. It is not related to the popup feature.
JQuery in combination with VML was causing this problem. I updated to version 1.7.1 and everything is working fine.
More information here: http://bugs.jquery.com/ticket/7071

How to close a sidebar in firefox

I have a sidebar inside my firefox addon. I want the following behavior for this sidebar - I should force close the sidebar if it is open when the browser is being closed (so that the next time the browser is opened the sidebar is not in an open state). I am trying to do this:
uninit: function() {
var sidebarWindow = document.getElementById("sidebar").contentWindow;
if (sidebarWindow.location.href == "chrome://myaddon/content/mysidebar.xul") {
// Act on the sidebar content
toggleSidebar('mySampleSidebar');
}
}
I call this uninit for the window.unload event:
window.addEventListener("unload", function() { myobj.uninit()}, false);
Can someone tell me how to achieve this, as what I am trying to do is not working.
Thanks
Kapil
In your firefox sidebar overlay javascript add
toggleSidebar();
in the "load" event listener function.
See here for example:
sidebar.onFirefoxLoad = function(event) {
document.getElementById("contentAreaContextMenu")
.addEventListener("popupshowing", function (e)
{ sidebar.showFirefoxContextMenu(e); }, false);
toggleSidebar();
};
window.addEventListener("load", sidebar.onFirefoxLoad, false);
Your code is correct for closing your sidebar, but I think unload is too late to change the startup state of the browser window (browser.xul), because browser.xul has already been unloaded (and its state, including sidebar state, has already been stored away).
Instead use beforeunload. I tested the following and it seems to work fine:
window.addEventListener("unload", myobj.uninit, false)
On rare occasions the browser process could be killed so unload would not be called (user kills it or it crashes). I'm not sure if occasionally stores the state of the sidebar like it does tabs, but if it does it could open and have the sidebar visible in that rare case. To handle that case, you can add what #Vinothkumar suggested.
window.addEventListener("load", myobj.uninit, false)

Resources