メインコンテンツへ飛ぶ

ウインドウのカスタマイズ

BrowserWindow モジュールは、Electron アプリケーションの基盤であり、ブラウザウインドウの外観や動作を変更するために多くの API を公開しています。 このチュートリアルでは、macOS、Windows、Linux でのウインドウのカスタマイズにあたってさまざまなユースケースをご説明します。

フレームレスウインドウの作成

フレームレスウインドウは、クローム が無いウインドウです。 Google Chrome ブラウザとの混同にご注意ください。ウインドウの クローム とは、ウェブページの一部ではないウインドウの部分 (ツールバーやコントロールなど) を指します。

フレームレスウインドウを作成するには、BrowserWindow のコンストラクタで framefalse に設定する必要があります。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })

カスタムのタイトルバースタイルの適用 macOS Windows

タイトルバースタイルは、システムのネイティブなウインドウコントロールを維持したまま BrowserWindow のクロームのほとんどを隠すことができます。これは BrowserWindow のコンストラクタの titleBarStyle オプションで設定できます。

タイトルバースタイルに hidden を適用すると、タイトルバーが隠され、コンテンツがフルサイズなウインドウを表示します。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })

信号機ボタンの制御 macOS

macOS では、タイトルバースタイルに hidden を適用しても、左上に標準ウインドウコントロール (「信号機ボタン」) が表示されます。

信号機ボタンの見た目のカスタマイズ macOS

タイトルバースタイルを customButtonsOnHover にすると、信号機ボタンにカーソルを合わせるまでそれを隠します。 これは、HTML でカスタムの信号機ボタンを作成したいものの、ウインドウコントロールにはネイティブ UI を使用したい場合に便利です。

const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })

信号機ボタンの位置のカスタマイズ macOS

ウインドウ制御の信号機ボタンの位置を変更するには、2 つの設定オプションがあります。

タイトルバースタイルに hiddenInset を適用すると、信号機ボタンが垂直方向に一定量だけずれます。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })

信号機ボタンの位置をより細かく制御する必要がある場合は、BrowserWindow のコンストラクタの trafficLightPosition オプションに座標を渡すことでできます。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})

プログラムによる信号機ボタンの表示と非表示 macOS

信号機ボタンの表示と非表示はメインプロセスからプログラムでもできます。 win.setWindowButtonVisibility はその引数の真偽値に応じて、信号機ボタンを強制的に表示または非表示にします。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// 信号機ボタンを隠します
win.setWindowButtonVisibility(false)

注意: 利用可能な API の数を考えると、これを実現する方法はたくさんあります。 例えば、frame: falsewin.setWindowButtonVisibility(true) を組み合わせると、titleBarStyle: 'hidden' の設定と同じレイアウト結果になります。

ウインドウコントロールオーバーレイ

ウインドウコントロールオーバーレイ API は、デスクトップにインストールされたウェブアプリケーションがタイトルバーの領域をカスタマイズする機能を提供するウェブ標準です。 Electron では BrowserWindow のコンストラクタのオプション titleBarOverlay を介してこの API を公開しています。

This option only works whenever a custom titlebarStyle is applied. titleBarOverlay を有効にすると、ウインドウコントロールはデフォルトの位置で表示されるようになり、DOM 要素はこの領域の下にある領域を使用できなくなります。

titleBarOverlay オプションは、2 つの異なる値の形式を受け付けます。

どのプラットフォームでも true を指定すれば、デフォルトのシステムカラーでオーバーレイ領域を表示します。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})

どちらのプラットフォームでも titleBarOverlay はオブジェクトにできます。 オーバーレイの高さは height プロパティで指定できます。 Windows と Linux では、オーバーレイの色は color プロパティで指定できます。 Windows と Linux では、オーバーレイとシンボルの色はそれぞれ colorsymbolColor プロパティで指定できます。 rgba()hsla()、および #RRGGBBAA の色形式もサポートしており、透明度を適用できます。

