Глобальные сочетания клавиш
Регистрируйте общесистемные сочетания клавиш, которые срабатывают, даже когда ваше приложение не находится в фокусе
Глобальные сочетания клавиш — это общесистемные сочетания, которые срабатывают независимо от того, какое приложение сейчас находится в фокусе, пока запущено ваше приложение Wails. Они идеально подходят для горячих клавиш показа и скрытия, инструментов быстрого захвата, управления мультимедиа и других функций, которые должны быть доступны пользователям отовсюду.
Глобальные сочетания клавиш реализованы непосредственно на основе нативных возможностей каждой платформы и не добавляют сторонних зависимостей.
Доступ к диспетчеру глобальных сочетаний клавиш
Диспетчер доступен через свойство GlobalShortcut экземпляра вашего приложения:
app := application.New(application.Options{
Name: "Global Shortcuts Demo",
})
globalShortcuts := app.GlobalShortcutРегистрация сочетания клавиш
Register принимает акселератор и функцию обратного вызова. При каждом нажатии сочетания функция обратного вызова выполняется в отдельной горутине.
err := app.GlobalShortcut.Register("CmdOrCtrl+Shift+G", func() {
// Runs even when another application is focused.
window.Show()
window.Focus()
})
if err != nil {
app.Logger.Error("could not register shortcut", "error", err)
}Сочетания клавиш можно регистрировать до вызова app.Run. В этом случае привязка в операционной системе выполняется автоматически при запуске приложения.
Формат акселератора
Для глобальных сочетаний клавиш используется тот же формат акселераторов, что и для акселераторов меню и привязок клавиш:
"CmdOrCtrl+Shift+G" // Command on macOS, Control elsewhere
"Ctrl+Alt+K" // Control + Alt + K
"Cmd+Option+Space" // Command + Option + Space (macOS)
"Super+D" // Super / Windows / Logo key + D
"Ctrl+Shift+F5" // Function keys are supportedCmdOrCtrl соответствует Command в macOS и Control в Windows и Linux, что удобно для кроссплатформенных сочетаний клавиш.
Управление сочетаниями клавиш
// Check whether a shortcut is registered (modifier order does not matter).
registered := app.GlobalShortcut.IsRegistered("Ctrl+Shift+G")
// List every shortcut this application has registered.
for _, accelerator := range app.GlobalShortcut.GetAll() {
app.Logger.Info("global shortcut", "accelerator", accelerator)
}
// Release a single shortcut.
app.GlobalShortcut.Unregister("Ctrl+Shift+G")
// Release everything (also done automatically on shutdown).
app.GlobalShortcut.UnregisterAll()При завершении работы приложения все зарегистрированные сочетания клавиш освобождаются автоматически, поэтому удалять их вручную не нужно.
Что происходит при двукратной регистрации одного сочетания клавиш
Есть два разных случая, которые Wails обрабатывает по-разному.
Одно приложение дважды регистрирует сочетание клавиш
Этот случай обрабатывает сам Wails, и поведение одинаково на всех платформах. Второй вызов Register возвращает ошибку, а исходная привязка сохраняется («ошибка с сохранением»). Благодаря этому поведение остаётся предсказуемым, а ошибка становится явной вместо незаметной замены рабочего сочетания клавиш.
app.GlobalShortcut.Register("Ctrl+Shift+G", showWindow) // ok
err := app.GlobalShortcut.Register("Shift+Ctrl+G", doSomething) // err: already registered
// showWindow is still the active callback for this shortcut.Чтобы изменить функцию обратного вызова для сочетания клавиш, сначала выполните для него Unregister, а затем снова Register.
Сочетание клавиш уже занято другим приложением
Решение принимает операционная система, поэтому результат зависит от платформы:
| Платформа | Поведение, если сочетание клавиш занято другим приложением |
|---|---|
| macOS | Регистрация завершается успешно. macOS позволяет нескольким приложениям регистрировать одну и ту же горячую клавишу, поэтому ваша функция обратного вызова добавляется наряду с существующим владельцем, а не отклоняется. |
| Windows | Регистрация завершается ошибкой, и Register возвращает ошибку. Сочетание остаётся у приложения, которое зарегистрировало его первым. |
| Linux (X11) | Регистрация завершается ошибкой, и Register возвращает ошибку, поскольку X-сервер отклоняет повторный захват того же сочетания. |
| Linux (Wayland) | Решение принимает композитор. Обычно пользователю предлагается подтвердить или выбрать привязку в диалоговом окне глобальных сочетаний клавиш среды рабочего стола. |
Из-за этих различий всегда проверяйте ошибку, возвращаемую Register, и предусмотрите запасное сочетание клавиш или уведомление пользователя на случай, если зарегистрировать сочетание не удастся.
Особенности платформ
Для глобальных сочетаний клавиш используется API горячих клавиш Carbon Event Manager. Это стандартный механизм общесистемных горячих клавиш в macOS, не требующий разрешения «Универсальный доступ».
Горячие клавиши привязываются к физическому расположению клавиш, поэтому в раскладках, отличных от QWERTY, сочетание соответствует клавише в позиции стандартной раскладки ANSI/QWERTY.
Для глобальных сочетаний клавиш используется API Win32 RegisterHotKey. Автоповтор подавляется, поэтому при удержании клавиш функция обратного вызова срабатывает один раз, а не многократно.
Регистрация завершается ошибкой, если сочетание уже занято другим приложением, поэтому для значений по умолчанию выбирайте менее распространённые сочетания.
В сеансах X11 Wails регистрирует сочетание клавиш непосредственно на X-сервере, поэтому запрошенный акселератор назначается в точности так, как указано.
В сеансах Wayland приложения по архитектурным причинам не могут напрямую перехватывать нажатия клавиш. Вместо этого Wails использует интерфейс XDG Desktop Portal org.freedesktop.portal.GlobalShortcuts. При работе через портал переданный акселератор служит предпочтительным триггером, а окончательное сочетание клавиш определяет композитор (и в конечном счёте пользователь). Обратный вызов по-прежнему срабатывает при активации сочетания, однако фактические клавиши могут не совпадать с запрошенными, а IsRegistered/GetAll сообщают запрошенное вами сочетание, а не назначенное композитором.
Для работы портала требуется среда рабочего стола, реализующая портал глобальных сочетаний клавиш (например, последние версии GNOME или KDE Plasma).
Полный пример
package main
import (
"log"
"github.com/wailsapp/wails/v3/pkg/application"
)
func main() {
app := application.New(application.Options{
Name: "Global Shortcuts Demo",
})
window := app.Window.New()
// Bring the window to the front from anywhere.
if err := app.GlobalShortcut.Register("CmdOrCtrl+Shift+G", func() {
window.Show()
window.Focus()
}); err != nil {
log.Printf("could not register show shortcut: %v", err)
}
// Hide the window from anywhere.
if err := app.GlobalShortcut.Register("CmdOrCtrl+Shift+H", func() {
window.Hide()
}); err != nil {
log.Printf("could not register hide shortcut: %v", err)
}
if err := app.Run(); err != nil {
log.Fatal(err)
}
}