Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Контекстное меню

Контекстное меню — меню, которое появляется по правому щелчку мыши. В Electron его по умолчанию нет вообще: правый щелчок по полю ввода ничего не показывает. Меню создаётся тем же Menu.buildFromTemplate, что и меню приложения, но показывается методом popup в нужном месте.

Меню для полей ввода

Главный процесс узнаёт о правом щелчке по событию context-menu у webContents окна. Добавьте в createWindow в main.js:

// main.js
win.webContents.on('context-menu', (event, params) => {
  if (!params.isEditable) {
    return;
  }
  const menu = Menu.buildFromTemplate([
    { role: 'cut', label: 'Вырезать' },
    { role: 'copy', label: 'Копировать' },
    { role: 'paste', label: 'Вставить' },
    { type: 'separator' },
    { role: 'selectAll', label: 'Выделить всё' },
  ]);
  menu.popup({ window: win });
});

params.isEditable равен true, если щелчок пришёлся на поле ввода. Щёлкните правой кнопкой по полю заметки — появится меню с привычными командами. Роли выполняют действия сами, click писать не нужно.

Что есть в params

ПолеЗначение
isEditableЩелчок по полю ввода
selectionTextВыделенный текст
linkURLАдрес ссылки под курсором
x, yКоординаты щелчка

Меню для заметки

Чтобы удалить конкретную заметку, главному процессу нужно знать, по какой из них щёлкнули. Это знает только страница, поэтому она сама просит показать меню:

// renderer.js
list.addEventListener('contextmenu', (event) => {
  const li = event.target.closest('li');
  if (!li) {
    return;
  }
  event.preventDefault();
  window.notes.showNoteMenu(Number(li.dataset.index));
});

При выводе списка каждому li записывается li.dataset.index = i. Вызов preventDefault отменяет стандартную обработку правого щелчка.

// preload.js
showNoteMenu: (index) => ipcRenderer.send('notes:menu', index),
onDeleteNote: (callback) => ipcRenderer.on('notes:delete', (event, index) => callback(index)),

Показ меню в главном процессе

// main.js
ipcMain.on('notes:menu', (event, index) => {
  const menu = Menu.buildFromTemplate([
    { label: 'Удалить заметку', click: () => event.sender.send('notes:delete', index) },
  ]);
  menu.popup({ window: BrowserWindow.fromWebContents(event.sender) });
});

Ответ не нужен, поэтому используется пара send и ipcMain.on. Выбранный пункт отправляет странице номер заметки по каналу notes:delete.

// renderer.js
window.notes.onDeleteNote(async (index) => {
  notes.splice(index, 1);
  await window.notes.save(notes);
  render();
});

Правый щелчок по заметке и пункт «Удалить заметку» убирают её из списка и из файла.

Частая ошибка

Без параметра window метод popup откроет меню у текущего активного окна, и при нескольких окнах оно может появиться не там. Всегда передавайте окно, из которого пришёл щелчок: menu.popup({ window: win }).

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.