色のオプションを指定しない場合、ウインドウのコントロールボタンの色は既定でシステムカラーになります。 同様に、高さのオプションが指定されていない場合は既定の高さになります。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})

注意: メインプロセスからタイトルバーのオーバーレイを有効にすると、JavaScript APICSS 環境変数 の組み合わせで、レンダラーから読み取り専用のオーバーレイの色と寸法の値にアクセスできます。

透過ウインドウの作成

transparent オプションを true に設定することで、完全に透明なウインドウを作成できます。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })

制限事項

  • 透明な領域越しにはクリックできません。 詳しくは #1335 をご参照ください。
  • 透明なウィンドウは、サイズを変更できません。 resizabletrue に設定すると、いくつかのプラットフォームでは透明なウインドウが機能しなくなることがあります。
  • CSS の blur() フィルターはウインドウのウェブコンテンツにのみ適用されるため、ウインドウの下にあるコンテンツ (ユーザーのシステムで開いている他のアプリケーションなど) にぼかし効果を適用する方法はありません。
  • デベロッパー ツールが開かれているとウインドウは透過しません。
  • Windows では:
    • DWM が無効だと透過ウインドウは動作しません。
    • Windows システムメニューの利用やタイトルバーのダブルクリックでは、透過ウインドウを最大化できません。 背景にある理由はプルリクエスト #28207 に記載してあります。
  • macOS では:
    • ネイティブウインドウの影は透過ウインドウで表示されません。

クリックスルーウインドウの作成

クリックスルーウインドウを作成する、すなわち、ウインドウにすべてのマウスイベントを無視させるには、win.setIgnoreMouseEvents(ignore) APIを呼び出して下さい。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)

マウスイベントの転送 macOS Windows

マウスメッセージを無視すると、ウェブコンテンツはマウスの動きを感知しないようになり、マウスを動かしたときのイベントが発生しなくなります。 Windows および macOS では、オプションのパラメータを使用してマウス移動のメッセージをウェブページに転送し、mouseleave などのイベントを発生させられます。

main.js
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')

const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(ignore, options)
})
preload.js
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})

これにより、ウェブページは #clickThroughElement 要素の上ではクリックスルーとなり、その外側では通常の状態に戻ります。

ドラッグ可能な領域の設定

既定では、フレームレスウインドウはドラッグできません。 アプリは、どの領域が (OSの標準のタイトルバーのように) ドラッグ可能であるかをElectronに伝えるため、CSSで -webkit-app-region: drag を指定することが必要です。また、アプリは、ドラッグ可能な領域からドラッグ不可能な領域を除外するため、-webkit-app-region: no-drag を使用することもできます。 現在のところ、長方形の形状しかサポートされていないことに注意して下さい。

ウインドウ全体をドラッグ可能にするには、body のスタイルとして -webkit-app-region: drag を追加して下さい。

styles.css
body {
-webkit-app-region: drag;
}

そして、ウインドウ全体をドラッグ可能にした場合、ボタンをドラッグ不可として同時にマークしなければなりません。そうでなければ、ユーザーがボタンをクリックすることができなくなります。

styles.css
button {
-webkit-app-region: no-drag;
}

カスタムのタイトルバーをドラッグ可能に設定するだけの場合、同時にタイトルバーのすべてのボタンもドラッグ不可にする必要があります。

ヒント: テキスト選択の無効化

ドラッグ可能な領域を作成したときに、ドラッグの動作がテキストの選択と競合することがあるでしょう。 例えば、タイトルバーをドラッグしたときに、誤ってそのテキストコンテンツを選択してしまうことがあります。 これを防止するには、以下のようにドラッグ可能な領域内のテキスト選択を無効にする必要があります。

.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}

ヒント: コンテキストメニューの無効化

いくつかのプラットフォームでは、ドラッグ可能な領域は非クライアントのフレームとして扱われます。そのため、ドラッグ可能な領域を右クリックするとシステムメニューが現れます。 すべてのプラットフォームでコンテキストメニューが正しく動作するようにするには、絶対にカスタムのコンテキストメニューをドラッグ可能な領域で使用しないでください。