MacアプリのNSMenuが変な場所に表示される
https://gyazo.com/0a8d8de6dade4316bd01eeea23b91117
Macアプリ でこちら↑のようなメニューを NSMenu で表示すると、なぜかボタンの位置ではなく、画面の左下に表示されてしまいました。 メニューが左下に表示されるときは、EventType が systemDefined になっていたため、 mouseLocation が取れずに、原点座標にメニューが表示されたようです。 なぜ、 NSEvent が systemDefined になっていたかというと、どうやら別スレッドを通していたからのようです。
ボタンをクリック→別スレッドでメニュー表示データを取得する処理を実行→メインスレッドでメニュー表示処理を呼び出す
という処理の流れなので、別スレッドで処理をしている間に、マウスクリックイベントが電子の海に流れていったのでしょう。
対応策
というわけで、対応策を考えてみました。
code: Swift
class ViewController: NSViewController {
private var lastEvent: NSEvent?
@IBAction func clickButton(_ sender: NSButton) {
lastEvent = NSApplication.shared.currentEvent
// メニューを表示するための前処理
}
func presentMenu() {
guard let event = lastEvent else {
return
}
let menu = NSMenu(title: "ボタンメニュー")
menu.delegate = self
NSMenu.popUpContextMenu(menu, with: event, for: menuButton)
}
}
extension ViewController: NSMenuDelegate {
func menuDidClose(_ menu: NSMenu) {
lastEvent = nil
}
}
ボタンをクリックしたときに、 NSEvent をインスタンス変数 lastEvent に保存します。
ベストプラクティスかはわかりませんが、いまのところは問題なく動いています。