Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemCocoa.mm')
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm490
1 files changed, 226 insertions, 264 deletions
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index f42d4af109a..9c28449a4e5 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -80,7 +80,7 @@ static GHOST_TButtonMask convertButton(int button)
}
/**
- * Converts Mac rawkey codes (same for Cocoa & Carbon)
+ * Converts Mac raw-key codes (same for Cocoa & Carbon)
* into GHOST key codes
* \param rawCode: The raw physical key code
* \param recvChar: the character ignoring modifiers (except for shift)
@@ -386,13 +386,11 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
- (id)init
{
self = [super init];
- if (self) {
- NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
- selector:@selector(windowWillClose:)
- name:NSWindowWillCloseNotification
- object:nil];
- }
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserver:self
+ selector:@selector(windowWillClose:)
+ name:NSWindowWillCloseNotification
+ object:nil];
return self;
}
@@ -563,92 +561,96 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
SetFrontProcess(&psn);
}*/
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication]; // initializes NSApp
-
- if ([NSApp mainMenu] == nil) {
- NSMenu *mainMenubar = [[NSMenu alloc] init];
- NSMenuItem *menuItem;
- NSMenu *windowMenu;
- NSMenu *appMenu;
-
- // Create the application menu
- appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
-
- [appMenu addItemWithTitle:@"About Blender"
- action:@selector(orderFrontStandardAboutPanel:)
- keyEquivalent:@""];
- [appMenu addItem:[NSMenuItem separatorItem]];
-
- menuItem = [appMenu addItemWithTitle:@"Hide Blender"
- action:@selector(hide:)
- keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
-
- menuItem = [appMenu addItemWithTitle:@"Hide Others"
- action:@selector(hideOtherApplications:)
- keyEquivalent:@"h"];
- [menuItem
- setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand)];
-
- [appMenu addItemWithTitle:@"Show All"
- action:@selector(unhideAllApplications:)
- keyEquivalent:@""];
-
- menuItem = [appMenu addItemWithTitle:@"Quit Blender"
- action:@selector(terminate:)
- keyEquivalent:@"q"];
- [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
-
- menuItem = [[NSMenuItem alloc] init];
- [menuItem setSubmenu:appMenu];
-
- [mainMenubar addItem:menuItem];
- [menuItem release];
- [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; // Needed for 10.5
- [appMenu release];
-
- // Create the window menu
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- menuItem = [windowMenu addItemWithTitle:@"Minimize"
- action:@selector(performMiniaturize:)
- keyEquivalent:@"m"];
- [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
-
- [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
-
- menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen"
- action:@selector(toggleFullScreen:)
- keyEquivalent:@"f"];
- [menuItem
- setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
-
- menuItem = [windowMenu addItemWithTitle:@"Close"
- action:@selector(performClose:)
- keyEquivalent:@"w"];
- [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
-
- menuItem = [[NSMenuItem alloc] init];
- [menuItem setSubmenu:windowMenu];
-
- [mainMenubar addItem:menuItem];
- [menuItem release];
-
- [NSApp setMainMenu:mainMenubar];
- [NSApp setWindowsMenu:windowMenu];
- [windowMenu release];
- }
+ @autoreleasepool {
+ [NSApplication sharedApplication]; // initializes NSApp
+
+ if ([NSApp mainMenu] == nil) {
+ NSMenu *mainMenubar = [[NSMenu alloc] init];
+ NSMenuItem *menuItem;
+ NSMenu *windowMenu;
+ NSMenu *appMenu;
+
+ // Create the application menu
+ appMenu = [[NSMenu alloc] initWithTitle:@"Blender"];
+
+ [appMenu addItemWithTitle:@"About Blender"
+ action:@selector(orderFrontStandardAboutPanel:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+
+ menuItem = [appMenu addItemWithTitle:@"Hide Blender"
+ action:@selector(hide:)
+ keyEquivalent:@"h"];
+ [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
+
+ menuItem = [appMenu addItemWithTitle:@"Hide Others"
+ action:@selector(hideOtherApplications:)
+ keyEquivalent:@"h"];
+ [menuItem
+ setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand)];
+
+ [appMenu addItemWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)
+ keyEquivalent:@""];
+
+ menuItem = [appMenu addItemWithTitle:@"Quit Blender"
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+ [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
+
+ menuItem = [[NSMenuItem alloc] init];
+ [menuItem setSubmenu:appMenu];
+
+ [mainMenubar addItem:menuItem];
+ [menuItem release];
+ [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; // Needed for 10.5
+ [appMenu release];
+
+ // Create the window menu
+ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+
+ menuItem = [windowMenu addItemWithTitle:@"Minimize"
+ action:@selector(performMiniaturize:)
+ keyEquivalent:@"m"];
+ [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
+
+ [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""];
+
+ menuItem = [windowMenu addItemWithTitle:@"Enter Full Screen"
+ action:@selector(toggleFullScreen:)
+ keyEquivalent:@"f"];
+ [menuItem
+ setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
+
+ menuItem = [windowMenu addItemWithTitle:@"Close"
+ action:@selector(performClose:)
+ keyEquivalent:@"w"];
+ [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
+
+ menuItem = [[NSMenuItem alloc] init];
+ [menuItem setSubmenu:windowMenu];
+
+ [mainMenubar addItem:menuItem];
+ [menuItem release];
+
+ [NSApp setMainMenu:mainMenubar];
+ [NSApp setWindowsMenu:windowMenu];
+ [windowMenu release];
+ }
- if ([NSApp delegate] == nil) {
- CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
- [appDelegate setSystemCocoa:this];
- [NSApp setDelegate:appDelegate];
- }
+ if ([NSApp delegate] == nil) {
+ CocoaAppDelegate *appDelegate = [[CocoaAppDelegate alloc] init];
+ [appDelegate setSystemCocoa:this];
+ [NSApp setDelegate:appDelegate];
+ }
- [NSApp finishLaunching];
+ // AppKit provides automatic window tabbing. Blender is a single-tabbed application
+ // without a macOS tab bar, and should explicitly opt-out of this. This is also
+ // controlled by the macOS user default #NSWindowTabbingEnabled.
+ NSWindow.allowsAutomaticWindowTabbing = NO;
- [pool drain];
+ [NSApp finishLaunching];
+ }
}
return success;
}
@@ -671,30 +673,26 @@ GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
{
// Note that OS X supports monitor hot plug
// We do not support multiple monitors at the moment
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- GHOST_TUns8 count = [[NSScreen screens] count];
-
- [pool drain];
- return count;
+ @autoreleasepool {
+ return NSScreen.screens.count;
+ }
}
void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- // Get visible frame, that is frame excluding dock and top menu bar
- NSRect frame = [[NSScreen mainScreen] visibleFrame];
-
- // Returns max window contents (excluding title bar...)
- NSRect contentRect = [NSWindow
- contentRectForFrameRect:frame
- styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
- NSWindowStyleMaskMiniaturizable)];
-
- width = contentRect.size.width;
- height = contentRect.size.height;
-
- [pool drain];
+ @autoreleasepool {
+ // Get visible frame, that is frame excluding dock and top menu bar
+ NSRect frame = [[NSScreen mainScreen] visibleFrame];
+
+ // Returns max window contents (excluding title bar...)
+ NSRect contentRect = [NSWindow
+ contentRectForFrameRect:frame
+ styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable)];
+
+ width = contentRect.size.width;
+ height = contentRect.size.height;
+ }
}
void GHOST_SystemCocoa::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
@@ -715,53 +713,52 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_IWindow *window = NULL;
-
- // Get the available rect for including window contents
- NSRect frame = [[NSScreen mainScreen] visibleFrame];
- NSRect contentRect = [NSWindow
- contentRectForFrameRect:frame
- styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
- NSWindowStyleMaskMiniaturizable)];
-
- GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top;
-
- // Ensures window top left is inside this available rect
- left = left > contentRect.origin.x ? left : contentRect.origin.x;
- // Add contentRect.origin.y to respect docksize
- bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
-
- window = new GHOST_WindowCocoa(this,
- title,
- left,
- bottom,
- width,
- height,
- state,
- type,
- glSettings.flags & GHOST_glStereoVisual,
- glSettings.flags & GHOST_glDebugContext,
- is_dialog,
- (GHOST_WindowCocoa *)parentWindow);
-
- if (window->getValid()) {
- // Store the pointer to the window
- GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
- m_windowManager->addWindow(window);
- m_windowManager->setActiveWindow(window);
- /* Need to tell window manager the new window is the active one
- * (Cocoa does not send the event activate upon window creation). */
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
- pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
- }
- else {
- GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
- delete window;
- window = NULL;
+ @autoreleasepool {
+
+ // Get the available rect for including window contents
+ NSRect frame = [[NSScreen mainScreen] visibleFrame];
+ NSRect contentRect = [NSWindow
+ contentRectForFrameRect:frame
+ styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable)];
+
+ GHOST_TInt32 bottom = (contentRect.size.height - 1) - height - top;
+
+ // Ensures window top left is inside this available rect
+ left = left > contentRect.origin.x ? left : contentRect.origin.x;
+ // Add contentRect.origin.y to respect docksize
+ bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
+
+ window = new GHOST_WindowCocoa(this,
+ title,
+ left,
+ bottom,
+ width,
+ height,
+ state,
+ type,
+ glSettings.flags & GHOST_glStereoVisual,
+ glSettings.flags & GHOST_glDebugContext,
+ is_dialog,
+ (GHOST_WindowCocoa *)parentWindow);
+
+ if (window->getValid()) {
+ // Store the pointer to the window
+ GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
+ m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
+ /* Need to tell window manager the new window is the active one
+ * (Cocoa does not send the event activate upon window creation). */
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window));
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
+ delete window;
+ window = NULL;
+ }
}
-
- [pool drain];
return window;
}
@@ -836,29 +833,28 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_T
if (!window)
return GHOST_kFailure;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSScreen *windowScreen = window->getScreen();
- NSRect screenRect = [windowScreen frame];
+ @autoreleasepool {
+ NSScreen *windowScreen = window->getScreen();
+ NSRect screenRect = [windowScreen frame];
- // Set position relative to current screen
- xf -= screenRect.origin.x;
- yf -= screenRect.origin.y;
+ // Set position relative to current screen
+ xf -= screenRect.origin.x;
+ yf -= screenRect.origin.y;
- // Quartz Display Services uses the old coordinates (top left origin)
- yf = screenRect.size.height - yf;
+ // Quartz Display Services uses the old coordinates (top left origin)
+ yf = screenRect.size.height - yf;
- CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription]
- objectForKey:@"NSScreenNumber"] unsignedIntValue],
- CGPointMake(xf, yf));
+ CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription]
+ objectForKey:@"NSScreenNumber"] unsignedIntValue],
+ CGPointMake(xf, yf));
- // See https://stackoverflow.com/a/17559012. By default, hardware events
- // will be suppressed for 500ms after a synthetic mouse event. For unknown
- // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
- // however calling CGAssociateMouseAndMouseCursorPosition also removes the
- // delay, even if this is undocumented.
- CGAssociateMouseAndMouseCursorPosition(true);
-
- [pool drain];
+ // See https://stackoverflow.com/a/17559012. By default, hardware events
+ // will be suppressed for 500ms after a synthetic mouse event. For unknown
+ // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
+ // however calling CGAssociateMouseAndMouseCursorPosition also removes the
+ // delay, even if this is undocumented.
+ CGAssociateMouseAndMouseCursorPosition(true);
+ }
return GHOST_kSuccess;
}
@@ -923,42 +919,40 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
}
#endif
do {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- event = [NSApp nextEventMatchingMask:NSEventMaskAny
- untilDate:[NSDate distantPast]
- inMode:NSDefaultRunLoopMode
- dequeue:YES];
- if (event == nil) {
- [pool drain];
- break;
- }
+ @autoreleasepool {
+ event = [NSApp nextEventMatchingMask:NSEventMaskAny
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+ if (event == nil) {
+ break;
+ }
- anyProcessed = true;
+ anyProcessed = true;
- // Send event to NSApp to ensure Mac wide events are handled,
- // this will send events to CocoaWindow which will call back
- // to handleKeyEvent, handleMouseEvent and handleTabletEvent
+ // Send event to NSApp to ensure Mac wide events are handled,
+ // this will send events to CocoaWindow which will call back
+ // to handleKeyEvent, handleMouseEvent and handleTabletEvent
- // There is on special exception for ctrl+(shift)+tab. We do not
- // get keyDown events delivered to the view because they are
- // special hotkeys to switch between views, so override directly
+ // There is on special exception for ctrl+(shift)+tab. We do not
+ // get keyDown events delivered to the view because they are
+ // special hotkeys to switch between views, so override directly
- if ([event type] == NSEventTypeKeyDown && [event keyCode] == kVK_Tab &&
- ([event modifierFlags] & NSEventModifierFlagControl)) {
- handleKeyEvent(event);
- }
- else {
- // For some reason NSApp is swallowing the key up events when modifier
- // key is pressed, even if there seems to be no apparent reason to do
- // so, as a workaround we always handle these up events.
- if ([event type] == NSEventTypeKeyUp &&
- ([event modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagOption)))
+ if ([event type] == NSEventTypeKeyDown && [event keyCode] == kVK_Tab &&
+ ([event modifierFlags] & NSEventModifierFlagControl)) {
handleKeyEvent(event);
-
- [NSApp sendEvent:event];
+ }
+ else {
+ // For some reason NSApp is swallowing the key up events when modifier
+ // key is pressed, even if there seems to be no apparent reason to do
+ // so, as a workaround we always handle these up events.
+ if ([event type] == NSEventTypeKeyUp &&
+ ([event modifierFlags] & (NSEventModifierFlagCommand | NSEventModifierFlagOption)))
+ handleKeyEvent(event);
+
+ [NSApp sendEvent:event];
+ }
}
-
- [pool drain];
} while (event != nil);
#if 0
} while (waitForEvent && !anyProcessed); // Needed only for timer implementation
@@ -1672,10 +1666,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
NSEventPhase momentumPhase = NSEventPhaseNone;
NSEventPhase phase = NSEventPhaseNone;
- if ([event respondsToSelector:@selector(momentumPhase)])
- momentumPhase = [event momentumPhase];
- if ([event respondsToSelector:@selector(phase)])
- phase = [event phase];
+ momentumPhase = [event momentumPhase];
+ phase = [event phase];
/* when pressing a key while momentum scrolling continues after
* lifting fingers off the trackpad, the action can unexpectedly
@@ -1948,78 +1940,48 @@ GHOST_TUns8 *GHOST_SystemCocoa::getClipboard(bool selection) const
GHOST_TUns8 *temp_buff;
size_t pastedTextSize;
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
-
- if (pasteBoard == nil) {
- [pool drain];
- return NULL;
- }
-
- NSArray *supportedTypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
+ @autoreleasepool {
- NSString *bestType = [[NSPasteboard generalPasteboard] availableTypeFromArray:supportedTypes];
-
- if (bestType == nil) {
- [pool drain];
- return NULL;
- }
+ NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
- NSString *textPasted = [pasteBoard stringForType:NSStringPboardType];
+ NSString *textPasted = [pasteBoard stringForType:NSStringPboardType];
- if (textPasted == nil) {
- [pool drain];
- return NULL;
- }
+ if (textPasted == nil) {
+ return NULL;
+ }
- pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+ pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1);
+ temp_buff = (GHOST_TUns8 *)malloc(pastedTextSize + 1);
- if (temp_buff == NULL) {
- [pool drain];
- return NULL;
- }
-
- strncpy(
- (char *)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
+ if (temp_buff == NULL) {
+ return NULL;
+ }
- temp_buff[pastedTextSize] = '\0';
+ strncpy(
+ (char *)temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
- [pool drain];
+ temp_buff[pastedTextSize] = '\0';
- if (temp_buff) {
- return temp_buff;
- }
- else {
- return NULL;
+ if (temp_buff) {
+ return temp_buff;
+ }
+ else {
+ return NULL;
+ }
}
}
void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
{
- NSString *textToCopy;
-
if (selection)
return; // for copying the selection, used on X11
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ @autoreleasepool {
- NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
-
- if (pasteBoard == nil) {
- [pool drain];
- return;
+ NSPasteboard *pasteBoard = NSPasteboard.generalPasteboard;
+ [pasteBoard declareTypes:@[ NSStringPboardType ] owner:nil];
+ NSString *textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
+ [pasteBoard setString:textToCopy forType:NSStringPboardType];
}
-
- NSArray *supportedTypes = [NSArray arrayWithObject:NSStringPboardType];
-
- [pasteBoard declareTypes:supportedTypes owner:nil];
-
- textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
-
- [pasteBoard setString:textToCopy forType:NSStringPboardType];
-
- [pool drain];
}