「Xamarin.MacでGlobal Event Monitorを使いキー入力を監視する」の版間の差分

提供: MonoBook
ナビゲーションに移動 検索に移動
(ページの作成:「==概要== Xamarin.Macで開発している社内アプリで確実に動くファンクションキーを実現したい。 何も考えずに単純にキー入...」)
 
imported>Administrator
 
(他の1人の利用者による、間の5版が非表示)
10行目: 10行目:
 
NSEventにNSEvent.AddGlobalMonitorForEventsMatchingMaskを叩いて監視対象のイベントの種類と発生時に呼ばれるイベントハンドラを設定するだけである。
 
NSEventにNSEvent.AddGlobalMonitorForEventsMatchingMaskを叩いて監視対象のイベントの種類と発生時に呼ばれるイベントハンドラを設定するだけである。
 
非常に簡単。
 
非常に簡単。
 +
 +
当初はNSEventMask.KeyDownで実装してみたが、これは文字キーの入力でしかイベントが発生せず、[[Shiftキー]]や[[Ctrlキー]]などを単品で押した場合には何も起こらない。
 +
実装中のアプリでは[[Ctrlキー]]単品を[[ショートカットキー]]としており上記ではダメであった。
 +
そこでNSEventMask.FlagsChangedに変えて実装してみたところ[[Ctrlキー]]単品でも上手くいった。
 +
 
<source lang="csharp">
 
<source lang="csharp">
 
         public override void DidFinishLaunching(NSNotification notification)
 
         public override void DidFinishLaunching(NSNotification notification)
33行目: 38行目:
  
 
===アプリを許可する===
 
===アプリを許可する===
Global Event Monitorは[[OS]]のあらゆるイベントを監視できるので[[スパイウェア]]や[[キーロガー]]などの非常に危ういアプリも簡単に作り放題となる。
+
Global Event Monitorは[[OS]]のあらゆるイベントを監視できるため、一歩間違えば[[スパイウェア]]や[[キーロガー]]などの非常に危ういアプリも簡単に作り放題となる。
そのため[[Mac OS X]]では[[システム環境設定]]から明示的にアプリを許可しないとGlobal Event Monitorは機能しないようになっている。
+
そのため[[Mac OS X]]では[[システム環境設定]]から明示的に許可したアプリでしかGlobal Event Monitorは機能しないようになっている。
 
#左上のリンゴマークをクリック
 
#左上のリンゴマークをクリック
 
#システム環境設定を開く
 
#システム環境設定を開く
43行目: 48行目:
 
#中央のプラスマークをクリックして許可するアプリを追加する
 
#中央のプラスマークをクリックして許可するアプリを追加する
  
なお、アクセシビリティの許可がされていない状態でGlobal Event Monitorを使用しているアプリを実行してもエラーも何も発生しない。
+
なお、このアクセシビリティの許可がされていない状態でGlobal Event Monitorを使用しているアプリを実行してもエラーも何も発生しない。
この挙動は確実に半年くらいしてどんな実装だったかを忘れたころにトラブルになり、[[エラー]]も出ないの[[でデバッグ]]も捗らず原因不明の[[バグ]]に悩まされ[[デスマーチ]]突入は決定的である。
+
この挙動は確実に半年くらいしてどんな実装だったかを忘れたころにトラブルになり、[[エラー]]も出ないので[[デバッグ]]も捗らず原因不明の[[バグ]]に悩まされ[[デスマーチ]]突入は決定的である。
そのためアプリ起動時にアクセシビリティの許可がされているかを確認し警告を出す方法を模索しているが、まだ解決方法は見つかっていない。
+
 
 +
これを回避するにはアプリ起動時にアクセシビリティの許可がされているかを確認し警告を出す必要がある。
 +
*[[Xamarin.Mac/アクセシビリティの許可の有無を取得する]]
  
 
==関連項目==
 
==関連項目==
 +
*[[Xamarin.Mac/アクセシビリティの許可の有無を取得する]]
 
*[[Xamarin.Mac/システム環境設定を開く]]
 
*[[Xamarin.Mac/システム環境設定を開く]]
 
*[[MonoMac/フルスクリーン表示に対応する]]
 
*[[MonoMac/フルスクリーン表示に対応する]]

2019年5月22日 (水) 05:14時点における最新版

概要[編集 | ソースを編集]

Xamarin.Macで開発している社内アプリで確実に動くファンクションキーを実現したい。

何も考えずに単純にキー入力を監視する実装にしたところ、一部で「キーを押しても動かない」という苦情が発生した。 原因は、ウインドウはひとつしか開いておらず、一見するとウインドウにフォーカスが当たっているように見えるが、実はデスクトップにフォーカスが当たっているという状況であった。 対策として、アプリ起動時に強制的にフルスクリーンにしてやろうかとも思ったがWindows 8並にスマートではないので、そのような状況でも動くファンクションキーの実装方法を模索している。

実装[編集 | ソースを編集]

アプリを開発する[編集 | ソースを編集]

NSEventにNSEvent.AddGlobalMonitorForEventsMatchingMaskを叩いて監視対象のイベントの種類と発生時に呼ばれるイベントハンドラを設定するだけである。 非常に簡単。

当初はNSEventMask.KeyDownで実装してみたが、これは文字キーの入力でしかイベントが発生せず、ShiftキーCtrlキーなどを単品で押した場合には何も起こらない。 実装中のアプリではCtrlキー単品をショートカットキーとしており上記ではダメであった。 そこでNSEventMask.FlagsChangedに変えて実装してみたところCtrlキー単品でも上手くいった。

        public override void DidFinishLaunching(NSNotification notification)
        {
            NSEvent.AddGlobalMonitorForEventsMatchingMask(NSEventMask.KeyDown, (theEvent) => {
                
                Console.WriteLine("keydown: " + theEvent.Characters);
            });

            NSEvent.AddGlobalMonitorForEventsMatchingMask(NSEventMask.FlagsChanged, (theEvent) => {
                var flags = theEvent.ModifierFlags & NSEventModifierMask.DeviceIndependentModifierFlagsMask;
                if (flags == 0)
                {
                    Console.WriteLine("release");
                }
                else
                {
                    Console.WriteLine("modifier: " + flags);
                }
             });
        }

アプリを許可する[編集 | ソースを編集]

Global Event MonitorはOSのあらゆるイベントを監視できるため、一歩間違えばスパイウェアキーロガーなどの非常に危ういアプリも簡単に作り放題となる。 そのためMac OS Xではシステム環境設定から明示的に許可したアプリでしかGlobal Event Monitorは機能しないようになっている。

  1. 左上のリンゴマークをクリック
  2. システム環境設定を開く
  3. セキュリティとプライバシーを開く
  4. プライバシーのタブを開く
  5. アクセシビリティを選ぶ
  6. 左下の鍵マークをクリックして認証する
  7. 中央のプラスマークをクリックして許可するアプリを追加する

なお、このアクセシビリティの許可がされていない状態でGlobal Event Monitorを使用しているアプリを実行してもエラーも何も発生しない。 この挙動は確実に半年くらいしてどんな実装だったかを忘れたころにトラブルになり、エラーも出ないのでデバッグも捗らず原因不明のバグに悩まされデスマーチ突入は決定的である。

これを回避するにはアプリ起動時にアクセシビリティの許可がされているかを確認し警告を出す必要がある。

関連項目[編集 | ソースを編集]

参考文献[編集 | ソースを編集]