static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
bool created = false ;
CGContextRef cgContext = NULL ;
OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
bool created = false ;
CGContextRef cgContext = NULL ;
OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
- thisWindow->MacVisibilityChanged() ;
+ // we might have two native controls attributed to the same wxWindow instance
+ // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
+ // control, as otherwise native and wx visibility are different
+ if ( thisWindow->GetPeer() != NULL && thisWindow->GetPeer()->GetControlRef() == controlRef )
+ {
+ thisWindow->MacVisibilityChanged() ;
+ }
wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
// remove this as soon as posting the synthesized event works properly
static bool inKillFocusEvent = false ;
// remove this as soon as posting the synthesized event works properly
static bool inKillFocusEvent = false ;
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
// panel wants to track the window which was the last to have focus in it
wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
// panel wants to track the window which was the last to have focus in it
wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
ControlPartCode previousControlPart = 0;
verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart));
ControlPartCode previousControlPart = 0;
verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart));
ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
// synthesize the event focus changed event
EventRef evRef = NULL ;
ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
// synthesize the event focus changed event
EventRef evRef = NULL ;
OSStatus err = MacCreateEvent(
NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) ,
kEventAttributeUserEvent , &evRef );
verify_noerr( err );
OSStatus err = MacCreateEvent(
NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) ,
kEventAttributeUserEvent , &evRef );
verify_noerr( err );
wxMacCarbonEvent iEvent( evRef ) ;
iEvent.SetParameter<ControlRef>( kEventParamDirectObject , controlRef ) ;
iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ) ;
iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ) ;
wxMacCarbonEvent iEvent( evRef ) ;
iEvent.SetParameter<ControlRef>( kEventParamDirectObject , controlRef ) ;
iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ) ;
iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ) ;
#if 0
// TODO test this first, avoid double posts etc...
PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
#if 0
// TODO test this first, avoid double posts etc...
PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
#endif
wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
#endif
wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow));
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
inKillFocusEvent = true ;
wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
// panel wants to track the window which was the last to have focus in it
wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
// panel wants to track the window which was the last to have focus in it
wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow));
wxChildFocusEvent eventFocus((wxWindow*)thisWindow);
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
event.SetEventObject(thisWindow);
-/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
+/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
#else
// the resulting string will never have more chars than the utf16 version, so this is safe
wxMBConvUTF16 converter ;
#else
// the resulting string will never have more chars than the utf16 version, so this is safe
wxMBConvUTF16 converter ;
- NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
- multiple times to update the active range during inline input, so this handler will often receive
- uncommited text, which should usually not trigger side effects. It might be a good idea to check the
- kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
- On the other hand, it can be useful for some applications to react to uncommitted text (for example,
- to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
- should add new event types to support advanced text input. For now, I would keep things as they are.
-
- However, the code that was being used caused additional problems:
+ NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
+ multiple times to update the active range during inline input, so this handler will often receive
+ uncommited text, which should usually not trigger side effects. It might be a good idea to check the
+ kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
+ On the other hand, it can be useful for some applications to react to uncommitted text (for example,
+ to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
+ should add new event types to support advanced text input. For now, I would keep things as they are.
+
+ However, the code that was being used caused additional problems:
- Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
- input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
- for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
- (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
- (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
- Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
- overlap with Unicode within the (7-bit) ASCII range.
- But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
- for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
- characters as they are and replaces the rest with '?', ensuring that update events are triggered.
- It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
- I don't have time to look into that right now.
- -- CL
+ Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
+ input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
+ for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
+ (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
+ (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
+ Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
+ overlap with Unicode within the (7-bit) ASCII range.
+ But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
+ for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
+ characters as they are and replaces the rest with '?', ensuring that update events are triggered.
+ It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
+ I don't have time to look into that right now.
+ -- CL
*/
if ( wxTheApp->MacSendCharEvent(
focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
*/
if ( wxTheApp->MacSendCharEvent(
focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
{
m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
// do not trigger refreshes upon invisible and possible partly created objects
{
m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
// do not trigger refreshes upon invisible and possible partly created objects
wxPoint point(actualX, actualY);
wxMoveEvent event(point, m_windowId);
event.SetEventObject(this);
wxPoint point(actualX, actualY);
wxMoveEvent event(point, m_windowId);
event.SetEventObject(this);
wxSize size(actualWidth, actualHeight);
wxSizeEvent event(size, m_windowId);
event.SetEventObject(this);
wxSize size(actualWidth, actualHeight);
wxSizeEvent event(size, m_windowId);
event.SetEventObject(this);
m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
// do not trigger refreshes upon invisible and possible partly created objects
m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
// do not trigger refreshes upon invisible and possible partly created objects
-bool wxWindowMac::MacIsReallyShown()
-{
- // only under OSX the visibility of the TLW is taken into account
- if ( m_isBeingDeleted )
- return false ;
-
-#if TARGET_API_MAC_OSX
- if ( m_peer && m_peer->Ok() )
- return m_peer->IsVisible();
-#endif
-
- wxWindow* win = this ;
- while ( win->IsShown() )
- {
- if ( win->IsTopLevel() )
- return true ;
-
- win = win->GetParent() ;
- if ( win == NULL )
- return true ;
- }
-
- return false ;
-}
-
- if ( m_peer && m_peer->Ok() )
- {
- m_peer->SetDrawingEnabled( true ) ;
- m_peer->InvalidateWithChildren() ;
- }
+ m_peer->SetDrawingEnabled( true ) ;
+ m_peer->InvalidateWithChildren() ;
+ else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
+ {
+ // don't skip the event here, custom background means that the app
+ // is drawing it itself in its OnPaint(), so don't draw it at all
+ // now to avoid flicker
+ }
m_peer->GetRect( &rect ) ;
int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
CGContextSaveGState( cgContext );
m_peer->GetRect( &rect ) ;
int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ;
CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ;
CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ;
CGContextSaveGState( cgContext );
- CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
+ CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 );
}
CGContextFillRect( cgContext, cgrect );
CGContextRestoreGState( cgContext );
}
CGContextFillRect( cgContext, cgrect );
CGContextRestoreGState( cgContext );
{
wxSizeEvent event(GetSize(), m_windowId);
event.SetEventObject(this);
{
wxSizeEvent event(GetSize(), m_windowId);
event.SetEventObject(this);
else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE );
wxEraseEvent eevent( GetId(), dc );
eevent.SetEventObject( this );
wxEraseEvent eevent( GetId(), dc );
eevent.SetEventObject( this );
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
this->GetId(),
this->ClientToScreen(event.GetPosition()));
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
this->GetId(),
this->ClientToScreen(event.GetPosition()));
+
+bool wxWindowMac::IsShownOnScreen() const
+{
+#if TARGET_API_MAC_OSX
+ if ( m_peer && m_peer->Ok() )
+ {
+ bool peerVis = m_peer->IsVisible();
+ bool wxVis = wxWindowBase::IsShownOnScreen();
+ if( peerVis != wxVis )
+ {
+ // CS : put a breakpoint here to investigate differences
+ // between native an wx visibilities
+ // the only place where I've encountered them until now
+ // are the hiding/showing sequences where the vis-changed event is
+ // first sent to the innermost control, while wx does things
+ // from the outmost control
+ wxVis = wxWindowBase::IsShownOnScreen();
+ return wxVis;
+ }
+
+ return m_peer->IsVisible();
+ }
+#endif
+
+ return wxWindowBase::IsShownOnScreen();
+}