From 1e158e522f05d8676ebb5eee94ae5d03081e20f0 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Sat, 11 Oct 2025 11:08:20 +0800 Subject: [PATCH 2/4] gui/minimal_macosx/intf.m --- modules/gui/minimal_macosx/intf.m | 130 ++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 44 deletions(-) diff --git modules/gui/minimal_macosx/intf.m modules/gui/minimal_macosx/intf.m index a778e3bc56..b476fd0c02 100644 --- modules/gui/minimal_macosx/intf.m +++ modules/gui/minimal_macosx/intf.m @@ -81,58 +81,105 @@ extern OSErr CPSGetCurrentProcess(CPSProcessSerNum *psn); extern OSErr CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); extern OSErr CPSSetFrontProcess(CPSProcessSerNum *psn); - /***************************************************************************** * Run: main loop *****************************************************************************/ static void Run(intf_thread_t *p_intf) { CPSProcessSerNum PSN; - @autoreleasepool { - [NSApplication sharedApplication]; - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [NSApplication sharedApplication]; - } + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + [NSApplication sharedApplication]; + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [NSApplication sharedApplication]; + [pool release]; } /***************************************************************************** * Vout window management *****************************************************************************/ + static int WindowControl(vout_window_t *, int i_query, va_list); +struct minimal_window_create_ctx { + VLCMinimalVoutWindow **window_ptr; + NSRect rect; +}; + +static void minimal_create_window(void *context) +{ + struct minimal_window_create_ctx *ctx = (struct minimal_window_create_ctx *)context; + *(ctx->window_ptr) = [[VLCMinimalVoutWindow alloc] initWithContentRect:ctx->rect]; + if (*(ctx->window_ptr)) + [*(ctx->window_ptr) makeKeyAndOrderFront:nil]; +} + int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg) { if (cfg->type != VOUT_WINDOW_TYPE_INVALID && cfg->type != VOUT_WINDOW_TYPE_NSOBJECT) return VLC_EGENERIC; - @autoreleasepool { - NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height); + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition]; - [o_window makeKeyAndOrderFront:nil]; + NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height); + VLCMinimalVoutWindow *o_window = nil; - if (!o_window) { - msg_Err(p_wnd, "window creation failed"); - return VLC_EGENERIC; - } + struct minimal_window_create_ctx ctx = { &o_window, proposedVideoViewPosition }; + dispatch_sync_f(dispatch_get_main_queue(), &ctx, minimal_create_window); - msg_Dbg(p_wnd, "returning video window with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height); - p_wnd->handle.nsobject = (void *)CFBridgingRetain([o_window contentView]); - - p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT; - p_wnd->control = WindowControl; + if (!o_window) { + msg_Err(p_wnd, "window creation failed"); + [pool release]; + return VLC_EGENERIC; } + msg_Dbg(p_wnd, "returning video window with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height); + + p_wnd->handle.nsobject = (void *)[o_window contentView]; + + p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT; + p_wnd->control = WindowControl; + + [pool release]; vout_window_SetFullScreen(p_wnd, cfg->is_fullscreen); return VLC_SUCCESS; } +struct minimal_size_ctx { + NSWindow *window; + unsigned int width; + unsigned int height; +}; + +static void minimal_set_size(void *context) +{ + struct minimal_size_ctx *ctx = (struct minimal_size_ctx *)context; + NSRect theFrame = [ctx->window frame]; + theFrame.size.width = ctx->width; + theFrame.size.height = ctx->height; + [ctx->window setFrame:theFrame display:YES animate:YES]; +} + +struct minimal_fullscreen_ctx { + NSWindow *window; + int is_fullscreen; +}; + +static void minimal_set_fullscreen(void *context) +{ + struct minimal_fullscreen_ctx *ctx = (struct minimal_fullscreen_ctx *)context; + if (ctx->is_fullscreen) + [(VLCMinimalVoutWindow*)ctx->window enterFullscreen]; + else + [(VLCMinimalVoutWindow*)ctx->window leaveFullscreen]; +} + static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args) { - NSWindow* o_window = [(__bridge id)p_wnd->handle.nsobject window]; + NSView *view = (NSView*)p_wnd->handle.nsobject; + NSWindow* o_window = [view window]; if (!o_window) { msg_Err(p_wnd, "failed to recover cocoa window"); return VLC_EGENERIC; @@ -142,36 +189,29 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args) case VOUT_WINDOW_SET_STATE: { unsigned i_state = va_arg(args, unsigned); - [o_window setLevel:i_state]; - return VLC_SUCCESS; } case VOUT_WINDOW_SET_SIZE: { unsigned int i_width = va_arg(args, unsigned int); unsigned int i_height = va_arg(args, unsigned int); - @autoreleasepool { - dispatch_sync(dispatch_get_main_queue(), ^{ - NSRect theFrame = [o_window frame]; - theFrame.size.width = i_width; - theFrame.size.height = i_height; - [o_window setFrame:theFrame display:YES animate:YES]; - }); - } + + struct minimal_size_ctx ctx; + ctx.window = o_window; + ctx.width = i_width; + ctx.height = i_height; + dispatch_sync_f(dispatch_get_main_queue(), &ctx, minimal_set_size); return VLC_SUCCESS; } case VOUT_WINDOW_SET_FULLSCREEN: { int i_full = va_arg(args, int); - @autoreleasepool { - dispatch_sync(dispatch_get_main_queue(), ^{ - if (i_full) - [(VLCMinimalVoutWindow*)o_window enterFullscreen]; - else - [(VLCMinimalVoutWindow*)o_window leaveFullscreen]; - }); - } + + struct minimal_fullscreen_ctx ctx; + ctx.window = o_window; + ctx.is_fullscreen = i_full; + dispatch_sync_f(dispatch_get_main_queue(), &ctx, minimal_set_fullscreen); return VLC_SUCCESS; } default: @@ -182,9 +222,11 @@ static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args) void WindowClose(vout_window_t *p_wnd) { - @autoreleasepool { - NSWindow * o_window = [(__bridge id)p_wnd->handle.nsobject window]; - if (o_window) - o_window = nil; + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSView *view = (NSView*)p_wnd->handle.nsobject; + NSWindow *o_window = [view window]; + if (o_window) { + [o_window orderOut:nil]; } + [pool release]; } -- 2.51.0