mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 736729 - Fix display-port on first paint and page-size changes. r=kats
Previously, we only set the display-port in response to a page scrolling itself, or when we adjust the viewport. This meant that the display-port could be incorrect if a viewport adjustment was sent after a page-size changed, but before a render had completed. Similarly, we were not updating the display-port when the viewport of a foreground document that hadn't been displayed yet was changing. This would cause the first-paint to have an incorrect (and often too small) display port, which wouldn't be corrected until the page was scrolled.
This commit is contained in:
parent
7fbfb4bae3
commit
ebc07011a5
@ -109,6 +109,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
|
||||
mLayerRenderer = new LayerRenderer(view);
|
||||
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:Update", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:PageSize", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:CalculateDisplayPort", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Checkerboard:Toggle", this);
|
||||
|
||||
@ -242,25 +243,55 @@ public class GeckoLayerClient implements GeckoEventResponder,
|
||||
mGeckoViewport = viewportMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* The different types of Viewport messages handled. All viewport events
|
||||
* expect a display-port to be returned, but can handle one not being
|
||||
* returned.
|
||||
*/
|
||||
private enum ViewportMessageType {
|
||||
UPDATE, // The viewport has changed and should be entirely updated
|
||||
PAGE_SIZE // The viewport's page-size has changed
|
||||
}
|
||||
|
||||
/** Viewport message handler. */
|
||||
private void handleViewportMessage(JSONObject message, ViewportMessageType type) throws JSONException {
|
||||
ViewportMetrics messageMetrics = new ViewportMetrics(message);
|
||||
synchronized (mLayerController) {
|
||||
final ViewportMetrics newMetrics;
|
||||
ImmutableViewportMetrics oldMetrics = mLayerController.getViewportMetrics();
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case UPDATE:
|
||||
newMetrics = messageMetrics;
|
||||
// Keep the old viewport size
|
||||
newMetrics.setSize(oldMetrics.getSize());
|
||||
mLayerController.abortPanZoomAnimation();
|
||||
break;
|
||||
case PAGE_SIZE:
|
||||
newMetrics = new ViewportMetrics(oldMetrics);
|
||||
newMetrics.setPageSize(messageMetrics.getPageSize());
|
||||
break;
|
||||
}
|
||||
|
||||
mLayerController.post(new Runnable() {
|
||||
public void run() {
|
||||
mGeckoViewport = newMetrics;
|
||||
}
|
||||
});
|
||||
mLayerController.setViewportMetrics(newMetrics);
|
||||
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
|
||||
}
|
||||
mReturnDisplayPort = mDisplayPort;
|
||||
}
|
||||
|
||||
/** Implementation of GeckoEventResponder/GeckoEventListener. */
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
try {
|
||||
if ("Viewport:Update".equals(event)) {
|
||||
final ViewportMetrics newMetrics = new ViewportMetrics(message);
|
||||
synchronized (mLayerController) {
|
||||
// keep the old viewport size, but update everything else
|
||||
ImmutableViewportMetrics oldMetrics = mLayerController.getViewportMetrics();
|
||||
newMetrics.setSize(oldMetrics.getSize());
|
||||
mLayerController.post(new Runnable() {
|
||||
public void run() {
|
||||
mGeckoViewport = newMetrics;
|
||||
}
|
||||
});
|
||||
mLayerController.setViewportMetrics(newMetrics);
|
||||
mLayerController.abortPanZoomAnimation();
|
||||
mDisplayPort = calculateDisplayPort(mLayerController.getViewportMetrics());
|
||||
mReturnDisplayPort = mDisplayPort;
|
||||
}
|
||||
handleViewportMessage(message, ViewportMessageType.UPDATE);
|
||||
} else if ("Viewport:PageSize".equals(event)) {
|
||||
handleViewportMessage(message, ViewportMessageType.PAGE_SIZE);
|
||||
} else if ("Viewport:CalculateDisplayPort".equals(event)) {
|
||||
ImmutableViewportMetrics newMetrics = new ImmutableViewportMetrics(new ViewportMetrics(message));
|
||||
mReturnDisplayPort = calculateDisplayPort(newMetrics);
|
||||
|
@ -1515,6 +1515,7 @@ Tab.prototype = {
|
||||
this.browser.addEventListener("DOMWindowClose", this, true);
|
||||
this.browser.addEventListener("DOMWillOpenModalDialog", this, true);
|
||||
this.browser.addEventListener("scroll", this, true);
|
||||
this.browser.addEventListener("MozScrolledAreaChanged", this, true);
|
||||
this.browser.addEventListener("PluginClickToPlay", this, true);
|
||||
this.browser.addEventListener("pagehide", this, true);
|
||||
this.browser.addEventListener("pageshow", this, true);
|
||||
@ -1562,6 +1563,7 @@ Tab.prototype = {
|
||||
this.browser.removeEventListener("DOMWillOpenModalDialog", this, true);
|
||||
this.browser.removeEventListener("scroll", this, true);
|
||||
this.browser.removeEventListener("PluginClickToPlay", this, true);
|
||||
this.browser.removeEventListener("MozScrolledAreaChanged", this, true);
|
||||
this.browser.removeEventListener("pagehide", this, true);
|
||||
this.browser.removeEventListener("pageshow", this, true);
|
||||
|
||||
@ -1689,17 +1691,16 @@ Tab.prototype = {
|
||||
return viewport;
|
||||
},
|
||||
|
||||
sendViewportUpdate: function() {
|
||||
sendViewportUpdate: function(aPageSizeUpdate) {
|
||||
let message;
|
||||
if (BrowserApp.selectedTab == this) {
|
||||
// for foreground tabs, send the viewport update unless the document
|
||||
// displayed is different from the content document
|
||||
if (!BrowserApp.isBrowserContentDocumentDisplayed())
|
||||
return;
|
||||
// for foreground tabs, send the viewport update unless the document
|
||||
// displayed is different from the content document. In that case, just
|
||||
// calculate the display port.
|
||||
if (BrowserApp.selectedTab == this && BrowserApp.isBrowserContentDocumentDisplayed()) {
|
||||
message = this.getViewport();
|
||||
message.type = "Viewport:Update";
|
||||
message.type = aPageSizeUpdate ? "Viewport:PageSize" : "Viewport:Update";
|
||||
} else {
|
||||
// for bcakground tabs, request a new display port calculation, so that
|
||||
// for background tabs, request a new display port calculation, so that
|
||||
// when we do switch to that tab, we have the correct display port and
|
||||
// don't need to draw twice (once to allow the first-paint viewport to
|
||||
// get to java, and again once java figures out the display port).
|
||||
@ -1859,6 +1860,17 @@ Tab.prototype = {
|
||||
break;
|
||||
}
|
||||
|
||||
case "MozScrolledAreaChanged": {
|
||||
// This event is only fired for root scroll frames, and only when the
|
||||
// scrolled area has actually changed, so no need to check for that.
|
||||
// Just make sure it's the event for the correct root scroll frame.
|
||||
if (aEvent.originalTarget != this.browser.contentDocument)
|
||||
return;
|
||||
|
||||
this.sendViewportUpdate(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case "PluginClickToPlay": {
|
||||
// Keep track of the number of plugins to know whether or not to show
|
||||
// the hidden plugins doorhanger
|
||||
@ -2194,11 +2206,12 @@ Tab.prototype = {
|
||||
// and then use the metadata to figure out how it needs to be updated
|
||||
ViewportHandler.updateMetadata(this);
|
||||
|
||||
// The document element must have a display port on it whenever we are about to
|
||||
// paint. This is the point just before the first paint, so we set the display port
|
||||
// to a default value here. Once Java is aware of this document it will overwrite
|
||||
// it with a better-calculated display port.
|
||||
this.setDisplayPort(0, 0, {left: 0, top: 0, right: gScreenWidth, bottom: gScreenHeight });
|
||||
// If we draw without a display-port, things can go wrong. While it's
|
||||
// almost certain a display-port has been set via the
|
||||
// MozScrolledAreaChanged event, make sure by sending a viewport
|
||||
// update here. As it's the first paint, this will end up being a
|
||||
// display-port request only.
|
||||
this.sendViewportUpdate();
|
||||
|
||||
BrowserApp.displayedDocumentChanged();
|
||||
this.contentDocumentIsDisplayed = true;
|
||||
|
Loading…
Reference in New Issue
Block a user