-webkit-app-regionを使わずにドラッグでWindowを移動(Electron)

Electron

普通に実装する場合はcssで以下を付けたりして対応します。

-webkit-app-region: drag;

だいたいのケースはこれで事足りるんですが、これをやると該当部分のマウスイベントを受け取れなくなるので回避したい場合はMainProcessと通信しながらWindow位置を変更します。

とりあえず動くだけなら以下のような感じで動作します。
ただし、残念ながらapp-region: drag;のようにスムーズには動きません。

renderer process

let wX;
let wY;
let dragging = false;
const hoge= document.getElementById('hoge');

hoge.onmousedown = e => {
    dragging = true;
    wX = e.pageX;
    wY = e.pageY;
};

window.onmousemove = e => {
    e.stopPropagation();
    e.preventDefault();
    if (dragging) {
        const x = e.screenX - wX;
        const y = e.screenY - wY;

        try {
            window.api.send('moveWindow', { x, y });
        } catch (err) {
            console.log(err);
        }
    }
};

hoge.mouseup = e => {
    dragging = false;
};
main process

ipcMain.on('moveWindow', (event, args) => {
    mainWindow.setPosition(args.x, args.y);
});

これだと実用に耐えかねないので色々と探してみたところStackOverflowでよさそうな記事を発見。
かなりスムーズになりました。
app-region: drag;には及びませんが、かなりの高い精度で追随するためこれで困ることはなさそうです。

renderer process

let animationId;
let mouseX;
let mouseY;

menuButton.onmousedown = onMouseDown;

function onMouseDown(e) {
    mouseX = e.clientX;
    mouseY = e.clientY;

    document.addEventListener('mouseup', onMouseUp);
    requestAnimationFrame(moveWindow);
}

function onMouseUp(e) {
    window.api.send('windowMoved');
    document.removeEventListener('mouseup', onMouseUp);
    cancelAnimationFrame(animationId);
}

function moveWindow() {
    window.api.send('windowMoving', { mouseX, mouseY });
    animationId = requestAnimationFrame(moveWindow);
}
main process

ipcMain.on('windowMoving', (e, { mouseX, mouseY }) => {
    const { x, y } = screen.getCursorScreenPoint();
    mainWindow.setPosition(x - mouseX, y - mouseY);
});

ipcMain.on('windowMoved', () => {
    // Do somehting when dragging stop
});
-webkit-app-region: drag eats all click events · Issue #1354 · electron/electron
Whensetting-webkit-app-region:dragtomakethewindowdraggableallclick/mousedown/mouseupcannolongerbecaptured.//assumingbody{-webkit-app-region:drag;}document.body....

画面端等にドラッグした時の最大化など、OSによるWindowの変化で動作がおかしくなる場合がある、というような注意を書いてくださってる方もいます。
万能ではありませんが、多少の動作不良に目をつむってもコレで実現できるのでは?

コメント