如何在 Electron 中跟踪 BrowserWindow 的拖动?

How do I track dragging of a BrowserWindow in Electron?

我有一个 BrowserWindow 实例。我想知道 window 什么时候出现在屏幕上 dragged/moved。

我曾尝试使用 moved 事件,但只有在 window 被移动后才会触发该事件。拖动 window 时不会触发。

如何跟踪 window 何时被拖动?

Electron API 似乎不提供拖动过程中实际 window 位置的跟踪。

但是,与其尝试跟踪 window 本身的新位置,不如在可拖动的 window 区域中跟踪鼠标光标移动期间的鼠标光标移动。

代码大纲:

  • 检测拖动事件
  • 检查拖动事件是否在拖动区域范围内
  • 使用 mousemove 事件跟踪鼠标光标移动

您可以 运行 循环不断检查 window.screenXwindow.screenY 值是否已更改。以下内容:

function onScreenMove(cb) {

    var lastScreenX;
    var lastScreenY;

    function detectScreenMove() {
        if (lastScreenY !== window.screenY || lastScreenX !== window.screenX) {
            lastScreenY = window.screenY;
            lastScreenX = window.screenX;
            cb();
        }
        requestAnimationFrame(detectScreenMove);
    }
    requestAnimationFrame(detectScreenMove);
}

onScreenMove(function() {
    // do something
});

据我所知,读取 screenX/screenY 值的过程不是很昂贵,因此您不会杀死处理器。

不幸的是,Object.observe() 从 v50 开始已经离开 Chrome,因此似乎没有更 "under the hood" 的方法来检查 window 属性 变化。

每当 window 移动一个像素时,BrowserWindowmove(和 moved)事件就会发出。如果 window 被拖动和移动,那么 move 事件会持续触发,直到鼠标停止。

当检测到 move 时,您可以获得 window 的位置作为

let position = window.GetPosition();
let x = position[0];
let y = position[1];

然后根据需要使用那些位置

我遇到了同样的问题,我用另一种方式解决了。 我创建了一个无框架的 BrowserWindow,并在 window.

中加载了我想要的图标和我想要的网页中的侦听器。

这个很好用,也不贵。

    let wX;
    let wY;
    let dragging = false;
    $('#systembar').mousedown(function (e) {
        ipcRenderer.send('asynchronous-message', 'down')
        dragging = true;
        wX = e.pageX;
        wY = e.pageY;
    });

    $(window).mousemove(function (e) {
        e.stopPropagation();
        e.preventDefault();
        if (dragging) {
            var xLoc = e.screenX - wX;
            var yLoc = e.screenY - wY;

            try {
                remote.BrowserWindow.getFocusedWindow().setPosition(xLoc, yLoc);
            } catch (err) {
                console.log(err);
            }
        }
    });

    $('#systembar').mouseup(function () {
        dragging = false;
        ipcRenderer.send('asynchronous-message', 'up')
    });