Создание пользовательской строки заголовка для вашего электронного приложения может быть немного беспокойным, особенно при обработке крайних случаев. Недавно я работал над электронным приложением, где мне пришлось провести небольшое исследование, чтобы создать пользовательскую строку заголовка. Меня вдохновила статья Ронни Датты. Я заметил, что удаленный модуль устарел в Electron, поэтому я реализовал функциональность с IPC и добавил строку заголовка MAC.

Итак, вот руководство по созданию пользовательской строки заголовка для вашего приложения, совместимой как с Windows, так и с MAC.

Первоначальный стиль

Во-первых, мы добавим некоторые базовые стили в приложение быстрого запуска. Откройте/создайте пустой файл style.css и добавьте следующее:

Сделать окно безрамным

Давайте удалим строку заголовка и границу по умолчанию. В main.js измените новую строку BrowserWindow(), чтобы она включала frame: false:

nodeIntegration включено для оконных элементов управления JavaScript для работы

Раскомментируйте mainWindow.webContents.openDevTools(), чтобы открывать инструменты разработчика при каждом запуске приложения.

Если мы запустим наше приложение сейчас, мы заметим, что строка заголовка по умолчанию исчезла.

Создайте заменяющую строку заголовка

Мы собираемся создать нашу пользовательскую строку заголовка, используя HTML и CSS (что также можно сделать в React). Давайте также поместим остальную часть содержимого приложения в его div:

Высота строки заголовка по умолчанию в Windows составляет 32 пикселя. Мы хотим, чтобы строка заголовка была зафиксирована в верхней части DOM. Добавлена ​​граница 1px к окну. Нам нужно добавить верхнее поле в 32 пикселя к #main и изменить overflow-y для #main и body (теперь #main заменяет body в качестве прокручиваемого содержимого).

Теперь, чтобы сделать нашу строку заголовка перетаскиваемой, мы добавляем div, который служит нашей перетаскиваемой областью.

и теперь мы добавляем стиль -webkit-app-region: drag, чтобы сделать его перетаскиваемым.

Причина, по которой мы не добавим этот стиль просто к #titlebar, заключается в том, что мы также хотим, чтобы курсор изменялся в размере, когда мы наводим курсор на край окна вверху. Если бы можно было перетаскивать всю строку заголовка, этого бы не произошло. Поэтому мы также добавляем отступ к неперетаскиваемому элементу #titlebar.

Добавление и оформление кнопок управления окном

Теперь давайте добавим кнопки свернуть, развернуть, восстановить и закрыть. Для этого нам понадобятся иконки. Вы можете получить ресурсы значков здесь:

github.com/binaryfunt/electron-seamless-tit..

Мы поместим кнопки внутри блока #drag-region.

Добавлено window-hover, чтобы у нас был эффект наведения на кнопки. Позже мы заменим его на mac-hover для наведения на элементы управления Mac.

Мы будем использовать сетку CSS, чтобы перекрывать кнопки максимизации/восстановления, а позже использовать JavaScript, чтобы чередовать их.

Прежде всего, кнопки не должны быть частью области перетаскивания окна, поэтому мы их исключим. Кроме того, мы не хотим иметь возможность выбирать изображения значков. Нам также нужно добавить эффекты наведения. Цвет при наведении кнопки закрытия Windows по умолчанию — #E81123. При активации кнопка становится #F1707A, а значок становится черным, чего можно добиться с помощью инвертирующего фильтра. Наконец, мы скроем кнопку восстановления по умолчанию (опять же, позже мы реализуем переключение между кнопками развертывания/восстановления).

Мы написали отдельный CSS для строки заголовка Mac и Windows.

Для значка Mac мы создаем значки с их div с круглым радиусом и фоном и помещаем в него изображения с помощью display: none, изображение значка появится при наведении курсора на mac-controls.

mac-hover — это класс над изображением значка элемента управления. mac-controls — это оболочка вокруг значков управления Mac, поэтому, когда мы наводим курсор на область значков, изображения значков появляются так, как это происходит в Mac.

Теперь строка заголовка Windows должна выглядеть так:

Теперь давайте реализуем строку заголовка для Mac. Мы можем сделать это двумя способами: либо создать другую панель инструментов с нуля, либо просто изменить css и значки в соответствии с нашими потребностями, потому что мы добавим те же функции на значки элементов управления Mac, а также Windows. Поэтому я выберу последнее и просто изменю CSS строки заголовка Windows, когда мы обнаружим process.platform === "darwin".

