Electronと透過ウィンドウ


ウィンドウを透過させる

BrowserWindowの引数によって、ウィンドウを透過させることができます。
transparentとopacityのどちらを使用するかによって、透過の適用範囲が変わるので、用途により。

transparent を使用する場合

transparentは背景のみを透過し、ラベルやボタン等の要素は透過させません。

index.js
win = new BrowserWindow({
  transparent: true,
  frame: false,       // フレームを非表示にする
  resizable: false    // ウィンドウリサイズ禁止
})
  • frame
    ウィンドウに付随する何かがあると、transparentが効かない模様。
    frameは勿論、Developer Toolsも同様なので、Undockしておく必要あり。
  • resizable
    resizableが有効だと、一部環境によっては透過が機能しなくなる可能性があります。1

opacity を使用する場合

opacityは背景・要素・フレーム・Developer Tools全てを透過させます。

index.js
win = new BrowserWindow({
  opacity: 0.3
}

ウィンドウを透過させ、マウスイベントを無視する

透過ウィンドウの上から他のウィンドウを操作したい場合、透過ウィンドウにマウスイベントを無視させる必要があります。

一切のマウスイベントを無視する

setIgnoreMouseEvents(true)を指定することで、ウィンドウがマウスイベントを受け付けなくなります。

index.js
win = new BrowserWindow({
  transparent: true,
  frame: false,
  resizable: false,
  alwaysOnTop: true  // 常に最前表示 処理には関係ないけど、恐らくセットで使うはず
})

win.setIgnoreMouseEvents(true)

特定の要素ではマウスイベントを受け取る

例えば、背景やラベルではマウスイベントを無視したいが、ボタンだけは押せるようにしたい、といった場合。
マウスポインタの位置に応じて、都度setIgnoreMouseEventsを呼び出す必要があります。

index.js
win = new BrowserWindow({
  transparent: true,
  frame: false,
  resizable: false,
  alwaysOnTop: true
})

// forwardオプション: mouseenterやmouseleaveといったイベントを検知できるようになる
// clickが貫通するのは変わらず
win.setIgnoreMouseEvents(true, { forward: true })
App.vue
<template>
  <div>
    <label>無視したいラベル</label>
    <button
      v-on:mouseenter="onMouseEnter"
      v-on:mouseleave="onMouseLeave"
    >
      押したいボタン
    </button>
  </div>
</template>

<script>
const win = require('electron').remote.getCurrentWindow()

export default {
  methods: {
    onMouseEnter () {
      // 要素にマウスポインタが乗っている間、マウスイベントの無視をやめる
      win.setIgnoreMouseEvents(false)
    },
    onMouseLeave () {
      // 要素からマウスが離れたら、マウスイベントを無視する
      win.setIgnoreMouseEvents(true, { forward: true })
    }
  }
}
</script>

参考


  1. 具体的にどうすれば機能しないのかは不明でした……。が、フレームを非表示にする以上は不要ですし、ついでに切っておくが吉?