You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux系统下Electron应用锁屏时SetTimeout失效的解决方案咨询

解决Electron在Linux锁屏时SetTimeout失效及捕获锁屏状态问题

一、捕获Linux锁屏/解锁事件

Electron官方未提供Linux下的锁屏事件API,可通过DBus监听桌面环境的屏幕保护信号实现,主流桌面环境(GNOME、KDE、Xfce等)均基于DBus通信。

实现步骤

  1. 安装DBus Node.js模块(推荐dbus-next):
npm install dbus-next
  1. 在Electron主进程中编写监听逻辑,兼容不同桌面环境:
const { app } = require('electron');
const { sessionBus } = require('dbus-next');

async function setupScreenLockMonitor() {
  // 尝试监听GNOME桌面锁屏信号
  try {
    const bus = sessionBus();
    const screensaverProxy = await bus.getProxyObject('org.gnome.ScreenSaver', '/org/gnome/ScreenSaver');
    const screensaverIface = screensaverProxy.getInterface('org.gnome.ScreenSaver');
    
    screensaverIface.on('ActiveChanged', (isLocked) => {
      if (isLocked) {
        // 处理锁屏逻辑
        console.log('系统已锁屏');
      } else {
        // 处理解锁逻辑
        console.log('系统已解锁');
      }
    });
    return;
  } catch (e) {}

  // 尝试监听KDE/Freedesktop标准锁屏信号
  try {
    const bus = sessionBus();
    const screensaverProxy = await bus.getProxyObject('org.freedesktop.ScreenSaver', '/org/freedesktop/ScreenSaver');
    const screensaverIface = screensaverProxy.getInterface('org.freedesktop.ScreenSaver');
    
    screensaverIface.on('ActiveChanged', (isLocked) => {
      isLocked ? console.log('系统已锁屏') : console.log('系统已解锁');
    });
    return;
  } catch (e) {}

  // 尝试监听Xfce桌面锁屏信号
  try {
    const bus = sessionBus();
    const screensaverProxy = await bus.getProxyObject('org.xfce.ScreenSaver', '/org/xfce/ScreenSaver');
    const screensaverIface = screensaverProxy.getInterface('org.xfce.ScreenSaver');
    
    screensaverIface.on('ActiveChanged', (isLocked) => {
      isLocked ? console.log('系统已锁屏') : console.log('系统已解锁');
    });
    return;
  } catch (e) {
    console.warn('当前桌面环境暂不支持监听锁屏事件');
  }
}

// 在应用就绪后启动监听
app.whenReady().then(setupScreenLockMonitor);

二、让SetTimeout在锁屏时持续运行

Linux锁屏时系统可能会将应用进程挂起以节省功耗,导致定时器暂停,可通过以下两种方式解决:

方法1:使用Electron powerSaveBlocker阻止进程挂起

Electron内置的powerSaveBlocker模块可阻止系统进入低功耗模式,保证进程持续运行:

const { powerSaveBlocker } = require('electron');

// 启动阻止显示器休眠的锁(不会完全禁用节电,仅保证进程运行)
const blockerId = powerSaveBlocker.start('prevent-display-sleep');

// 验证锁是否启动成功
console.log('电源锁状态:', powerSaveBlocker.isStarted(blockerId));

// 当不需要时关闭锁(比如应用退出或进入后台)
// powerSaveBlocker.stop(blockerId);

方法2:使用Worker Threads独立运行定时器

将定时器逻辑放在Node.js工作线程中,避免主线程被系统挂起影响定时器:

// main.js 主进程
const { Worker } = require('worker_threads');
const path = require('path');

// 创建工作线程
const timerWorker = new Worker(path.join(__dirname, 'timer-worker.js'));

// 监听工作线程消息
timerWorker.on('message', (msg) => {
  console.log('定时器触发:', msg);
});

// timer-worker.js 工作线程
const { parentPort } = require('worker_threads');

function runTimer() {
  setTimeout(() => {
    parentPort.postMessage('定时任务执行');
    runTimer(); // 循环触发
  }, 1000);
}

runTimer();

内容的提问来源于stack exchange,提问作者Henil Mehta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:46:03