[
  {
    "path": ".gitignore",
    "content": "node_modules\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Seyyid Fatih KOÇ\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.MD",
    "content": "[![npm version](https://badge.fury.io/js/electron-tray-window.svg)](https://www.npmjs.com/package/electron-tray-window)\n[![npm version](https://img.shields.io/github/languages/code-size/sfatihk/electron-tray-window)](https://github.com/sfatihk/electron-tray-window)\n[![npm version](https://img.shields.io/npm/dt/electron-tray-window)](https://github.com/sfatihk/electron-tray-window)\n[![npm version](https://img.shields.io/github/issues/sfatihk/electron-tray-window)](https://github.com/sfatihk/electron-tray-window)\n[![npm version](https://img.shields.io/github/license/sfatihk/electron-tray-window)](https://github.com/sfatihk/electron-tray-window)\n\n\n\n\n\n<p align=\"center\">\n<img src=\"resources/icon.png\" style=\"max-width:100%; width:300px\"/>\n</p>\n<h2 align=\"center\">Quickly create customizable  menu/pop-up for your application in system tray.</h2>\n\n---\n\nElectron Tray Window, basically places the window near the tray icon. While these happening, you can customize window / tray or tracking the events.\n\n## Preview [demo project](https://github.com/sfatihk/electron-tray-window/tree/master/examples)\n\n<img src=\"https://raw.githubusercontent.com/sfatihk/electron-tray-window/master/resources/showcase-short.gif\" style=\"max-width:100%; width:300px\"  /> <img src=\"https://raw.githubusercontent.com/sfatihk/electron-tray-window/master/resources/showcase.gif\" style=\"max-width:100%; width:550px\"/>\n\n## Install\n\n```\nnpm install electron-tray-window\n```\n\nor\n\n```\nyarn add electron-tray-window\n```\n\n## Usage\n\n```js\nconst trayWindow = require(\"electron-tray-window\");\n```\n\nYou can use different ways. \"setOptions()\" function accepts object value.\n\nIf you have already created tray or window outside **TrayWindow**, you can pass as arguments to **.setOptions()** function,\n\n```js\n//...\n\ntray = new Tray(...);\nwindow = new BrowserWindow(...);\nwindow.loadUrl(...);\n\ntrayWindow.setOptions({tray: tray,window: window});\n\n//...\n```\n\nor if you pass just tray icon path or window url, it prepare automatically.\n\n```js\n//...\n\ntrayWindow.setOptions({\n  trayIconPath: \"...\",\n  windowUrl: \"...\"\n});\n\n//...\n```\n\nBy the way you can make different combines. But object must contains;\n\n- **tray** or **trayIconPath**\n- **window** or **windowUrl**\n\n```js\n\n//...\n\ntray = new Tray(...);\ntrayWindow.setOptions({\n  tray: tray,\n  windowUrl: \"...\"\n});\n\n//...\n\nwindow = new BrowserWindow(...);\n\ntrayWindow.setOptions({\n  trayIconPath: \"...\",\n  window: window\n});\n\n//...\n```\n\n## Other Functions\n\nYou can always change **TrayWindow** with setOptions() and you can use different functions after setOptions().\n\n## .setTray( tray )\n\n```js\n//...\n\ntrayWindow.setOptions({...});\n\n//...\n\ndifferentTray = new Tray(...);\n\ntrayWindow.setTray(differentTray); //now, follows different tray\n\n//..\n```\n\n## .setWindow( window )\n\n```js\n//...\n\ntrayWindow.setOptions({...});\n\n//...\n\ndifferentWindow = new BrowserWindow(...);\n\ntrayWindow.setWindow(differentWindow); //now, shows different window\n\n//..\n```\n\n## .setWindowSize( object )\n\n```js\n//...\n\ntrayWindow.setOptions({...});\n\n//...\n\ndifferentWindow = new BrowserWindow(...);\n\ntrayWindow.setWindowSize({\n    width    : 200,    //optional\n    height   : 300,   //optional\n    margin_x : 10,  //optional\n    margin_y : 10   //optional\n});\n\n//..\n```\n\n## Events\n\nYou can listen events. All event contains window and tray objects\n\n```js\n//...\nconst { ipcMain } = electron;\n\nipcMain.on(\"tray-window-ready\", (e, a) => {\n  console.log(\"tray window is ready\");\n  //console.log(e.window)\n  //console.log(e.tray)\n});\n\nipcMain.on(\"tray-window-clicked\", (e, a) => {\n  console.log(\"clicked the tray icon\");\n  //console.log(e.window)\n  //console.log(e.tray)\n});\n\nipcMain.on(\"tray-window-visible\", (e, a) => {\n  console.log(\"tray window is visible now\");\n  //console.log(e.window)\n  //console.log(e.tray)\n});\n\nipcMain.on(\"tray-window-hidden\", (e, a) => {\n  console.log(\"tray window is hidden now\");\n  //console.log(e.window)\n  //console.log(e.tray)\n});\n\n//..\n```\n\n## Overview\n\n### All parameters of setOptions()\n\n| parameter    | description                                      | default |\n| ------------ | ------------------------------------------------ | ------- |\n| tray         | Electron's tray object type                      |         |\n| trayIconPath | Image file path                                  |         |\n| window       | Electron's BrowserWindow object type             |         |\n| windowUrl    | Html etc. file path or website url               |         |\n| width        | Window width                                     | 200px   |\n| height       | Window height                                    | 200px   |\n| margin_x     | Vertical distance between window and tray icon   | 0px     |\n| margin_y     | Horizontal distance between window and tray icon | 0px     |\n| framed       | Is it window framed?                             | false   |\n\n### Other functions\n\n| function      | description                                                       |\n| ------------- | ----------------------------------------------------------------- |\n| setTray       | Electron's tray object type.                                      |\n| setWindow     | Electron's BrowserWindow object type                              |\n| setWindowSize | Object type. Optional arguments width, height, margin_x, margin_y |\n\n### IPC (Inter-Process Communication) Events\n\n| event               | description              |\n| ------------------- | ------------------------ |\n| tray-window-ready   | when created TrayWindow. |\n| tray-window-clicked | when clicked tray icon   |\n| tray-window-visible | when window show up      |\n| tray-window-hidden  | when window close down   |\n\n### Default Window Properties\n\n| properties                           | default in TrayWindow |\n| ------------------------------------ | --------------------- |\n| width                                | 200px                 |\n| height                               | 300px                 |\n| maxWidth                             | 200px                 |\n| maxHeight                            | 300px                 |\n| show                                 | false                 |\n| frame                                | false                 |\n| fullscreenable                       | false                 |\n| resizable                            | false                 |\n| useContentSize                       | true                  |\n| transparent                          | true                  |\n| alwaysOnTop                          | true                  |\n| webPreferences{backgroundThrottling} | false                 |\n\nP.S. : if you use this way `setOptions({windowUrl:\"...\"})`, default window values uses.\n"
  },
  {
    "path": "examples/README.MD",
    "content": "## install dependencies\n```npm install```\n\n## then run the project\n```npm start```\n"
  },
  {
    "path": "examples/index.js",
    "content": "const TrayWindow = require(\"electron-tray-window\");\n\nconst { ipcMain, Tray, app, BrowserWindow } = require(\"electron\");\nconst path = require(\"path\");\n\napp.on(\"ready\", () => {\n  var timeout = 10;\n  if (process.platform === \"linux\") {\n    timeout = 200;\n  }\n  setTimeout(function () {\n    TrayWindow.setOptions({\n      trayIconPath: path.join(\"resources/icon.png\"),\n      windowUrl: `file://${path.join(__dirname, \"resources/index.html\")}`,\n      width: 340,\n      height: 380,\n    });\n  }, timeout);\n});\n"
  },
  {
    "path": "examples/package.json",
    "content": "{\n  \"name\": \"examples\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"start\": \"electron --enable-transparent-visuals .\"\n  },\n  \"author\": \"sfatihk <sakkarmen@gmail.com>\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"electron-tray-window\": \"^1.2.2\"\n  }\n}\n"
  },
  {
    "path": "examples/resources/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Electron-Tray-Window Example</title>\n  </head>\n  <style>\n    body {\n      overflow: hidden;\n      width: 341px;\n    }\n    #container {\n      border-radius: 30px;\n      border: 20px;\n      border-color: #434344;\n      border-style: solid;\n      width: 290px;\n      height: 330px;\n      background-color: #cd970c;\n    }\n    #left-wrapper {\n      width: 140px;\n      margin-left: 10px;\n      margin-top: 20px;\n      float: left;\n    }\n    .small-box {\n      border-radius: 7px;\n      width: 40px;\n      height: 40px;\n      background-color: #434344;\n      float: left;\n      margin-left: 20px;\n      margin-top: 20px;\n    }\n    #big-box {\n      border-radius: 7px;\n      background-color: #434344;\n      float: left;\n      width: 100px;\n      height: 100px;\n      margin-right: 20px;\n      margin-top: 40px;\n      color: #cd970c;\n      font-weight: bolder;\n      font-size: 18px;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      font-family: \"Segoe UI\";\n    }\n    #wide-box {\n      border-radius: 7px;\n      background-color: #434344;\n      float: left;\n      width: 100px;\n      height: 40px;\n      margin-left: 30px;\n      margin-top: 20px;\n      color: #cd970c;\n      font-weight: bolder;\n      font-size: 18px;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      font-family: \"Segoe UI\";\n    }\n    #center-wrapper {\n      float: left;\n      width: 120px;\n    }\n    #huge-box {\n      border-radius: 7px;\n      background-color: #434344;\n      float: left;\n      width: 220px;\n      height: 80px;\n      margin-left: 30px;\n      margin-top: 20px;\n      color: #cd970c;\n      font-weight: bolder;\n      font-size: 18px;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      font-family: \"Segoe UI\";\n    }\n    .interactive {\n      cursor: pointer !important;\n    }\n    .interactive:hover {\n      background-color: #3c3c40 !important;\n      color: #e9af1d !important;\n    }\n  </style>\n\n  <body>\n    <div id=\"container\">\n      <div id=\"left-wrapper\">\n        <div class=\"small-box\"></div>\n        <div class=\"small-box\"></div>\n        <div class=\"small-box\"></div>\n        <div class=\"small-box\"></div>\n      </div>\n      <div id=\"big-box\" class=\"interactive\">ELECTRON</div>\n      <div id=\"wide-box\" class=\"interactive\">TRAY</div>\n      <div id=\"center-wrapper\">\n        <div class=\"small-box\"></div>\n        <div class=\"small-box\"></div>\n      </div>\n      <div id=\"huge-box\" class=\"interactive\">WINDOWS</div>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"electron-tray-window\",\n  \"version\": \"1.2.7\",\n  \"description\": \"A package for generate custom tray windows with Electron.js\",\n  \"main\": \"src/index.js\",\n  \"files\": [\n    \"src\"\n  ],\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/sfatihk/electron-tray-window.git\"\n  },\n  \"keywords\": [\n    \"electron\",\n    \"tray\",\n    \"window\",\n    \"popup\",\n    \"menu\"\n  ],\n  \"author\": \"Seyyid Fatih KOÇ\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/sfatihk/electron-tray-window/issues\"\n  },\n  \"homepage\": \"https://github.com/sfatihk/electron-tray-window#readme\",\n  \"dependencies\": {\n    \"electron\": \"^3.0.10\"\n  },\n  \"peerDependencies\": {\n    \"electron\": \"^3.0.10\"\n  }\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "const electron = require(\"electron\");\n\nconst { BrowserWindow, ipcMain, Tray } = electron;\n\nlet tray = undefined;\nlet window = undefined;\n\n//defaults\nlet width = 200;\nlet height = 300;\n\nlet margin_x = 0;\nlet margin_y = 0;\nlet framed = false;\n\nfunction setOptions(options) {\n  if (!validation(options)) return;\n\n  init(options);\n}\n\nfunction validation(options) {\n  if (typeof options !== \"object\") {\n    console.log(\"tray-window can not create without any [options]!!!\");\n    return false;\n  }\n  if (!options.tray && !options.trayIconPath) {\n    console.log(\n      \"tray-window can not create without [tray] or [trayIconPath] parameters!!!\"\n    );\n    return false;\n  }\n  if (!options.window && !options.windowUrl) {\n    console.log(\n      \"tray-window can not create without [window] or [windowUrl] parameters!!!\"\n    );\n    return false;\n  }\n\n  return true;\n}\n\nfunction init(options) {\n  setWindowSize(options);\n\n  options.tray ? setTray(options.tray) : createTray(options.trayIconPath);\n  options.window ? setWindow(options.window) : createWindow(options.windowUrl);\n\n  tray.on(\"click\", function(event) {\n    ipcMain.emit(\"tray-window-clicked\", { window: window, tray: tray });\n    toggleWindow();\n  });\n\n  setWindowAutoHide();\n  alignWindow();\n\n  ipcMain.emit(\"tray-window-ready\", { window: window, tray: tray });\n}\n\nfunction setWindowSize(options) {\n  if (options.width) width = options.width;\n  if (options.height) height = options.height;\n  if (options.margin_x) margin_x = options.margin_x;\n  if (options.margin_y) margin_y = options.margin_y;\n  if (options.framed) framed = options.framed;\n}\n\nfunction createTray(trayIconPath) {\n  tray = new Tray(trayIconPath);\n}\n\nfunction setTray(newTray) {\n  tray = newTray;\n}\n\nfunction setWindow(newWindow) {\n  window = newWindow;\n  setWindowSize(window.getBounds());\n}\n\nfunction createWindow(windowUrl) {\n  window = undefined;\n\n  window = new BrowserWindow({\n    width: width,\n    height: height,\n    maxWidth: width,\n    maxHeight: height,\n    show: false,\n    frame: framed,\n    fullscreenable: false,\n    resizable: false,\n    useContentSize: true,\n    transparent: true,\n    alwaysOnTop: true,\n    webPreferences: {\n      backgroundThrottling: false\n    }\n  });\n  window.setMenu(null);\n\n  setWindowUrl(windowUrl);\n\n  return window;\n}\n\nfunction setWindowUrl(windowUrl) {\n  window.loadURL(windowUrl);\n}\n\nfunction setWindowAutoHide() {\n  window.hide();\n  window.on(\"blur\", () => {\n    if (!window.webContents.isDevToolsOpened()) {\n      window.hide();\n      ipcMain.emit(\"tray-window-hidden\", { window: window, tray: tray });\n    }\n  });\n  if (framed) {\n    window.on(\"close\", function(event) {\n      event.preventDefault();\n      window.hide();\n    });\n  }\n}\n\nfunction toggleWindow() {\n  if (window.isVisible()) {\n    window.hide();\n    ipcMain.emit(\"tray-window-hidden\", { window: window, tray: tray });\n    return;\n  }\n\n  showWindow();\n  ipcMain.emit(\"tray-window-visible\", { window: window, tray: tray });\n}\n\nfunction alignWindow() {\n  const position = calculateWindowPosition();\n  window.setBounds({\n    width: width,\n    height: height,\n    x: position.x,\n    y: position.y\n  });\n}\n\nfunction showWindow() {\n  alignWindow();\n  window.show();\n}\n\nfunction calculateWindowPosition() {\n  const screenBounds = electron.screen.getPrimaryDisplay().size;\n  const trayBounds = tray.getBounds();\n\n  //where is the icon on the screen?\n  let trayPos = 4; // 1:top-left 2:top-right 3:bottom-left 4.bottom-right\n  trayPos = trayBounds.y > screenBounds.height / 2 ? trayPos : trayPos / 2;\n  trayPos = trayBounds.x > screenBounds.width / 2 ? trayPos : trayPos - 1;\n\n  let DEFAULT_MARGIN = { x: margin_x, y: margin_y };\n\n  //calculate the new window position\n  switch (trayPos) {\n    case 1: // for TOP - LEFT\n      x = Math.floor(trayBounds.x + DEFAULT_MARGIN.x + trayBounds.width / 2);\n      y = Math.floor(trayBounds.y + DEFAULT_MARGIN.y + trayBounds.height / 2);\n      break;\n\n    case 2: // for TOP - RIGHT\n      x = Math.floor(\n        trayBounds.x - width - DEFAULT_MARGIN.x + trayBounds.width / 2\n      );\n      y = Math.floor(trayBounds.y + DEFAULT_MARGIN.y + trayBounds.height / 2);\n      break;\n\n    case 3: // for BOTTOM - LEFT\n      x = Math.floor(trayBounds.x + DEFAULT_MARGIN.x + trayBounds.width / 2);\n      y = Math.floor(\n        trayBounds.y - height - DEFAULT_MARGIN.y + trayBounds.height / 2\n      );\n      break;\n\n    case 4: // for BOTTOM - RIGHT\n      x = Math.floor(\n        trayBounds.x - width - DEFAULT_MARGIN.x + trayBounds.width / 2\n      );\n      y = Math.floor(\n        trayBounds.y - height - DEFAULT_MARGIN.y + trayBounds.height / 2\n      );\n      break;\n  }\n\n  return { x: x, y: y };\n}\n\nmodule.exports = { setOptions, setTray, setWindow, setWindowSize };\n"
  }
]