ウインドウのカスタマイズ
BrowserWindow
モジュールは、Electron アプリケーションの基盤であり、ブラウザウインドウの外観や動作を変更するために多くの API を公開しています。 このチュートリアルでは、macOS、Windows、Linux でのウインドウのカスタマイズにあたってさまざまなユースケースをご説明します。
フレームレスウインドウの作成
フレームレスウインドウは、クローム が無いウインドウです。 Google Chrome ブラウザとの混同にご注意ください。ウインドウの クローム とは、ウェブページの一部ではないウインドウの部分 (ツールバーやコントロールなど) を指します。
フレームレスウインドウを作成するには、BrowserWindow
のコンストラクタで frame
を false
に設定する必要があります。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
カスタムのタイトルバースタイルの適用 macOS Windows
タイトルバースタイルは、システムのネイティブなウインドウコントロールを維持したまま BrowserWindow のクロームのほとんどを隠すことができます。これは BrowserWindow
のコンストラクタの titleBarStyle
オプションで設定できます。
タイトルバースタイルに hidden
を適用すると、タイトルバーが隠され、コンテンツがフルサイズなウインドウを表示します。
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
を適用すると、信号機ボタンが垂直方向に一定量だけずれます。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
信号機ボタンの位置をより細かく制御する必要がある場合は、BrowserWindow
のコンストラクタの trafficLightPosition
オプションに座標を渡すことでできます。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
プログラムによる信号機ボタンの表示と非表示 macOS
信号機ボタンの表示と非表示はメインプロセスからプログラムでもできます。 win.setWindowButtonVisibility
はその引数の真偽値に応じて、信号機ボタンを強制的に表示または非表示にします。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// 信号機ボタンを隠します
win.setWindowButtonVisibility(false)
注意: 利用可能な API の数を考えると、これを実現する方法はたくさんあります。 例えば、
frame: false
とwin.setWindowButtonVisibility(true)
を組み合わせると、titleBarStyle: 'hidden'
の設定と同じレイアウト結果になります。
Window Controls Overlay
ウインドウコントロールオーバーレイ API は、デスクトップにインストールされたウェブアプリケーションがタイトルバーの領域をカスタマイズする機能を提供するウェブ標準です。 Electron では BrowserWindow
のコンストラクタのオプション titleBarOverlay
を介してこの API を公開しています。
このオプションは、macOS または Windows でカスタムの titlebarStyle
を適用している場合にのみ機能します。 titleBarOverlay
を有効にすると、ウインドウコントロールはデフォルトの位置で表示されるようになり、DOM 要素はこの領域の下にある領域を使用できなくなります。
titleBarOverlay
オプションは、2 つの異なる値の形式を受け付けます。
どのプラットフォームでも true
を指定すれば、デフォルトのシステムカラーでオーバーレイ領域を表示します。
// macOS または Windows にて
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
どちらのプラットフォームでも titleBarOverlay
はオブジェクトにできます。 The height of the overlay can be specified with the height
property. On Windows and Linux, the color of the overlay and can be specified using the color
property. On Windows and Linux, the color of the overlay and its symbols can be specified using the color
and symbolColor
properties respectively. The rgba()
, hsla()
, and #RRGGBBAA
color formats are supported to apply transparency.
色のオプションを指定しない場合、ウインドウのコントロールボタンの色は既定でシステムカラーになります。 同様に、高さのオプションが指定されていない場合は既定の高さになります。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})
注意: メインプロセスからタイトルバーのオーバーレイを有効にすると、JavaScript API と CSS 環境変数 の組み合わせで、レンダラーから読み取り専用のオーバーレイの色と寸法の値にアクセスできます。
透過ウインドウの作成
transparent
オプションを true
に設定することで、完全に透明なウインドウを作成できます。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
制限事項
- 透明な領域越しにはクリックできません。 詳しくは #1335 をご参照ください。
- 透明なウィンドウは、サイズを変更できません。
resizable
をtrue
に設定すると、いくつかのプラットフォームでは透明なウインドウが機能しなくなることがあります。 - CSS の
blur()
フィルターはウインドウのウェブコンテンツにのみ適用されるため、ウインドウの下にあるコンテンツ (ユーザーのシステムで開いている他のアプリケーションなど) にぼかし効果を適用する方法はありません。 - デベロッパー ツールが開かれているとウインドウは透過しません。
- Windows では:
- DWM が無効だと透過ウインドウは動作しません。
- Windows システムメニューの利用やタイトルバーのダブルクリックでは、透過ウインドウを最大化できません。 背景にある理由はプルリクエスト #28207 に記載してあります。
- macOS では:
- ネイティブウインドウの影は透過ウインドウで表示されません。
クリックスルーウインドウの作成
クリックスルーウインドウを作成する、すなわち、ウインドウにすべてのマウスイベントを無視させるには、win.setIgnoreMouseEvents(ignore) APIを呼び出して下さい。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
マウスイベントの転送 macOS Windows
マウスメッセージを無視すると、ウェブコンテンツはマウスの動きを感知しないようになり、マウスを動かしたときのイベントが発生しなくなります。 Windows および macOS では、オプションのパラメータを使用してマウス移動のメッセージをウェブページに転送し、mouseleave
などのイベントを発生させられます。
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)
})
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
を追加して下さい。
body {
-webkit-app-region: drag;
}
そして、ウインドウ全体をドラッグ可能にした場合、ボタンをドラッグ不可として同時にマークしなければなりません。そうでなければ、ユーザーがボタンをクリックすることができなくなります。
button {
-webkit-app-region: no-drag;
}
カスタムのタイトルバーをドラッグ可能に設定するだけの場合、同時にタイトルバーのすべてのボタンもドラッグ不可にする必要があります。
ヒント: テキスト選択の無効化
ドラッグ可能な領域を作成したときに、ドラッグの動作がテキストの選択と競合することがあるでしょう。 例えば、タイトルバーをドラッグしたときに、誤ってそのテキストコンテンツを選択してしまうことがあります。 これを防止するには、以下のようにドラッグ可能な領域内のテキスト選択を無効にする必要があります。
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
ヒント: コンテキストメニューの無効化
いくつかのプラットフォームでは、ドラッグ可能な領域は非クライアントのフレームとして扱われます。そのため、ドラッグ可能な領域を右クリックするとシステムメニューが現れます。 すべてのプラットフォームでコンテキストメニューが正しく動作するようにするには、絶対にカスタムのコンテキストメニューをドラッグ可能な領域で使用しないでください。