电子应用程序强制关闭仅在Linux Mint版本中

时间:2019-01-07 12:19:45

标签: linux angular electron linuxmint electron-builder

我有一个电子应用程序,它使用电子生成器分发。 这是main.js文件。该应用程序在ubuntu上运行,但是当我们为linux mint提供构建版本并单击任务栏图标时,它将自动关闭。首先,我给出了目标为“ deb”的构建。我尝试将其更改为“ AppImage”。 我尝试在Mac Windows和Linux上提供构建。它适用于除Linux Mint之外的所有三个。我已经尝试过

  app.disableHardwareAcceleration();
  app.commandLine.appendSwitch("disable-gpu");
  app.commandLine.appendArgument("disable-gpu");

这是main.ts

import { app, BrowserWindow, screen, ipcMain, Tray, Menu, shell, nativeImage } from 'electron';
import * as ioHook from 'iohook';
import * as path from 'path';
import * as url from 'url';
import * as moment from 'moment';
import { CronJob } from 'cron';
import { notify } from 'node-notifier';
app.commandLine.appendSwitch("disable-gpu");
app.commandLine.appendArgument("disable-gpu");
let serve, size, isTrack, keyboardCount, mouseCount, screenshotTimerHandlers, settingData;
let takeScreenshotEvent, createNewActivityEvent, trayControlEvent, tray, selectProjectEvent, controlEvent;
let hourCronjobHandler, trackingIntervalHandler, engagementIntervalHandler, checkTrackOnHandler;
let contextMenu, currentTaskId, currentProjectId, selectedTaskId, selectedProjectId, previousTimestamp;
let idleSettingTimeInMins, lastTrackTimestamp, idleTimeInMilliSecs, lastProjectTimestamp, lastEngagementPer;
let projectsDetail, selectedProject, menuTemplate;
let trackingTimeIntervalMins, engagementTimeIntervalMins;
let win = null;
lastTrackTimestamp = 0;
lastProjectTimestamp = 0;
idleTimeInMilliSecs = 0;
keyboardCount = 0;
mouseCount = 0;
lastEngagementPer = 0;
currentTaskId = -1;
currentProjectId = -1;
selectedTaskId = -1;
selectedProjectId = -1;
previousTimestamp = 0;
trackingTimeIntervalMins = 0;
engagementTimeIntervalMins = 0;

isTrack = false;

settingData = {};
projectsDetail = {};
selectedProject = {};
menuTemplate = [];
screenshotTimerHandlers = [];

const args = process.argv.slice(1);
serve = args.some(val => val === '--serve');
app.disableHardwareAcceleration();

console.log(process.versions.electron , 'electron version');


function createWindow() {

  const electronScreen = screen;
  size = electronScreen.getPrimaryDisplay().workAreaSize;


  // Create the browser window.
  win = new BrowserWindow({
    x: 0,
    y: 0,
    width: 1280,
    height: 720,
    // width: 472,
    // height: 667,
    center: true,
    icon: nativeImage.createFromPath(path.join(__dirname, '/icons/256x256.png')),
    minWidth: 472,
    minHeight: 667,
    // maxWidth: 472,
    // maxHeight: 667,
    maximizable: true,
    minimizable: true,
    webPreferences:{
      webSecurity: false,
    }
    // width: size.width,x
    // height: size.height
  });

  if (serve) {
    require('electron-reload')(__dirname, {
      electron: require(`${__dirname}/node_modules/electron`)
    });
    win.loadURL('http://localhost:4200');
  } else {
    win.loadURL(url.format({
      pathname: path.join(__dirname, 'dist/index.html'),
      protocol: 'file:',
      slashes: true
    }));
  }

  createTrayMenu();
  initData();

  // win.webContents.openDevTools();



  // Emitted when the window is closed.
  win.on('closed', () => {
    // Dereference the window object, usually you would store window
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    // win.close();
    if (win) {
      win = null;
    }
  });

}

/**
 * init data
 */
function initData() {
  idleTimeInMilliSecs = 0;
  projectsDetail = {};
  // customNotify('Test', 'Test');
}

function customNotify(title, message) {
  notify({
    title: title,
    message: message
  }, (err, res) => {
  });
}


/**
 * create tray menu
 */
