1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mac/toplevel.cpp
3 // Purpose: implements wxTopLevelWindow for MSW
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "toplevel.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #include "wx/toplevel.h"
35 #include "wx/string.h"
40 #include "wx/mac/uma.h"
41 #include "wx/mac/aga.h"
43 #include "wx/tooltip.h"
46 #define wxMAC_DEBUG_REDRAW 0
47 #ifndef wxMAC_DEBUG_REDRAW
48 #define wxMAC_DEBUG_REDRAW 0
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 // list of all frames and modeless dialogs
56 wxWindowList wxModelessWindows
;
58 // double click testing
59 static Point gs_lastWhere
;
60 static long gs_lastWhen
= 0;
62 // ============================================================================
63 // wxTopLevelWindowMac implementation
64 // ============================================================================
66 // ---------------------------------------------------------------------------
68 // ---------------------------------------------------------------------------
72 extern long wxMacTranslateKey(unsigned char key
, unsigned char code
) ;
74 static const EventTypeSpec eventList
[] =
76 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
78 { kEventClassKeyboard, kEventRawKeyDown } ,
79 { kEventClassKeyboard, kEventRawKeyRepeat } ,
80 { kEventClassKeyboard, kEventRawKeyUp } ,
81 { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
83 { kEventClassWindow
, kEventWindowUpdate
} ,
84 { kEventClassWindow
, kEventWindowActivated
} ,
85 { kEventClassWindow
, kEventWindowDeactivated
} ,
86 { kEventClassWindow
, kEventWindowBoundsChanging
} ,
87 { kEventClassWindow
, kEventWindowBoundsChanged
} ,
88 { kEventClassWindow
, kEventWindowClose
} ,
90 { kEventClassMouse
, kEventMouseDown
} ,
91 { kEventClassMouse
, kEventMouseUp
} ,
92 { kEventClassMouse
, kEventMouseMoved
} ,
93 { kEventClassMouse
, kEventMouseDragged
} ,
97 static pascal OSStatus
TextInputEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
99 OSStatus result
= eventNotHandledErr
;
102 if ( wxMacConvertEventToRecord( event
, &rec
) )
104 wxTheApp
->m_macCurrentEvent
= &rec
;
105 wxWindow
* focus
= wxWindow::FindFocus() ;
106 if ( (focus
!= NULL
) && !UMAMenuEvent(&rec
) && wxTheApp
->MacSendKeyDownEvent( focus
, rec
.message
, rec
.modifiers
, rec
.when
, rec
.where
.h
, rec
.where
.v
) )
108 // was handled internally
116 static pascal OSStatus
MouseEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
118 OSStatus result
= eventNotHandledErr
;
120 wxTopLevelWindowMac
* toplevelWindow
= (wxTopLevelWindowMac
*) data
;
122 UInt32 modifiers
= 0;
123 EventMouseButton button
= 0 ;
126 GetEventParameter( event
, kEventParamMouseLocation
, typeQDPoint
, NULL
,
127 sizeof( Point
), NULL
, &point
);
128 GetEventParameter( event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
129 sizeof( UInt32
), NULL
, &modifiers
);
130 GetEventParameter( event
, kEventParamMouseButton
, typeMouseButton
, NULL
,
131 sizeof( EventMouseButton
), NULL
, &button
);
132 GetEventParameter( event
, kEventParamClickCount
, typeUInt32
, NULL
,
133 sizeof( UInt32
), NULL
, &click
);
135 if ( button
== 0 || GetEventKind( event
) == kEventMouseUp
)
136 modifiers
+= btnState
;
139 short windowPart
= ::FindWindow(point
, &window
);
140 if ( windowPart
== inContent
)
142 switch ( GetEventKind( event
) )
144 case kEventMouseDown
:
145 toplevelWindow
->MacFireMouseEvent( mouseDown
, point
.h
, point
.v
, modifiers
, EventTimeToTicks( GetEventTime( event
) ) ) ;
149 toplevelWindow
->MacFireMouseEvent( mouseUp
, point
.h
, point
.v
, modifiers
, EventTimeToTicks( GetEventTime( event
) ) ) ;
152 case kEventMouseMoved
:
153 toplevelWindow
->MacFireMouseEvent( nullEvent
, point
.h
, point
.v
, modifiers
, EventTimeToTicks( GetEventTime( event
) ) ) ;
156 case kEventMouseDragged
:
157 toplevelWindow
->MacFireMouseEvent( nullEvent
, point
.h
, point
.v
, modifiers
, EventTimeToTicks( GetEventTime( event
) ) ) ;
169 static pascal OSStatus
WindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
171 OSStatus result
= eventNotHandledErr
;
172 OSStatus err
= noErr
;
175 WindowRef windowRef
;
176 wxTopLevelWindowMac
* toplevelWindow
= (wxTopLevelWindowMac
*) data
;
178 GetEventParameter( event
, kEventParamDirectObject
, typeWindowRef
, NULL
,
179 sizeof( WindowRef
), NULL
, &windowRef
);
181 switch( GetEventKind( event
) )
183 case kEventWindowUpdate
:
184 if ( !wxPendingDelete
.Member(toplevelWindow
) )
185 toplevelWindow
->MacUpdate( EventTimeToTicks( GetEventTime( event
) ) ) ;
188 case kEventWindowActivated
:
189 toplevelWindow
->MacActivate( EventTimeToTicks( GetEventTime( event
) ) , true) ;
192 case kEventWindowDeactivated
:
193 toplevelWindow
->MacActivate( EventTimeToTicks( GetEventTime( event
) ) , false) ;
196 case kEventWindowClose
:
197 toplevelWindow
->Close() ;
200 case kEventWindowBoundsChanged
:
201 err
= GetEventParameter( event
, kEventParamAttributes
, typeUInt32
,
202 NULL
, sizeof( UInt32
), NULL
, &attributes
);
205 Rect newContentRect
;
207 GetEventParameter( event
, kEventParamCurrentBounds
, typeQDRectangle
, NULL
,
208 sizeof( newContentRect
), NULL
, &newContentRect
);
210 toplevelWindow
->SetSize( newContentRect
.left
, newContentRect
.top
,
211 newContentRect
.right
- newContentRect
.left
,
212 newContentRect
.bottom
- newContentRect
.top
, wxSIZE_USE_EXISTING
);
223 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
225 OSStatus result
= eventNotHandledErr
;
227 switch ( GetEventClass( event
) )
229 case kEventClassTextInput
:
230 result
= TextInputEventHandler( handler
, event
, data
) ;
232 case kEventClassWindow
:
233 result
= WindowEventHandler( handler
, event
, data
) ;
235 case kEventClassMouse
:
236 result
= MouseEventHandler( handler
, event
, data
) ;
244 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
248 // ---------------------------------------------------------------------------
249 // wxWindowMac utility functions
250 // ---------------------------------------------------------------------------
252 // Find an item given the Macintosh Window Reference
254 wxList
*wxWinMacWindowList
= NULL
;
255 wxTopLevelWindowMac
*wxFindWinFromMacWindow(WXWindow inWindowRef
)
257 wxNode
*node
= wxWinMacWindowList
->Find((long)inWindowRef
);
260 return (wxTopLevelWindowMac
*)node
->GetData();
263 void wxAssociateWinWithMacWindow(WXWindow inWindowRef
, wxTopLevelWindowMac
*win
)
265 // adding NULL WindowRef is (first) surely a result of an error and
266 // (secondly) breaks menu command processing
267 wxCHECK_RET( inWindowRef
!= (WindowRef
) NULL
, "attempt to add a NULL WindowRef to window list" );
269 if ( !wxWinMacWindowList
->Find((long)inWindowRef
) )
270 wxWinMacWindowList
->Append((long)inWindowRef
, win
);
273 void wxRemoveMacWindowAssociation(wxTopLevelWindowMac
*win
)
275 wxWinMacWindowList
->DeleteObject(win
);
279 // ----------------------------------------------------------------------------
280 // wxTopLevelWindowMac creation
281 // ----------------------------------------------------------------------------
283 WXHWND
wxTopLevelWindowMac::s_macWindowInUpdate
= NULL
;
285 void wxTopLevelWindowMac::Init()
288 m_maximizeOnShow
= FALSE
;
289 m_macNoEraseUpdateRgn
= NewRgn() ;
290 m_macNeedsErasing
= false ;
293 m_macEventHandler
= NULL
;
297 class wxMacDeferredWindowDeleter
: public wxObject
300 wxMacDeferredWindowDeleter( WindowRef windowRef
)
302 m_macWindow
= windowRef
;
304 virtual ~wxMacDeferredWindowDeleter()
306 UMADisposeWindow( (WindowRef
) m_macWindow
) ;
309 WindowRef m_macWindow
;
312 bool wxTopLevelWindowMac::Create(wxWindow
*parent
,
314 const wxString
& title
,
318 const wxString
& name
)
323 m_windowStyle
= style
;
327 m_windowId
= id
== -1 ? NewControlId() : id
;
329 wxTopLevelWindows
.Append(this);
332 parent
->AddChild(this);
337 wxTopLevelWindowMac::~wxTopLevelWindowMac()
341 wxToolTip::NotifyWindowDelete(m_macWindow
) ;
342 wxPendingDelete
.Append( new wxMacDeferredWindowDeleter( (WindowRef
) m_macWindow
) ) ;
346 if ( m_macEventHandler
)
348 ::RemoveEventHandler((EventHandlerRef
) m_macEventHandler
);
349 m_macEventHandler
= NULL
;
353 wxRemoveMacWindowAssociation( this ) ;
355 if ( wxModelessWindows
.Find(this) )
356 wxModelessWindows
.DeleteObject(this);
358 DisposeRgn( (RgnHandle
) m_macNoEraseUpdateRgn
) ;
362 // ----------------------------------------------------------------------------
363 // wxTopLevelWindowMac maximize/minimize
364 // ----------------------------------------------------------------------------
366 void wxTopLevelWindowMac::Maximize(bool maximize
)
368 // not available on mac
371 bool wxTopLevelWindowMac::IsMaximized() const
376 void wxTopLevelWindowMac::Iconize(bool iconize
)
378 // not available on mac
381 bool wxTopLevelWindowMac::IsIconized() const
383 // mac dialogs cannot be iconized
387 void wxTopLevelWindowMac::Restore()
389 // not available on mac
392 // ----------------------------------------------------------------------------
393 // wxTopLevelWindowMac misc
394 // ----------------------------------------------------------------------------
396 void wxTopLevelWindowMac::SetIcon(const wxIcon
& icon
)
399 wxTopLevelWindowBase::SetIcon(icon
);
402 void wxTopLevelWindowMac::MacCreateRealWindow( const wxString
& title
,
406 const wxString
& name
)
409 m_windowStyle
= style
;
430 ::SetRect(&theBoundsRect
, m_x
, m_y
, m_x
+ m_width
, m_y
+ m_height
);
432 // translate the window attributes in the appropriate window class and attributes
434 WindowClass wclass
= 0;
435 WindowAttributes attr
= kWindowNoAttributes
;
437 if ( HasFlag( wxFRAME_TOOL_WINDOW
) )
440 HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
441 HasFlag( wxSYSTEM_MENU
) || HasFlag( wxCAPTION
) ||
442 HasFlag(wxTINY_CAPTION_HORIZ
) || HasFlag(wxTINY_CAPTION_VERT
)
445 wclass
= kFloatingWindowClass
;
446 if ( HasFlag(wxTINY_CAPTION_VERT
) )
448 attr
|= kWindowSideTitlebarAttribute
;
454 wclass
= kPlainWindowClass
;
456 wclass
= kFloatingWindowClass
;
460 else if ( HasFlag( wxCAPTION
) )
462 if ( HasFlag( wxDIALOG_MODAL
) )
464 wclass
= kDocumentWindowClass
; // kMovableModalWindowClass ;
468 wclass
= kDocumentWindowClass
;
473 if ( HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) ||
474 HasFlag( wxSYSTEM_MENU
) )
476 wclass
= kDocumentWindowClass
;
481 wclass
= kPlainWindowClass
;
483 wclass
= kModalWindowClass
;
488 if ( HasFlag( wxMINIMIZE_BOX
) || HasFlag( wxMAXIMIZE_BOX
) )
490 attr
|= kWindowFullZoomAttribute
;
491 attr
|= kWindowCollapseBoxAttribute
;
493 if ( HasFlag( wxRESIZE_BORDER
) )
495 attr
|= kWindowResizableAttribute
;
497 if ( HasFlag( wxSYSTEM_MENU
) )
499 attr
|= kWindowCloseBoxAttribute
;
502 ::CreateNewWindow( wclass
, attr
, &theBoundsRect
, (WindowRef
*)&m_macWindow
) ;
503 wxAssociateWinWithMacWindow( m_macWindow
, this ) ;
505 if( wxApp::s_macDefaultEncodingIsPC
)
506 label
= wxMacMakeMacStringFromPC( title
) ;
509 UMASetWTitleC( (WindowRef
)m_macWindow
, label
) ;
510 ::CreateRootControl( (WindowRef
)m_macWindow
, (ControlHandle
*)&m_macRootControl
) ;
512 InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow
)) ) ;
513 InstallWindowEventHandler(MAC_WXHWND(m_macWindow
), GetwxMacWindowEventHandlerUPP(),
514 GetEventTypeCount(eventList
), eventList
, this, &((EventHandlerRef
)m_macEventHandler
));
519 void wxTopLevelWindowMac::MacGetPortParams(WXPOINTPTR localOrigin
, WXRECTPTR clipRect
, WXHWND
*window
, wxWindowMac
** rootwin
)
521 ((Point
*)localOrigin
)->h
= 0;
522 ((Point
*)localOrigin
)->v
= 0;
523 ((Rect
*)clipRect
)->left
= 0;
524 ((Rect
*)clipRect
)->top
= 0;
525 ((Rect
*)clipRect
)->right
= m_width
;
526 ((Rect
*)clipRect
)->bottom
= m_height
;
527 *window
= m_macWindow
;
531 void wxTopLevelWindowMac::Clear()
536 WXWidget
wxTopLevelWindowMac::MacGetContainerForEmbedding()
538 return m_macRootControl
;
542 void wxTopLevelWindowMac::MacUpdate( long timestamp
)
545 wxMacPortStateHelper
help( (GrafPtr
) GetWindowPort( (WindowRef
) m_macWindow
) ) ;
547 BeginUpdate( (WindowRef
)m_macWindow
) ;
549 RgnHandle updateRgn
= NewRgn();
550 RgnHandle diffRgn
= NewRgn() ;
551 if ( updateRgn
&& diffRgn
)
553 GetPortVisibleRegion( GetWindowPort( (WindowRef
)m_macWindow
), updateRgn
);
554 DiffRgn( updateRgn
, (RgnHandle
) m_macNoEraseUpdateRgn
, diffRgn
) ;
555 if ( !EmptyRgn( updateRgn
) )
557 MacRedraw( updateRgn
, timestamp
, m_macNeedsErasing
|| !EmptyRgn( diffRgn
) ) ;
561 DisposeRgn( updateRgn
);
563 DisposeRgn( diffRgn
);
564 EndUpdate( (WindowRef
)m_macWindow
) ;
565 SetEmptyRgn( (RgnHandle
) m_macNoEraseUpdateRgn
) ;
566 m_macNeedsErasing
= false ;
570 // Raise the window to the top of the Z order
571 void wxTopLevelWindowMac::Raise()
573 ::BringToFront( (WindowRef
)m_macWindow
) ;
576 // Lower the window to the bottom of the Z order
577 void wxTopLevelWindowMac::Lower()
579 ::SendBehind( (WindowRef
)m_macWindow
, NULL
) ;
582 void wxTopLevelWindowMac::MacFireMouseEvent(
583 wxUint16 kind
, wxInt32 x
, wxInt32 y
,wxUint32 modifiers
, long timestamp
)
585 wxMouseEvent
event(wxEVT_LEFT_DOWN
);
586 bool isDown
= !(modifiers
& btnState
) ; // 1 is for up
587 bool controlDown
= modifiers
& controlKey
; // for simulating right mouse
589 event
.m_leftDown
= isDown
&& !controlDown
;
591 event
.m_middleDown
= FALSE
;
592 event
.m_rightDown
= isDown
&& controlDown
;
594 if ( kind
== mouseDown
)
597 event
.SetEventType(wxEVT_RIGHT_DOWN
) ;
599 event
.SetEventType(wxEVT_LEFT_DOWN
) ;
601 else if ( kind
== mouseUp
)
604 event
.SetEventType(wxEVT_RIGHT_UP
) ;
606 event
.SetEventType(wxEVT_LEFT_UP
) ;
610 event
.SetEventType(wxEVT_MOTION
) ;
613 event
.m_shiftDown
= modifiers
& shiftKey
;
614 event
.m_controlDown
= modifiers
& controlKey
;
615 event
.m_altDown
= modifiers
& optionKey
;
616 event
.m_metaDown
= modifiers
& cmdKey
;
624 ::SetPort( UMAGetWindowPort( (WindowRef
)m_macWindow
) ) ;
625 ::GlobalToLocal( &localwhere
) ;
628 if ( kind
== mouseDown
)
630 if ( timestamp
- gs_lastWhen
<= GetDblTime() )
632 if ( abs( localwhere
.h
- gs_lastWhere
.h
) < 3 && abs( localwhere
.v
- gs_lastWhere
.v
) < 3 )
634 // This is not right if the second mouse down
635 // event occured in a differen window. We
636 // correct this in MacDispatchMouseEvent.
638 event
.SetEventType(wxEVT_RIGHT_DCLICK
) ;
640 event
.SetEventType(wxEVT_LEFT_DCLICK
) ;
646 gs_lastWhen
= timestamp
;
648 gs_lastWhere
= localwhere
;
651 event
.m_x
= localwhere
.h
;
652 event
.m_y
= localwhere
.v
;
656 event
.m_timeStamp
= timestamp
;
657 event
.SetEventObject(this);
658 if ( wxTheApp
->s_captureWindow
)
662 wxTheApp
->s_captureWindow
->ScreenToClient( &x
, &y
) ;
665 event
.SetEventObject( wxTheApp
->s_captureWindow
) ;
666 wxTheApp
->s_captureWindow
->GetEventHandler()->ProcessEvent( event
) ;
668 if ( kind
== mouseUp
)
670 wxTheApp
->s_captureWindow
= NULL
;
673 m_cursor
.MacInstall() ;
679 MacDispatchMouseEvent( event
) ;
684 void wxTopLevelWindowMac::MacMouseDown( WXEVENTREF ev
, short part
)
686 MacFireMouseEvent( mouseDown
, ((EventRecord
*)ev
)->where
.h
, ((EventRecord
*)ev
)->where
.v
,
687 ((EventRecord
*)ev
)->modifiers
, ((EventRecord
*)ev
)->when
) ;
690 void wxTopLevelWindowMac::MacMouseUp( WXEVENTREF ev
, short part
)
696 MacFireMouseEvent( mouseUp
, ((EventRecord
*)ev
)->where
.h
, ((EventRecord
*)ev
)->where
.v
,
697 ((EventRecord
*)ev
)->modifiers
, ((EventRecord
*)ev
)->when
) ;
703 void wxTopLevelWindowMac::MacMouseMoved( WXEVENTREF ev
, short part
)
709 MacFireMouseEvent( nullEvent
/*moved*/ , ((EventRecord
*)ev
)->where
.h
, ((EventRecord
*)ev
)->where
.v
,
710 ((EventRecord
*)ev
)->modifiers
, ((EventRecord
*)ev
)->when
) ;
718 void wxTopLevelWindowMac::MacActivate( long timestamp
, bool inIsActivating
)
720 wxActivateEvent
event(wxEVT_ACTIVATE
, inIsActivating
, m_windowId
);
721 event
.m_timeStamp
= timestamp
;
722 event
.SetEventObject(this);
724 GetEventHandler()->ProcessEvent(event
);
726 UMAHighlightAndActivateWindow( (WindowRef
)m_macWindow
, inIsActivating
) ;
728 // Early versions of MacOS X don't refresh backgrounds properly,
729 // so refresh the whole window on activation and deactivation.
730 long osVersion
= UMAGetSystemVersion();
731 if (osVersion
>= 0x1000 && osVersion
< 0x1020)
734 MacSuperEnabled( inIsActivating
) ;
739 void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev
)
745 void wxTopLevelWindowMac::SetTitle(const wxString
& title
)
747 wxWindow::SetTitle( title
) ;
751 if( wxApp::s_macDefaultEncodingIsPC
)
752 label
= wxMacMakeMacStringFromPC( m_label
) ;
756 UMASetWTitleC( (WindowRef
)m_macWindow
, label
) ;
759 bool wxTopLevelWindowMac::Show(bool show
)
761 if ( !wxWindow::Show(show
) )
766 ::TransitionWindow((WindowRef
)m_macWindow
,kWindowZoomTransitionEffect
,kWindowShowTransitionAction
,nil
);
767 ::SelectWindow( (WindowRef
)m_macWindow
) ;
768 // no need to generate events here, they will get them triggered by macos
769 // actually they should be , but apparently they are not
770 wxSize
size(m_width
, m_height
);
771 wxSizeEvent
event(size
, m_windowId
);
772 event
.SetEventObject(this);
773 GetEventHandler()->ProcessEvent(event
);
777 ::TransitionWindow((WindowRef
)m_macWindow
,kWindowZoomTransitionEffect
,kWindowHideTransitionAction
,nil
);
791 void wxTopLevelWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
)
795 int former_w
= m_width
;
796 int former_h
= m_height
;
798 int actualWidth
= width
;
799 int actualHeight
= height
;
803 if ((m_minWidth
!= -1) && (actualWidth
< m_minWidth
))
804 actualWidth
= m_minWidth
;
805 if ((m_minHeight
!= -1) && (actualHeight
< m_minHeight
))
806 actualHeight
= m_minHeight
;
807 if ((m_maxWidth
!= -1) && (actualWidth
> m_maxWidth
))
808 actualWidth
= m_maxWidth
;
809 if ((m_maxHeight
!= -1) && (actualHeight
> m_maxHeight
))
810 actualHeight
= m_maxHeight
;
812 bool doMove
= false ;
813 bool doResize
= false ;
815 if ( actualX
!= former_x
|| actualY
!= former_y
)
819 if ( actualWidth
!= former_w
|| actualHeight
!= former_h
)
824 if ( doMove
|| doResize
)
828 m_width
= actualWidth
;
829 m_height
= actualHeight
;
832 ::MoveWindow((WindowRef
)m_macWindow
, m_x
, m_y
, false); // don't make frontmost
835 ::SizeWindow((WindowRef
)m_macWindow
, m_width
, m_height
, true);
837 // the OS takes care of invalidating and erasing the new area so we only have to
838 // take care of refreshing for full repaints
840 if ( doResize
&& !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE
) )
844 if ( IsKindOf( CLASSINFO( wxFrame
) ) )
846 wxFrame
* frame
= (wxFrame
*) this ;
847 frame
->PositionStatusBar();
848 frame
->PositionToolBar();
851 wxWindowMac::MacTopLevelWindowChangedPosition() ; // like this only children will be notified
853 MacRepositionScrollBars() ;
856 wxPoint
point(m_x
, m_y
);
857 wxMoveEvent
event(point
, m_windowId
);
858 event
.SetEventObject(this);
859 GetEventHandler()->ProcessEvent(event
) ;
863 MacRepositionScrollBars() ;
864 wxSize
size(m_width
, m_height
);
865 wxSizeEvent
event(size
, m_windowId
);
866 event
.SetEventObject(this);
867 GetEventHandler()->ProcessEvent(event
);
874 * Invalidation Mechanism
876 * The update mechanism reflects exactely the windows mechanism
877 * the rect gets added to the window invalidate region, if the eraseBackground flag
878 * has been true for any part of the update rgn the background is erased in the entire region
879 * not just in the specified rect.
881 * In order to achive this, we also have an internal m_macNoEraseUpdateRgn, all rects that have
882 * the eraseBackground flag set to false are also added to this rgn. upon receiving an update event
883 * the update rgn is compared to the m_macNoEraseUpdateRgn and in case they differ, every window
884 * will get the eraseBackground event first
887 void wxTopLevelWindowMac::MacInvalidate( const WXRECTPTR rect
, bool eraseBackground
)
890 GetPort( &formerPort
) ;
891 SetPortWindowPort( (WindowRef
)m_macWindow
) ;
893 m_macNeedsErasing
|= eraseBackground
;
895 // if we already know that we will have to erase, there's no need to track the rest
896 if ( !m_macNeedsErasing
)
898 // we end only here if eraseBackground is false
899 // if we already have a difference between m_macNoEraseUpdateRgn and UpdateRgn
900 // we will have to erase anyway
902 RgnHandle updateRgn
= NewRgn();
903 RgnHandle diffRgn
= NewRgn() ;
904 if ( updateRgn
&& diffRgn
)
906 GetWindowUpdateRgn( (WindowRef
)m_macWindow
, updateRgn
);
908 LocalToGlobal( &pt
) ;
909 OffsetRgn( updateRgn
, -pt
.h
, -pt
.v
) ;
910 DiffRgn( updateRgn
, (RgnHandle
) m_macNoEraseUpdateRgn
, diffRgn
) ;
911 if ( !EmptyRgn( diffRgn
) )
913 m_macNeedsErasing
= true ;
917 DisposeRgn( updateRgn
);
919 DisposeRgn( diffRgn
);
921 if ( !m_macNeedsErasing
)
923 RgnHandle rectRgn
= NewRgn() ;
924 SetRectRgn( rectRgn
, ((Rect
*)rect
)->left
, ((Rect
*)rect
)->top
, ((Rect
*)rect
)->right
, ((Rect
*)rect
)->bottom
) ;
925 UnionRgn( (RgnHandle
) m_macNoEraseUpdateRgn
, rectRgn
, (RgnHandle
) m_macNoEraseUpdateRgn
) ;
926 DisposeRgn( rectRgn
) ;
929 InvalWindowRect( (WindowRef
)m_macWindow
, (Rect
*)rect
) ;
930 // turn this on to debug the refreshing cycle
931 #if wxMAC_DEBUG_REDRAW
934 SetPort( formerPort
) ;