[vlc-commits] [Git][videolan/vlc][master] 3 commits: macosx: update Xcode project to recommended settings
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Wed Dec 8 14:58:51 UTC 2021
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
18cd6b6a by Marvin Scholz at 2021-12-08T14:43:31+00:00
macosx: update Xcode project to recommended settings
Makes new versions of Xcode happy.
- - - - -
d7cf9a8d by Marvin Scholz at 2021-12-08T14:43:31+00:00
vout: macosx: add standalone window provider
Initial version of a standalone vout window provider for macOS,
it still lacks mouse handling and only works if the macosx inteface
module was loaded (or NSApp was initialized by other means).
- - - - -
c8797d1a by Marvin Scholz at 2021-12-08T14:43:31+00:00
macosx: add standalone vout window to Xcode project
- - - - -
3 changed files:
- extras/package/macosx/VLC.xcodeproj/project.pbxproj
- modules/video_output/Makefile.am
- + modules/video_output/window_macosx.m
Changes:
=====================================
extras/package/macosx/VLC.xcodeproj/project.pbxproj
=====================================
@@ -80,6 +80,7 @@
6B0292E61F43256300A50082 /* VLCBottomBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0292E51F43256300A50082 /* VLCBottomBarView.m */; };
6B0AB0F01F1AC8B3003A1B4E /* VLCSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0AB0ED1F1AC8B3003A1B4E /* VLCSlider.m */; };
6B0AB0F11F1AC8B3003A1B4E /* VLCSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B0AB0EF1F1AC8B3003A1B4E /* VLCSliderCell.m */; };
+ 6B196852265E974400870512 /* window_macosx.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B19684F265E928A00870512 /* window_macosx.m */; };
6B2EFC601F2819F700F3C0EA /* VLCVolumeSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B2EFC5F1F2819F700F3C0EA /* VLCVolumeSlider.m */; };
6B2EFC631F281A0900F3C0EA /* VLCVolumeSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B2EFC621F281A0900F3C0EA /* VLCVolumeSliderCell.m */; };
6B397C4F216C8EB200403ED0 /* NSString+Helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B397C4E216C8EB200403ED0 /* NSString+Helpers.m */; };
@@ -231,6 +232,7 @@
6B0AB0EF1F1AC8B3003A1B4E /* VLCSliderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCSliderCell.m; sourceTree = "<group>"; };
6B13E2A61BC67678001AD24A /* VLCScrollingClipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCScrollingClipView.h; sourceTree = "<group>"; };
6B13E2A71BC67678001AD24A /* VLCScrollingClipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCScrollingClipView.m; sourceTree = "<group>"; };
+ 6B19684F265E928A00870512 /* window_macosx.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = window_macosx.m; path = ../../../modules/video_output/window_macosx.m; sourceTree = "<group>"; };
6B2EFC5E1F2819F700F3C0EA /* VLCVolumeSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCVolumeSlider.h; sourceTree = "<group>"; };
6B2EFC5F1F2819F700F3C0EA /* VLCVolumeSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCVolumeSlider.m; sourceTree = "<group>"; };
6B2EFC611F281A0900F3C0EA /* VLCVolumeSliderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCVolumeSliderCell.h; sourceTree = "<group>"; };
@@ -1534,6 +1536,7 @@
CCDDF1AE172FF4CE007729A1 /* vout */ = {
isa = PBXGroup;
children = (
+ 6B19684F265E928A00870512 /* window_macosx.m */,
CCDBA3B313D32E200006127B /* macosx.m */,
7DBB06631CC2314D004C74D2 /* caopengllayer.m */,
);
@@ -1645,7 +1648,7 @@
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1150;
+ LastUpgradeCheck = 1240;
TargetAttributes = {
1CCB5F2E1A62A6A5004C3E90 = {
CreatedOnToolsVersion = 6.1.1;
@@ -1835,6 +1838,7 @@
files = (
7D903EA92243921000917358 /* darwinvlc.m in Sources */,
7D903EB6224394BE00917358 /* specific.c in Sources */,
+ 6B196852265E974400870512 /* window_macosx.m in Sources */,
7D903E0E22438F8F00917358 /* error.c in Sources */,
7D903E2222438F8F00917358 /* dirs.m in Sources */,
7D903E4D22438F8F00917358 /* netconf.m in Sources */,
@@ -2092,6 +2096,7 @@
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -2146,6 +2151,7 @@
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -2198,6 +2204,7 @@
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
=====================================
modules/video_output/Makefile.am
=====================================
@@ -50,6 +50,12 @@ endif
if HAVE_OSX
+libwindow_macosx_plugin_la_SOURCES = video_output/window_macosx.m
+libwindow_macosx_plugin_la_LDFLAGS = $(AM_LDFLAGS) \
+ -Wl,-framework,Cocoa
+libwindow_macosx_plugin_la_OBJCFLAGS = $(AM_OBJCFLAGS) \
+ -fobjc-arc -fobjc-exceptions
+
libvout_macosx_plugin_la_SOURCES = video_output/macosx.m \
$(OPENGL_VOUT_COMMONSOURCES)
libvout_macosx_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAVE_GL_CORE_SYMBOLS
@@ -64,7 +70,7 @@ libcaopengllayer_plugin_la_LIBADD = libvlc_opengl.la
libcaopengllayer_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \
-Wl,-framework,OpenGL,-framework,Cocoa,-framework,QuartzCore
-vout_LTLIBRARIES += libvout_macosx_plugin.la libcaopengllayer_plugin.la
+vout_LTLIBRARIES += libvout_macosx_plugin.la libcaopengllayer_plugin.la libwindow_macosx_plugin.la
endif
libvout_ios_plugin_la_SOURCES = video_output/opengl/display.c $(OPENGL_VOUT_COMMONSOURCES)
=====================================
modules/video_output/window_macosx.m
=====================================
@@ -0,0 +1,590 @@
+/**
+ * @file window_macosx.m
+ * @brief macOS Window and View output provider
+ */
+
+/* Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * Authors: Marvin Scholz <epirat 07 at gmail dot com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#import <Cocoa/Cocoa.h>
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout_window.h>
+
+#define VLC_ASSERT_MAINTHREAD NSAssert([[NSThread currentThread] isMainThread], \
+ @"Must be called from the main thread!")
+
+/**
+ * Style mask for a decorated window
+ */
+static const NSWindowStyleMask decoratedWindowStyleMask =
+ NSWindowStyleMaskTitled
+ | NSWindowStyleMaskClosable
+ | NSWindowStyleMaskMiniaturizable
+ | NSWindowStyleMaskResizable;
+
+/**
+ * Style mask for a non-decorated window
+ */
+static const NSWindowStyleMask undecoratedWindowStyleMask =
+ NSWindowStyleMaskBorderless
+ | NSWindowStyleMaskResizable;
+
+
+#pragma mark -
+#pragma mark Obj-C Interfaces
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * Window delegate and Core interactions class
+ *
+ * Acts as delegate for the Window and handles communication
+ * of the window state from/to the core. This is not done directly
+ * in the window controller, as the module on VLCs side might be
+ * already gone when the window and its controller is still around
+ * so we need a separate object that we can invalidate as soon
+ * as the VLC module object is gone.
+ */
+ at interface VLCVideoWindowModuleDelegate : NSObject {
+ @private
+ // VLC window object, only use it on the eventQueue
+ vout_window_t* vlc_vout_window;
+ dispatch_queue_t eventQueue;
+
+ BOOL _isViewSet;
+}
+
+- (instancetype)initWithVLCVoutWindow:(vout_window_t *)vout_window;
+
+/// Reports that the window is fullscreen now
+- (void)reportFullscreen;
+
+/// Reports that the previously fullscreen window is no longer fullscreen
+- (void)reportWindowed;
+
+/// Reports the new window size in pixels
+- (void)reportSizeChanged:(NSSize)newSize;
+
+/// Reports that the window was closed
+- (void)reportClose;
+
+ at end
+
+/**
+ * Video output window class
+ *
+ * Custom NSWindow subclass, mostly to overwrite that the window
+ * can become the key window even if its using the borderless
+ * (undecorated) style.
+ */
+ at interface VLCVideoWindow : NSWindow
+ at end
+
+
+/**
+ * Video view class
+ *
+ * Custom NSWindow subclass, used to track resizes so that
+ * the core can be notified about the new sizes in a timely manner.
+ */
+ at interface VLCVideoWindowContentView : NSView {
+ @private
+ __weak VLCVideoWindowModuleDelegate *_moduleDelegate;
+}
+
+- (instancetype)initWithModuleDelegate:(VLCVideoWindowModuleDelegate *)delegate;
+ at end
+
+/**
+ * Video output window controller class
+ *
+ * Controller for the VLC standalone video window (independent of the interface)
+ *
+ * Implements all interactions between the display module and the NSWindow
+ * class, except for resizes (which is handled by VLCVideoWindowContentView).
+ */
+ at interface VLCVideoStandaloneWindowController : NSWindowController <NSWindowDelegate> {
+ at private
+ __weak VLCVideoWindowModuleDelegate *_moduleDelegate;
+}
+
+- (instancetype)initWithModuleDelegate:(VLCVideoWindowModuleDelegate *)delegate;
+- (void)showWindowWithConfig:(const vout_window_cfg_t *restrict)config;
+
+/* Methods called by the callbacks to change properties of the Window */
+- (void)setWindowDecorated:(BOOL)decorated;
+- (void)setWindowFullscreen:(BOOL)fullscreen;
+
+ at end
+
+
+#pragma mark -
+#pragma mark Obj-C Implementations
+
+ at implementation VLCVideoWindowModuleDelegate : NSObject
+
+- (instancetype)initWithVLCVoutWindow:(vout_window_t *)vout_window
+{
+ NSAssert(vout_window != NULL,
+ @"VLCVideoWindowDelegate must be initialized with a valid vout_window");
+
+ self = [super init];
+ if (self) {
+ eventQueue = dispatch_queue_create("org.videolan.vlc.vout", DISPATCH_QUEUE_SERIAL);
+
+ vlc_vout_window = vout_window;
+ }
+
+ return self;
+}
+
+- (void)enqueueEventBlock:(void (^)(void))block
+{
+ dispatch_async(eventQueue, block);
+}
+
+- (void)setViewObject:(id)view
+{
+ NSAssert(_isViewSet == NO,
+ @"VLCVideoWindowDelegate's viewObject must only bet set once");
+ vlc_vout_window->type = VOUT_WINDOW_TYPE_NSOBJECT;
+ vlc_vout_window->handle.nsobject = (__bridge void*)view;
+}
+
+- (void)reportFullscreen
+{
+ [self enqueueEventBlock:^void (void) {
+ vout_window_ReportFullscreen(vlc_vout_window, NULL);
+ }];
+}
+
+- (void)reportWindowed
+{
+ [self enqueueEventBlock:^void (void) {
+ vout_window_ReportWindowed(vlc_vout_window);
+ }];
+}
+
+- (void)reportSizeChanged:(NSSize)newSize
+{
+ [self enqueueEventBlock:^void (void) {
+ vout_window_ReportSize(vlc_vout_window,
+ (unsigned int)newSize.width,
+ (unsigned int)newSize.height);
+ }];
+}
+
+- (void)reportClose
+{
+ [self enqueueEventBlock:^void (void) {
+ vout_window_ReportClose(vlc_vout_window);
+ }];
+}
+
+- (void)dealloc
+{
+ dispatch_sync(eventQueue, ^void (void) {
+ self->vlc_vout_window = NULL;
+ });
+}
+
+ at end
+
+
+ at implementation VLCVideoStandaloneWindowController
+
+/**
+ * Initializes the window controller with the given module delegate
+ */
+- (instancetype)initWithModuleDelegate:(VLCVideoWindowModuleDelegate *)delegate;
+{
+ VLC_ASSERT_MAINTHREAD;
+
+ NSWindow *window = [[NSWindow alloc] initWithContentRect:NSZeroRect
+ styleMask:decoratedWindowStyleMask
+ backing:NSBackingStoreBuffered
+ defer:YES];
+
+ self = [super initWithWindow:window];
+ if (self) {
+ // Set the initial vout title
+ [window setTitle:[NSString stringWithUTF8String:VOUT_TITLE " (VLC Video Output)"]];
+
+ // The content always changes during live resize
+ [window setPreservesContentDuringLiveResize:NO];
+
+ // Do not release on close (we might want to re-open the window later)
+ [window setReleasedWhenClosed:NO];
+
+ // Hint that the window should become a primary fullscreen window
+ [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+
+ // Create and set custom content view for the window
+ VLCVideoWindowContentView *view =
+ [[VLCVideoWindowContentView alloc] initWithModuleDelegate:delegate];
+
+ if (view == nil)
+ return nil;
+
+ [window setContentView:view];
+
+ [window setDelegate:self];
+
+ // Position the window in the center
+ [window center];
+
+ [self setWindowFrameAutosaveName:@"VLCVideoStandaloneWindow"];
+
+ _moduleDelegate = delegate;
+
+ [_moduleDelegate setViewObject:view];
+ }
+
+ return self;
+}
+
+/**
+ * Applies the given config to the window and shows it.
+ */
+- (void)showWindowWithConfig:(const vout_window_cfg_t *restrict)config
+{
+ VLC_ASSERT_MAINTHREAD;
+
+ // Convert from backing to window coordinates
+ NSRect backingRect = NSMakeRect(0, 0, config->width, config->height);
+ NSRect windowRect = [self.window convertRectFromBacking:backingRect];
+ [self.window setContentSize:windowRect.size];
+
+ // Set decoration
+ [self setWindowDecorated:config->is_decorated];
+
+ // This should always be called last, to ensure we only show the
+ // window once its fully configured. Else there could be visible
+ // changes or animations when the config is applied.
+ [self showWindow:nil];
+ [self.window makeKeyAndOrderFront:nil];
+}
+
+- (BOOL)windowShouldClose:(NSWindow *)sender
+{
+ [_moduleDelegate reportClose];
+ return YES;
+}
+
+#pragma mark Helper methods
+
+- (BOOL)isWindowFullscreen
+{
+ return ((self.window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask);
+}
+
+#pragma mark Module interactions
+
+- (void)setWindowDecorated:(BOOL)decorated
+{
+ NSWindowStyleMask mask =
+ (decorated) ? decoratedWindowStyleMask : undecoratedWindowStyleMask;
+
+ [self.window setStyleMask:mask];
+}
+
+- (void)setWindowFullscreen:(BOOL)fullscreen
+{
+ if (!!fullscreen == !![self isWindowFullscreen]) {
+ // Nothing to do, just report the state to core
+ if (fullscreen) {
+ [_moduleDelegate reportFullscreen];
+ } else {
+ [_moduleDelegate reportWindowed];
+ }
+ return;
+ }
+
+ [self.window toggleFullScreen:nil];
+}
+
+#pragma mark Window delegate
+
+- (void)windowDidEnterFullScreen:(NSNotification *)notification
+{
+ [_moduleDelegate reportFullscreen];
+}
+
+- (void)windowDidExitFullScreen:(NSNotification *)notification
+{
+ [_moduleDelegate reportWindowed];
+}
+
+ at end
+
+
+
+ at implementation VLCVideoWindowContentView
+
+- (instancetype)initWithModuleDelegate:(VLCVideoWindowModuleDelegate *)delegate;
+{
+ self = [super init];
+ if (self) {
+ NSAssert(delegate != nil, @"Invalid VLCVideoWindowModuleDelegate passed.");
+ _moduleDelegate = delegate;
+ }
+ return self;
+}
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ [[NSColor blackColor] setFill];
+ NSRectFill(dirtyRect);
+}
+
+/**
+ * Report the view size in the backing size dimensions to VLC core
+ */
+- (void)reportBackingSize
+{
+ NSRect bounds = [self convertRectToBacking:self.bounds];
+ [_moduleDelegate reportSizeChanged:bounds.size];
+}
+
+/**
+ * Handle view size changes
+ */
+- (void)resizeSubviewsWithOldSize:(NSSize)oldSize
+{
+ [self reportBackingSize];
+ [super resizeSubviewsWithOldSize:oldSize];
+}
+
+/**
+ * Handle view backing property changes
+ */
+- (void)viewDidChangeBackingProperties
+{
+ // When the view backing size changes, it means the view effectively
+ // resizes from VLC core perspective, as it operates on the real
+ // backing dimensions, not the view point size.
+ [self reportBackingSize];
+ [super viewDidChangeBackingProperties];
+}
+
+ at end
+
+ at implementation VLCVideoWindow
+
+- (BOOL)canBecomeKeyWindow
+{
+ // A window with NSWindowStyleMaskBorderless can usually not become key
+ // window, unless we return YES here.
+ return YES;
+}
+
+ at end
+
+NS_ASSUME_NONNULL_END
+
+
+#pragma mark -
+#pragma mark VLC module
+
+typedef struct
+{
+ VLCVideoStandaloneWindowController *windowController;
+ VLCVideoWindowModuleDelegate *delegate;
+} vout_window_sys_t;
+
+/* Enable Window
+ */
+static int WindowEnable(vout_window_t *wnd, const vout_window_cfg_t *restrict cfg)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [weakWc showWindowWithConfig:cfg];
+ });
+ }
+
+ return VLC_SUCCESS;
+}
+
+/* Request to close the window */
+static void WindowDisable(vout_window_t *wnd)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakWc close];
+ });
+ }
+}
+
+/* Request to resize the window */
+static void WindowResize(vout_window_t *wnd, unsigned width, unsigned height)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ VLCVideoStandaloneWindowController *wc = weakWc;
+ // Convert from backing to window coordinates
+ NSRect backingRect = NSMakeRect(0, 0, width, height);
+ NSRect windowRect = [wc.window convertRectFromBacking:backingRect];
+ [wc.window setContentSize:windowRect.size];
+
+ // Size is reported by resizeSubviewsWithOldSize:, do not
+ // report it here, else it would get reported twice.
+ });
+ }
+}
+
+/* Request to enable/disable Window decorations */
+static void SetDecoration(vout_window_t *wnd, bool decorated)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakWc setWindowDecorated:decorated];
+ });
+ }
+}
+
+/* Request to enter fullscreen */
+static void WindowSetFullscreen(vout_window_t *wnd, const char *idstr)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakWc setWindowFullscreen:YES];
+ });
+ }
+}
+
+/* Request to exit fullscreen */
+static void WindowUnsetFullscreen(vout_window_t *wnd)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakWc setWindowFullscreen:NO];
+ });
+ }
+}
+
+static void WindowSetTitle(struct vout_window_t *wnd, const char *title)
+{
+ vout_window_sys_t *sys = wnd->sys;
+ @autoreleasepool {
+ __weak VLCVideoStandaloneWindowController *weakWc = sys->windowController;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakWc.window setTitle:[NSString stringWithUTF8String:title]];
+ });
+ }
+}
+
+/*
+ * Module destruction
+ */
+void Close(vout_window_t *wnd)
+{
+ vout_window_sys_t *sys = wnd->sys;
+
+ // ARC can not know when to release an object in a heap-allocated
+ // struct, so we need to explicitly set it to nil here.
+ sys->windowController = nil;
+ sys->delegate = nil;
+}
+
+/*
+ * Callbacks
+ */
+static const struct vout_window_operations ops = {
+ .enable = WindowEnable,
+ .disable = WindowDisable,
+ .resize = WindowResize,
+ .set_state = NULL,
+ .unset_fullscreen = WindowUnsetFullscreen,
+ .set_fullscreen = WindowSetFullscreen,
+ .set_title = WindowSetTitle,
+ .destroy = Close,
+};
+
+/*
+ * Module initialization
+ */
+int Open(vout_window_t *wnd)
+{
+ @autoreleasepool {
+ msg_Info(wnd, "using the macOS new video output window module");
+
+ // Check if there is an NSApplication, needed for the connection
+ // to the Window Server so we can use NSWindows, NSViews, etc.
+ if (NSApp == nil) {
+ msg_Err(wnd, "cannot create video output window without NSApplication");
+ return VLC_EGENERIC;
+ }
+
+ vout_window_sys_t *sys = vlc_obj_calloc(VLC_OBJECT(wnd), 1, sizeof(*sys));
+ if (unlikely(sys == NULL))
+ return VLC_ENOMEM;
+
+ VLCVideoWindowModuleDelegate *_moduleDelegate;
+ _moduleDelegate = [[VLCVideoWindowModuleDelegate alloc] initWithVLCVoutWindow:wnd];
+ if (unlikely(_moduleDelegate == nil))
+ return VLC_ENOMEM;
+ sys->delegate = _moduleDelegate;
+
+ __block VLCVideoStandaloneWindowController *_windowController;
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ _windowController = [[VLCVideoStandaloneWindowController alloc] initWithModuleDelegate:_moduleDelegate];
+ });
+ if (unlikely(_windowController == nil))
+ return VLC_ENOMEM;
+ sys->windowController = _windowController;
+
+ wnd->ops = &ops;
+ wnd->sys = sys;
+
+ return VLC_SUCCESS;
+ }
+}
+
+/*
+ * Module declaration
+ */
+vlc_module_begin()
+ set_description("macOS Video Output Window")
+ set_capability("vout window", 1000)
+ set_callback(Open)
+vlc_module_end()
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/34d0186ecd6a1506e1f2cd65023c78f123ea4462...c8797d1a224baccae34db9b3c5185634ae5faa98
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/34d0186ecd6a1506e1f2cd65023c78f123ea4462...c8797d1a224baccae34db9b3c5185634ae5faa98
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list