// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "toplevel.h"
#endif
#include "wx/log.h"
#include "wx/intl.h"
#include "wx/settings.h"
+ #include "wx/strconv.h"
+ #include "wx/control.h"
#endif //WX_PRECOMP
#include "wx/mac/uma.h"
static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
-
- wxWindow* focus = wxWindow::FindFocus() ;
+ // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl)
+ // FindFocus does not return the actual focus window,but the enclosing window
+ wxWindow* focus = wxWindow::DoFindFocus();
if ( focus == NULL )
return result ;
char charCode ;
+ wxChar uniChar = 0 ;
UInt32 keyCode ;
UInt32 modifiers ;
Point point ;
UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+#if wxUSE_UNICODE
+ UInt32 dataSize = 0 ;
+ if ( GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0 , &dataSize , NULL ) == noErr )
+ {
+ UniChar buf[2] ;
+
+ UniChar* charBuf = buf ;
+
+ if ( dataSize > 4 )
+ charBuf = new UniChar[ dataSize / sizeof( UniChar) ] ;
+ GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
+#if SIZEOF_WCHAR_T == 2
+ uniChar = charBuf[0] ;
+#else
+ wxMBConvUTF16BE converter ;
+ converter.MB2WC( &uniChar , (const char*)charBuf , 1 ) ;
+#endif
+ if ( dataSize > 4 )
+ delete[] charBuf ;
+ }
+#endif
+
GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
sizeof( Point ), NULL, &point );
-
+
UInt32 message = (keyCode << 8) + charCode;
switch( GetEventKind( event ) )
{
WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
wxTheApp->MacSetCurrentEvent( event , handler ) ;
if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
- focus , message , modifiers , when , point.h , point.v ) )
+ focus , message , modifiers , when , point.h , point.v , uniChar ) )
{
result = noErr ;
}
break ;
case kEventRawKeyUp :
if ( (focus != NULL) && wxTheApp->MacSendKeyUpEvent(
- focus , message , modifiers , when , point.h , point.v ) )
+ focus , message , modifiers , when , point.h , point.v , uniChar ) )
{
result = noErr ;
}
event.m_controlDown = modifiers & controlKey;
event.m_altDown = modifiers & optionKey;
event.m_metaDown = modifiers & cmdKey;
-
+#if wxUSE_UNICODE
+ event.m_uniChar = uniChar ;
+#endif
event.m_x = point.h;
event.m_y = point.v;
- event.m_timeStamp = when;
- wxWindow* focus = wxWindow::FindFocus() ;
+ event.SetTimestamp(when);
event.SetEventObject(focus);
if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & controlKey )
}
}
-ControlRef wxMacFindSubControl( Point location , ControlRef superControl , ControlPartCode *outPart )
+ControlRef wxMacFindSubControl( wxTopLevelWindowMac* toplevelWindow, Point location , ControlRef superControl , ControlPartCode *outPart )
{
if ( superControl )
{
UMAGetControlBoundsInWindowCoords( sibling , &r ) ;
if ( MacPtInRect( location , &r ) )
{
- ControlHandle child = wxMacFindSubControl( location , sibling , outPart ) ;
+ ControlHandle child = wxMacFindSubControl( toplevelWindow , location , sibling , outPart ) ;
if ( child )
return child ;
else
{
Point testLocation = location ;
-#if TARGET_API_MAC_OSX
- testLocation.h -= r.left ;
- testLocation.v -= r.top ;
-#endif
+
+ if ( toplevelWindow && toplevelWindow->MacUsesCompositing() )
+ {
+ testLocation.h -= r.left ;
+ testLocation.v -= r.top ;
+ }
+
*outPart = TestControl( sibling , testLocation ) ;
return sibling ;
}
return NULL ;
}
-ControlRef wxMacFindControlUnderMouse( Point location , WindowRef window , ControlPartCode *outPart )
+ControlRef wxMacFindControlUnderMouse( wxTopLevelWindowMac* toplevelWindow , Point location , WindowRef window , ControlPartCode *outPart )
{
#if TARGET_API_MAC_OSX
- if ( UMAGetSystemVersion() >= 0x1030 )
+ if ( UMAGetSystemVersion() >= 0x1030 && ( toplevelWindow == 0 || toplevelWindow->MacUsesCompositing() ) )
return FindControlUnderMouse( location , window , outPart ) ;
#endif
ControlRef rootControl = NULL ;
verify_noerr( GetRootControl( window , &rootControl ) ) ;
- return wxMacFindSubControl( location , rootControl , outPart ) ;
+ return wxMacFindSubControl( toplevelWindow , location , rootControl , outPart ) ;
}
pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
+ wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
OSStatus result = eventNotHandledErr ;
else if ( (IsWindowActive(window) && windowPart == inContent) )
{
ControlPartCode part ;
- control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ;
+ control = wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &part ) ;
// if there is no control below the mouse position, send the event to the toplevel window itself
if ( control == 0 )
currentMouseWindow = (wxWindow*) data ;
currentMouseWindow = wxFindControlFromMacControl( control ) ;
if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved )
{
+#if wxUSE_TOOLBAR
// for wxToolBar to function we have to send certaint events to it
// instead of its children (wxToolBarTools)
ControlRef parent ;
wxWindow *wxParent = wxFindControlFromMacControl( parent ) ;
if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) )
currentMouseWindow = wxParent ;
+#endif
}
}
}
} // if ( windowPart == inMenuBar )
else if ( currentMouseWindow )
{
+ wxWindow *currentMouseWindowParent = currentMouseWindow->GetParent();
+
currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;
wxevent.SetEventObject( currentMouseWindow ) ;
- // update cursor
-
- wxWindow* cursorTarget = currentMouseWindow ;
- wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
-
- while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
- {
- cursorTarget = cursorTarget->GetParent() ;
- if ( cursorTarget )
- cursorPoint += cursorTarget->GetPosition() ;
- }
-
// make tooltips current
#if wxUSE_TOOLTIPS
wxToolTip::RelayEvent( currentMouseWindow , wxevent);
#endif // wxUSE_TOOLTIPS
if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )
+ {
+ if ((currentMouseWindowParent != NULL) &&
+ (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
+ currentMouseWindow = NULL;
+
result = noErr;
+ }
else
{
// if the user code did _not_ handle the event, then perform the
// if built-in find control is finding the wrong control (ie static box instead of overlaid
// button, we cannot let the standard handler do its job, but must handle manually
- if ( ( cEvent.GetKind() == kEventMouseDown ) &&
+ if ( ( cEvent.GetKind() == kEventMouseDown )
+#ifdef __WXMAC_OSX__
+ &&
(FindControlUnderMouse(windowMouseLocation , window , &dummyPart) !=
- wxMacFindControlUnderMouse( windowMouseLocation , window , &dummyPart ) ) )
+ wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &dummyPart ) )
+#endif
+ )
{
if ( currentMouseWindow->MacIsReallyEnabled() )
{
EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
Point clickLocation = windowMouseLocation ;
- #if TARGET_API_MAC_OSX
- currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
- #endif
+
+ if ( toplevelWindow->MacUsesCompositing() )
+ currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
+
HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
modifiers , (ControlActionUPP ) -1 ) ;
+
+ if ((currentMouseWindowParent != NULL) &&
+ (currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
+ currentMouseWindow = NULL;
}
result = noErr ;
}
wxTheApp->s_captureWindow = NULL ;
// update cursor ?
}
+
+ // update cursor
+
+ wxWindow* cursorTarget = currentMouseWindow ;
+ wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
+
+ while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
+ {
+ cursorTarget = cursorTarget->GetParent() ;
+ if ( cursorTarget )
+ cursorPoint += cursorTarget->GetPosition();
+ }
+
} // else if ( currentMouseWindow )
else
{
// don't mess with controls we don't know about
// for some reason returning eventNotHandledErr does not lead to the correct behaviour
// so we try sending them the correct control directly
- wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
if ( cEvent.GetKind() == kEventMouseDown && toplevelWindow && control )
{
EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
Point clickLocation = windowMouseLocation ;
-#if TARGET_API_MAC_OSX
- HIPoint hiPoint ;
- hiPoint.x = clickLocation.h ;
- hiPoint.y = clickLocation.v ;
- HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control ) ;
- clickLocation.h = (int)hiPoint.x ;
- clickLocation.v = (int)hiPoint.y ;
+ if ( toplevelWindow->MacUsesCompositing() )
+ {
+#ifdef __WXMAC_OSX__
+ HIPoint hiPoint ;
+ hiPoint.x = clickLocation.h ;
+ hiPoint.y = clickLocation.v ;
+ HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control ) ;
+ clickLocation.h = (int)hiPoint.x ;
+ clickLocation.v = (int)hiPoint.y ;
#endif
+ }
HandleControlClick( control , clickLocation ,
modifiers , (ControlActionUPP ) -1 ) ;
result = noErr ;
cEvent.SetParameter<Rect>( kEventParamCurrentBounds , &adjustedRect ) ;
}
- result = noErr ;
+ result = noErr ;
break ;
}
default :
m_maximizeOnShow = FALSE;
m_macWindow = NULL ;
#if TARGET_API_MAC_OSX
- m_macUsesCompositing = TRUE;
-#else
- m_macUsesCompositing = FALSE;
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ {
+ m_macUsesCompositing = TRUE;
+ }
+ else
#endif
+ {
+ m_macUsesCompositing = FALSE;
+ }
m_macEventHandler = NULL ;
m_macFullScreenData = NULL ;
}
MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
+
+ if (GetExtraStyle() & wxFRAME_EX_METAL)
+ MacSetMetalAppearance(true);
wxTopLevelWindows.Append(this);
{
if ( m_macWindow )
{
+#if wxUSE_TOOLTIPS
wxToolTip::NotifyWindowDelete(m_macWindow) ;
+#endif
wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
}
WindowClass wclass = 0;
WindowAttributes attr = kWindowNoAttributes ;
+ WindowGroupRef group = NULL ;
if ( HasFlag( wxFRAME_TOOL_WINDOW) )
{
else if ( HasFlag( wxFRAME_DRAWER ) )
{
wclass = kDrawerWindowClass;
- // Should this be left for compositing check below?
- // CreateNewWindow will fail without it, should wxDrawerWindow turn
- // on compositing before calling MacCreateRealWindow?
- attr |= kWindowCompositingAttribute;// | kWindowStandardHandlerAttribute;
+ // we must force compositing on a drawer
+ m_macUsesCompositing = TRUE ;
}
#endif //10.2 and up
else
attr |= kWindowLiveResizeAttribute;
}
- if (HasFlag(wxSTAY_ON_TOP))
- wclass = kUtilityWindowClass;
+ if ( HasFlag(wxSTAY_ON_TOP) )
+ {
+ group = GetWindowGroupOfClass(kUtilityWindowClass) ;
+ }
#if TARGET_API_MAC_OSX
- attr |= kWindowCompositingAttribute;
+ if ( m_macUsesCompositing )
+ attr |= kWindowCompositingAttribute;
#endif
if ( HasFlag(wxFRAME_SHAPED) )
err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
}
+ if ( err == noErr && m_macWindow != NULL && group != NULL )
+ SetWindowGroup( (WindowRef) m_macWindow , group ) ;
+
wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") );
// the create commands are only for content rect, so we have to set the size again as
wxAssociateWinWithMacWindow( (WindowRef) m_macWindow , this ) ;
UMASetWTitle( (WindowRef) m_macWindow , title , m_font.GetEncoding() ) ;
- m_peer = new wxMacControl() ;
+ m_peer = new wxMacControl(this , true /*isRootControl*/) ;
#if TARGET_API_MAC_OSX
- // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
- // the content view, so we have to retrieve it explicitely
- HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID ,
- m_peer->GetControlRefAddr() ) ;
- if ( !m_peer->Ok() )
+
+ if ( m_macUsesCompositing )
{
- // compatibility mode fallback
- GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ;
+ // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
+ // the content view, so we have to retrieve it explicitely
+ HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID ,
+ m_peer->GetControlRefAddr() ) ;
+ if ( !m_peer->Ok() )
+ {
+ // compatibility mode fallback
+ GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ;
+ }
}
-#else
- ::CreateRootControl( (WindowRef)m_macWindow , m_peer->GetControlRefAddr() ) ;
#endif
+ {
+ ::CreateRootControl( (WindowRef)m_macWindow , m_peer->GetControlRefAddr() ) ;
+ }
// the root control level handleer
MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ;
void wxTopLevelWindowMac::MacSetMetalAppearance( bool set )
{
#if TARGET_API_MAC_OSX
- UInt32 attr = 0 ;
- GetWindowAttributes((WindowRef) m_macWindow , &attr ) ;
- wxASSERT_MSG( attr & kWindowCompositingAttribute ,
+ wxASSERT_MSG( m_macUsesCompositing ,
wxT("Cannot set metal appearance on a non-compositing window") ) ;
MacChangeWindowAttributes( set ? kWindowMetalAttribute : kWindowNoAttributes ,
return attr ;
}
+// Attracts the users attention to this window if the application is
+// inactive (should be called when a background event occurs)
+
+static pascal void wxMacNMResponse( NMRecPtr ptr )
+{
+ NMRemove( ptr ) ;
+ DisposePtr( (Ptr) ptr ) ;
+}
+
+
+void wxTopLevelWindowMac::RequestUserAttention(int flags )
+{
+ NMRecPtr notificationRequest = (NMRecPtr) NewPtr( sizeof( NMRec) ) ;
+ static wxMacNMUPP nmupp( wxMacNMResponse )
+ ;
+ memset( notificationRequest , 0 , sizeof(*notificationRequest) ) ;
+ notificationRequest->qType = nmType ;
+ notificationRequest->nmMark = 1 ;
+ notificationRequest->nmIcon = 0 ;
+ notificationRequest->nmSound = 0 ;
+ notificationRequest->nmStr = NULL ;
+ notificationRequest->nmResp = nmupp ;
+ verify_noerr( NMInstall( notificationRequest ) ) ;
+}
+
// ---------------------------------------------------------------------------
// Shape implementation
// ---------------------------------------------------------------------------