私はメニュー項目のview
としてNSButton
秒で、あなたのようなテストプロジェクトを設定し、あなたが見たのと同じ動作を見ました。それは本当に面白いです。 NSApplication
をサブクラス化し、その-sendEvent:
メソッドをオーバーライドして、どのイベントがメカニズムを通過するかを見るためにログを追加すると、を実行してもが実際には呼び出されないことがわかります。それは奇妙じゃない?したがって、次に試すべきことはNSButton
をサブクラス化し、-mouseDown:
のオーバーライドを追加してそこにブレークポイントを配置することです。もちろん、開いているサブメニューではブレークポイントにヒットすることはありませんが、他のボタンではヒットします。我々はそれを行うときには、バックトレースは次のとおりです。
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000100002fa0 menutest`MyButton.mouseDown(event=0x0000608000121900, self=0x0000600000140a50) at AppDelegate.swift:33
frame #1: 0x000000010000303c menutest`@objc MyButton.mouseDown(with:) at AppDelegate.swift:0
frame #2: 0x00007fffa9f6724f AppKit`-[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 6341
frame #3: 0x00007fffa9f63a6c AppKit`-[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 1942
frame #4: 0x00007fffa9f62f0a AppKit`-[NSWindow(NSEventRouting) sendEvent:] + 541
frame #5: 0x00007fffa9a2328d AppKit`-[NSCarbonWindow sendEvent:] + 118
frame #6: 0x00007fffa9a20261 AppKit`NSMenuItemCarbonEventHandler + 10597
frame #7: 0x00007fffab0acd85 HIToolbox`DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1708
frame #8: 0x00007fffab0abff6 HIToolbox`SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 428
frame #9: 0x00007fffab0c1d14 HIToolbox`SendEventToEventTarget + 40
frame #10: 0x00007fffab0ea7df HIToolbox`ToolboxEventDispatcherHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 2503
frame #11: 0x00007fffab0ad17a HIToolbox`DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 2721
frame #12: 0x00007fffab0abff6 HIToolbox`SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 428
frame #13: 0x00007fffab0c1d14 HIToolbox`SendEventToEventTarget + 40
frame #14: 0x00007fffab12e928 HIToolbox`IsUserStillTracking(MenuSelectData*, unsigned char*) + 1658
frame #15: 0x00007fffab255dc4 HIToolbox`TrackMenuCommon(MenuSelectData&, unsigned char*, SelectionData*, MenuResult*, MenuResult*) + 1664
frame #16: 0x00007fffab13a223 HIToolbox`MenuSelectCore(MenuData*, Point, double, unsigned int, OpaqueMenuRef**, unsigned short*) + 554
frame #17: 0x00007fffab139f66 HIToolbox`_HandleMenuSelection2 + 460
frame #18: 0x00007fffa97ee368 AppKit`_NSHandleCarbonMenuEvent + 239
frame #19: 0x00007fffa9a68702 AppKit`_DPSEventHandledByCarbon + 54
frame #20: 0x00007fffa9de90c5 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 963
frame #21: 0x00007fffa96623db AppKit`-[NSApplication run] + 926
frame #22: 0x00007fffa962ce0e AppKit`NSApplicationMain + 1237
frame #23: 0x00000001000035fd menutest`main at AppDelegate.swift:13
frame #24: 0x00007fffc12fc235 libdyld.dylib`start + 1
あなたが見ることができるようにメニューが実際に炭素であるため、イベントはココアイベントディスパッチ機構を介して派遣されていません。そうですが、64ビットへの移行で削除されたと思われるCarbon APIやサブシステムの多くは、実際にはまだ生き残っています。彼らはただのプライベートAPIです。 は、これらを64ビットモードで使用することはできませんが、Appleが可能で、メニューシステム全体がまだCarbonイベントモデルの上に実装されています。サードパーティの開発者はPhotoshopを一から書き直す必要はありますが、誰かが1997年に書いたそのメニュー処理コードは、あきらめるだけの価値があります。私は確信しています。
とにかく、このバックトレース(最上位レベルのもの以外)でもっとも初期のObjective-Cメソッドである-[NSCarbonWindow sendEvent:]
を振りかざすことによって少しテストを行い、サブメニューアイテムがクリックされたときにそれはそうではありません。だから私が推測しなければならないのは、Carbonイベントハンドラに問題があると言えます。さて、これは後端の痛みのビットかもしれないが、ちょっと、問題はない!これを回避するには、Carbonレベルに落として、独自のCarbonイベントハンドラをインストールします。いいえ、あなたの袖を巻いてみましょう。th-
ああ、右。
これらのAPIを64ビットモードで使用することはできません。
とにかく、私は悲しいことに、これは将来の破損をthis guy didようになりました民間のAPIが何であるかを使用するように厄介なハックを使用して危険にさらすの短い仕事に取得する方法があるように起こっているとは思わない(言うまでもありませんApp StoreからInstabannedされている)。または何かをやって実際にバックトレースでそれらのCの機能のうちの1つをモンスキッペンドしているように狂っている可能性がさらに悪化する可能性があります。しかし、この全体の問題は、レーダーの報告に値すると思われる。 file one with Appleをお知らせして、この問題について知らせてください。将来のリリースで修正されるかもしれません。
編集:実際には解決策があります。サブメニューを持たないメニュー項目に添付されたビューは、期待するマウスイベントを受け取るので、submenu
の設定を無視して、自分のビューにmouseEntered:
イベントとmouseExited:
イベントをキャッチして自分でメニューを表示するだけで、サブメニュー。世界で最も理想的なソリューションではありませんが、それは少なくとも何かです。
メニュー項目を追加するときにコードを投稿できますか?あなたの写真から、メニュー項目をカスタム表示にするのではなく、メニュー項目に(上に)表示を追加するように見えます。これは面白い質問のようです。 – Farini