aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfuzzard <fuzzard@kodi.tv>2021-10-29 16:59:03 +1000
committerfuzzard <fuzzard@kodi.tv>2022-04-16 19:07:54 +1000
commitba9d5b1be195dff3a5bc3bd9fd68742e569d6237 (patch)
treefa3b012c3924135a53bceb7d9b623b73f8ce4170
parent6ba89e19445909a8da54f48f36fc6f2601cfe8ef (diff)
[OSX] Further improvements to windowing/input
relocate GL based code to own folders fixups for input handling rework/tidy of XBMCApplication
-rw-r--r--cmake/treedata/osx/subdirs.txt1
-rw-r--r--xbmc/Application.cpp4
-rw-r--r--xbmc/platform/darwin/osx/CMakeLists.txt7
-rw-r--r--xbmc/platform/darwin/osx/OSXGLWindow.h38
-rw-r--r--xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp7
-rw-r--r--xbmc/platform/darwin/osx/XBMCApplication.mm190
-rw-r--r--xbmc/windowing/osx/CMakeLists.txt5
-rw-r--r--xbmc/windowing/osx/OpenGL/CMakeLists.txt14
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.h (renamed from xbmc/platform/darwin/osx/OSXGLView.h)9
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.mm (renamed from xbmc/platform/darwin/osx/OSXGLView.mm)14
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLWindow.h19
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLWindow.mm (renamed from xbmc/platform/darwin/osx/OSXGLWindow.mm)37
-rw-r--r--xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h (renamed from xbmc/windowing/osx/WinSystemOSXGL.h)2
-rw-r--r--xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm (renamed from xbmc/windowing/osx/WinSystemOSXGL.mm)0
-rw-r--r--xbmc/windowing/osx/WinEventsOSX.mm2
-rw-r--r--xbmc/windowing/osx/WinEventsOSXImpl.h3
-rw-r--r--xbmc/windowing/osx/WinEventsOSXImpl.mm145
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.h10
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.mm294
19 files changed, 355 insertions, 446 deletions
diff --git a/cmake/treedata/osx/subdirs.txt b/cmake/treedata/osx/subdirs.txt
index abc1d9036d..9bee62332f 100644
--- a/cmake/treedata/osx/subdirs.txt
+++ b/cmake/treedata/osx/subdirs.txt
@@ -17,4 +17,5 @@ xbmc/platform/posix/storage/discs platform/posix/storage/discs
xbmc/platform/posix/threads platform/posix/threads
xbmc/platform/posix/utils platform/posix/utils
xbmc/windowing/osx windowing/osx
+xbmc/windowing/osx/OpenGL windowing/osx/OpenGL
xbmc/windowing/osx/SDL windowing/osx/SDL
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 8309414741..bde74257ad 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -4242,8 +4242,7 @@ void CApplication::ProcessSlow()
{
CServiceBroker::GetPowerManager().ProcessEvents();
-#if defined(TARGET_DARWIN_OSX)
-#if defined(SDL_FOUND)
+#if defined(TARGET_DARWIN_OSX) && defined(SDL_FOUND)
// There is an issue on OS X that several system services ask the cursor to become visible
// during their startup routines. Given that we can't control this, we hack it in by
// forcing the
@@ -4252,7 +4251,6 @@ void CApplication::ProcessSlow()
Cocoa_HideMouse();
}
#endif
-#endif
// Temporarily pause pausable jobs when viewing video/picture
int currentWindow = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
diff --git a/xbmc/platform/darwin/osx/CMakeLists.txt b/xbmc/platform/darwin/osx/CMakeLists.txt
index b26f9d1559..125135b610 100644
--- a/xbmc/platform/darwin/osx/CMakeLists.txt
+++ b/xbmc/platform/darwin/osx/CMakeLists.txt
@@ -12,11 +12,4 @@ set(HEADERS CocoaInterface.h
smc.h
XBMCHelper.h)
-if(NOT SDL_FOUND)
- list(APPEND SOURCES OSXGLView.mm
- OSXGLWindow.mm)
- list(APPEND HEADERS OSXGLView.h
- OSXGLWindow.h)
-endif()
-
core_add_library(platform_osx)
diff --git a/xbmc/platform/darwin/osx/OSXGLWindow.h b/xbmc/platform/darwin/osx/OSXGLWindow.h
deleted file mode 100644
index d993f018da..0000000000
--- a/xbmc/platform/darwin/osx/OSXGLWindow.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2021- Team Kodi
- * This file is part of Kodi - https://kodi.tv
- *
- * SPDX-License-Identifier: GPL-2.0-or-later
- * See LICENSES/README.md for more information.
- */
-
-#import <Cocoa/Cocoa.h>
-
-@interface OSXGLWindow : NSWindow <NSWindowDelegate>
-
-@property(atomic) bool resizeState;
-
-- (id)initWithContentRect:(NSRect)box styleMask:(uint)style;
-- (void)dealloc;
-
-- (BOOL)windowShouldClose:(id)sender;
-- (void)windowWillEnterFullScreen:(NSNotification*)pNotification;
-- (void)windowDidExitFullScreen:(NSNotification*)pNotification;
-
-- (void)windowDidChangeScreen:(NSNotification*)notification;
-- (void)windowDidExpose:(NSNotification*)aNotification;
-- (void)windowDidMove:(NSNotification*)aNotification;
-- (void)windowDidMiniaturize:(NSNotification*)aNotification;
-- (void)windowDidDeminiaturize:(NSNotification*)aNotification;
-
-- (void)windowDidBecomeKey:(NSNotification*)aNotification;
-- (void)windowDidResignKey:(NSNotification*)aNotification;
-
-- (void)windowDidResize:(NSNotification*)aNotification;
-- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize;
-- (void)windowWillStartLiveResize:(NSNotification*)notification;
-- (void)windowDidEndLiveResize:(NSNotification*)notification;
-
-@end
diff --git a/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp b/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp
index 786704c040..a5d9db273e 100644
--- a/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp
+++ b/xbmc/platform/darwin/osx/PlatformDarwinOSX.cpp
@@ -9,7 +9,10 @@
#include "PlatformDarwinOSX.h"
#include "Util.h"
-#include "windowing/osx/WinSystemOSXGL.h"
+
+#if defined(HAS_GL)
+#include "windowing/osx/OpenGL/WinSystemOSXGL.h"
+#endif
#include "platform/darwin/osx/XBMCHelper.h"
#include "platform/darwin/osx/powermanagement/CocoaPowerSyscall.h"
@@ -27,7 +30,9 @@ bool CPlatformDarwinOSX::InitStageOne()
if (!CPlatformDarwin::InitStageOne())
return false;
+#if defined(HAS_GL)
CWinSystemOSXGL::Register();
+#endif
CCocoaPowerSyscall::Register();
diff --git a/xbmc/platform/darwin/osx/XBMCApplication.mm b/xbmc/platform/darwin/osx/XBMCApplication.mm
index a1c27a24f7..bf79f6cf40 100644
--- a/xbmc/platform/darwin/osx/XBMCApplication.mm
+++ b/xbmc/platform/darwin/osx/XBMCApplication.mm
@@ -21,77 +21,16 @@
#import "platform/darwin/osx/storage/OSXStorageProvider.h"
+#import <Foundation/Foundation.h>
#import <sys/param.h> /* for MAXPATHLEN */
#import <unistd.h>
-// For some reason, Apple removed setAppleMenu from the headers in 10.4,
-// but the method still is there and works. To avoid warnings, we declare
-// it ourselves here.
-@interface NSApplication (Missing_Methods)
-- (void)setAppleMenu:(NSMenu*)menu;
-@end
-
-// Portions of CPS.h
-typedef struct CPSProcessSerNum
-{
- UInt32 lo;
- UInt32 hi;
-} CPSProcessSerNum;
-
-extern "C"
-{
- extern OSErr CPSGetCurrentProcess(CPSProcessSerNum* psn);
- extern OSErr CPSEnableForegroundOperation(
- CPSProcessSerNum* psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
- extern OSErr CPSSetFrontProcess(CPSProcessSerNum* psn);
-}
-
static int gArgc;
static char** gArgv;
static BOOL gCalledAppMainline = FALSE;
-static NSString* getApplicationName(void)
-{
- NSString* appName = 0;
-
- // Determine the application name
- NSDictionary* dict = (NSDictionary*)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
- if (dict)
- appName = [dict objectForKey:@"CFBundleName"];
-
- if (![appName length])
- appName = NSProcessInfo.processInfo.processName;
-
- return appName;
-}
-static void setupApplicationMenu(void)
-{
- // warning: this code is very odd
- NSString* appName = getApplicationName();
- NSMenu* appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
- // Add menu items
- NSString* title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title
- action:@selector(orderFrontStandardAboutPanel:)
- keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
- // Put menu into the menubar
- NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [NSApplication.sharedApplication.mainMenu addItem:menuItem];
-
- // Tell the application object that this is now the application menu
- [NSApplication.sharedApplication setAppleMenu:appleMenu];
-}
-
// Create a window menu
-static void setupWindowMenu(void)
+static NSMenu* setupWindowMenu()
{
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
@@ -107,42 +46,29 @@ static void setupWindowMenu(void)
menuItem = [[NSMenuItem alloc] initWithTitle:@"Float on Top"
action:@selector(floatOnTopToggle:)
keyEquivalent:@"t"];
- menuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl;
+ menuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand;
[windowMenu addItem:menuItem];
// "Minimize" item
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
- menuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand | NSEventModifierFlagControl;
+ menuItem.keyEquivalentModifierMask = NSEventModifierFlagCommand;
[windowMenu addItem:menuItem];
- // Put menu into the menubar
- NSMenuItem* windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window"
- action:nil
- keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [NSApplication.sharedApplication.mainMenu addItem:windowMenuItem];
-
- // Tell the application object that this is now the window menu
- [NSApplication.sharedApplication setWindowsMenu:windowMenu];
+ return windowMenu;
}
// The main class of the application, the application's delegate
@implementation XBMCDelegate
// Set the working directory to the .app's parent directory
+//! @todo Whats this for, is it required?
- (void)setupWorkingDirectory
{
- char parentdir[MAXPATHLEN];
- CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
- CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
- if (CFURLGetFileSystemRepresentation(url2, true, (UInt8*)parentdir, MAXPATHLEN))
- {
- assert(chdir(parentdir) == 0); /* chdir to the binary app's parent */
- }
- CFRelease(url);
- CFRelease(url2);
+ auto parentPath = NSBundle.mainBundle.bundlePath.stringByDeletingLastPathComponent;
+ NSAssert([NSFileManager.defaultManager changeCurrentDirectoryPath:parentPath],
+ @"SetupWorkingDirectory Failed to cwd");
}
- (void)stopRunLoop
@@ -186,7 +112,7 @@ static void setupWindowMenu(void)
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rlim) == -1)
- CLog::Log(LOGDEBUG, "Failed to set core size limit (%s)", strerror(errno));
+ CLog::Log(LOGDEBUG, "Failed to set core size limit ({})", strerror(errno));
#endif
setlocale(LC_NUMERIC, "C");
@@ -196,13 +122,6 @@ static void setupWindowMenu(void)
XBMC_Run(true, appParamParser);
-#ifdef _DEBUG
- CServiceBroker::GetLogging().SetLogLevel(LOG_LEVEL_DEBUG);
-#else
- // CServiceBroker::GetLogging().SetLogLevel(LOG_LEVEL_NORMAL);
- CServiceBroker::GetLogging().SetLogLevel(LOG_LEVEL_DEBUG);
-#endif
-
std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
if (appPort)
appPort->SetRenderGUI(false);
@@ -217,7 +136,41 @@ static void setupWindowMenu(void)
occluded = false;
CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
- winSystem->SetOcclusionState(occluded);
+ if (winSystem)
+ winSystem->SetOcclusionState(occluded);
+}
+
+- (void)applicationWillFinishLaunching:(NSNotification*)notification
+{
+ NSMenu* menubar = [NSMenu new];
+ NSMenuItem* menuBarItem = [NSMenuItem new];
+ [menubar addItem:menuBarItem];
+ [NSApp setMainMenu:menubar];
+
+ // Main menu
+ NSMenu* appMenu = [NSMenu new];
+ NSMenuItem* quitMenuItem = [[NSMenuItem alloc] initWithTitle:@"Quit"
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+ [appMenu addItem:quitMenuItem];
+ [menuBarItem setSubmenu:appMenu];
+
+ // Window Menu
+ NSMenuItem* windowMenuItem = [menubar addItemWithTitle:@"" action:nil keyEquivalent:@""];
+ NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+ [menubar setSubmenu:windowMenu forItem:windowMenuItem];
+ NSMenuItem* fullscreenMenuItem = [[NSMenuItem alloc] initWithTitle:@"Full/Windowed Toggle"
+ action:@selector(fullScreenToggle:)
+ keyEquivalent:@"f"];
+ fullscreenMenuItem.keyEquivalentModifierMask =
+ NSEventModifierFlagCommand | NSEventModifierFlagControl;
+ [windowMenu addItem:fullscreenMenuItem];
+ [windowMenu addItemWithTitle:@"Float on Top"
+ action:@selector(floatOnTopToggle:)
+ keyEquivalent:@"t"];
+ [windowMenu addItemWithTitle:@"Minimize"
+ action:@selector(performMiniaturize:)
+ keyEquivalent:@"m"];
}
// Called after the internal event loop has started running.
@@ -247,7 +200,7 @@ static void setupWindowMenu(void)
gCalledAppMainline = TRUE;
//window.acceptsMouseMovedEvents = TRUE;
-
+ [NSApp activateIgnoringOtherApps:YES];
// kick our mainloop into an extra thread
[NSThread detachNewThreadSelector:@selector(mainLoopThread:) toTarget:self withObject:nil];
}
@@ -293,6 +246,8 @@ static void setupWindowMenu(void)
*
* This message is ignored once the app's mainline has been called.
*/
+
+//! @Todo Transition to application: openURLs:
- (BOOL)application:(NSApplication*)theApplication openFile:(NSString*)filename
{
const char* temparg;
@@ -307,11 +262,11 @@ static void setupWindowMenu(void)
temparg = [filename UTF8String];
arglen = strlen(temparg) + 1;
arg = (char*)malloc(arglen);
- if (arg == NULL)
+ if (arg == nullptr)
return FALSE;
newargv = (char**)realloc(gArgv, sizeof(char*) * (gArgc + 2));
- if (newargv == NULL)
+ if (newargv == nullptr)
{
free(arg);
return FALSE;
@@ -320,14 +275,13 @@ static void setupWindowMenu(void)
strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
- gArgv[gArgc] = NULL;
+ gArgv[gArgc] = nullptr;
return TRUE;
}
- (void)deviceDidMountNotification:(NSNotification*)note
{
- // calling into c++ code, need to use autorelease pools
@autoreleasepool
{
NSString* volumeLabel = [note.userInfo objectForKey:@"NSWorkspaceVolumeLocalizedNameKey"];
@@ -342,7 +296,6 @@ static void setupWindowMenu(void)
- (void)deviceDidUnMountNotification:(NSNotification*)note
{
- // calling into c++ code, need to use autorelease pools
@autoreleasepool
{
NSString* volumeLabel = [note.userInfo objectForKey:@"NSWorkspaceVolumeLocalizedNameKey"];
@@ -383,30 +336,24 @@ static void setupWindowMenu(void)
}
}
+- (NSMenu*)applicationDockMenu:(NSApplication*)sender
+{
+ return setupWindowMenu();
+}
+
@end
int main(int argc, char* argv[])
{
@autoreleasepool
{
- XBMCDelegate* xbmc_delegate;
-
- // Block SIGPIPE
- // SIGPIPE repeatably kills us, turn it off
- {
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, SIGPIPE);
- sigprocmask(SIG_BLOCK, &set, NULL);
- }
-
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0)
{
gArgv = (char**)malloc(sizeof(char*) * 2);
gArgv[0] = argv[0];
- gArgv[1] = NULL;
+ gArgv[1] = nullptr;
gArgc = 1;
}
else
@@ -420,24 +367,17 @@ int main(int argc, char* argv[])
// Ensure the application object is initialised
[NSApplication sharedApplication];
- CPSProcessSerNum PSN;
- /* Tell the dock about us */
- if (!CPSGetCurrentProcess(&PSN))
- if (!CPSEnableForegroundOperation(&PSN, 0x03, 0x3C, 0x2C, 0x1103))
- if (!CPSSetFrontProcess(&PSN))
- [NSApplication sharedApplication];
-
- // Set up the menubars
- [NSApplication.sharedApplication setMainMenu:[[NSMenu alloc] init]];
- setupApplicationMenu();
- setupWindowMenu();
+ // Make sure we call applicationWillTerminate on SIGTERM
+ [NSProcessInfo.processInfo disableSuddenTermination];
- // Create XBMCDelegate and make it the app delegate
- xbmc_delegate = [[XBMCDelegate alloc] init];
- [NSApplication.sharedApplication setDelegate:xbmc_delegate];
+ // Set App Delegate
+ auto appDelegate = [XBMCDelegate new];
+ NSApp.delegate = appDelegate;
+ // Set NSApp to show in dock
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Start the main event loop
- [NSApplication.sharedApplication run];
+ [NSApp run];
return 1;
}
diff --git a/xbmc/windowing/osx/CMakeLists.txt b/xbmc/windowing/osx/CMakeLists.txt
index 20af0813fd..433f5cfe14 100644
--- a/xbmc/windowing/osx/CMakeLists.txt
+++ b/xbmc/windowing/osx/CMakeLists.txt
@@ -14,9 +14,4 @@ if(NOT SDL_FOUND)
WinSystemOSX.h)
endif()
-if(OPENGL_FOUND)
- list(APPEND SOURCES WinSystemOSXGL.mm)
- list(APPEND HEADERS WinSystemOSXGL.h)
-endif()
-
core_add_library(windowing_osx)
diff --git a/xbmc/windowing/osx/OpenGL/CMakeLists.txt b/xbmc/windowing/osx/OpenGL/CMakeLists.txt
new file mode 100644
index 0000000000..fd250d74ef
--- /dev/null
+++ b/xbmc/windowing/osx/OpenGL/CMakeLists.txt
@@ -0,0 +1,14 @@
+if(OPENGL_FOUND)
+ set(SOURCES WinSystemOSXGL.mm)
+ set(HEADERS WinSystemOSXGL.h)
+
+ if(NOT SDL_FOUND)
+ list(APPEND SOURCES OSXGLView.mm
+ OSXGLWindow.mm)
+ list(APPEND HEADERS OSXGLView.h
+ OSXGLWindow.h)
+ endif()
+
+ core_add_library(windowing_osx_opengl)
+
+endif()
diff --git a/xbmc/platform/darwin/osx/OSXGLView.h b/xbmc/windowing/osx/OpenGL/OSXGLView.h
index 7849cea24d..577642dc5e 100644
--- a/xbmc/platform/darwin/osx/OSXGLView.h
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.h
@@ -11,17 +11,8 @@
#import <Cocoa/Cocoa.h>
@interface OSXGLView : NSOpenGLView
-{
- NSOpenGLContext* m_glcontext;
- NSOpenGLPixelFormat* m_pixFmt;
- NSTrackingArea* m_trackingArea;
- BOOL pause;
-}
-
-@property(readonly, getter=getCurrentNSContext) NSOpenGLContext* context;
- (id)initWithFrame:(NSRect)frameRect;
-- (void)dealloc;
- (NSOpenGLContext*)getGLContext;
@end
diff --git a/xbmc/platform/darwin/osx/OSXGLView.mm b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
index c7fa7b67c8..eb899ac5b9 100644
--- a/xbmc/platform/darwin/osx/OSXGLView.mm
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
@@ -20,6 +20,12 @@
#include "system_gl.h"
@implementation OSXGLView
+{
+ NSOpenGLContext* m_glcontext;
+ NSOpenGLPixelFormat* m_pixFmt;
+ NSTrackingArea* m_trackingArea;
+ BOOL pause;
+}
- (id)initWithFrame:(NSRect)frameRect
{
@@ -55,11 +61,9 @@
- (void)drawRect:(NSRect)rect
{
- static BOOL firstRender = YES;
- if (firstRender)
- {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
[m_glcontext setView:self];
- firstRender = NO;
// clear screen on first render
glClearColor(0, 0, 0, 0);
@@ -67,7 +71,7 @@
glClearColor(0, 0, 0, 0);
[m_glcontext update];
- }
+ });
}
- (void)updateTrackingAreas
diff --git a/xbmc/windowing/osx/OpenGL/OSXGLWindow.h b/xbmc/windowing/osx/OpenGL/OSXGLWindow.h
new file mode 100644
index 0000000000..a722804c8d
--- /dev/null
+++ b/xbmc/windowing/osx/OpenGL/OSXGLWindow.h
@@ -0,0 +1,19 @@
+#pragma once
+
+/*
+ * Copyright (C) 2021- Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface OSXGLWindow : NSWindow <NSWindowDelegate>
+
+@property(atomic) bool resizeState;
+
+- (id)initWithContentRect:(NSRect)box styleMask:(uint)style;
+
+@end
diff --git a/xbmc/platform/darwin/osx/OSXGLWindow.mm b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm
index a550301259..366d0674e2 100644
--- a/xbmc/platform/darwin/osx/OSXGLWindow.mm
+++ b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm
@@ -18,11 +18,11 @@
#include "settings/DisplaySettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#import "windowing/osx/OpenGL/OSXGLView.h"
#include "windowing/osx/WinEventsOSX.h"
#import "windowing/osx/WinSystemOSX.h"
#include "platform/darwin/osx/CocoaInterface.h"
-#import "platform/darwin/osx/OSXGLView.h"
//------------------------------------------------------------------------------------------
@implementation OSXGLWindow
@@ -52,7 +52,7 @@
- (BOOL)windowShouldClose:(id)sender
{
if (!g_application.m_bStop)
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT);
return NO;
}
@@ -96,20 +96,20 @@
if (!m_resizeState)
{
NSRect rect = [self contentRectForFrameRect:self.frame];
+ int width = static_cast<int>(rect.size.width);
+ int height = static_cast<int>(rect.size.height);
if (!CServiceBroker::GetWinSystem()->IsFullScreen())
{
RESOLUTION res_index = RES_DESKTOP;
- if ((static_cast<int>(rect.size.width) ==
- CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iWidth) &&
- (static_cast<int>(rect.size.height) ==
- CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iHeight))
+ if ((width == CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iWidth) &&
+ (height == CDisplaySettings::GetInstance().GetResolutionInfo(res_index).iHeight))
return;
}
XBMC_Event newEvent = {};
newEvent.type = XBMC_VIDEORESIZE;
- newEvent.resize.w = static_cast<int>(rect.size.width);
- newEvent.resize.h = static_cast<int>(rect.size.height);
+ newEvent.resize.w = width;
+ newEvent.resize.h = height;
// check for valid sizes cause in some cases
// we are hit during fullscreen transition from osx
@@ -140,6 +140,9 @@
- (void)windowWillEnterFullScreen:(NSNotification*)pNotification
{
CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
+ if (!winSystem)
+ return;
+
// if osx is the issuer of the toggle
// call XBMCs toggle function
if (!winSystem->GetFullscreenWillToggle())
@@ -149,7 +152,7 @@
// called from XBMCs gui thread
winSystem->SetFullscreenWillToggle(true);
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_TOGGLEFULLSCREEN);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_TOGGLEFULLSCREEN);
}
else
{
@@ -163,6 +166,9 @@
- (void)windowDidExitFullScreen:(NSNotification*)pNotification
{
auto winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
+ if (!winSystem)
+ return;
+
// if osx is the issuer of the toggle
// call XBMCs toggle function
if (!winSystem->GetFullscreenWillToggle())
@@ -171,7 +177,7 @@
// flag will be reset in SetFullscreen once its
// called from XBMCs gui thread
winSystem->SetFullscreenWillToggle(true);
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_TOGGLEFULLSCREEN);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_TOGGLEFULLSCREEN);
}
else
{
@@ -182,6 +188,17 @@
}
}
+- (NSApplicationPresentationOptions)window:(NSWindow*)window
+ willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
+{
+ // customize our appearance when entering full screen:
+ // we don't want the dock to appear but we want the menubar to hide/show automatically
+ //
+ return (NSApplicationPresentationFullScreen | // support full screen for this window (required)
+ NSApplicationPresentationHideDock | // completely hide the dock
+ NSApplicationPresentationAutoHideMenuBar); // yes we want the menu bar to show/hide
+}
+
- (void)windowDidMiniaturize:(NSNotification*)aNotification
{
g_application.m_AppFocused = false;
diff --git a/xbmc/windowing/osx/WinSystemOSXGL.h b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h
index 750d2ad9c7..c38e5e3491 100644
--- a/xbmc/windowing/osx/WinSystemOSXGL.h
+++ b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.h
@@ -11,7 +11,7 @@
#if defined(HAS_SDL)
#include "windowing/osx/SDL/WinSystemOSXSDL.h"
#else
-#include "WinSystemOSX.h"
+#include "windowing/osx/WinSystemOSX.h"
#endif
#include "rendering/gl/RenderSystemGL.h"
diff --git a/xbmc/windowing/osx/WinSystemOSXGL.mm b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm
index 30e44f2b34..30e44f2b34 100644
--- a/xbmc/windowing/osx/WinSystemOSXGL.mm
+++ b/xbmc/windowing/osx/OpenGL/WinSystemOSXGL.mm
diff --git a/xbmc/windowing/osx/WinEventsOSX.mm b/xbmc/windowing/osx/WinEventsOSX.mm
index ac04bb8333..b2d07db936 100644
--- a/xbmc/windowing/osx/WinEventsOSX.mm
+++ b/xbmc/windowing/osx/WinEventsOSX.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2018 Team Kodi
+ * Copyright (C) 2011-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/xbmc/windowing/osx/WinEventsOSXImpl.h b/xbmc/windowing/osx/WinEventsOSXImpl.h
index 8e732bd7a3..2dcacd44f0 100644
--- a/xbmc/windowing/osx/WinEventsOSXImpl.h
+++ b/xbmc/windowing/osx/WinEventsOSXImpl.h
@@ -10,15 +10,16 @@
#include "windowing/osx/WinEventsOSX.h"
+#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
@interface CWinEventsOSXImpl : NSObject
-- (instancetype)init;
- (void)MessagePush:(XBMC_Event*)newEvent;
- (size_t)GetQueueSize;
- (bool)MessagePump;
- (void)enableInputEvents;
- (void)disableInputEvents;
+- (XBMC_Event)keyPressEvent:(CGEventRef*)event;
@end
diff --git a/xbmc/windowing/osx/WinEventsOSXImpl.mm b/xbmc/windowing/osx/WinEventsOSXImpl.mm
index 7edeef46d6..950777ea4c 100644
--- a/xbmc/windowing/osx/WinEventsOSXImpl.mm
+++ b/xbmc/windowing/osx/WinEventsOSXImpl.mm
@@ -17,13 +17,15 @@
#include "input/mouse/MouseStat.h"
#include "messaging/ApplicationMessenger.h"
#include "threads/CriticalSection.h"
-#include "threads/SingleLock.h"
+#include "utils/log.h"
#include "windowing/osx/WinSystemOSX.h"
-#include <list>
#include <memory>
+#include <mutex>
+#include <queue>
#import <AppKit/AppKit.h>
+#import <Carbon/Carbon.h> // kvk_ANSI_ keycodes
#import <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
@@ -31,8 +33,8 @@
@implementation CWinEventsOSXImpl
{
- std::list<XBMC_Event> events;
- CCriticalSection g_inputCond;
+ std::queue<XBMC_Event> events;
+ CCriticalSection m_inputlock;
id mLocalMonitorId;
}
@@ -49,8 +51,8 @@
- (void)MessagePush:(XBMC_Event*)newEvent
{
- CSingleLock lock(g_inputCond);
- events.push_back(*newEvent);
+ std::unique_lock<CCriticalSection> lock(m_inputlock);
+ events.emplace(*newEvent);
}
- (bool)MessagePump
@@ -66,11 +68,11 @@
// deeper message loop and call the deeper MessagePump from there.
XBMC_Event pumpEvent = {};
{
- CSingleLock lock(g_inputCond);
+ std::unique_lock<CCriticalSection> lock(m_inputlock);
if (events.size() == 0)
return ret;
pumpEvent = events.front();
- events.pop_front();
+ events.pop();
}
std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
if (appPort)
@@ -81,7 +83,7 @@
- (size_t)GetQueueSize
{
- CSingleLock lock(g_inputCond);
+ std::unique_lock<CCriticalSection> lock(m_inputlock);
return events.size();
}
@@ -89,19 +91,19 @@
{
switch (character)
{
- case 0x1c:
- case 0xf702:
+ case kVK_ANSI_8:
+ case NSLeftArrowFunctionKey:
return XBMCK_LEFT;
- case 0x1d:
- case 0xf703:
+ case kVK_ANSI_0:
+ case NSRightArrowFunctionKey:
return XBMCK_RIGHT;
- case 0x1e:
- case 0xf700:
+ case kVK_ANSI_RightBracket:
+ case NSUpArrowFunctionKey:
return XBMCK_UP;
- case 0x1f:
- case 0xf701:
+ case kVK_ANSI_O:
+ case NSDownArrowFunctionKey:
return XBMCK_DOWN;
- case 0x7f:
+ case NSDeleteCharacter:
return XBMCK_BACKSPACE;
default:
return character;
@@ -127,35 +129,35 @@
if (appleModifier & kCGEventFlagMaskCommand)
xbmcModifier |= XBMCKMOD_LMETA;
- return (XBMCMod)xbmcModifier;
+ return static_cast<XBMCMod>(xbmcModifier);
}
- (bool)ProcessOSXShortcuts:(XBMC_Event&)event
{
- bool cmd = !!(event.key.keysym.mod & (XBMCKMOD_LMETA | XBMCKMOD_RMETA));
+ const auto cmd = (event.key.keysym.mod & (XBMCKMOD_LMETA | XBMCKMOD_RMETA)) != 0;
if (cmd && event.type == XBMC_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case XBMCK_q: // CMD-q to quit
if (!g_application.m_bStop)
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_QUIT);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT);
return true;
- case XBMCK_CTRLF: // CMD-f to toggle fullscreen
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_TOGGLEFULLSCREEN);
+ case XBMCK_CTRLF: // CMD-CTRL-f to toggle fullscreen
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_TOGGLEFULLSCREEN);
return true;
case XBMCK_s: // CMD-s to take a screenshot
{
CAction* action = new CAction(ACTION_TAKE_SCREENSHOT);
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(
- TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(action));
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1,
+ static_cast<void*>(action));
return true;
}
case XBMCK_h: // CMD-h to hide (but we minimize for now)
case XBMCK_m: // CMD-m to minimize
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_MINIMIZE);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_MINIMIZE);
return true;
default:
@@ -170,12 +172,19 @@
{
[self disableInputEvents]; // allow only one registration at a time
+ // clang-format off
// Create an event tap. We are interested in mouse and keyboard events.
NSEventMask eventMask =
- NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp | NSEventMaskRightMouseDown |
- NSEventMaskRightMouseUp | NSEventMaskLeftMouseDragged | NSEventMaskRightMouseDragged |
- NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp | NSEventMaskOtherMouseDragged |
- NSEventMaskMouseMoved | NSEventMaskScrollWheel | NSEventMaskKeyDown | NSEventMaskKeyUp;
+ NSEventMaskKeyDown | NSEventMaskKeyUp |
+ NSEventMaskLeftMouseDown | NSEventMaskLeftMouseUp |
+ NSEventMaskRightMouseDown | NSEventMaskRightMouseUp |
+ NSEventMaskOtherMouseDown | NSEventMaskOtherMouseUp |
+ NSEventMaskScrollWheel |
+ NSEventMaskLeftMouseDragged |
+ NSEventMaskRightMouseDragged |
+ NSEventMaskOtherMouseDragged |
+ NSEventMaskMouseMoved;
+ // clang-format on
mLocalMonitorId = [NSEvent addLocalMonitorForEventsMatchingMask:eventMask
handler:^(NSEvent* event) {
@@ -187,7 +196,7 @@
{
// Disable the local Monitor
if (mLocalMonitorId != nil)
- [NSEvent removeMonitor:(id)mLocalMonitorId];
+ [NSEvent removeMonitor:mLocalMonitorId];
mLocalMonitorId = nil;
}
@@ -210,9 +219,6 @@
NSRect frame = winSystem->GetWindowDimensions();
location.y = frame.size.height - location.y;
- UniChar unicodeString[10];
- UniCharCount actualStringLength = 10;
- CGKeyCode keycode;
XBMC_Event newEvent = {};
switch (type)
@@ -290,40 +296,15 @@
// handle keyboard events and transform them into the xbmc event world
case kCGEventKeyUp:
- keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
- CGEventKeyboardGetUnicodeString(event, sizeof(unicodeString) / sizeof(*unicodeString),
- &actualStringLength, unicodeString);
- if (actualStringLength > 0)
- unicodeString[0] = [self OsxKey2XbmcKey:unicodeString[0]];
- else
- unicodeString[0] = [self OsxKey2XbmcKey:[nsevent.characters characterAtIndex:0]];
-
+ newEvent = [self keyPressEvent:&event];
newEvent.type = XBMC_KEYUP;
- newEvent.key.keysym.scancode = keycode;
- newEvent.key.keysym.sym = (XBMCKey)unicodeString[0];
- newEvent.key.keysym.unicode = unicodeString[0];
- if (actualStringLength > 1)
- newEvent.key.keysym.unicode |= (unicodeString[1] << 8);
- newEvent.key.keysym.mod = [self OsxMod2XbmcMod:CGEventGetFlags(event)];
+
[self MessagePush:&newEvent];
passEvent = false;
break;
case kCGEventKeyDown:
- keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
- CGEventKeyboardGetUnicodeString(event, sizeof(unicodeString) / sizeof(*unicodeString),
- &actualStringLength, unicodeString);
- if (actualStringLength > 0)
- unicodeString[0] = [self OsxKey2XbmcKey:unicodeString[0]];
- else
- unicodeString[0] = [self OsxKey2XbmcKey:[nsevent.characters characterAtIndex:0]];
-
+ newEvent = [self keyPressEvent:&event];
newEvent.type = XBMC_KEYDOWN;
- newEvent.key.keysym.scancode = keycode;
- newEvent.key.keysym.sym = (XBMCKey)unicodeString[0];
- newEvent.key.keysym.unicode = unicodeString[0];
- if (actualStringLength > 1)
- newEvent.key.keysym.unicode |= (unicodeString[1] << 8);
- newEvent.key.keysym.mod = [self OsxMod2XbmcMod:CGEventGetFlags(event)];
if (![self ProcessOSXShortcuts:newEvent])
[self MessagePush:&newEvent];
@@ -340,4 +321,44 @@
return nullptr;
}
+- (XBMC_Event)keyPressEvent:(CGEventRef*)event
+{
+ UniCharCount actualStringLength = 0;
+ // Get stringlength of event
+ CGEventKeyboardGetUnicodeString(*event, 0, &actualStringLength, nullptr);
+
+ // Create array with size of event string
+ UniChar unicodeString[actualStringLength];
+ memset(unicodeString, 0, sizeof(unicodeString));
+
+ auto keycode =
+ static_cast<CGKeyCode>(CGEventGetIntegerValueField(*event, kCGKeyboardEventKeycode));
+ CGEventKeyboardGetUnicodeString(*event, sizeof(unicodeString) / sizeof(*unicodeString),
+ &actualStringLength, unicodeString);
+
+ XBMC_Event newEvent = {};
+
+ // May be possible for actualStringLength > 1. Havent been able to replicate anything
+ // larger than 1, but keep in mind for any regressions
+ if (actualStringLength == 0)
+ {
+ return newEvent;
+ }
+ else if (actualStringLength > 1)
+ {
+ CLog::Log(LOGERROR, "CWinEventsOSXImpl::keyPressEvent - event string > 1 - size: {}",
+ static_cast<int>(actualStringLength));
+ return newEvent;
+ }
+
+ unicodeString[0] = [self OsxKey2XbmcKey:unicodeString[0]];
+
+ newEvent.key.keysym.scancode = keycode;
+ newEvent.key.keysym.sym = static_cast<XBMCKey>(unicodeString[0]);
+ newEvent.key.keysym.unicode = unicodeString[0];
+ newEvent.key.keysym.mod = [self OsxMod2XbmcMod:CGEventGetFlags(*event)];
+
+ return newEvent;
+}
+
@end
diff --git a/xbmc/windowing/osx/WinSystemOSX.h b/xbmc/windowing/osx/WinSystemOSX.h
index d527b7b60f..0ac08d4d38 100644
--- a/xbmc/windowing/osx/WinSystemOSX.h
+++ b/xbmc/windowing/osx/WinSystemOSX.h
@@ -26,8 +26,8 @@ class CWinEventsOSX;
@class NSWindow;
@class OSXGLView;
#else
-class NSWindow;
-class OSXGLView;
+struct NSWindow;
+struct OSXGLView;
#endif
class CWinSystemOSX : public CWinSystemBase, public ITimerCallback
@@ -95,8 +95,8 @@ protected:
void EnableVSync(bool enable);
bool SwitchToVideoMode(int width, int height, double refreshrate);
void FillInVideoModes();
- bool FlushBuffer(void);
- bool IsObscured(void);
+ bool FlushBuffer();
+ bool IsObscured();
bool DestroyWindowInternal();
@@ -114,7 +114,7 @@ protected:
std::vector<IDispResource*> m_resources;
CTimer m_lostDeviceTimer;
bool m_delayDispReset;
- XbmcThreads::EndTime m_dispResetTimer;
+ XbmcThreads::EndTime<> m_dispResetTimer;
bool m_fullscreenWillToggle;
CCriticalSection m_critSection;
};
diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm
index 5ab150aafc..492aeada6c 100644
--- a/xbmc/windowing/osx/WinSystemOSX.mm
+++ b/xbmc/windowing/osx/WinSystemOSX.mm
@@ -27,23 +27,24 @@
#include "settings/DisplaySettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
-#include "threads/SingleLock.h"
+#include "threads/CriticalSection.h"
#include "utils/StringUtils.h"
#include "utils/log.h"
#include "windowing/osx/CocoaDPMSSupport.h"
#include "windowing/osx/OSScreenSaverOSX.h"
+#import "windowing/osx/OpenGL/OSXGLView.h"
+#import "windowing/osx/OpenGL/OSXGLWindow.h"
#include "windowing/osx/VideoSyncOsx.h"
#include "windowing/osx/WinEventsOSX.h"
#include "platform/darwin/DarwinUtils.h"
#include "platform/darwin/DictionaryUtils.h"
#include "platform/darwin/osx/CocoaInterface.h"
-#import "platform/darwin/osx/OSXGLView.h"
-#import "platform/darwin/osx/OSXGLWindow.h"
#include "platform/darwin/osx/powermanagement/CocoaPowerSyscall.h"
#include <chrono>
#include <cstdlib>
+#include <mutex>
#include <signal.h>
#import <Cocoa/Cocoa.h>
@@ -55,39 +56,22 @@
using namespace KODI;
using namespace MESSAGING;
using namespace WINDOWING;
+using namespace std::chrono_literals;
#define MAX_DISPLAYS 32
static NSWindow* blankingWindows[MAX_DISPLAYS];
-//---------------------------------------------------------------------------------
-void SetMenuBarVisible(bool visible)
-{
- if (visible)
- {
- dispatch_sync(dispatch_get_main_queue(), ^{
- NSApplicationPresentationOptions options = NSApplicationPresentationDefault;
- [NSApplication.sharedApplication setPresentationOptions:options];
- });
- }
- else
- {
- dispatch_sync(dispatch_get_main_queue(), ^{
- NSApplicationPresentationOptions options =
- NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock;
- [NSApplication.sharedApplication setPresentationOptions:options];
- });
- }
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-// No replacement for CGDisplayModeCopyPixelEncoding
-// Disable warning for now
size_t DisplayBitsPerPixelForMode(CGDisplayModeRef mode)
{
size_t bitsPerPixel = 0;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ // No replacement for CGDisplayModeCopyPixelEncoding
+ // Disable warning for now
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
+#pragma GCC diagnostic pop
+
if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) ==
kCFCompareEqualTo)
{
@@ -108,22 +92,25 @@ size_t DisplayBitsPerPixelForMode(CGDisplayModeRef mode)
return bitsPerPixel;
}
-#pragma GCC diagnostic pop
#pragma mark - GetScreenName
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-// No real replacement of CGDisplayIOServicePort
-// Stackoverflow links to https://github.com/glfw/glfw/pull/192 as a possible replacement
-// disable warning for now
NSString* screenNameForDisplay(CGDirectDisplayID displayID)
{
NSString* screenName;
@autoreleasepool
{
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ // No real replacement of CGDisplayIOServicePort
+ // Stackoverflow links to https://github.com/glfw/glfw/pull/192 as a possible replacement
+ // disable warning for now
NSDictionary* deviceInfo = (__bridge_transfer NSDictionary*)IODisplayCreateInfoDictionary(
CGDisplayIOServicePort(displayID), kIODisplayOnlyPreferredName);
+
+#pragma GCC diagnostic pop
+
NSDictionary* localizedNames =
[deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];
@@ -145,18 +132,17 @@ NSString* screenNameForDisplay(CGDirectDisplayID displayID)
return screenName;
}
-#pragma GCC diagnostic pop
#pragma mark - GetDisplay
CGDirectDisplayID GetDisplayID(int screen_index)
{
CGDirectDisplayID displayArray[MAX_DISPLAYS];
- CGDisplayCount numDisplays;
+ uint32_t numDisplays;
// Get the list of displays.
CGGetActiveDisplayList(MAX_DISPLAYS, displayArray, &numDisplays);
- if (screen_index >= 0 && screen_index < numDisplays)
+ if (screen_index >= 0 && screen_index < static_cast<int>(numDisplays))
return (displayArray[screen_index]);
else
return (displayArray[0]);
@@ -215,18 +201,18 @@ CFArrayRef GetAllDisplayModes(CGDirectDisplayID display)
if (!number)
{
CLog::Log(LOGERROR, "GetAllDisplayModes - could not create Number!");
- return NULL;
+ return nullptr;
}
CFStringRef key = kCGDisplayShowDuplicateLowResolutionModes;
CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&key,
- (const void**)&number, 1, NULL, NULL);
+ (const void**)&number, 1, nullptr, nullptr);
CFRelease(number);
if (!options)
{
CLog::Log(LOGERROR, "GetAllDisplayModes - could not create Dictionary!");
- return NULL;
+ return nullptr;
}
CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(display, options);
@@ -235,7 +221,7 @@ CFArrayRef GetAllDisplayModes(CGDirectDisplayID display)
if (!displayModes)
{
CLog::Log(LOGERROR, "GetAllDisplayModes - no displaymodes found!");
- return NULL;
+ return nullptr;
}
return displayModes;
@@ -246,33 +232,31 @@ CFArrayRef GetAllDisplayModes(CGDirectDisplayID display)
CGDisplayModeRef GetMode(int width, int height, double refreshrate, int screenIdx)
{
if (screenIdx >= (signed)[[NSScreen screens] count])
- return NULL;
+ return nullptr;
bool stretched;
bool interlaced;
bool safeForHardware;
- bool televisionoutput;
int w, h, bitsperpixel;
double rate;
RESOLUTION_INFO res;
- CLog::Log(LOGDEBUG, "GetMode looking for suitable mode with %d x %d @ %f Hz on display %d", width,
+ CLog::Log(LOGDEBUG, "GetMode looking for suitable mode with {} x {} @ {} Hz on display {}", width,
height, refreshrate, screenIdx);
- CFArrayRef displayModes = GetAllDisplayModes(GetDisplayID(screenIdx));
+ CFArrayRef allModes = GetAllDisplayModes(GetDisplayID(screenIdx));
- if (!displayModes)
- return NULL;
+ if (!allModes)
+ return nullptr;
- for (int i = 0; i < CFArrayGetCount(displayModes); ++i)
+ for (int i = 0; i < CFArrayGetCount(allModes); ++i)
{
- CGDisplayModeRef displayMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
+ CGDisplayModeRef displayMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
uint32_t flags = CGDisplayModeGetIOFlags(displayMode);
- stretched = flags & kDisplayModeStretchedFlag ? true : false;
- interlaced = flags & kDisplayModeInterlacedFlag ? true : false;
+ stretched = (flags & kDisplayModeStretchedFlag) != 0;
+ interlaced = (flags & kDisplayModeInterlacedFlag) != 0;
bitsperpixel = DisplayBitsPerPixelForMode(displayMode);
- safeForHardware = flags & kDisplayModeSafetyFlags ? true : false;
- televisionoutput = flags & kDisplayModeTelevisionFlag ? true : false;
+ safeForHardware = (flags & kDisplayModeSafetyFlags) != 0;
w = CGDisplayModeGetWidth(displayMode);
h = CGDisplayModeGetHeight(displayMode);
rate = CGDisplayModeGetRefreshRate(displayMode);
@@ -281,24 +265,23 @@ CGDisplayModeRef GetMode(int width, int height, double refreshrate, int screenId
(interlaced == false) && (w == width) && (h == height) &&
(rate == refreshrate || rate == 0))
{
+ CFRelease(allModes);
CLog::Log(LOGDEBUG, "GetMode found a match!");
- return displayMode;
+ return CGDisplayModeRetain(displayMode);
}
}
- CFRelease(displayModes);
+ CFRelease(allModes);
CLog::Log(LOGERROR, "GetMode - no match found!");
- return NULL;
+ return nullptr;
}
// mimic former behavior of deprecated CGDisplayBestModeForParameters
-CGDisplayModeRef BestMatchForMode(
- CGDirectDisplayID display, size_t bitsPerPixel, size_t width, size_t height, boolean_t& match)
+CGDisplayModeRef BestMatchForMode(CGDirectDisplayID display,
+ size_t bitsPerPixel,
+ size_t width,
+ size_t height)
{
-
- // Get a copy of the current display mode
- CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(display);
-
// Loop through all display modes to determine the closest match.
// CGDisplayBestModeForParameters is deprecated on 10.6 so we will emulate it's behavior
// Try to find a mode with the requested depth and equal or greater dimensions first.
@@ -306,35 +289,44 @@ CGDisplayModeRef BestMatchForMode(
// If still no match is found, just use the current mode.
CFArrayRef allModes = GetAllDisplayModes(display);
+ if (!allModes)
+ return nullptr;
+
+ CGDisplayModeRef displayMode = nullptr;
+
for (int i = 0; i < CFArrayGetCount(allModes); i++)
{
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
+ if (!mode)
+ continue;
+
if (DisplayBitsPerPixelForMode(mode) != bitsPerPixel)
continue;
if ((CGDisplayModeGetWidth(mode) == width) && (CGDisplayModeGetHeight(mode) == height))
{
- CGDisplayModeRelease(displayMode); // release the copy we got before ...
displayMode = mode;
- match = true;
break;
}
}
// No depth match was found
- if (!match)
+ if (!displayMode)
{
for (int i = 0; i < CFArrayGetCount(allModes); i++)
{
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
+
+ if (!mode)
+ continue;
+
if (DisplayBitsPerPixelForMode(mode) >= bitsPerPixel)
continue;
if ((CGDisplayModeGetWidth(mode) == width) && (CGDisplayModeGetHeight(mode) == height))
{
displayMode = mode;
- match = true;
break;
}
}
@@ -384,10 +376,7 @@ void BlankOtherDisplays(int screen_index)
void UnblankDisplays(void)
{
- int numDisplays = NSScreen.screens.count;
- int i = 0;
-
- for (i = 0; i < numDisplays; i++)
+ for (auto i = 0; i < static_cast<int>(NSScreen.screens.count); i++)
{
if (blankingWindows[i] != 0)
{
@@ -399,7 +388,7 @@ void UnblankDisplays(void)
}
#pragma mark - Fade Display
-
+//! @Todo Look to replace Fade with CABasicAnimation
static NSWindow* curtainWindow;
void fadeInDisplay(NSScreen* theScreen, double fadeTime)
{
@@ -462,7 +451,7 @@ static void DisplayReconfigured(CGDirectDisplayID display,
if (!winsys)
return;
- CLog::Log(LOGDEBUG, "CWinSystemOSX::DisplayReconfigured with flags %d", flags);
+ CLog::Log(LOGDEBUG, "CWinSystemOSX::DisplayReconfigured with flags {}", flags);
// we fire the callbacks on start of configuration
// or when the mode set was finished
@@ -537,13 +526,13 @@ CWinSystemOSX::~CWinSystemOSX() = default;
void CWinSystemOSX::Register(IDispResource* resource)
{
- CSingleLock lock(m_resourceSection);
+ std::unique_lock<CCriticalSection> lock(m_resourceSection);
m_resources.push_back(resource);
}
void CWinSystemOSX::Unregister(IDispResource* resource)
{
- CSingleLock lock(m_resourceSection);
+ std::unique_lock<CCriticalSection> lock(m_resourceSection);
std::vector<IDispResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
if (i != m_resources.end())
m_resources.erase(i);
@@ -551,22 +540,23 @@ void CWinSystemOSX::Unregister(IDispResource* resource)
void CWinSystemOSX::AnnounceOnLostDevice()
{
- CSingleLock lock(m_resourceSection);
+ std::unique_lock<CCriticalSection> lock(m_resourceSection);
// tell any shared resources
- CLog::Log(LOGDEBUG, "CWinSystemOSX::AnnounceOnLostDevice");
+ CLog::LogF(LOGDEBUG, "Lost Device Announce");
for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
(*i)->OnLostDisplay();
}
void CWinSystemOSX::HandleOnResetDevice()
{
-
- int delay = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
- "videoscreen.delayrefreshchange");
- if (delay > 0)
+ auto delay =
+ std::chrono::milliseconds(CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
+ "videoscreen.delayrefreshchange") *
+ 100);
+ if (delay > 0ms)
{
m_delayDispReset = true;
- m_dispResetTimer.Set(delay * 100);
+ m_dispResetTimer.Set(delay);
}
else
{
@@ -586,9 +576,9 @@ void CWinSystemOSX::AnnounceOnResetDevice()
CServiceBroker::GetWinSystem()->GetGfxContext().SetFPS(currentFps);
- CSingleLock lock(m_resourceSection);
+ std::unique_lock<CCriticalSection> lock(m_resourceSection);
// tell any shared resources
- CLog::Log(LOGDEBUG, "CWinSystemOSX::AnnounceOnResetDevice");
+ CLog::LogF(LOGDEBUG, "Reset Device Announce");
for (std::vector<IDispResource*>::iterator i = m_resources.begin(); i != m_resources.end(); ++i)
(*i)->OnResetDisplay();
}
@@ -600,7 +590,7 @@ void CWinSystemOSX::StartLostDeviceTimer()
if (m_lostDeviceTimer.IsRunning())
m_lostDeviceTimer.Restart();
else
- m_lostDeviceTimer.Start(std::chrono::milliseconds(3000), false);
+ m_lostDeviceTimer.Start(3000ms, false);
}
void CWinSystemOSX::StopLostDeviceTimer()
@@ -633,7 +623,7 @@ bool CWinSystemOSX::DestroyWindowSystem()
if (m_glView)
{
- m_glView = NULL;
+ m_glView = nullptr;
}
UnblankDisplays();
@@ -660,7 +650,7 @@ bool CWinSystemOSX::CreateNewWindow(const std::string& name, bool fullScreen, RE
// for native fullscreen we always want to set the
// same windowed flags
- __block NSUInteger windowStyleMask;
+ NSUInteger windowStyleMask;
if (fullScreen)
windowStyleMask = NSWindowStyleMaskBorderless;
else
@@ -744,7 +734,7 @@ bool CWinSystemOSX::DestroyWindowInternal()
if (m_appWindow)
{
NSWindow* oldAppWindow = m_appWindow;
- m_appWindow = NULL;
+ m_appWindow = nullptr;
dispatch_sync(dispatch_get_main_queue(), ^{
[oldAppWindow setContentView:nil];
});
@@ -879,21 +869,12 @@ bool CWinSystemOSX::ResizeWindow(int newWidth, int newHeight, int newLeft, int n
bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool blankOtherDisplays)
{
- CSingleLock lock(m_critSection);
-
- static NSPoint last_window_origin;
-
- static NSSize last_view_size;
- static NSPoint last_view_origin;
+ std::unique_lock<CCriticalSection> lock(m_critSection);
// if (m_lastDisplayNr == -1)
// m_lastDisplayNr = res.iScreen;
__block NSWindow* window = m_appWindow;
- __block OSXGLView* view;
- dispatch_sync(dispatch_get_main_queue(), ^{
- view = window.contentView;
- });
const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
m_lastDisplayNr = GetDisplayIndex(settings->GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR));
@@ -923,53 +904,29 @@ bool CWinSystemOSX::SetFullScreen(bool fullScreen, RESOLUTION_INFO& res, bool bl
if (m_bFullScreen)
{
- // Save info about the windowed context so we can restore it when returning to windowed.
- __block NSPoint block_last_window_origin;
- __block NSSize block_last_view_size;
- __block NSPoint block_last_view_origin;
-
- dispatch_sync(dispatch_get_main_queue(), ^{
- block_last_view_size = view.frame.size;
- block_last_view_origin = view.frame.origin;
- block_last_window_origin = window.frame.origin;
- });
-
- last_view_size = block_last_view_size;
- last_view_origin = block_last_view_origin;
- last_window_origin = block_last_window_origin;
-
// This is Cocoa Windowed FullScreen Mode
// Get the screen rect of our current display
NSScreen* pScreen = [NSScreen.screens objectAtIndex:m_lastDisplayNr];
- NSRect screenRect = pScreen.frame;
// remove frame origin offset of original display
- screenRect.origin = NSZeroPoint;
+ pScreen.frame.origin = NSZeroPoint;
- window = m_appWindow;
dispatch_sync(dispatch_get_main_queue(), ^{
- view = [window contentView];
- [view setFrameSize:NSMakeSize(m_nWidth, m_nHeight)];
-
- NSString* title = [NSString stringWithFormat:@"%s", ""];
- window.title = title;
+ [window.contentView setFrameSize:NSMakeSize(m_nWidth, m_nHeight)];
+ window.title = @"";
+ [window setAllowsConcurrentViewDrawing:YES];
});
- // Hide the menu bar.
- SetMenuBarVisible(false);
-
// Blank other displays if requested.
if (blankOtherDisplays)
BlankOtherDisplays(m_lastDisplayNr);
-
- dispatch_sync(dispatch_get_main_queue(), ^{
- [window setAllowsConcurrentViewDrawing:YES];
- });
}
else
{
// Show menubar.
- SetMenuBarVisible(true);
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [NSApplication.sharedApplication setPresentationOptions:NSApplicationPresentationDefault];
+ });
// Unblank.
// Force the unblank when returning from fullscreen, we get called with blankOtherDisplays set false.
@@ -998,7 +955,8 @@ void CWinSystemOSX::UpdateResolutions()
CWinSystemBase::UpdateResolutions();
// Add desktop resolution
- int w, h;
+ int w;
+ int h;
double fps;
int dispIdx = GetDisplayIndex(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
@@ -1024,7 +982,7 @@ void CWinSystemOSX::GetScreenResolution(int* w, int* h, double* fps, int screenI
*h = CGDisplayModeGetHeight(mode);
*fps = CGDisplayModeGetRefreshRate(mode);
CGDisplayModeRelease(mode);
- if ((int)*fps == 0)
+ if (static_cast<int>(*fps) == 0)
{
// NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays.
*fps = 60.0;
@@ -1035,8 +993,7 @@ void CWinSystemOSX::GetScreenResolution(int* w, int* h, double* fps, int screenI
bool CWinSystemOSX::SwitchToVideoMode(int width, int height, double refreshrate)
{
- boolean_t match = false;
- CGDisplayModeRef dispMode = NULL;
+ CGDisplayModeRef dispMode = nullptr;
int screenIdx = GetDisplayIndex(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_VIDEOSCREEN_MONITOR));
@@ -1051,30 +1008,28 @@ bool CWinSystemOSX::SwitchToVideoMode(int width, int height, double refreshrate)
//not found - fallback to bestemdeforparameters
if (!dispMode)
{
- dispMode = BestMatchForMode(display_id, 32, width, height, match);
+ dispMode = BestMatchForMode(display_id, 32, width, height);
- if (!match)
- dispMode = BestMatchForMode(display_id, 16, width, height, match);
-
- // still no match? fallback to current resolution of the display which HAS to work [tm]
- if (!match)
+ if (!dispMode)
{
- int tmpWidth;
- int tmpHeight;
- double tmpRefresh;
-
- GetScreenResolution(&tmpWidth, &tmpHeight, &tmpRefresh, screenIdx);
- dispMode = GetMode(tmpWidth, tmpHeight, tmpRefresh, screenIdx);
+ dispMode = BestMatchForMode(display_id, 16, width, height);
- // no way to get a resolution set
+ // still no match? fallback to current resolution of the display which HAS to work [tm]
if (!dispMode)
- return false;
- }
+ {
+ int currentWidth;
+ int currentHeight;
+ double currentRefresh;
- if (!match)
- return false;
- }
+ GetScreenResolution(&currentWidth, &currentHeight, &currentRefresh, screenIdx);
+ dispMode = GetMode(currentWidth, currentHeight, currentRefresh, screenIdx);
+ // no way to get a resolution set
+ if (!dispMode)
+ return false;
+ }
+ }
+ }
// switch mode and return success
CGDisplayCapture(display_id);
CGDisplayConfigRef cfg;
@@ -1095,15 +1050,11 @@ void CWinSystemOSX::FillInVideoModes()
int dispIdx = GetDisplayIndex(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
CSettings::SETTING_VIDEOSCREEN_MONITOR));
- // Add full screen settings for additional monitors
- int numDisplays = NSScreen.screens.count;
-
- for (int disp = 0; disp < numDisplays; disp++)
+ for (int disp = 0; disp < static_cast<int>(NSScreen.screens.count); disp++)
{
bool stretched;
bool interlaced;
bool safeForHardware;
- bool televisionoutput;
int w, h, bitsperpixel;
double refreshrate;
RESOLUTION_INFO res;
@@ -1111,9 +1062,9 @@ void CWinSystemOSX::FillInVideoModes()
CFArrayRef displayModes = GetAllDisplayModes(GetDisplayID(disp));
NSString* dispName = screenNameForDisplay(GetDisplayID(disp));
- CLog::Log(LOGINFO, "Display %i has name %s", disp, [dispName UTF8String]);
+ CLog::LogF(LOGINFO, "Display {} has name {}", disp, [dispName UTF8String]);
- if (nullptr == displayModes)
+ if (!displayModes)
continue;
for (int i = 0; i < CFArrayGetCount(displayModes); ++i)
@@ -1121,11 +1072,10 @@ void CWinSystemOSX::FillInVideoModes()
CGDisplayModeRef displayMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
uint32_t flags = CGDisplayModeGetIOFlags(displayMode);
- stretched = flags & kDisplayModeStretchedFlag ? true : false;
- interlaced = flags & kDisplayModeInterlacedFlag ? true : false;
+ stretched = (flags & kDisplayModeStretchedFlag) != 0;
+ interlaced = (flags & kDisplayModeInterlacedFlag) != 0;
bitsperpixel = DisplayBitsPerPixelForMode(displayMode);
- safeForHardware = flags & kDisplayModeSafetyFlags ? true : false;
- televisionoutput = flags & kDisplayModeTelevisionFlag ? true : false;
+ safeForHardware = (flags & kDisplayModeSafetyFlags) != 0;
if ((bitsperpixel == 32) && (safeForHardware == true) && (stretched == false) &&
(interlaced == false))
@@ -1138,7 +1088,7 @@ void CWinSystemOSX::FillInVideoModes()
// NOTE: The refresh rate will be REPORTED AS 0 for many DVI and notebook displays.
refreshrate = 60.0;
}
- CLog::Log(LOGINFO, "Found possible resolution for display %d with %d x %d @ %f Hz", disp, w,
+ CLog::Log(LOGINFO, "Found possible resolution for display {} with {} x {} @ {} Hz", disp, w,
h, refreshrate);
// only add the resolution if it belongs to "our" screen
@@ -1158,17 +1108,17 @@ void CWinSystemOSX::FillInVideoModes()
#pragma mark - Occlusion
-bool CWinSystemOSX::IsObscured(void)
+bool CWinSystemOSX::IsObscured()
{
if (m_obscured)
- CLog::Log(LOGDEBUG, "CWinSystemOSX::IsObscured(void) - TRUE");
+ CLog::LogF(LOGDEBUG, "Obscured");
return m_obscured;
}
void CWinSystemOSX::SetOcclusionState(bool occluded)
{
// m_obscured = occluded;
- // CLog::Log(LOGDEBUG, "CWinSystemOSX::SetOcclusionState(bool occluded) - %s", occluded ? "true":"false");
+ // CLog::LogF(LOGDEBUG, "{}", occluded ? "true":"false");
}
void CWinSystemOSX::NotifyAppFocusChange(bool bGaining)
@@ -1190,7 +1140,6 @@ void CWinSystemOSX::NotifyAppFocusChange(bool bGaining)
window = view.window;
if (window)
{
- SetMenuBarVisible(false);
[window orderFront:nil];
}
}
@@ -1204,8 +1153,8 @@ void CWinSystemOSX::OnMove(int x, int y)
{
static double oldRefreshRate = m_refreshRate;
Cocoa_CVDisplayLinkUpdate();
- int dummy = 0;
+ int dummy = 0;
GetScreenResolution(&dummy, &dummy, &m_refreshRate, m_lastDisplayNr);
if (oldRefreshRate != m_refreshRate)
@@ -1215,8 +1164,8 @@ void CWinSystemOSX::OnMove(int x, int y)
// send a message so that videoresolution (and refreshrate) is changed
NSWindow* win = m_appWindow;
NSRect frame = win.contentView.frame;
- KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(
- TMSG_VIDEORESIZE, frame.size.width, frame.size.height);
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_VIDEORESIZE, frame.size.width,
+ frame.size.height);
}
}
@@ -1260,7 +1209,7 @@ CGLContextObj CWinSystemOSX::GetCGLContextObj()
return cglcontex;
}
-bool CWinSystemOSX::FlushBuffer(void)
+bool CWinSystemOSX::FlushBuffer()
{
if (m_appWindow)
{
@@ -1285,8 +1234,7 @@ void CWinSystemOSX::EnableVSync(bool enable)
std::unique_ptr<CVideoSync> CWinSystemOSX::GetVideoSync(void* clock)
{
- std::unique_ptr<CVideoSync> pVSync(new CVideoSyncOsx(clock));
- return pVSync;
+ return std::make_unique<CVideoSyncOsx>(clock);
}
std::vector<std::string> CWinSystemOSX::GetConnectedOutputs()
@@ -1309,7 +1257,7 @@ std::vector<std::string> CWinSystemOSX::GetConnectedOutputs()
std::unique_ptr<IOSScreenSaver> CWinSystemOSX::GetOSScreenSaverImpl()
{
- return std::unique_ptr<IOSScreenSaver>(new COSScreenSaverOSX);
+ return std::make_unique<COSScreenSaverOSX>();
}
#pragma mark - Input
@@ -1329,7 +1277,7 @@ void CWinSystemOSX::disableInputEvents()
m_winEvents->disableInputEvents();
}
-std::string CWinSystemOSX::GetClipboardText(void)
+std::string CWinSystemOSX::GetClipboardText()
{
std::string utf8_text;