electron#Menu JavaScript Examples

The following examples show how to use electron#Menu. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: menu.js    From brisque-2.0-desktop with MIT License 6 votes vote down vote up
setupDevelopmentEnvironment() {
    this.mainWindow.openDevTools()
    this.mainWindow.webContents.on('context-menu', (e, props) => {
      const { x, y } = props
      
      Menu.buildFromTemplate([
        {
          label: 'Inspect element',
          click: () => {
            this.mainWindow.inspectElement(x, y)
          }
        }
      ]).popup(this.mainWindow)
    })
  }
Example #2
Source File: index.js    From FreeTube-Vue with GNU Affero General Public License v3.0 6 votes vote down vote up
function setMenu () {
  if (process.platform === 'darwin') {
    template.unshift({
      label: app.getName(),
      submenu: [
        { role: 'about' },
        { type: 'separator' },
        { role: 'services' },
        { type: 'separator' },
        { role: 'hide' },
        { role: 'hideothers' },
        { role: 'unhide' },
        { type: 'separator' },
        { role: 'quit' }
      ]
    })

    template.push({
      role: 'window'
    })

    template.push({
      role: 'help'
    })

    template.push({ role: 'services' })
  }

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}
Example #3
Source File: menu.js    From juggernaut-desktop with MIT License 6 votes vote down vote up
buildMenu() {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate();

    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

    return menu;
  }
Example #4
Source File: menu.js    From juggernaut-desktop with MIT License 6 votes vote down vote up
setupDevelopmentEnvironment() {
    this.mainWindow.webContents.on('context-menu', (e, props) => {
      const { x, y } = props;

      Menu.buildFromTemplate([
        {
          label: 'Inspect element',
          click: () => {
            this.mainWindow.inspectElement(x, y);
          }
        }
      ]).popup(this.mainWindow);
    });
  }
Example #5
Source File: menu.js    From NoteMaster with GNU General Public License v3.0 6 votes vote down vote up
buildMenu() {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment();
    }

    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate();

    const menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);

    return menu;
  }
Example #6
Source File: menu.js    From NoteMaster with GNU General Public License v3.0 6 votes vote down vote up
setupDevelopmentEnvironment() {
    this.mainWindow.openDevTools();
    this.mainWindow.webContents.on('context-menu', (e, props) => {
      const { x, y } = props;

      Menu.buildFromTemplate([
        {
          label: 'Inspect element',
          click: () => {
            this.mainWindow.inspectElement(x, y);
          }
        }
      ]).popup(this.mainWindow);
    });
  }
Example #7
Source File: menu.js    From brisque-2.0-desktop with MIT License 6 votes vote down vote up
buildMenu() {
    if (
      process.env.NODE_ENV === 'development' ||
      process.env.DEBUG_PROD === 'true'
    ) {
      this.setupDevelopmentEnvironment()
    }
    
    const template =
      process.platform === 'darwin'
        ? this.buildDarwinTemplate()
        : this.buildDefaultTemplate()
    
    const menu = Menu.buildFromTemplate(template)
    Menu.setApplicationMenu(menu)
    
    return menu
  }
