guides

Wayland上のテキスト展開:なぜ動かなくなるのか、実際に機能する方法

Trofin Sorin-IoanTrofin Sorin-IoanCTO, Lightning Assist2026年7月26日9 分で読了
waylandlinuxx11text-expandergnomekdexwaylandinput
シェア:

簡単な回答: テキストエキスパンダーは、システム全体のあらゆるキー入力を監視し、フォーカスのあるアプリへ入力をシミュレートする必要があります。X11ではどちらもデフォルトで許可されていましたが、Waylandのコンポジターはセキュリティ上の理由から、意図的にその両方を制限しています。だからこそ、Ubuntu 20.04では完璧に動作していたテキストエキスパンダーが、最新のWaylandセッションではエラーメッセージも出ないまま、インストールはできても何一つ機能しないということが起こります。唯一の解決策というものは存在せず、実際に取りうる選択肢はXWayland(互換レイヤー内で従来どおりに動かす)、input groupへの明示的なアクセス権を持つevdev/uinputバックエンド、あるいは一度だけの権限付与を求める専用の低レベル入力バックエンドのいずれかです。Lightning Assistは最後の方式を採用しています。

テキストエキスパンダーをインストールし、トリガーを入力してみたものの、何も起こらなかった——エラーもクラッシュもなく、ただ沈黙するだけ——という場合、あなたはほぼ間違いなくWaylandを使っています。そしてこれは、選んだツール固有のバグではなく、よく知られた種類の問題です。

WaylandがグローバルなKey Listeningをブロックする理由

X11では、どのプロセスでも低レベルのキーボードフックを登録して、システム上のあらゆるキー入力を読み取ることができ、どのプロセスでも現在フォーカスのあるウィンドウへキー入力をシミュレートすることができます——xdotoolのようなツールがやっていることはまさにこれであり、テキストエキスパンダーやホットキーマネージャー、リモート制御ソフトウェアがLinux上で20年間、大きな摩擦もなく動作してきた理由もここにあります。同時に、セキュリティの観点から見れば、これはまさにデフォルトでは避けたい類のものでもあります。侵害されたアプリケーションを含む、どんなアプリケーションでもキー入力をログに残したり、銀行取引のセッションに任意の入力を注入したりできてしまうからです。

Waylandのコンポジター(GNOME用のMutter、KDE Plasma用のKWin、Swayなどが使うwlrootsベースのもの)は、正反対のデフォルトを前提に設計されています。アプリケーションは自分のウィンドウ宛ての入力イベントしか見ることができず、明示的かつ意図的な仕組みなしには、他のアプリケーションへ合成入力を注入することはできません。これは見落としでも機能の欠落でもなく、セキュリティモデルが意図どおりに機能している結果です。その代償として、X11の「どのプロセスでも監視・注入できる」という挙動に依存していたすべてのツールは、同じ仕事をするために別の、たいていはより制限された方法を必要とします。

実際に起こる結果はこうです。X11方式でキー入力をフックするテキストエキスパンダーは、純粋なWaylandセッションでは何も検知できず、X11方式でテキストを注入するテキストエキスパンダーは、注入先そのものがありません。明確なエラーが出るわけではなく、たいていは静かに失敗します。例外が投げられるわけではなく、監視しているはずのイベントがそもそも一切届かないだけだからです。

ブラウザ拡張機能がデスクトップ全体をカバーできない理由

自然な回避策として、ブラウザ拡張機能ベースのテキストエキスパンダーがあり、ブラウザのタブの中だけであればうまく機能します——拡張機能はページのDOM内で動作するため、Waylandの入力モデルとは無関係だからです。問題は対象範囲です。拡張機能は、それがインストールされているブラウザしか見ることができません。ターミナル、IDE、ネイティブのGTKやQtアプリケーション、SlackやDiscordのデスクトップクライアント、PDFリーダーの中でスニペットを展開することはできません。もし1日の作業の中にブラウザタブの外での作業が含まれるなら——開発者やサポートチームにとっては、それが1日の大半を占めるはずです——ブラウザ拡張機能は問題のごく一部しか解決せず、デスクトップの残りの部分は手つかずのままになります。

現在Waylandで実際に存在する手段