function createTrayMenu() {
  /**
   * Set tray icon
   */
  const iconPath = path.join(__dirname, 'icons', '16x16.png');

  tray = new Tray(iconPath);
  menuTemplate = [
    {
      label: updateEngagement(0)
    },
    {
      label: '',
      visible: false
    },
    {
      type: 'separator'
    },
    {
      label: 'Timer is running',
      click: () => {
        if (currentProjectId >= 0 && trayControlEvent) {
          trayControlEvent.sender.send('tray-icon-control-reply', {
            status: 'stop',
            taskId: currentTaskId,
            projectId: currentProjectId
          });
        }
      },
      icon: path.join(__dirname, 'icons', 'pause.png'),
      visible: false
    },
    {
      label: 'Timer is paused',
      click: () => {
        if (selectedProjectId >= 0 && trayControlEvent) {
          trayControlEvent.sender.send('tray-icon-control-reply', {
            status: 'start',
            taskId: selectedTaskId,
            projectId: selectedProjectId
          });
        }
      },
      icon: path.join(__dirname, 'icons', 'play.png'),
      enabled: false
    },
    {
      type: 'separator'
    },
    {
      label: 'Switch Projects',
    },
    {
      type: 'separator'
    },
    {
      label: 'Add a note',
      click: () => {
        controlEvent.sender.send('control-event-reply', {type: 'note'});
        win.focus();
      },
      enabled: false
    },
    {
      type: 'separator'
    },
    {
      label: 'Open Dashboard',
      click: () => {
        shell.openExternal('https://tracklyapp.appup.cloud/trackly/#/430/1587/dashboard');
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'Settings',
      click: () => {
        controlEvent.sender.send('control-event-reply', {type: 'setting'});
        win.focus();
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'About Track.ly',
      click: () => {
        shell.openExternal('https://www.track.ly/');
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'Help',
      click: () => {
        controlEvent.sender.send('control-event-reply', {type: 'help'});
        win.focus();
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'Check for updates',
      click: () => {
        controlEvent.sender.send('control-event-reply', {type: 'check'});
        win.focus();
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'Sign out',
      click: () => {
        controlEvent.sender.send('control-event-reply', {type: 'signout'});
        menuTemplate[4].enabled = false;
        win.focus();
      }
    },
    {
      type: 'separator'
    },
    {
      label: 'Quit tracker',
      click: () => {
        if (win) {
          win = null;
        }

        app.quit();
      }
    }
  ];

  contextMenu = Menu.buildFromTemplate(menuTemplate);
  tray.setContextMenu(contextMenu);
  tray.setToolTip('Time Tracker');
}



/**
 * destroy ipcMain listeners and cron job handler
 */
function destroyListners() {
  if (ipcMain) {
    ipcMain.removeAllListeners('get-current-ids');
    ipcMain.removeAllListeners('get-selected-ids');
    ipcMain.removeAllListeners('get-window-size');
    ipcMain.removeAllListeners('take-screenshot');
    ipcMain.removeAllListeners('select-task');
    ipcMain.removeAllListeners('start-track');
    ipcMain.removeAllListeners('stop-track');
    ipcMain.removeAllListeners('create-new-activity');
    ipcMain.removeAllListeners('tray-icon-control');
    ipcMain.removeAllListeners('select-project');
    ipcMain.removeAllListeners('control-event');
  }

  if (trackingIntervalHandler) {
    clearInterval(trackingIntervalHandler);
  }

  if (engagementIntervalHandler) {
    clearInterval(engagementIntervalHandler);
  }

  if (checkTrackOnHandler) {
    clearInterval(checkTrackOnHandler);
  }

  if (hourCronjobHandler) {
    hourCronjobHandler.stop();
  }
}

// function parseCookies (rc) {
//   var list = {};

//   rc && rc.split(';').forEach(function( cookie ) {
//     var parts = cookie.split('=');
//     list[parts.shift().trim()] = decodeURI(parts.join('='));
//   });

//   return list;
// }

try {

  // This method will be called when Electron has finished
  // initialization and is ready to create browser windows.
  // Some APIs can only be used after this event occurs.
  app.on('ready', createWindow);

  // Quit when all windows are closed.
  app.on('window-all-closed', () => {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    // if (process.platform !== 'darwin') {

    // }
    app.quit();
  });

  app.on('activate', () => {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (win === null) {
      createWindow();
    }
  });

  app.on('before-quit', (evt) => {
    if (tray) {
      tray.destroy();
      tray = null;
    }
    ioHook.stop();
    ioHook.unload();
    destroyListners();
  });

  /**
   * Cron Job for Engagement
   */
  hourCronjobHandler = new CronJob('0 0 */1 * * *', () => {

    if (contextMenu && menuTemplate.length > 0) {
      console.log('engagement cronjob running:');
      const engagementPer = round(calculateEngagementPer(), 2);
      menuTemplate[0].label = updateEngagement(engagementPer);
      contextMenu = Menu.buildFromTemplate(menuTemplate);
      tray.setContextMenu(contextMenu);
      lastEngagementPer = engagementPer;
      idleTimeInMilliSecs = 0;
    }

    // check the reset time
    const currentTime = new Date();
    const currentHours = currentTime.getHours();
    const currentMinutes = currentTime.getMinutes();

    if (currentHours === 0 && currentMinutes === 0) {
      for (const key in projectsDetail) {
        if (projectsDetail.hasOwnProperty(key)) {
          projectsDetail[key]['time'] = 0;
        }
      }
    }
  }, null, true);

  /**
   * ipcMain lisner to get current task id and project id
   */
  ipcMain.on('get-current-ids', (event, arg) => {
    event.sender.send('get-current-ids-reply', {
      currentTaskId: currentTaskId,
      currentProjectId: currentProjectId
    });
  });

  /**
   * ipcMain lisner to get selected task id and project id
   */
  ipcMain.on('get-selected-ids', (event, arg) => {
    event.sender.send('get-selected-ids-reply', {
      selectedTaskId: selectedTaskId,
      selectedProjectId: selectedProjectId
    });
  });

  /**
   * ipcMain lisner to get current desktop window size
   */
  ipcMain.on('get-window-size', (event, arg) => {
    event.sender.send('get-window-size-reply', size);
  });

  /**
   * ipcMain lisner to get screenshot event
   */
  ipcMain.on('take-screenshot', (event, arg) => {
    takeScreenshotEvent = event;
  });

  /**
   * ipcMain lisner to get control event
   */
  ipcMain.on('control-event', (event, arg) => {
    controlEvent = event;
  });

  /**
   * ipcMain lisner to get task id selected
   */
  ipcMain.on('select-task', (event, arg) => {
    if (currentProjectId < 0 && currentTaskId < 0) {
      selectedTaskId = parseInt(arg['taskId'], 10);
      selectedProjectId = parseInt(arg['projectId'], 10);
      event.sender.send('get-selected-ids-reply', {
        selectedTaskId: selectedTaskId,
        selectedProjectId: selectedProjectId
      });

      if (tray && menuTemplate.length > 0) {
        menuTemplate[3].visible = false;
        menuTemplate[4].visible = true;
        menuTemplate[4].enabled = true;
        contextMenu = Menu.buildFromTemplate(menuTemplate);
        tray.setContextMenu(contextMenu);
      }
    }
  });

  /**
   * ipcMain lisner to quit the app
   */
  ipcMain.on('quit-app', (event, arg) => {
    if (win) {
      win = null;
    }

    app.quit();
  });

  /**
   * ipcMain lisner to get start time tracking event
   */
  ipcMain.on('start-track', (event, arg) => {
    if (currentTaskId >= 0 && currentProjectId >= 0) {
      if (currentTaskId !== arg['taskId'] || currentProjectId !== arg['projectId']) {
        isTrack = false;
        if (tray && menuTemplate.length > 0) {
          menuTemplate[3].visible = false;
          menuTemplate[4].visible = true;
          menuTemplate[4].enabled = true;
          contextMenu = Menu.buildFromTemplate(menuTemplate);
          tray.setContextMenu(contextMenu);
        }
        updateTracks(currentProjectId, currentTaskId, Date.now());
        clearTrackData();
      }
    }

    isTrack = true;
    lastTrackTimestamp = Date.now();

    if (tray && menuTemplate.length) {
      menuTemplate[3].visible = true;
      menuTemplate[4].visible = false;
      contextMenu = Menu.buildFromTemplate(menuTemplate);
      tray.setContextMenu(contextMenu);
    }

    currentTaskId = arg['taskId'];
    selectedTaskId = arg['taskId'];
    currentProjectId = arg['projectId'];
    selectedProjectId = arg['projectId'];
    previousTimestamp = Date.now();
    // takeScreenShots(currentTaskId, trackingTimeIntervalMins * 60 * 1000, true);
    event.sender.send('start-track-reply', {
      currentTaskId: currentTaskId,
      currentProjectId: currentProjectId,
      selectedTaskId: selectedTaskId,
      selectedProjectId: selectedProjectId
    });
  });

  /**
   * ipcMain lisner to get stop time tracking event
   */
  ipcMain.on('stop-track', (event, arg) => {
    if (isTrack) {
      updateTracks(arg['projectId'], arg['taskId'], Date.now());
      clearTrackData();

      if (tray && menuTemplate.length > 0) {
        menuTemplate[3].visible = false;
        menuTemplate[4].visible = true;
        contextMenu = Menu.buildFromTemplate(menuTemplate);
        tray.setContextMenu(contextMenu);
      }

      event.sender.send('stop-track-reply', {
        currentTaskId: currentTaskId,
        currentProjectId: currentProjectId,
        selectedTaskId: selectedTaskId,
        selectedProjectId: selectedProjectId
      });
    }
  });

  /**
   * ipcMain lisner to update setting
   */
  ipcMain.on('update-setting', (event, arg) => {
    settingData = arg['setting'];
    checkTrackOnStatus();
  });

  /**
   * ipcMain lisner to select project
   */
  ipcMain.on('select-project', (event, arg) => {
    const current = Date.now();
    selectProjectEvent = event;
    selectedProject = arg['project'];

    if (selectedProject['id']) { // if project is selected
      selectedProjectId = selectedProject['id'];
      idleSettingTimeInMins = selectedProject['ideal_time_interval_mins'] ? parseInt(selectedProject['ideal_time_interval_mins'], 10) : 0;
      trackingTimeIntervalMins = selectedProject['time_interval_mins'] ? parseInt(selectedProject['time_interval_mins'], 10) : 0;
      engagementTimeIntervalMins = selectedProject['engagement_interval_mins'] ?
        parseInt(selectedProject['engagement_interval_mins'], 10) : 0;
      clearTimeIntervals();
      startTimeIntervals();
      lastProjectTimestamp = current;
      if (tray && menuTemplate.length > 0) {
        menuTemplate[3].visible = false;
        menuTemplate[4].visible = true;
        menuTemplate[4].enabled = true;
        contextMenu = Menu.buildFromTemplate(menuTemplate);
        tray.setContextMenu(contextMenu);
      }
      buildProjectInfo();
    } else { // if any project is not selected
      if (
        isTrack &&
        Object.keys(selectedProject).length !== 0 &&
        selectedProject['id'] &&
        projectsDetail.hasOwnProperty(selectedProject['id'])
      ) { // if there is previous selected project
        const diffInMilliSecs = current - lastProjectTimestamp;
        projectsDetail[selectedProject['id']]['time'] += diffInMilliSecs;
      }

      selectedProject = {};
      selectedProjectId = -1;
      if (tray) {
        if (tray && menuTemplate.length > 0 && !isTrack) {
          menuTemplate[1].visible = false;
          menuTemplate[3].visible = false;
          menuTemplate[4].visible = true;
          menuTemplate[4].enabled = false;
          contextMenu = Menu.buildFromTemplate(menuTemplate);
          tray.setContextMenu(contextMenu);
        }
      }
    }
  });

  /**
   * ipcMain lisner to get all projects and tasks
   */
  ipcMain.on('get-all-projects-tasks', (event, arg) => {
    let projectSubMenu = [];

    if (arg['projects'] && arg['projects'].length > 0) {
      for (let index = 0; index < arg['projects'].length; index ++) {
        if (arg['projects'][index] && arg['projects'][index]['id']) {
          if (!projectsDetail.hasOwnProperty(arg['projects'][index]['id'])) {
            projectsDetail[arg['projects'][index]['id']] = {
              time: 0
            };
          }

          projectsDetail[arg['projects'][index]['id']]['data'] = arg['projects'][index];
        }
      }

      projectSubMenu = buildProjectMenu(arg['projects'], arg['tasks']);
    }

    if (tray && menuTemplate.length > 3) {
      if (projectSubMenu.length > 0) {
        menuTemplate[6].submenu = projectSubMenu;
      }

      contextMenu = Menu.buildFromTemplate(menuTemplate);
      tray.setContextMenu(contextMenu);
    }
  });

  /**
   * ipcMain activity lisner
   */
  ipcMain.on('activity-notification', (event, arg) => {
    if (tray && menuTemplate.length > 0) {
      menuTemplate[8].enabled = true;
      contextMenu = Menu.buildFromTemplate(menuTemplate);
      tray.setContextMenu(contextMenu);
    }
  });

  /**
   * ipcMain lisner to get event of tray icon control
   */
  ipcMain.on('tray-icon-control', (event, arg) => {
    trayControlEvent = event;
  });

  /**
   * ipcMain lisner to get event of new activity creation
   */
  ipcMain.on('create-new-activity', (event, arg) => {
    createNewActivityEvent = event;
  });

  /**
   * ioHook listener to get key down event
   */
  ioHook.on('keydown', event => {
    if (isTrack) {
      keyboardCount ++;
      lastTrackTimestamp = Date.now();
    }
  });

  /**
   * ioHook listener to get mouse down event
   */
  ioHook.on('mousedown', event => {
    if (isTrack) {
      mouseCount ++;
      lastTrackTimestamp = Date.now();
    }
  });

  // Register and start hook
  ioHook.start(false);

} catch (e) {
  console.log('error: ', e);
  // Catch Error
  // throw e;
}

单击任务栏图标后,该应用程序将在Linux Mint中强制关闭。但这不是在Windows / Mac和Ubuntu中发生的。它仅在Linux Mint上发生。请帮忙。

0 个答案:

没有答案