Example #8
Source File: shortcut.js    From Memocast with MIT License 6 votes vote down vote up
callMenuCallback = (menuInfo, win) => {
  const { click, id } = menuInfo
  if (click) {
    let menuItem = null
    if (id) {
      const menus = Menu.getApplicationMenu()
      menuItem = menus.getMenuItemById(id)
    }

    // Allow all shortcuts/menus without id and only enabled menus with id (GH#980).
    if (!menuItem || menuItem.enabled !== false) {
      click(menuItem, win)
    }
  } else {
    console.error('ERROR: callback function is not defined.')
  }
}
Example #9
Source File: main.js    From makerverse with GNU General Public License v3.0 6 votes vote down vote up
inputMenu = Menu.buildFromTemplate([
    { role: 'undo' },
    { role: 'redo' },
    { type: 'separator' },
    { role: 'cut' },
    { role: 'copy' },
    { role: 'paste' },
    { type: 'separator' },
    { role: 'selectall' }
])
Example #10
Source File: index.js    From desktop with GNU General Public License v3.0 6 votes vote down vote up
buildTrayMenu = () => {
  if (!tray) {
    return;
  }

  let menuItems = [{ label: "Open VPN.ht", click: () => openMainWin() }];

  if (isConnected) {
    menuItems = [
      ...menuItems,
      { label: "Disconnect", click: () => disconnect() }
    ];
  }

  menuItems = [...menuItems, { label: "Exit", click: () => app.quit() }];
  const contextMenu = Menu.buildFromTemplate(menuItems);

  // windows context is shown only on right click
  tray.setContextMenu(contextMenu);

  // we show app if we left click
  // right click will show context (on windows)
  if (process.platform !== "darwin") {
    tray.on("click", function() {
      openMainWin();
    });

    tray.on("double-click", function() {
      openMainWin();
    });
  }
}
Example #11
Source File: background.js    From dev-sidecar with Mozilla Public License 2.0 5 votes vote down vote up
// 隐藏主窗口,并创建托盘,绑定关闭事件
function setTray () {
  // const topMenu = Menu.buildFromTemplate({})
  // Menu.setApplicationMenu(topMenu)
  // 用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区
  // 通常被添加到一个 context menu 上.
  // 系统托盘右键菜单
  const trayMenuTemplate = [

    {
      // 系统托盘图标目录
      label: 'DevTools',
      click: () => {
        win.webContents.openDevTools()
      }
    },
    {
      // 系统托盘图标目录
      label: '退出',
      click: () => {
        log.info('force quit')
        forceClose = true
        quit()
      }
    }
  ]
  // 设置系统托盘图标
  const iconRootPath = path.join(__dirname, '../extra/icons/tray')
  let iconPath = path.join(iconRootPath, 'icon.png')
  const iconWhitePath = path.join(iconRootPath, 'icon-white.png')
  const iconBlackPath = path.join(iconRootPath, 'icon-black.png')
  if (isMac) {
    iconPath = nativeTheme.shouldUseDarkColors ? iconWhitePath : iconBlackPath
  }

  const trayIcon = nativeImage.createFromPath(iconPath)
  const appTray = new Tray(trayIcon)

  // 当桌面主题更新时
  if (isMac) {
    nativeTheme.on('updated', () => {
      console.log('i am changed')
      if (nativeTheme.shouldUseDarkColors) {
        console.log('i am dark.')
        tray.setImage(iconWhitePath)
      } else {
        console.log('i am light.')
        tray.setImage(iconBlackPath)
        // tray.setPressedImage(iconWhitePath)
      }
    })
  }

  // 图标的上下文菜单
  const contextMenu = Menu.buildFromTemplate(trayMenuTemplate)

  // 设置托盘悬浮提示
  appTray.setToolTip('DevSidecar-开发者边车辅助工具')
  // 单击托盘小图标显示应用
  appTray.on('click', () => {
    // 显示主程序
    showWin()
  })

  appTray.on('right-click', function (event, bounds) {
    setTimeout(function () {
      appTray.popUpContextMenu(contextMenu)
    }, 200)
  })

  return appTray
}
Example #12
Source File: mainWindow.js    From p2p-tunnel with GNU General Public License v2.0 5 votes vote down vote up
Menu.setApplicationMenu(null);
Example #13
Source File: main.js    From makerverse with GNU General Public License v3.0 5 votes vote down vote up
selectionMenu = Menu.buildFromTemplate([
    { role: 'copy' },
    { type: 'separator' },
    { role: 'selectall' }
])
Example #14
Source File: background.js    From linked with GNU General Public License v3.0 5 votes vote down vote up
Menu.setApplicationMenu(menu)
Example #15
Source File: background.js    From linked with GNU General Public License v3.0 5 votes vote down vote up
menu = Menu.buildFromTemplate(template)
Example #16
Source File: index.js    From invizi with GNU General Public License v3.0 5 votes vote down vote up
function addMenu () {
  const template = [
    {
      label: 'Invizi',
      submenu: [
        {role: 'quit'}
      ]
    },
    {
      label: 'Edit',
      submenu: [
        {role: 'undo'},
        {role: 'redo'},
        {type: 'separator'},
        {role: 'cut'},
        {role: 'copy'},
        {role: 'paste'},
        {role: 'pasteandmatchstyle'},
        {role: 'delete'},
        {role: 'selectall'}
      ]
    },
    {
      label: 'View',
      submenu: [
        {role: 'reload'},
        {role: 'forcereload'},
        {role: 'toggledevtools'},
        {type: 'separator'},
        {role: 'resetzoom'},
        {role: 'zoomin'},
        {role: 'zoomout'},
        {type: 'separator'},
        {role: 'togglefullscreen'}
      ]
    },
    {
      role: 'window',
      submenu: [
        {role: 'close'},
        {role: 'minimize'},
        {role: 'zoom'},
        {
          label: 'New Window',
          click () { newWindow() }
        },
        {type: 'separator'},
        {role: 'front'}
      ]
    },
    {
      role: 'help',
      submenu: [
        {
          label: 'Learn More',
          click () { require('electron').shell.openExternal('https://invizi.co') }
        }
      ]
    }
  ]

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}
Example #17
Source File: background.js    From dev-sidecar with Mozilla Public License 2.0 5 votes vote down vote up
function createWindow (startHideWindow) {
  // Create the browser window.

  win = new BrowserWindow({
    width: 900,
    height: 750,
    title: 'DevSidecar',
    webPreferences: {
      enableRemoteModule: true,
      contextIsolation: false,
      nativeWindowOpen: true, // ADD THIS
      // preload: path.join(__dirname, 'preload.js'),
      // Use pluginOptions.nodeIntegration, leave this alone
      // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
      nodeIntegration: true// process.env.ELECTRON_NODE_INTEGRATION
    },
    show: !startHideWindow,
    // eslint-disable-next-line no-undef
    icon: path.join(__static, 'icon.png')
  })

  Menu.setApplicationMenu(null)
  win.setMenu(null)

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol('app')
    // Load the index.html when not in development
    win.loadURL('app://./index.html')
  }

  if (startHideWindow) {
    hideWin()
  }

  win.on('closed', async (e) => {
    win = null
    tray = null
  })

  ipcMain.on('close', async (event, message) => {
    if (message.value === 1) {
      quit()
    } else {
      hideWin()
    }
  })

  win.on('close', (e) => {
    if (forceClose) {
      return
    }
    e.preventDefault()
    if (isLinux()) {
      quit(app)
      return
    }
    const config = DevSidecar.api.config.get()
    const closeStrategy = config.app.closeStrategy
    if (closeStrategy === 0) {
      // 提醒
      win.webContents.send('close.showTip')
    } else if (closeStrategy === 1) {
      // 直接退出
      quit()
    } else if (closeStrategy === 2) {
      // 隐藏窗口
      hideWin()
    }
  })

  win.on('session-end', async (e) => {
    log.info('session-end', e)
    await quit()
  })
}
Example #18
Source File: application.js    From razer-macos with GNU General Public License v2.0 5 votes vote down vote up
createWindow() {
    this.browserWindow = new BrowserWindow({
      webPreferences: { nodeIntegration: true },
      //titleBarStyle: 'hidden',
      height: 800, // This is adjusted later with window.setSize
      resizable: false,
      width: 500,
      minWidth: 320,
      minHeight: 320,
      y: 100,
      // Set the default background color of the window to match the CSS
      // background color of the page, this prevents any white flickering
      backgroundColor: '#202124',
      // Don't show the window until it's ready, this prevents any white flickering
      show: false,
    });
    if (this.isDevelopment) {
      this.browserWindow.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`);
      this.browserWindow.resizable = true;
    } else {
      this.browserWindow.loadFile(path.join(__dirname, 'index.html'));
    }

    // Handle window logic properly on macOS:
    // 1. App should not terminate if window has been closed
    // 2. Click on icon in dock should re-open the window
    // 3. ⌘+Q should close the window and quit the app
    this.browserWindow.on('close', (e) => {
      if (!this.forceQuit) {
        e.preventDefault();
        this.browserWindow.hide();
      }
    });

    this.app.on('activate', () => {
      this.browserWindow.show();
    });

    this.app.on('before-quit', () => {
      this.forceQuit = true;
    });

    if (this.isDevelopment) {
      // auto-open dev tools
      //this.browserWindow.webContents.openDevTools();

      // add inspect element on right click menu
      this.browserWindow.webContents.on('context-menu', (e, props) => {
        const that = this;
        Menu.buildFromTemplate([
          {
            label: 'Inspect element',
            click() {
              that.browserWindow.inspectElement(props.x, props.y);
            },
          },
        ]).popup(this.browserWindow);
      });
    }
  }
Example #19
Source File: application.js    From razer-macos with GNU General Public License v2.0 5 votes vote down vote up
refreshTray(withDeviceRefresh) {
    const refresh = withDeviceRefresh ? this.razerApplication.refresh() : Promise.resolve(true);
    refresh.then(() => {
      const contextMenu = Menu.buildFromTemplate(getMenuFor(this));
      this.tray.setContextMenu(contextMenu);
    });
  }
Example #20
Source File: electron-main.js    From loa-details with GNU General Public License v3.0 4 votes vote down vote up
function startApplication() {
  tray = new Tray(
    process.env.DEBUGGING
      ? path.resolve(__dirname, "../../src-electron/icons/icon.png")
      : path.resolve(__dirname, "icons/icon.png")
  );

  const contextMenu = Menu.buildFromTemplate([
    {
      label: "Show LOA Details",
      click() {
        mainWindow.show();
        if (mainWindow.isMinimized()) mainWindow.restore();
        mainWindow.focus();
      },
    },
    {
      label: "Quit",
      click() {
        app.quit();
      },
    },
  ]);

  tray.setToolTip("LOA Details");
  tray.setContextMenu(contextMenu);

  tray.on("click", () => {
    mainWindow.show();
    if (mainWindow.isMinimized()) mainWindow.restore();
    mainWindow.focus();
  });

  setupBridge(appSettings);

  httpServerEventEmitter.on("packet", (value) => {
    logParser.parseLogLine(value);
  });

  httpServerEventEmitter.on("debug", (data) => {
    log.info("debug:", data);
  });

  /*   const dontShowPatreonBox = store.get("dont_show_patreon_box");
  if (!dontShowPatreonBox) {
    const userSelection = dialog.showMessageBoxSync(mainWindow, {
      type: "info",
      title: "Support LOA Details",
      message: "Would you like to support this project by donating on Patreon?",
      buttons: ["No", "Yes"],
      defaultId: 0,
      cancelId: 0,
    });

    if (userSelection === 1) {
      shell.openExternal("https://www.patreon.com/loadetails");
    }

    store.set("dont_show_patreon_box", "true");
  } */

  mainWindow = createMainWindow(appSettings);
  damageMeterWindow = createDamageMeterWindow(logParser, appSettings);

  initializeShortcuts(appSettings);

  shortcutEventEmitter.on("shortcut", (shortcut) => {
    log.debug(shortcut);

    if (shortcut.action === "minimizeDamageMeter") {
      damageMeterWindow.webContents.send(
        "shortcut-action",
        "toggle-minimized-state"
      );
    } else if (shortcut.action === "resetSession") {
      damageMeterWindow.webContents.send("shortcut-action", "reset-session");
    } else if (shortcut.action === "pauseDamageMeter") {
      damageMeterWindow.webContents.send(
        "shortcut-action",
        "pause-damage-meter"
      );
    }
  });
}
Example #21
Source File: index.js    From desktop with GNU General Public License v3.0 4 votes vote down vote up
updateHamburgerMenu = () => {
  hamburgerMenu = new Menu();

  let menuItems = [];

  if (isLogged) {
    menuItems = [
      ...menuItems,
      {
        label: "Home",
        click: () => {
          rpc.emit("change view", CONNECT_VIEW);
        }
      }
    ];
  }

  menuItems = [
    ...menuItems,
    {
      label: "View logs",
      click: () => {
        rpc.emit("change view", LOGS_VIEW);
      }
    },
    {
      label: "Check updates",
      click: async () => {
        const lastVersion = await lastRelease();
        if (lastVersion && version !== lastVersion) {
          showUpdateDialog(lastVersion);
        } else {
          showUpdateDialogNoVersion();
        }
      }
    }
  ];

  if (isLogged) {
    menuItems = [
      ...menuItems,
      {
        label: "Settings",
        click: () => {
          rpc.emit("change view", SETTINGS_VIEW);
        }
      }
    ];
  }

  menuItems = [
    ...menuItems,
    {
      type: "separator"
    }
  ];

  if (isConnected) {
    menuItems = [
      ...menuItems,
      {
        label: "Disconnect",
        click: async () => {
          await disconnect();
        }
      },
      {
        type: "separator"
      }
    ];
  }

  if (isLogged) {
    menuItems = [
      ...menuItems,
      {
        label: "Sign out",
        click: () => {
          rpc.emit("logout", null);
        }
      }
    ];
  }

  menuItems = [
    ...menuItems,
    {
      label: "Exit",
      click: () => {
        app.quit();
      }
    }
  ];

  buildHamburgerMenu(menuItems);
}
Example #22
Source File: index.js    From desktop with GNU General Public License v3.0 4 votes vote down vote up
checkService = async () => {
  info("Process ready");

  // ping service
  const servicePing = await ping();
  const timeout = 6000;

  // make sure our path is created
  try {
    const fileExist = fs.existsSync(profilePath());
    if (!fileExist) {
      fs.mkdirSync(profilePath(), { recursive: true });
    }
  } catch (error) {}

  // delete current file
  try {
    fs.unlinkSync(vpnLogPath());
  } catch (error) {}

  // write an empty file
  try {
    fs.closeSync(fs.openSync(vpnLogPath(), "w"));
  } catch (error) {}

  if (!servicePing) {
    warning("can't connect to service... trying to wake up");
    setTimeout(async () => {
      try {
        const servicePing = await ping();
        if (!servicePing) {
          errorLog("unable to connect to service");
          const clickedButton = dialog.showMessageBoxSync(null, {
            type: "warning",
            buttons: ["Exit", "Retry"],
            defaultId: 1,
            title: "VPN.ht - Service Error",
            message:
              "Unable to communicate with helper service, " +
              "try restarting computer"
          });
          if (clickedButton === 0) {
            app.quit();
          }
          if (clickedButton === 1) {
            checkService();
            return;
          }
        }
      } catch (error) {
        errorLog(error);

        if (error.statusCode && error.statusCode === 401) {
          dialog.showMessageBox(
            null,
            {
              type: "warning",
              buttons: ["Exit"],
              title: "VPN.ht - Service Error",
              message:
                "Unable to establish communication with helper " +
                "service, try restarting computer"
            },
            () => {
              app.quit();
            }
          );
        }
      }
    }, timeout);
    return;
  }

  // wake up the service and make sure it's ready to work
  const { statusCode: wakeUpStatusCode, wakeup: isWakeUp } = await wakeup();

  if (wakeUpStatusCode === 401) {
    errorLog("Can't wakeup the service (401)");
    dialog.showMessageBox(
      null,
      {
        type: "warning",
        buttons: ["Exit"],
        title: "VPN.ht - Service Error",
        message:
          "Unable to establish communication with helper " +
          "service, try restarting computer"
      },
      function() {
        app.quit();
      }
    );
    return;
  }

  if (isWakeUp) {
    errorLog("Can't wakeup the service (isWakeUp)");
    app.quit();
    return;
  }

  info("Service ready");

  // subscribe to service events
  const serviceEvents = subscribe();

  serviceEvents.on("message", async data => {
    const evt = JSON.parse(data);
    if (evt.type === "output") {
      try {
        const pathExist = fs.existsSync(profilePath());
        const logPath = vpnLogPath();
        if (!pathExist) {
          fs.mkdirSync(profilePath(), { recursive: true });
        }
        fs.appendFileSync(logPath, evt.data.output + "\n");
      } catch (error) {
        errorLog(error);
      }
    } else if (evt.type === "connected") {
      isConnected = true;
      updateHamburgerMenu();
      buildTrayMenu();
      if (tray) {
        tray.setImage(trayIcons.connected);
      }
    } else if (evt.type === "disconnected") {
      isConnected = false;
      updateHamburgerMenu();
      buildTrayMenu();
      if (tray) {
        tray.setImage(trayIcons.default);
      }
    } else if (evt.type === "wakeup") {
      openMainWin();
    }
  });

  let noMain = false;
  process.argv.forEach(function(val) {
    if (val === "--no-main") {
      noMain = true;
    }
  });

  if (!noMain) {
    openMainWin();
  } else if (process.platform === "linux") {
    app.quit();
    return;
  }

  const vpnStatus = await status();
  isConnected = vpnStatus;
  updateHamburgerMenu();

  if (process.platform !== "linux") {
    tray = new Tray(vpnStatus ? trayIcons.connected : trayIcons.default);
    buildTrayMenu();
  }

  // app menu
  const appMenu = Menu.buildFromTemplate([
    {
      label: "VPN.ht",
      submenu: [
        {
          label: `VPN.ht ${version}`
        },
        {
          label: "Close",
          accelerator: "CmdOrCtrl+Q",
          role: "close"
        },
        {
          label: "Exit",
          click: () => {
            app.quit();
          }
        }
      ]
    },
    {
      label: "Edit",
      submenu: [
        {
          label: "Undo",
          accelerator: "CmdOrCtrl+Z",
          role: "undo"
        },
        {
          label: "Redo",
          accelerator: "Shift+CmdOrCtrl+Z",
          role: "redo"
        },
        {
          type: "separator"
        },
        {
          label: "Cut",
          accelerator: "CmdOrCtrl+X",
          role: "cut"
        },
        {
          label: "Copy",
          accelerator: "CmdOrCtrl+C",
          role: "copy"
        },
        {
          label: "Paste",
          accelerator: "CmdOrCtrl+V",
          role: "paste"
        },
        {
          label: "Select All",
          accelerator: "CmdOrCtrl+A",
          role: "selectall"
        }
      ]
    },
    {
      label: "View",
      submenu: [
        {
          label: "Toggle Developer Tools",
          accelerator: "command+alt+i",
          click: () => {
            const webContents = mainWindow.webContents;
            if (webContents.isDevToolsOpened()) {
              webContents.closeDevTools();
            } else {
              webContents.openDevTools({ mode: "detach" });
            }
          }
        }
      ]
    }
  ]);

  Menu.setApplicationMenu(appMenu);
}
Example #23
Source File: main.js    From makerverse with GNU General Public License v3.0 4 votes vote down vote up
main = () => {
    // https://github.com/electron/electron/blob/master/docs/api/app.md#apprequestsingleinstancelock
    const gotSingleInstanceLock = app.requestSingleInstanceLock();
    const shouldQuitImmediately = !gotSingleInstanceLock;

    if (shouldQuitImmediately) {
        app.quit();
        return;
    }

    app.on('second-instance', (event, commandLine, workingDirectory) => {
        // Someone tried to run a second instance, we should focus our window.
        if (!windowManager) {
            return;
        }

        const window = windowManager.getWindow();
        if (window) {
            if (window.isMinimized()) {
                window.restore();
            }
            window.focus();
        }
    });

    const store = new Store();

    // Create the user data directory if it does not exist
    const userData = app.getPath('userData');
    mkdirp.sync(userData);

    app.on('ready', async () => {
        try {
            const res = await launchServer();
            const { address, port, mountPoints } = { ...res };
            if (!(address && port)) {
                console.error('Unable to start the server at ' + chalk.cyan(`http://${address}:${port}`));
                return;
            }

            const menu = Menu.buildFromTemplate(menuTemplate({ address, port, mountPoints }));
            Menu.setApplicationMenu(menu);

            windowManager = new WindowManager();

            const url = `http://${address}:${port}`;
            // The bounds is a rectangle object with the following properties:
            // * `x` Number - The x coordinate of the origin of the rectangle.
            // * `y` Number - The y coordinate of the origin of the rectangle.
            // * `width` Number - The width of the rectangle.
            // * `height` Number - The height of the rectangle.
            const bounds = {
                width: 1280, // Defaults to 1280
                height: 768, // Defaults to 768
                ...store.get('bounds')
            };
            const options = {
                ...bounds,
                title: `${pkg.name}`
            };
            const window = windowManager.openWindow(url, options);

            // Save window size and position
            window.on('close', () => {
                store.set('bounds', window.getBounds());
            });

            // https://github.com/electron/electron/issues/4068#issuecomment-274159726
            window.webContents.on('context-menu', (event, props) => {
                const { selectionText, isEditable } = props;

                if (isEditable) {
                    // Shows an input menu if editable
                    inputMenu.popup(window);
                } else if (selectionText && String(selectionText).trim() !== '') {
                    // Shows a selection menu if there was selected text
                    selectionMenu.popup(window);
                }
            });
        } catch (err) {
            console.error('Error:', err);
        }
    });
}
Example #24
Source File: PageConfig.js    From ntfstool with MIT License 4 votes vote down vote up
_homeWinMenu = () => {
    var template = [
        {
            label: 'Close',
            click: function () {
                win.close();
            },
            submenu: [
                {
                    label: 'About',
                    click: async () => {
                        openPageByName("openAboutPage");
                    }
                },
                {
                    label: 'Share',
                    click: () => {
                        trayPageHandle.send("OpenShare");
                    }
                },
                {type: 'separator'},
                {
                    label: 'preferences',
                    click: async () => {
                        openSettingPage();
                    }
                },
                {
                    label: 'Check update',
                    click: async () => {
                        console.warn("Checkforupdates");
                    }
                },
                {role: 'services'},
                {
                    label: 'Hide Desktop',
                    click: async () => {
                        if (homeWinHandle) {
                            homeWinHandle.hide();
                            homeWinHandle.setSkipTaskbar(true);
                            app.dock.hide()
                        }
                    }
                },
                {
                    label: 'Submit feedback',
                    click: async () => {
                        openFeedBackPage();
                    }
                },
                {type: 'separator'},
                {
                    label: 'Quit',
                    accelerator: 'CmdOrCtrl+Q',
                    role: 'quit'
                },
            ],
        },
        {
            label: 'Edit',
            submenu: [
                {role: 'undo'},
                {role: 'redo'},
                {type: 'separator'},
                {role: 'cut'},
                {role: 'copy'},
                {role: 'paste'},
                {role: 'pasteandmatchstyle'},
                {role: 'delete'},
                {role: 'selectall'}
            ]
        },
        {
            label: 'View',
            submenu: [
                {type: 'separator'},
                {role: 'togglefullscreen'}
            ]
        },
        {
            role: 'window',
            submenu: [
                {role: 'minimize'},
                {role: 'close'}
            ]
        },
        {
            role: 'help',
            submenu: [
                {
                    label: 'Learn More',
                    click() {
                        require('electron').shell.openExternal('https://ntfstool.com')
                    }
                }
            ]
        }
    ];

    Menu.setApplicationMenu(Menu.buildFromTemplate(template));
}
Example #25
Source File: index.js    From desktop with GNU General Public License v3.0 4 votes vote down vote up
app.on('web-contents-created', (event, webContents) => {
  webContents.on('context-menu', (event, params) => {
    const text = params.selectionText;
    const hasText = !!text;
    const menuItems = [];

    if (params.misspelledWord && params.dictionarySuggestions.length > 0) {
      for (const word of params.dictionarySuggestions) {
        menuItems.push({
          label: word,
          click: () => {
            webContents.replaceMisspelling(word);
          }
        });
      }
      menuItems.push({
        type: 'separator'
      });
    }

    const url = params.linkURL;
    if (params.linkURL) {
      menuItems.push({
        id: 'openLink',
        label: getTranslation('context.open-link'),
        enabled: !url.startsWith('blob:'),
        click() {
          if (isSafeOpenExternal(url)) {
            shell.openExternal(url);
          }
        }
      });
      menuItems.push({
        type: 'separator'
      });
    }

    if (params.isEditable) {
      menuItems.push({
        id: 'cut',
        label: getTranslation('context.cut'),
        enabled: hasText,
        click: () => {
          clipboard.writeText(text);
          webContents.cut();
        }
      });
    }
    if (hasText || params.isEditable) {
      menuItems.push({
        id: 'copy',
        label: getTranslation('context.copy'),
        enabled: hasText,
        click: () => {
          clipboard.writeText(text);
        }
      });
    }
    if (params.isEditable) {
      menuItems.push({
        id: 'Paste',
        label: getTranslation('context.paste'),
        click: () => {
          webContents.paste();
        }
      });
    }

    if (menuItems.length > 0) {
      const menu = Menu.buildFromTemplate(menuItems);
      menu.popup();
    }
  });

  if (!isMac) {
    // On Mac, shortcuts are handled by the menu bar.
    webContents.on('before-input-event', (e, input) => {
      if (input.isAutoRepeat || input.isComposing || input.type !== 'keyDown' || input.meta) {
        return;
      }
      const window = BrowserWindow.fromWebContents(webContents);
      // Ctrl+Shift+I to open dev tools
      if (
        input.control &&
        input.shift &&
        input.key.toLowerCase() === 'i' &&
        !input.alt
      ) {
        e.preventDefault();
        webContents.toggleDevTools();
      }
      // Ctrl+N to open new window
      if (
        input.control &&
        input.key.toLowerCase() === 'n'
      ) {
        e.preventDefault();
        createEditorWindow();
      }
      // Ctrl+Equals/Plus to zoom in
      if (
        input.control &&
        input.key === '='
      ) {
        e.preventDefault();
        webContents.setZoomLevel(webContents.getZoomLevel() + 1);
      }
      // Ctrl+Minus/Underscore to zoom out
      if (
        input.control &&
        input.key === '-'
      ) {
        e.preventDefault();
        webContents.setZoomLevel(webContents.getZoomLevel() - 1);
      }
      // Ctrl+0 to reset zoom
      if (
        input.control &&
        input.key === '0'
      ) {
        e.preventDefault();
        webContents.setZoomLevel(0);
      }
      // F11 and alt+enter to toggle fullscreen
      if (
        input.key === 'F11' ||
        (input.key === 'Enter' && input.alt)
      ) {
        e.preventDefault();
        window.setFullScreen(!window.isFullScreen());
      }
      // Escape to exit fullscreen
      if (
        input.key === 'Escape' &&
        window.isFullScreen()
      ) {
        e.preventDefault();
        // used by closeWindowWhenPressEscape
        e.didJustLeaveFullScreen = true;
        window.setFullScreen(false);
      }
      // Ctrl+R and Ctrl+Shift+R to reload
      if (
        input.control &&
        input.key.toLowerCase() === 'r'
      ) {
        e.preventDefault();
        if (input.shift) {
          webContents.reloadIgnoringCache();
        } else {
          webContents.reload();
        }
      }
    });
  }

  webContents.setWindowOpenHandler(defaultWindowOpenHandler);

  webContents.on('will-navigate', (e, url) => {
    if (url === 'mailto:[email protected]') {
      // If clicking on the contact email address, we'll let the OS figure out how to open it
      return;
    }
    try {
      const newURL = new URL(url);
      const baseURL = new URL(getURL(''));
      if (newURL.href.startsWith(baseURL.href)) {
        // Let the editor reload itself
        // For example, reloading to apply settings
      } else {
        e.preventDefault();
        if (isSafeOpenExternal(url)) {
          shell.openExternal(url);
        }
      }
    } catch (e) {
      e.preventDefault();
    }
  });
});
Example #26
Source File: electron-main.js    From Memocast with MIT License 4 votes vote down vote up
function createWindow () {
  const mainWindowState = windowStateKeeper({
    defaultWidth: 900,
    defaultHeight: 600
  })
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    width: mainWindowState.width < 600 ? 600 : mainWindowState.width,
    height: mainWindowState.height < 400 ? 400 : mainWindowState.height,
    useContentSize: true,
    // transparent: true,
    vibrancy: ThemeManager.colorMode, // 'light', 'medium-light' etc
    webPreferences: {
      // Change from /quasar.conf.js > electron > nodeIntegration;
      // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
      nodeIntegration: true,
      contextIsolation: false,
      nodeIntegrationInWorker: process.env.QUASAR_NODE_INTEGRATION,
      webSecurity: false,
      experimentalFeatures: false,
      enableRemoteModule: true

      // More info: /quasar-cli/developing-electron-apps/electron-preload-script
      // preload: path.resolve(__dirname, 'electron-preload.js')
    },
    frame: false,
    titleBarStyle: 'hiddenInset'
  })

  protocol.interceptFileProtocol('file', (req, callback) => {
    const url = req.url.substr(8)
    callback(decodeURI(url))
  }, (error) => {
    if (error) {
      console.error('Failed to register protocol')
    }
  })

  registerMemocastProtocol()

  if (!process.env.PROD) {
    mainWindow.webContents.openDevTools()
  }
  const menu = Menu.buildFromTemplate(configureMenu(new KeyBindings(), mainWindow))
  Menu.setApplicationMenu(menu)

  mainWindow.isMainWindow = true
  mainWindowState.manage(mainWindow)

  mainWindow.loadURL(process.env.APP_URL).then()
  // mainWindow.on('closed', () => {
  //   mainWindow = null
  // })
  mainWindow.on('close', (event) => {
    if (!forceQuit) {
      event.preventDefault() // This will cancel the close
      mainWindow.hide()
    }
  })

  mainWindow.on('closed', () => {
    mainWindow = null
  })

  mainWindow.webContents.on('new-window', (event, linkUrl) => {
    event.preventDefault()
    if (linkUrl.startsWith('http://localhost:') || linkUrl.startsWith('file://')) {
      // dialog.showErrorBox('Unsupported Url Protocol', `Memocast cannot resolve this protocol: ${linkUrl}, please copy it to browser manually!`)
      return
    }
    dialog.showMessageBox(mainWindow, {
      type: 'question',
      title: i18n.t('openLinkHint'),
      message: i18n.t('openLinkHint'),
      detail: linkUrl,
      buttons: [i18n.t('confirm'), i18n.t('cancel')]
    }).then((res) => {
      if (!res.response) {
        shell.openExternal(linkUrl).then()
      }
    })
  })
  registerApiHandler()
  global.themeManager = ThemeManager
  if (isMac) {
    enforceMacOSAppLocation()
  }

  require('@electron/remote/main').initialize()
  require('@electron/remote/main').enable(mainWindow.webContents)
}