万能の解決策は存在しませんが、それぞれにトレードオフのある、実在する文書化されたアプローチがいくつかあります。

XWayland——互換レイヤー内で従来どおりに動かす

ほとんどのWaylandデスクトップ環境(GNOME、Ubuntu 22.04以降やFedora 38以降で標準搭載のKDE Plasmaなど)は、ネイティブのWaylandコンポジターと並行してXWaylandを実行します——これはX11専用のアプリケーションを動かし続けるための互換レイヤーです。X11の入力フックを使って構築されたツールは、XWayland内で動くアプリケーションに対しては引き続き機能します。落とし穴は対象範囲です。XWaylandが明示的に無効化されたセッション(一部の強化されたGNOME構成など)にいる場合や、入力先の特定のアプリケーションがXWaylandではなくネイティブのWaylandクライアントである場合には、X11方式のフックはそこに届きません。

zwp_virtual_keyboard_v1プロトコル

一部のWaylandコンポジター——GNOMEのMutterやKDEのKWinなどが含まれます——は、zwp_virtual_keyboard_v1というWaylandプロトコルを実装しており、アプリケーションがキーボードイベントを正式にシミュレートする手段を提供しています。これは回避策というより、組み込みのプロトコルレベルでの解答に近いものですが、コンポジター依存です。これに頼るアプリは、そのコンポジターがこのプロトコルを実装することを選んだ場合にのみ動作し、挙動にもばらつきが残ります——一部の環境ではクリップボード貼り付けによる代替手段にフォールバックすることがあり、これは特殊な貼り付け処理を行うアプリ(bracketed-pasteモードを持つターミナルなど)では異なる挙動を示すことがあります。

xdg-desktop-portalのRemoteDesktopインターフェース

freedesktop.orgのportal仕様は、明示的に「デスクトップセッションのリモート制御を可能にする」ために作られたRemoteDesktopインターフェースを定義しています——キーボードやポインターのイベントを注入できますが、それはセッション開始時にユーザーがKEYBOARDPOINTERアクセスを許可した後に限られ、常時稼働のシステムフックというより権限スコープ付きのセッション機構です。これはWaylandが入力注入のために用意した正式な入口ですが、設計の前提はリモート制御や画面共有ツールであって、テキストエキスパンダーが実際に必要とする「バックグラウンドで、入力するすべてのトリガーを永遠に、静かに検知し続ける」という用途を想定したものではありません。

input-groupアクセスを使ったevdev/uinput

より低レベルの選択肢は、/dev/input(evdev)から直接生の入力を読み取り、/dev/uinputを通じて合成イベントを注入し、コンポジターの入力モデルを完全に迂回する方法です。これは真の意味でコンポジターを問わず動作します——GNOMEでもKDEでもSwayでも構いません。なぜなら、そのすべての下、カーネルの入力レイヤーで動作するからです。Espansoはまさにこの方式をWayland対応に採用しており、自身のドキュメントでも「現時点では実験的」と説明されています。rootとして実行せずに生の入力を読み取るには、バイナリに対する一度限りのsetcap cap_dac_override+p権限付与(あるいは環境によってはinputグループへの所属)が必要で、既知の注意点もあります——非US配列のキーボードには明示的な設定が必要、GNOMEセッションではクリップボードバックエンドのちらつきが発生することがある、新しいキーボードを接続するにはサービスの手動再起動が必要、などです。動作はしますが、現時点での立ち位置を表すには「実験的」という言葉がふさわしいでしょう。

そもそもWaylandに対応していないツール

一部のLinux自動化ツールは、xdotoolとX11のウィンドウツリーの上に直接構築されており、Waylandへの対応経路がまったくありません——AutoKeyが最も分かりやすい例です。これはX11専用であり、その入力シミュレーションはコンポジターではなくX11のウィンドウツリーを直接対象としているため、XWaylandがあっても助けにはなりません。純粋なWaylandセッションにいる場合、この種のツールはどう設定しようと、単純に動作しません。

Lightning Assistはどう対応しているか

