Commit 223f99d6 authored by Emilio Cobos Álvarez's avatar Emilio Cobos Álvarez
Browse files

Bug 1768278 - Draw menupopup shadows ourselves on Windows. r=dao,Gijs

This prevents long-standing artifacts on HiDPI screens on context menus and so
on.

This is much simpler than tooltips because menupopups and panels already have
the whole set-up ready.

The searchbar.css changes are kind of annoying, but they improve the rendering
a lot (see attached screenshots).

Let me know if you want me to draw shadows on all panels on Windows like we do
on Linux, it's probably doable and cleaner over-all.

Differential Revision: https://phabricator.services.mozilla.com/D145818
parent b1f8ba42
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -165,10 +165,19 @@

@media (-moz-platform: windows-win10) {
  #PopupSearchAutoComplete {
    /* A border is necessary because the shadow is bottom-right */
    border-color: var(--menu-border-color);
    border-radius: var(--arrowpanel-border-radius);
    -moz-window-shadow: cliprounded;
    appearance: none;
    border: none;
    background-color: transparent;

    margin: -4px;
    --panel-border-color: var(--menu-border-color);
    --panel-border-radius: var(--arrowpanel-border-radius);
  }
  /* TODO(emilio): We should consider adding shadows to all panels on Windows,
     probably */
  #PopupSearchAutoComplete::part(content) {
    margin: 4px;
    box-shadow: var(--windows-panel-box-shadow);
  }
}

+6 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@
    const contextmenu = await contextMenuPromise;
    ok(pointerUpSeen, "pointerup event was seen");
    is(contextmenu.button, 2, ".button indicates secondary button");

    // Close the context menu.
    await promiseNativePointerTap(container, "pen", 30, 30);
  });

  add_task(async function testPenContextMenuWhenButtonChange() {
@@ -60,5 +63,8 @@

    const contextmenu = await contextMenuPromise;
    is(contextmenu.button, 2, ".button still indicates secondary button");

    // Close the context menu.
    await promiseNativePointerTap(container, "pen", 30, 30);
  });
</script>
+2 −2
Original line number Diff line number Diff line
@@ -109,8 +109,8 @@ function openContextMenu() {
        var rootElement = win.document.documentElement;
        var platformIsMac = navigator.userAgent.indexOf("Mac") > -1;

        var x = menu.screenX - rootElement.screenX;
        var y = menu.screenY - rootElement.screenY;
        var x = menu.screenX - rootElement.screenX - parseFloat(getComputedStyle(menu).marginLeft);
        var y = menu.screenY - rootElement.screenY - parseFloat(getComputedStyle(menu).marginTop);

        if (platformIsMac)
        {
+24 −11
Original line number Diff line number Diff line
@@ -22,46 +22,59 @@
<![CDATA[

let menupopup;
function margins(popup) {
  let ret = {};
  let cs = getComputedStyle(popup);
  for (let side of ["top", "right", "bottom", "left"]) {
    ret[side] = parseFloat(cs.getPropertyValue("margin-" + side));
  }
  return ret;
}

let tests = [
  {
    test: () => menupopup.openPopupAtScreenRect("after_start", 150, 250, 30, 40),
    verify: popup => {
      let rect = popup.getOuterScreenRect();
      is(rect.left, 150, "popup at screen position x");
      is(rect.top, 290, "popup at screen position y");
      let margin = margins(popup);
      is(rect.left - margin.left, 150, "popup at screen position x");
      is(rect.top - margin.top, 290, "popup at screen position y");
    }
  },
  {
    test: () => menupopup.openPopupAtScreenRect("after_start", 150, 350, 30, 9000),
    verify: popup => {
      let rect = popup.getOuterScreenRect();
      is(rect.left, 150, "flipped popup at screen position x");
      is(rect.bottom, 350, "flipped popup at screen position y");
      let margin = margins(popup);
      is(rect.left - margin.left, 150, "flipped popup at screen position x");
      is(rect.bottom + margin.bottom, 350, "flipped popup at screen position y");
    }
  },
  {
    test: () => menupopup.openPopupAtScreenRect("end_before", 150, 250, 30, 40),
    verify: popup => {
      let rect = popup.getOuterScreenRect();
      is(rect.left, 180, "popup at end_before screen position x");
      is(rect.top, 250, "popup at end_before screen position y");
      let margin = margins(popup);
      is(rect.left - margin.left, 180, "popup at end_before screen position x");
      is(rect.top - margin.top, 250, "popup at end_before screen position y");
    }
  },
  {
    test: () => $("panel").openPopupAtScreenRect("after_start", 150, 250, 30, 40),
    verify: popup => {
      let rect = popup.getOuterScreenRect();
      is(rect.left, 150, "panel at screen position x");
      is(rect.top, 290, "panel at screen position y");
      let margin = margins(popup);
      is(rect.left - margin.left, 150, "panel at screen position x");
      is(rect.top - margin.top, 290, "panel at screen position y");
    }
  },
  {
    test: () => $("panel").openPopupAtScreenRect("before_start", 150, 250, 30, 40),
    verify: popup => {
      let rect = popup.getOuterScreenRect();
      is(rect.left, 150, "panel at before_start screen position x");
      is(rect.bottom, 250, "panel at before_start screen position y");
      let margin = margins(popup);
      is(rect.left - margin.left, 150, "panel at before_start screen position x");
      is(rect.bottom + margin.bottom, 250, "panel at before_start screen position y");
    }
  },
];
+12 −3
Original line number Diff line number Diff line
@@ -24,17 +24,26 @@ function is_close(got, exp, msg) {
  ok(Math.abs(got - exp) < 1, msg + ": " + got + " should be equal(-ish) to " + exp);
}

function margins(popup) {
  let ret = {};
  let cs = getComputedStyle(popup);
  for (let side of ["top", "right", "bottom", "left"]) {
    ret[side] = parseFloat(cs.getPropertyValue("margin-" + side));
  }
  return ret;
}

function checkPositionRelativeToAnchor(side) {
  var panelRect = panel.getBoundingClientRect();
  var anchorRect = anchor.getBoundingClientRect();
  switch (side) {
    case "left":
    case "right":
      is_close(panelRect.top, anchorRect.bottom, "top of panel should be at bottom of anchor");
      is_close(panelRect.top - margins(panel).top, anchorRect.bottom, "top of panel should be at bottom of anchor");
      break;
    case "top":
    case "bottom":
      is_close(panelRect.right, anchorRect.left, "right of panel should be left of anchor");
      is_close(panelRect.right + margins(panel).left, anchorRect.left, "right of panel should be left of anchor");
      break;
    default:
      ok(false, "unknown side " + side);
@@ -295,7 +304,7 @@ var tests = [
  ['after_start', 'left', function(next) {
    openPopup("after_start", function() {
      var panelRect = panel.getBoundingClientRect();
      is(panelRect.left, 0, "panel remains within the screen");
      ok(panelRect.left - margins(panel).left >= 0, "panel remains within the screen");
      checkPositionRelativeToAnchor("left");
      next();
    });
Loading