Таким образом, в нашем файле render.js мы можем проверить, является ли платформа Mac, и изменить стиль с помощью js. Мы сделаем это так:

Теперь строка заголовка Mac должна выглядеть так:

Реализация функциональности оконных элементов управления (с использованием IPC)

Теперь, как мы реализуем функциональность, чтобы окно максимизировалось при нажатии кнопки максимизации, а значок менялся, когда пользователь меняет состояние окна, перетаскивая и минимизируя его или Win + Arrow .

Эта двусторонняя связь может быть достигнута с помощью IPC в электронах:

ipcRenderer и ipcMain могут быть required из electron.

Давайте сначала напишем логику на стороне рендерера в render.js. Мы требуем ipcRenderer условно, если window.process отсутствует (т.е. его среда браузера), мы скрываем строку заголовка (обрабатывается для браузера).

if (window.process) { var { ipcRenderer } = window.require("electron"); } else { document.getElementById('titlebar').style.display='none' }

Мы инициализируем нашу функцию управления окном после загрузки документа.

document.onreadystatechange = { if (document.readyState == "complete") { handleWindowControls(); } };

Затем мы пишем логику для обработки действий кнопок, у нас есть общий css id для кнопок в Mac и Windows, поэтому мы добавляем прослушиватели событий для нажатия кнопки.

Мы используем ipcRenderer.send для отправки сообщения в main.js, где первым аргументом является имя события, а вторым — сообщение.

Здесь мы отправляем сообщение MAXIMIZE_WINDOW для максимизации и демаксимизации для удобства. Потому что кнопки максимизировать и развернуть заменяют друг друга.

Теперь мы можем отправить вызов IPC из renderer.js в main.js. Давайте обработаем запрос IPC в main.js.

Мы импортируем ipcMain в main.js и используем его для прослушивания любого запроса, отправленного от рендерера. У нас уже есть объект окна, который мы создали с помощью new BrowserWindow в начале. Если у нас есть несколько окон, использующих строку заголовка, то их соответствующий объект окна может быть передан в первом аргументе handleTitleBarActions.

ipcMain.on('TITLE_BAR_ACTION', { handleTitleBarActions(mainWindow, args) });

Теперь логика handleTitleBarActions следующая. Мы обрабатываем windowObj.isMaximized(), что, если окно уже развернуто, оно развернет окно.

Но, тем не менее, у нас есть несколько крайних случаев, когда мы разворачиваем или разворачиваем окно с помощью Win + Arrow key или используем перетаскивание, чтобы сделать то же самое. Иконка максимизации не меняется. Это связано с тем, что рендеринг не информируется, когда окно изменяется (разворачивается или разворачивается). Также, если мы обновим значок, он сбрасывается, чтобы развернуть кнопку.

Поэтому, чтобы решить эту проблему, мы должны отправить запрос из main.js в render.js. Для этого мы используем win.webContents.send, чтобы сообщить рендеру, что в main.js произошло какое-то событие. Мы обнаруживаем событие максимизации и развертывания окна obj с помощью:

mainWindow.on('unmaximize',()=>{ mainWindow.webContents.send("unmaximized") }) mainWindow.on('maximize',()=>{ mainWindow.webContents.send("maximized") })

Это будет держать окно обновленным. На стороне рендерера прослушивайте эти события и соответствующим образом меняйте значок. Чтобы избежать какой-либо ошибки браузера, я завернул его в window.process, если существует.

Также теперь давайте обработаем пограничный случай, когда при обновлении страницы значки развертывания и восстановления сбрасываются, а кнопка max видна, даже когда окно находится в неразвернутом состоянии. Для этого мы делаем следующее на стороне main.js

win.webContents.on('did-stop-loading', { if(win.isMaximized()===true){ win.webContents.send("maximized") } else{ win.webContents.send("unmaximized") } })

Теперь мы видим, что наша строка заголовка работает правильно как на Mac, так и на Windows, и значки правильно меняют свое состояние.

Это была моя реализация строки заголовка, которая совместима как с Mac, так и с Windows. Надеюсь, вам, ребята, понравилось,

Подпишитесь на информационный бюллетень, чтобы получать еженедельный контент, связанный с реакцией и javascript.

Первоначально опубликовано на https://ghosty.hashnode.dev.