Lightning Assistは、セッションの種類に応じて2つの経路を使い分けます。X11セッションおよびXWaylandセッションでは、標準的なX11入力フックを使用します——これは何年もの間Linux上で確実に機能してきた仕組みと同じものです。純粋なWaylandセッションでは、専用の低レベル入力バックエンドに切り替わります。必要になった最初の一度だけ、アプリが入力アクセスを求めるプロンプト(「Grant access」)を表示し、その一度限りの許可の後は、グローバルなキー検知とテキスト展開がGNOME・KDE・その他のコンポジターを問わず同じように機能します——YAMLも不要、自分でsetcapコマンドを実行する必要もなく、キーボードレイアウトごとの設定手順もありません。これは後付けのフォールバックではなく、この目的のために保守されている専用のバックエンドであり、一度限りの許可モデルのおかげで、セッションのたびに手動の手順を繰り返す必要がありません。

ツールを選ぶ前に確認しておきたい実践的チェックリスト

ツールごとにこれだけのばらつきがあることを踏まえると、Waylandデスクトップでどれか1つに決める前に、いくつか確認しておく価値があります。

  • Wayland対応を明示的に文書化しているか、それとも漠然と「Linux対応」とだけ謳っているか? 漠然とした主張は、たいてい「X11でテスト済み」でWaylandでの挙動は未検証であることを意味します。
  • Waylandで動かすために手動のsetcapやroot権限の手順が必要か? それ自体は決定的な欠点ではありませんが、インストール後に気づくのではなく、事前に把握しておくべきことです。
  • 一律に「Waylandで動作」と謳うのではなく、コンポジターごとの具体的な注意点(GNOME、KDE、Sway)を明記しているか? コンポジター固有の癖(クリップボードのちらつき、キーボードレイアウトの設定、新しいデバイス接続時の再起動)について正直に書いているツールは、たいてい実際にそこでテストされているものです。
  • XWaylandを有効なままにしておく必要があるか? ツールがXWayland経由でしか動作しない場合は、互換性があると決めつける前に、自分のデスクトップ環境でそれがデフォルトで有効になっているか(たいていは有効です)を確認してください。

よくある質問

なぜ、あるLinuxマシンではテキストエキスパンダーが動くのに、別のマシンでは動かないのですか?

最も多い原因はセッションの種類です。X11セッションとWaylandセッションでは、グローバルな入力の扱い方がまったく異なり、主にX11の入力フックを前提に作られたツールは、一方では完璧に動作し、もう一方では何も動作しないということが起こります。ターミナルでecho $XDG_SESSION_TYPEを実行すれば、現在どちらのセッションで動作しているかを確認できます。

Waylandは生産性ツールにとって単に壊れているだけなのでしょうか?

いいえ——これはバグではなく、異なる、より制限の厳しいセキュリティモデルというだけです。単純なグローバル入力ツールをブロックする制限は、悪意あるアプリがキー入力をログに残したり、銀行取引のセッションに入力を注入したりするのを難しくしている制限と同じものです。Waylandでうまく機能するツールとは、X11方式の無制限アクセスを前提にしたものではなく、その権限モデル(portal、zwp_virtual_keyboard_v1、あるいはinput-groupアクセスを使う専用のevdev/uinputバックエンド)を前提に、特別に作られたツールです。

XWaylandを無効化すると、テキスト展開は壊れますか?

壊れる可能性はあります。XWayland上で動くアプリケーションに届くためにX11方式のフックに依存しているツールであれば、なおさらです。XWaylandが明示的に無効化された強化構成を使っている場合は、自分のテキストエキスパンダーが(X11フックだけでなく)ネイティブのWaylandバックエンドを持っているかを具体的に確認してください——Lightning Assistの専用Wayland入力バックエンドと、Espansoの実験的なevdev/uinputモードは、どちらもまさにこのケースのために作られています。一方、AutoKeyのようにxdotoolやX11のウィンドウツリーアクセスだけで構築されたツールは対応していません。

Waylandサポートを機能させるために、ターミナルコマンドを実行する必要はありますか?

ツールによります。EspansoのWaylandモードでは、自分自身で実行する一度限りのsetcap権限付与(または同等のinput-groupへの所属)が必要です。一方Lightning AssistのWaylandバックエンドは、必要になった最初の一度だけアプリ内で「Grant access」の許可を求めるだけで済みます——ターミナルコマンドは不要です。

関連記事

出典