Skip to content

Commit

Permalink
Fix an issue with Chrome and hidden tabs.
Browse files Browse the repository at this point in the history
When the webpage is on a hidden tab, tiles are not rendered.  This seems
to only be a problem with Chrome.  This adds 'hidden' and 'unhidden'
events, so any feature can hook into these.

The webgl tile layer refreshes its tile cache when unhidden.
  • Loading branch information
manthey committed Oct 25, 2019
1 parent cff40dc commit bdb20c2
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Bug Fixes
- Removed extra calls to sceneObject constructors (#1039)
- Fixed an issue with rendering on hidden tabs in Chrome (#1042)

## Version 0.19.7

Expand Down
18 changes: 18 additions & 0 deletions src/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,24 @@ geo_event.draw = 'geo_draw';
*/
geo_event.drawEnd = 'geo_drawEnd';

/**
* Triggered when the map is shown (the browser tab is made visible)
*
* @event geo.event.unhidden
* @type {geo.event.base}
* @property {geo.map} target The current map.
*/
geo_event.unhidden = 'geo_unhidden';

/**
* Triggered when the map is hidden (the browser tab is no longer visible)
*
* @event geo.event.hidden
* @type {geo.event.base}
* @property {geo.map} target The current map.
*/
geo_event.hidden = 'geo_hidden';

/**
* Triggered on every `mousemove` over the map's DOM element unless a click
* might occur. The event object extends {@link geo.mouseState}.
Expand Down
46 changes: 46 additions & 0 deletions src/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,49 @@ var map = function (arg) {
return m_this;
};

/**
* Trigger an event when the browser is hidden or unhidden.
*
* See {@link geo.map.trackBrowserHidden}.
*/
function handleBrowserHidden() {
var hidden;

if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
hidden = 'hidden';
} else if (typeof document.msHidden !== 'undefined') {
hidden = 'msHidden';
} else if (typeof document.webkitHidden !== 'undefined') {
hidden = 'webkitHidden';
}
m_this.geoTrigger(document[hidden] ? geo_event.hidden : geo_event.unhidden);
}

/**
* Track when the browser tab is hidden or unhidden.
*
* Based on
* https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
* as accessed on 2019-10-24.
*
* @param {boolean} [enable] If `false`, remove the event listener.
*/
function trackBrowserHidden(enable) {
var visibilityChange;

if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
visibilityChange = 'visibilitychange';
} else if (typeof document.msHidden !== 'undefined') {
visibilityChange = 'msvisibilitychange';
} else if (typeof document.webkitHidden !== 'undefined') {
visibilityChange = 'webkitvisibilitychange';
}
document.removeEventListener(visibilityChange, handleBrowserHidden);
if (enable !== false) {
document.addEventListener(visibilityChange, handleBrowserHidden);
}
}

/**
* Initialize the map.
*
Expand All @@ -923,6 +966,8 @@ var map = function (arg) {
}
m_node.addClass('geojs-map');
m_node.data('data-geojs-map', m_this);

trackBrowserHidden();
return m_this;
};

Expand All @@ -947,6 +992,7 @@ var map = function (arg) {
* empties the associated DOM node.
*/
this.exit = function () {
trackBrowserHidden(false);
var i, layers = m_this.children();
for (i = layers.length - 1; i >= 0; i -= 1) {
layers[i]._exit();
Expand Down
10 changes: 10 additions & 0 deletions src/webgl/tileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ var webgl_tileLayer = function () {
* Destroy.
*/
this._exit = function () {
var map = m_this.map();
map.geoOff(geo_event.layerAdd, m_this._clearQuads);
map.geoOff(geo_event.layerRemove, m_this._clearQuads);
m_this._cleanup();
m_this.deleteFeature(m_quadFeature);
m_quadFeature = null;
Expand All @@ -219,6 +222,13 @@ var webgl_tileLayer = function () {
var map = m_this.map();
map.geoOn(geo_event.layerAdd, m_this._clearQuads);
map.geoOn(geo_event.layerRemove, m_this._clearQuads);

m_this.geoOn(geo_event.unhidden, () => {
m_this.map().scheduleAnimationFrame(() => {
m_this._clearQuads();
m_this.map().draw();
});
});
};

/* These functions don't need to do anything. */
Expand Down

0 comments on commit bdb20c2

Please sign in to comment.