コントリビュート

このドキュメントを編集

ドキュメントを翻訳するか、お使いのコンピューターでプロジェクト全体を開きます。

作業内容を送信するまで、何も公開されません。

グローバルショートカット

アプリケーションにフォーカスがない場合でも発動する、システム全体のキーボードショートカットを登録します

グローバルショートカットは、Wails アプリケーションの実行中、現在どのアプリケーションにフォーカスがあるかに関係なく発動する、システム全体のキーボードショートカットです。表示/非表示を切り替えるホットキー、クイックキャプチャツール、メディアコントロールなど、ユーザーがどこからでも利用できることを期待する機能に最適です。

グローバルショートカットは各プラットフォームのネイティブ機能上に直接構築されており、サードパーティ依存関係は追加されません。

グローバルショートカットマネージャーへのアクセス

マネージャーは、アプリケーションインスタンスの GlobalShortcut プロパティから利用できます。

go
app := application.New(application.Options{
    Name: "Global Shortcuts Demo",
})

globalShortcuts := app.GlobalShortcut

ショートカットの登録

Register は、アクセラレーターとコールバックを受け取ります。ショートカットが押されるたびに、コールバックが専用の goroutine で実行されます。

go
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 を呼び出す前にショートカットを登録できます。その場合、アプリケーションの起動時にオペレーティングシステムとのバインドが自動的に行われます。

アクセラレーターの形式

グローバルショートカットでは、メニューアクセラレーターやキーバインディングと同じアクセラレーター形式を使用します。

go
"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 supported

CmdOrCtrl は、macOS では Command、Windows と Linux では Control として解釈されるため、クロスプラットフォームのショートカットに便利です。

ショートカットの管理

go
// 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()

登録済みのショートカットはすべて、アプリケーションの終了時に自動的に解放されるため、手動でクリーンアップする必要はありません。

同じショートカットを 2 回登録した場合の動作

これには 2 つの異なるケースがあり、Wails はそれぞれを別の方法で処理します。

同じアプリケーションがショートカットを 2 回登録する場合

このケースは Wails 自体によって処理され、すべてのプラットフォームで同じ動作になります。2 回目の Register 呼び出しはエラーを返し、元のバインドは維持されます(「エラーを返して維持」)。これにより動作の予測可能性が保たれ、有効なショートカットを暗黙的に置き換えることなく、誤りが明らかになります。

go
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) X サーバーが同じキーの組み合わせに対する 2 回目のグラブを拒否するため、登録は失敗し、Register はエラーを返します。
Linux(Wayland) コンポジターが調停します。通常、デスクトップのグローバルショートカットダイアログを通じて、ユーザーにバインドの承認または選択を求めます。

このような違いがあるため、Register が返すエラーを必ず確認し、ショートカットを確保できない場合は代替ショートカットまたはユーザーへのフィードバックを用意してください。

プラットフォームに関する考慮事項

グローバルショートカットでは、Carbon Event Manager のホットキー API を使用します。これは macOS でシステム全体のホットキーを実現する標準的な仕組みであり、アクセシビリティ権限は必要ありません。

ホットキーは物理的なキー位置にバインドされるため、QWERTY 以外の配列では、ショートカットは標準の ANSI/QWERTY 配列で同じ位置にあるキーに対応します。

完全な例

go
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)
    }
}
ページを編集

最終更新: