tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

setDesktopBackground.js (8955B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /* import-globals-from /browser/base/content/utilityOverlay.js */
      6 
      7 var gSetBackground = {
      8  _position: AppConstants.platform == "macosx" ? "STRETCH" : "",
      9  _backgroundColor: AppConstants.platform != "macosx" ? 0 : undefined,
     10  _screenWidth: 0,
     11  _screenHeight: 0,
     12  _image: null,
     13  _canvas: null,
     14  _imageName: null,
     15 
     16  get _shell() {
     17    return Cc["@mozilla.org/browser/shell-service;1"].getService(
     18      Ci.nsIShellService
     19    );
     20  },
     21 
     22  load() {
     23    this._canvas = document.getElementById("screen");
     24    this._screenWidth = screen.width;
     25    this._screenHeight = screen.height;
     26    // Cap ratio to 4 so the dialog width doesn't get ridiculous. Highest
     27    // regular screens seem to be 32:9 (3.56) according to Wikipedia.
     28    let screenRatio = Math.min(this._screenWidth / this._screenHeight, 4);
     29    this._canvas.width = this._canvas.height * screenRatio;
     30    document.getElementById("preview-unavailable").style.width =
     31      this._canvas.width + "px";
     32 
     33    if (AppConstants.platform == "macosx") {
     34      document
     35        .getElementById("SetDesktopBackgroundDialog")
     36        .getButton("accept").hidden = true;
     37 
     38      document
     39        .getElementById("setDesktopBackground")
     40        .addEventListener("command", () => this.setDesktopBackground());
     41 
     42      document
     43        .getElementById("showDesktopPreferences")
     44        .addEventListener("command", () => {
     45          this._shell
     46            .QueryInterface(Ci.nsIMacShellService)
     47            .showDesktopPreferences();
     48        });
     49    } else {
     50      let multiMonitors = false;
     51      if (AppConstants.platform == "linux") {
     52        // getMonitors only ever returns the primary monitor on Linux, so just
     53        // always show the option
     54        multiMonitors = true;
     55      } else {
     56        const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
     57        const monitors = gfxInfo.getMonitors();
     58        multiMonitors = monitors.length > 1;
     59      }
     60 
     61      if (!multiMonitors) {
     62        // Hide span option on single monitor systems.
     63        document.getElementById("spanPosition").hidden = true;
     64      }
     65 
     66      document
     67        .getElementById("menuPosition")
     68        .addEventListener("command", () => this.updatePosition());
     69      document
     70        .getElementById("desktopColor")
     71        .addEventListener("change", event =>
     72          this.updateColor(event.currentTarget.value)
     73        );
     74    }
     75 
     76    document.addEventListener("dialogaccept", function () {
     77      gSetBackground.setDesktopBackground();
     78    });
     79    // make sure that the correct dimensions will be used
     80    setTimeout(
     81      function (self) {
     82        self.init(window.arguments[0], window.arguments[1]);
     83      },
     84      0,
     85      this
     86    );
     87  },
     88 
     89  init(aImage, aImageName) {
     90    this._image = aImage;
     91    this._imageName = aImageName;
     92 
     93    // set the size of the coordinate space
     94    this._canvas.width = this._canvas.clientWidth;
     95    this._canvas.height = this._canvas.clientHeight;
     96 
     97    var ctx = this._canvas.getContext("2d");
     98    ctx.scale(
     99      this._canvas.clientWidth / this._screenWidth,
    100      this._canvas.clientHeight / this._screenHeight
    101    );
    102 
    103    if (AppConstants.platform != "macosx") {
    104      this._initColor();
    105    } else {
    106      // Make sure to reset the button state in case the user has already
    107      // set an image as their desktop background.
    108      var setDesktopBackground = document.getElementById(
    109        "setDesktopBackground"
    110      );
    111      setDesktopBackground.hidden = false;
    112      document.l10n.setAttributes(
    113        setDesktopBackground,
    114        "set-desktop-background-accept"
    115      );
    116      setDesktopBackground.disabled = false;
    117 
    118      document.getElementById("showDesktopPreferences").hidden = true;
    119    }
    120    this.updatePosition();
    121  },
    122 
    123  setDesktopBackground() {
    124    if (AppConstants.platform != "macosx") {
    125      Services.xulStore.persist(
    126        document.getElementById("menuPosition"),
    127        "value"
    128      );
    129      this._shell.desktopBackgroundColor = this._hexStringToLong(
    130        this._backgroundColor
    131      );
    132    } else {
    133      Services.obs.addObserver(this, "shell:desktop-background-changed");
    134 
    135      var setDesktopBackground = document.getElementById(
    136        "setDesktopBackground"
    137      );
    138      setDesktopBackground.disabled = true;
    139      document.l10n.setAttributes(
    140        setDesktopBackground,
    141        "set-desktop-background-downloading"
    142      );
    143    }
    144    this._shell.setDesktopBackground(
    145      this._image,
    146      Ci.nsIShellService["BACKGROUND_" + this._position],
    147      this._imageName
    148    );
    149  },
    150 
    151  updatePosition() {
    152    var ctx = this._canvas.getContext("2d");
    153    ctx.clearRect(0, 0, this._screenWidth, this._screenHeight);
    154    document.getElementById("preview-unavailable").hidden = true;
    155 
    156    if (AppConstants.platform != "macosx") {
    157      this._position = document.getElementById("menuPosition").value;
    158    }
    159 
    160    switch (this._position) {
    161      case "TILE":
    162        ctx.save();
    163        ctx.fillStyle = ctx.createPattern(this._image, "repeat");
    164        ctx.fillRect(0, 0, this._screenWidth, this._screenHeight);
    165        ctx.restore();
    166        break;
    167      case "STRETCH":
    168        ctx.drawImage(this._image, 0, 0, this._screenWidth, this._screenHeight);
    169        break;
    170      case "CENTER": {
    171        let x = (this._screenWidth - this._image.naturalWidth) / 2;
    172        let y = (this._screenHeight - this._image.naturalHeight) / 2;
    173        ctx.drawImage(this._image, x, y);
    174        break;
    175      }
    176      case "FILL": {
    177        // Try maxing width first, overflow height.
    178        let widthRatio = this._screenWidth / this._image.naturalWidth;
    179        let width = this._image.naturalWidth * widthRatio;
    180        let height = this._image.naturalHeight * widthRatio;
    181        if (height < this._screenHeight) {
    182          // Height less than screen, max height and overflow width.
    183          let heightRatio = this._screenHeight / this._image.naturalHeight;
    184          width = this._image.naturalWidth * heightRatio;
    185          height = this._image.naturalHeight * heightRatio;
    186        }
    187        let x = (this._screenWidth - width) / 2;
    188        let y = (this._screenHeight - height) / 2;
    189        ctx.drawImage(this._image, x, y, width, height);
    190        break;
    191      }
    192      case "FIT": {
    193        // Try maxing width first, top and bottom borders.
    194        let widthRatio = this._screenWidth / this._image.naturalWidth;
    195        let width = this._image.naturalWidth * widthRatio;
    196        let height = this._image.naturalHeight * widthRatio;
    197        let x = 0;
    198        let y = (this._screenHeight - height) / 2;
    199        if (height > this._screenHeight) {
    200          // Height overflow, maximise height, side borders.
    201          let heightRatio = this._screenHeight / this._image.naturalHeight;
    202          width = this._image.naturalWidth * heightRatio;
    203          height = this._image.naturalHeight * heightRatio;
    204          x = (this._screenWidth - width) / 2;
    205          y = 0;
    206        }
    207        ctx.drawImage(this._image, x, y, width, height);
    208        break;
    209      }
    210      case "SPAN": {
    211        document.getElementById("preview-unavailable").hidden = false;
    212        ctx.fillStyle = "#222";
    213        ctx.fillRect(0, 0, this._screenWidth, this._screenHeight);
    214        ctx.stroke();
    215      }
    216    }
    217  },
    218 };
    219 
    220 if (AppConstants.platform != "macosx") {
    221  gSetBackground._initColor = function () {
    222    var color = this._shell.desktopBackgroundColor;
    223 
    224    const rMask = 4294901760;
    225    const gMask = 65280;
    226    const bMask = 255;
    227    var r = (color & rMask) >> 16;
    228    var g = (color & gMask) >> 8;
    229    var b = color & bMask;
    230    this.updateColor(this._rgbToHex(r, g, b));
    231 
    232    var colorpicker = document.getElementById("desktopColor");
    233    colorpicker.value = this._backgroundColor;
    234  };
    235 
    236  gSetBackground.updateColor = function (aColor) {
    237    this._backgroundColor = aColor;
    238    this._canvas.style.backgroundColor = aColor;
    239  };
    240 
    241  // Converts a color string in the format "#RRGGBB" to an integer.
    242  gSetBackground._hexStringToLong = function (aString) {
    243    return (
    244      (parseInt(aString.substring(1, 3), 16) << 16) |
    245      (parseInt(aString.substring(3, 5), 16) << 8) |
    246      parseInt(aString.substring(5, 7), 16)
    247    );
    248  };
    249 
    250  gSetBackground._rgbToHex = function (aR, aG, aB) {
    251    return (
    252      "#" +
    253      [aR, aG, aB]
    254        .map(aInt => aInt.toString(16).replace(/^(.)$/, "0$1"))
    255        .join("")
    256        .toUpperCase()
    257    );
    258  };
    259 } else {
    260  gSetBackground.observe = function (aSubject, aTopic) {
    261    if (aTopic == "shell:desktop-background-changed") {
    262      document.getElementById("setDesktopBackground").hidden = true;
    263      document.getElementById("showDesktopPreferences").hidden = false;
    264 
    265      Services.obs.removeObserver(this, "shell:desktop-background-changed");
    266    }
    267  };
    268 }
    269 
    270 window.addEventListener("load", () => gSetBackground.load());