🤖
枠なし NSWindow でトラックパッドのジェスチャの通知を受け取る
TL;DR
NSWindow
を使って作った枠なしのウインドウでトラックパッドのジェスチャの通知を受け取りたければ、NSWindow
クラスの canBecomeKeyWindow
メソッドをオーバーライドして、YES
を返すようにした上で、そのウインドウをアクティブにすると良いっぽい。
本編
通常、NSWindow
を利用して作ったウインドウでは、そのウインドウの delegate のクラスで magnifyWithEvent
や rotateWithEvent
や swipeWithEvent
を実装することで、例えば二本指での拡大縮小や回転などの、トラックパッド上でジェスチャが行われたという情報を受け取ることができます。
main.m
#import <AppKit/AppKit.h>
@interface AppDelegate : NSObject<NSApplicationDelegate>
@end
@interface Window : NSWindow
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
static Window *window;
window = [[Window alloc]
initWithContentRect:NSMakeRect(0, 0, 400, 200)
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable
backing:NSBackingStoreBuffered
defer:NO];
[window setTitle:@"test window"];
[window orderFront:window];
[window center];
}
@end
@implementation Window
-(void)scrollWheel:(NSEvent *)event { // ウインドウ上でスクロールしたら呼ばれる
NSLog(@"scrollWheel");
}
-(void)magnifyWithEvent:(NSEvent *)event { // ウインドウ上でピンチズームをしたら呼ばれる
NSLog(@"magnifyWithEvent");
}
@end
int main(void) {
[NSApplication sharedApplication];
[NSApp setDelegate:[[AppDelegate alloc] init]];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
}
ただ、ここで以下のようにウインドウを枠なし(タイトルバーなし?)にすると、scrollWheel
関数は依然呼び出されるもののなぜか magnifyWithEvent
関数が呼ばれなくなります。
diff --git a/main.m b/main.m
index b9419b7..8b8fd09 100644
--- a/main.m
+++ b/main.m
@@ -11,7 +11,7 @@
static Window *window;
window = [[Window alloc]
initWithContentRect:NSMakeRect(0, 0, 400, 200)
- styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable
+ styleMask:NSWindowStyleMaskBorderless
backing:NSBackingStoreBuffered
defer:NO];
[window setTitle:@"test window"];
詳しいことはよくわからないのですが、調べてみた感じだとどうやら magnifyWithEvent
等のトラックパッドジェスチャの通知はウインドウがキーウインドウで、かつアクティブな時のみしか飛んでこないようです。
以下のように canBecomeKeyWindow
メソッドを YES
を返すようにオーバーライドすると、再度 magnifyWithEvent
が呼ばれるようになりました。
diff --git a/main.m b/main.m
index 8b8fd09..99aa31a 100644
--- a/main.m
+++ b/main.m
@@ -27,6 +27,9 @@
-(void)magnifyWithEvent:(NSEvent *)event {
NSLog(@"magnifyWithEvent");
}
+-(BOOL)canBecomeKeyWindow {
+ return YES;
+}
@end
int main(void) {
まとめ
NSWindow
クラスの canBecomeKeyWindow
メソッドが YES
を返すようにオーバーライドすることで、枠なしのウインドウでもトラックパッドのジェスチャが行われた時に通知が飛んでくるようになります。
Cocoa ド素人なので、もしいろいろ変なことを書いてたらすみません。
Discussion