メインコンテンツにスキップ

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

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

フレームレスウィンドウを作成する

フレームレスウィンドウとは、クロムのないウィンドウです。Google Chromeブラウザと混同しないでください。ウィンドウの*クロム*とは、Webページの一部ではないウィンドウの部分(例:ツールバー、コントロール)を指します。

フレームレスウィンドウを作成するには、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()
// hides the traffic lights
win.setWindowButtonVisibility(false)

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

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

Window Controls Overlay APIは、デスクトップにインストールされたWebアプリがタイトルバー領域をカスタマイズできるようにするWeb標準です。Electronは、BrowserWindowコンストラクターオプションtitleBarOverlayを介してこのAPIを公開します。

このオプションは、カスタムのtitlebarStyleが適用されている場合にのみ機能します。 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では、オーバーレイとその記号の色は、それぞれcolorおよびsymbolColorプロパティを使用して指定できます。透明度を適用するには、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()フィルターはウィンドウのWebコンテンツにのみ適用されるため、ウィンドウの下のコンテンツ(つまり、ユーザーのシステムで開いている他のアプリケーション)にぼかし効果を適用する方法はありません。
  • DevToolsが開いていると、ウィンドウは透明になりません。
  • Windowsの場合
    • DWMが無効になっている場合、透明なウィンドウは機能しません。
    • 透明なウィンドウは、Windowsシステムメニューを使用するか、タイトルバーをダブルクリックすることで最大化できません。この背後にある理由は、PR #28207にあります。
  • macOSの場合
    • ネイティブウィンドウの影は、透明なウィンドウには表示されません。

クリック可能なウィンドウを作成する

クリック可能なウィンドウを作成するには、つまり、ウィンドウですべてのマウスイベントを無視するには、win.setIgnoreMouseEvents(ignore)APIを呼び出すことができます

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

マウスイベントを転送する macOS Windows

マウスメッセージを無視すると、Webコンテンツはマウスの動きを認識しなくなり、マウスの動きイベントは発生しません。WindowsとmacOSでは、オプションのパラメーターを使用して、マウスの移動メッセージをWebページに転送し、 `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`要素の上にマウスがある場合、Webページはクリック可能になり、その外側では通常の状態に戻ります。

カスタムドラッグ可能領域を設定する

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

ウィンドウ全体をドラッグ可能にするには、 `-webkit-app-region:drag`を `body`のスタイルとして追加できます

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

ウィンドウ全体をドラッグ可能にした場合は、ボタンもドラッグ不可としてマークする必要があることに注意してください。そうしないと、ユーザーがボタンをクリックできなくなります。

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

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

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

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

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

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

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