| | |
| | | |
| | | /* |
| | | #cgo CFLAGS: -x objective-c |
| | | #cgo LDFLAGS: -framework Cocoa |
| | | #cgo LDFLAGS: -framework Cocoa -framework ApplicationServices |
| | | #import <Cocoa/Cocoa.h> |
| | | #import <ApplicationServices/ApplicationServices.h> |
| | | #include <dispatch/dispatch.h> |
| | | #include <string.h> |
| | | |
| | |
| | | |
| | | @end |
| | | |
| | | // ---- Custom NSWindow for drag tracking ---- |
| | | @interface VoiceSnapOverlayWindow : NSWindow { |
| | | // ---- Custom NSPanel for drag tracking ---- |
| | | @interface VoiceSnapOverlayWindow : NSPanel { |
| | | NSPoint _dragStartOrigin; |
| | | } |
| | | @end |
| | |
| | | } |
| | | |
| | | - (BOOL)canBecomeKeyWindow { return NO; } |
| | | - (BOOL)canBecomeMainWindow { return NO; } |
| | | |
| | | @end |
| | | |
| | |
| | | static NSWindow* g_window = nil; |
| | | static VoiceSnapOverlayView* g_view = nil; |
| | | static NSTimer* g_timer = nil; |
| | | |
| | | static void applyOverlayWindowPolicy(NSWindow* window) { |
| | | if (!window) return; |
| | | [window setLevel:CGWindowLevelForKey(kCGStatusWindowLevelKey)]; |
| | | [window setCollectionBehavior: |
| | | NSWindowCollectionBehaviorCanJoinAllSpaces | |
| | | NSWindowCollectionBehaviorStationary | |
| | | NSWindowCollectionBehaviorFullScreenAuxiliary | |
| | | NSWindowCollectionBehaviorTransient | |
| | | NSWindowCollectionBehaviorIgnoresCycle]; |
| | | [window setCanHide:NO]; |
| | | if ([window isKindOfClass:[NSPanel class]]) { |
| | | [(NSPanel*)window setHidesOnDeactivate:NO]; |
| | | } |
| | | } |
| | | |
| | | static void animateBars(void) { |
| | | g_state.animTime += 0.033f; |
| | |
| | | } |
| | | |
| | | if (g_state.fadeTarget > 0 && ![g_window isVisible]) { |
| | | applyOverlayWindowPolicy(g_window); |
| | | [g_window orderFrontRegardless]; |
| | | } |
| | | |
| | |
| | | |
| | | VoiceSnapOverlayWindow* window = [[VoiceSnapOverlayWindow alloc] |
| | | initWithContentRect:NSMakeRect(0, 0, CAP_W, CAP_H) |
| | | styleMask:NSWindowStyleMaskBorderless |
| | | styleMask:NSWindowStyleMaskBorderless | NSWindowStyleMaskNonactivatingPanel |
| | | backing:NSBackingStoreBuffered |
| | | defer:NO]; |
| | | |
| | | [window setOpaque:NO]; |
| | | [window setBackgroundColor:[NSColor clearColor]]; |
| | | [window setLevel:NSFloatingWindowLevel]; |
| | | [window setCollectionBehavior: |
| | | NSWindowCollectionBehaviorCanJoinAllSpaces | |
| | | NSWindowCollectionBehaviorStationary | |
| | | NSWindowCollectionBehaviorFullScreenAuxiliary]; |
| | | applyOverlayWindowPolicy(window); |
| | | [window setIgnoresMouseEvents:NO]; |
| | | [window setMovableByWindowBackground:YES]; |
| | | [window setHasShadow:NO]; |
| | |
| | | g_state.hasPosition = 1; |
| | | } |
| | | |
| | | static void doBringOverlayForward(void* ctx) { |
| | | (void)ctx; |
| | | if (!g_window) return; |
| | | applyOverlayWindowPolicy(g_window); |
| | | [g_window orderFrontRegardless]; |
| | | } |
| | | |
| | | static void overlayShow(void) { |
| | | g_state.fadeTarget = 1.0f; |
| | | if (!g_state.hasPosition) { |
| | | dispatch_async_f(dispatch_get_main_queue(), NULL, doAutoPosition); |
| | | } |
| | | dispatch_async_f(dispatch_get_main_queue(), NULL, doBringOverlayForward); |
| | | } |
| | | |
| | | static void overlayHide(void) { |