Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4984,12 +4984,64 @@ public void mouseWheelMoved(WheelEvent e) {
pointerWheelMoved(x, y, dx, dy, true, 0);
}

/// The CSS color last given to the page, or null while it is the stylesheet's own.
private String pageBackground;

/// Gives the page behind the canvas the background of the form now showing (issue #6109).
///
/// Resizing a canvas clears it, and the browser grows the viewport before the worker hears
/// of it, so until the form repaints at the new size the page itself shows -- white, behind
/// a dark form, on every keyboard open and window resize. Nothing is painted here and no
/// paint is added: the page is only seen in that gap, so its color is set when a form
/// arrives and when the canvas is resized, and the DOM is written only when it changes. A
/// dialog keeps the color of the form beneath it, which still fills the screen.
///
/// A form without an opaque, single-color background leaves the page alone: what shows through it is
/// whatever was there, and a color guessed from the theme could be wrong.
private void syncPageBackground(Form f) {
if (f == null || f instanceof com.codename1.ui.Dialog) {
return;
}
Style s = f.getContentPane().getUnselectedStyle();
if ((s.getBgTransparency() & 0xff) != 0xff) {
s = f.getUnselectedStyle();
}
String color = null;
// An image or gradient is not one color; the page is left alone rather than given its base.
if ((s.getBgTransparency() & 0xff) == 0xff && s.getBgImage() == null
&& !isGradientBackground(s.getBackgroundType())) {
String hex = Integer.toHexString(s.getBgColor() & 0xffffff);
color = "#000000".substring(0, 7 - hex.length()) + hex;
}
if (color == null ? pageBackground == null : color.equals(pageBackground)) {
return;
}
pageBackground = color;
if (color == null) {
doc().getDocumentElement().getStyle().removeProperty("background-color");
doc().getBody().getStyle().removeProperty("background-color");
} else {
doc().getDocumentElement().getStyle().setProperty("background-color", color);
doc().getBody().getStyle().setProperty("background-color", color);
}
}

// Not BACKGROUND_NONE: a style's type defaults to BACKGROUND_IMAGE_SCALED and a theme
// writes no type for a plain color, so a plain fill is any image type with no image.
private static boolean isGradientBackground(byte type) {
return type == Style.BACKGROUND_GRADIENT_LINEAR_VERTICAL
|| type == Style.BACKGROUND_GRADIENT_LINEAR_HORIZONTAL
|| type == Style.BACKGROUND_GRADIENT_RADIAL
|| type >= Style.BACKGROUND_GRADIENT_LINEAR && type <= Style.BACKGROUND_GRADIENT_REPEATING_RADIAL;
}

private void updateCanvasSize() {
refreshDevicePixelRatio();
JavaScriptCanvasLayout.Dimensions dimensions = JavaScriptCanvasLayout.compute(
doc().getBody().getClientWidth(),
window.getInnerHeight() - chromeTopCss,
devicePixelRatioValue());
syncPageBackground(getCurrentForm());
canvas.setWidth(dimensions.getBackingWidth());
canvas.setHeight(dimensions.getBackingHeight());
outputCanvas.setWidth(dimensions.getBackingWidth());
Expand Down Expand Up @@ -13332,6 +13384,7 @@ public void setCurrentForm(Form f) {
// resolved then, so it is brought up to date as it appears rather than coming back in
// the old palette.
refreshThemeIfStale(f);
syncPageBackground(f);
// Taken for every arrival, whatever is done with it: the framework queues one direction
// per display asked for, and a queue read only on some paths would drift out of step
// with what is still waiting.
Expand Down Expand Up @@ -15729,6 +15782,16 @@ public void handleEvent(final MouseEvent evt) {
if (target == null || !"codenameone-canvas".equals(target.getAttribute("id"))) {
return;
}
// Only a right-click, never a finger. Android Chrome fires contextmenu for a touch
// long press too, so a long press landing on the canvas rather than on a native text
// overlay opened this desktop menu, while one landing on the overlay got the
// browser's -- the menu alternated between attempts (issue #6108). A long press is
// already TextSelection's (LongPointerPress) on canvas text, and the menu was placed
// at lastMouseEvent, which a touch never updates. touchDown covers a browser whose
// contextmenu is not a PointerEvent: it fires while the finger is still down.
if (isTouchPointer(evt) || pointerState.isTouchDown()) {
return;
}
Form f = CN.getCurrentForm();
if (f == null) {
return;
Expand Down
Loading