Skip to content

Commit

Permalink
Fixed window positioning issue (patch wrong window.screenY returned b…
Browse files Browse the repository at this point in the history
…y browsers)
  • Loading branch information
salmonb committed Aug 29, 2023
1 parent a104df9 commit 94e8383
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dev.webfx.kit.mapper.peers.javafxgraphics.HasNoChildrenPeers;
import dev.webfx.kit.mapper.peers.javafxgraphics.NodePeer;
import dev.webfx.kit.mapper.peers.javafxgraphics.emul_coupling.base.ScenePeerBase;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.shared.GwtWindowPeer;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.shared.HtmlSvgNodePeer;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.util.FxEvents;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.util.HtmlPaints;
Expand Down Expand Up @@ -81,7 +82,11 @@ private void installMouseListeners() {
// last mouse event will be the oncontextmenu event).
/*&& lastMouseEvent != null && "mouseup".equals(lastMouseEvent.type)*/) {
MouseEvent me = (MouseEvent) e;
listener.menuEvent(me.x, me.y, me.pageX, me.pageY, false);
// By the way, we set the correction for window.screenY (see GwtWindowPeer comment), knowing that pageY
// is giving the correct value for the context menu in the page coordinates.
GwtWindowPeer.windowScreenYCorrection = DomGlobal.window.screenY - me.screenY + me.pageY;
// Finally we generate the menu event for JavaFX
listener.menuEvent(me.x, me.y, me.screenX, me.screenY, false);
//lastMouseEvent = me;
}
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package dev.webfx.kit.mapper.peers.javafxgraphics.gwt.shared;

import dev.webfx.kit.mapper.peers.javafxgraphics.emul_coupling.base.ScenePeerBase;
import dev.webfx.kit.mapper.peers.javafxgraphics.emul_coupling.base.WindowPeerBase;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.html.HtmlScenePeer;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.util.HtmlUtil;
import elemental2.dom.CSSProperties;
import elemental2.dom.CSSStyleDeclaration;
import elemental2.dom.DomGlobal;
import elemental2.dom.HTMLElement;
import javafx.scene.Scene;
import javafx.stage.Window;
import dev.webfx.kit.mapper.peers.javafxgraphics.emul_coupling.base.ScenePeerBase;
import dev.webfx.kit.mapper.peers.javafxgraphics.emul_coupling.base.WindowPeerBase;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.html.HtmlScenePeer;
import dev.webfx.kit.mapper.peers.javafxgraphics.gwt.util.HtmlUtil;

import static elemental2.dom.DomGlobal.document;

public class GwtWindowPeer extends WindowPeerBase {

// Variable set by HtmlScenePeer that contains the correction to apply on window.screenY, because browsers return
// a wrong value! What WebFX expects from window.screenY is to return the position on the screen of the top left
// corner of the browser PAGE (good). However, browsers (at least on macOS) return the position of the top left
// corner of the browser WINDOW (bad). There can be a quite big difference between the 2, due to the presence of
// browser tabs, bookmarks bar, etc...
public static double windowScreenYCorrection;
// We actually don't create a separate window like in JavaFX, but simply simulate a window in the DOM
private final HTMLElement windowElement = HtmlUtil.createElement("fx-window");
private final CSSStyleDeclaration windowStyle = windowElement.style;

Expand All @@ -25,7 +33,8 @@ public GwtWindowPeer(Window window) {
//windowStyle.border = "orange 3px solid";
// HACK: the window won't resize properly if not in the DOM before showing (otherwise root layout bound will be 0)
windowStyle.opacity = CSSProperties.OpacityUnionType.of(0); // Setting opacity to 0 so it's not visible
document.body.appendChild(windowElement); // Adding to the DOM
// Adding the window to the DOM (it should appear in front of all other elements since it is the last child)
document.body.appendChild(windowElement);
}

@Override
Expand All @@ -36,11 +45,13 @@ protected ScenePeerBase getScenePeer() {

@Override
public void setBounds(float x, float y, boolean xSet, boolean ySet, float w, float h, float cw, float ch, float xGravity, float yGravity) {
//Logger.log("x = " + x + ", y = " + y + ", w = " + w + ", h = " + h + ", cw = " + cw + ", ch = " + ch);
// Console.log("x = " + x + ", y = " + y + ", w = " + w + ", h = " + h + ", cw = " + cw + ", ch = " + ch);
// Note: x & y here are screenX and screenY. But because this window is in reality in the DOM, we need to
// transform these screen coordinates into page coordinates by subtracting the current window screen position.
if (xSet)
windowStyle.left = x + "px";
windowStyle.left = (x - DomGlobal.window.screenX) + "px";
if (ySet)
windowStyle.top = y + "px";
windowStyle.top = (y - DomGlobal.window.screenY + windowScreenYCorrection) + "px";
if (w < 0 && cw > 0)
w = cw; // + 6;
if (h < 0 && ch > 0)
Expand Down

0 comments on commit 94e8383

Please sign in to comment.