- (void)setImagePosition:(NSCellImagePosition)aPosition;
@end
-long wxOSXTranslateCocoaKey( NSEvent* event )
+long wxOSXTranslateCocoaKey( NSEvent* event, int eventType )
{
long retval = 0;
// backspace char reports as delete w/modifiers for some reason
if ([s length] == 1)
{
- switch ( [s characterAtIndex:0] )
+ if ( eventType == wxEVT_CHAR && ([event modifierFlags] & NSControlKeyMask) && ( [s characterAtIndex:0] >= 'a' && [s characterAtIndex:0] <= 'z' ) )
{
- // backspace key
- case 0x7F :
- case 8 :
- retval = WXK_BACK;
- break;
- case NSUpArrowFunctionKey :
- retval = WXK_UP;
- break;
- case NSDownArrowFunctionKey :
- retval = WXK_DOWN;
- break;
- case NSLeftArrowFunctionKey :
- retval = WXK_LEFT;
- break;
- case NSRightArrowFunctionKey :
- retval = WXK_RIGHT;
- break;
- case NSInsertFunctionKey :
- retval = WXK_INSERT;
- break;
- case NSDeleteFunctionKey :
- retval = WXK_DELETE;
- break;
- case NSHomeFunctionKey :
- retval = WXK_HOME;
- break;
- // case NSBeginFunctionKey :
- // retval = WXK_BEGIN;
- // break;
- case NSEndFunctionKey :
- retval = WXK_END;
- break;
- case NSPageUpFunctionKey :
- retval = WXK_PAGEUP;
- break;
- case NSPageDownFunctionKey :
- retval = WXK_PAGEDOWN;
- break;
- case NSHelpFunctionKey :
- retval = WXK_HELP;
- break;
- default:
- int intchar = [s characterAtIndex: 0];
- if ( intchar >= NSF1FunctionKey && intchar <= NSF24FunctionKey )
- retval = WXK_F1 + (intchar - NSF1FunctionKey );
- break;
+ retval = WXK_CONTROL_A + ([s characterAtIndex:0] - 'a');
+ }
+ else
+ {
+ switch ( [s characterAtIndex:0] )
+ {
+ // backspace key
+ case 0x7F :
+ case 8 :
+ retval = WXK_BACK;
+ break;
+ case NSUpArrowFunctionKey :
+ retval = WXK_UP;
+ break;
+ case NSDownArrowFunctionKey :
+ retval = WXK_DOWN;
+ break;
+ case NSLeftArrowFunctionKey :
+ retval = WXK_LEFT;
+ break;
+ case NSRightArrowFunctionKey :
+ retval = WXK_RIGHT;
+ break;
+ case NSInsertFunctionKey :
+ retval = WXK_INSERT;
+ break;
+ case NSDeleteFunctionKey :
+ retval = WXK_DELETE;
+ break;
+ case NSHomeFunctionKey :
+ retval = WXK_HOME;
+ break;
+ // case NSBeginFunctionKey :
+ // retval = WXK_BEGIN;
+ // break;
+ case NSEndFunctionKey :
+ retval = WXK_END;
+ break;
+ case NSPageUpFunctionKey :
+ retval = WXK_PAGEUP;
+ break;
+ case NSPageDownFunctionKey :
+ retval = WXK_PAGEDOWN;
+ break;
+ case NSHelpFunctionKey :
+ retval = WXK_HELP;
+ break;
+ default:
+ int intchar = [s characterAtIndex: 0];
+ if ( intchar >= NSF1FunctionKey && intchar <= NSF24FunctionKey )
+ retval = WXK_F1 + (intchar - NSF1FunctionKey );
+ else if ( intchar > 0 && intchar < 32 )
+ retval = intchar;
+ break;
+ }
}
}
}
// command key
case 54:
case 55:
- retval = WXK_COMMAND;
+ retval = WXK_CONTROL;
break;
// caps locks key
case 57: // Capslock
// ctrl key
case 59: // Left Ctrl
case 62: // Right Ctrl
- retval = WXK_CONTROL;
+ retval = WXK_RAW_CONTROL;
break;
// clear key
case 71:
int eventType = [nsEvent type];
wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
- wxevent.m_controlDown = modifiers & NSControlKeyMask;
+ wxevent.m_rawControlDown = modifiers & NSControlKeyMask;
wxevent.m_altDown = modifiers & NSAlternateKeyMask;
- wxevent.m_metaDown = modifiers & NSCommandKeyMask;
+ wxevent.m_controlDown = modifiers & NSCommandKeyMask;
wxevent.m_rawCode = [nsEvent keyCode];
wxevent.m_rawFlags = modifiers;
wxString chars;
if ( eventType != NSFlagsChanged )
{
- NSString* nschars = [nsEvent charactersIgnoringModifiers];
+ NSString* nschars = [[nsEvent charactersIgnoringModifiers] uppercaseString];
if ( charString )
{
// if charString is set, it did not come from key up / key down
if (wxevent.GetEventType() != wxEVT_CHAR)
{
- keyval = wxOSXTranslateCocoaKey(nsEvent) ;
+ keyval = wxOSXTranslateCocoaKey(nsEvent, wxevent.GetEventType()) ;
switch (eventType)
{
case NSKeyDown :
case WXK_ALT:
wxevent.SetEventType( wxevent.m_altDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
break;
- case WXK_COMMAND:
- wxevent.SetEventType( wxevent.m_metaDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
+ case WXK_RAW_CONTROL:
+ wxevent.SetEventType( wxevent.m_rawControlDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
break;
}
break;
}
#if wxUSE_UNICODE
- wxevent.m_uniChar = aunichar;
+ // OS X generates events with key codes in Unicode private use area for
+ // unprintable symbols such as cursor arrows (WXK_UP is mapped to U+F700)
+ // and function keys (WXK_F2 is U+F705). We don't want to use them as the
+ // result of wxKeyEvent::GetUnicodeKey() however as it's supposed to return
+ // WXK_NONE for "non characters" so explicitly exclude them.
+ //
+ // We only exclude the private use area inside the Basic Multilingual Plane
+ // as key codes beyond it don't seem to be currently used.
+ if ( !(aunichar >= 0xe000 && aunichar < 0xf900) )
+ wxevent.m_uniChar = aunichar;
#endif
wxevent.m_keyCode = keyval;
wxevent.m_x = locationInViewWX.x;
wxevent.m_y = locationInViewWX.y;
wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
- wxevent.m_controlDown = modifiers & NSControlKeyMask;
+ wxevent.m_rawControlDown = modifiers & NSControlKeyMask;
wxevent.m_altDown = modifiers & NSAlternateKeyMask;
- wxevent.m_metaDown = modifiers & NSCommandKeyMask;
+ wxevent.m_controlDown = modifiers & NSCommandKeyMask;
wxevent.SetTimestamp( (int)([nsEvent timestamp] * 1000) ) ;
UInt32 mouseChord = 0;
updateRgn.Offset( wxpeer->MacGetLeftBorderSize() , wxpeer->MacGetTopBorderSize() );
}
- if ( wxpeer->MacGetTopLevelWindow()->GetWindowStyle() & wxFRAME_SHAPED )
+ // Restrict the update region to the shape of the window, if any, and also
+ // remember the region that we need to clear later.
+ wxNonOwnedWindow* const tlwParent = wxpeer->MacGetTopLevelWindow();
+ const bool isTopLevel = tlwParent == wxpeer;
+ wxRegion clearRgn;
+ if ( tlwParent->GetWindowStyle() & wxFRAME_SHAPED )
{
+ if ( isTopLevel )
+ clearRgn = updateRgn;
+
int xoffset = 0, yoffset = 0;
- wxRegion rgn = wxpeer->MacGetTopLevelWindow()->GetShape();
+ wxRegion rgn = tlwParent->GetShape();
wxpeer->MacRootWindowToWindow( &xoffset, &yoffset );
rgn.Offset( xoffset, yoffset );
updateRgn.Intersect(rgn);
+
+ if ( isTopLevel )
+ {
+ // Exclude the window shape from the region to be cleared below.
+ rgn.Xor(wxpeer->GetSize());
+ clearRgn.Intersect(rgn);
+ }
}
wxpeer->GetUpdateRegion() = updateRgn;
CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
CGContextScaleCTM( context, 1, -1 );
}
+
+ if ( isTopLevel )
+ {
+ // We also need to explicitly draw the part of the top level window
+ // outside of its region with transparent colour to ensure that it is
+ // really transparent.
+ if ( clearRgn.IsOk() )
+ {
+ wxMacCGContextStateSaver saveState(context);
+ wxWindowDC dc(wxpeer);
+ dc.SetBackground(wxBrush(wxTransparentColour));
+ dc.SetDeviceClippingRegion(clearRgn);
+ dc.Clear();
+ }
+
+#if wxUSE_GRAPHICS_CONTEXT
+ // If the window shape is defined by a path, stroke the path to show
+ // the window border.
+ const wxGraphicsPath& path = tlwParent->GetShapePath();
+ if ( !path.IsNull() )
+ {
+ CGContextSetLineWidth(context, 1);
+ CGContextSetStrokeColorWithColor(context, wxLIGHT_GREY->GetCGColor());
+ CGContextAddPath(context, (CGPathRef) path.GetNativePath());
+ CGContextStrokePath(context);
+ }
+#endif // wxUSE_GRAPHICS_CONTEXT
+ }
+
wxpeer->MacPaintChildrenBorders();
wxpeer->MacSetCGContextRef( NULL );
CGContextRestoreGState( context );
{
if ( [m_osxView respondsToSelector:@selector(setImage:)] )
{
- [m_osxView setImage:bitmap.GetNSImage()];
+ if (bitmap.IsOk())
+ [m_osxView setImage:bitmap.GetNSImage()];
+ else
+ [m_osxView setImage:nil];
+
[m_osxView setNeedsDisplay:YES];
}
}
{
if ( IsUserPane() && [event type] == NSKeyDown)
{
- if ( wxevent.GetKeyCode() < WXK_SPACE || wxevent.GetKeyCode() == WXK_DELETE || wxevent.GetKeyCode() >= WXK_START )
+ long keycode = wxOSXTranslateCocoaKey( event, wxEVT_CHAR );
+
+ if ( (keycode > 0 && keycode < WXK_SPACE) || keycode == WXK_DELETE || keycode >= WXK_START )
{
// eventually we could setup a doCommandBySelector catcher and retransform this into the wx key chars
wxKeyEvent wxevent2(wxevent) ;
wxevent2.SetEventType(wxEVT_CHAR);
+ wxevent2.m_keyCode = keycode;
result = GetWXPeer()->OSXHandleKeyEvent(wxevent2);
}
else