virtual OSStatus SendHICommand( UInt32 commandID , OptionBits inOptions = 0 );
 
-    virtual SInt32 GetMaximum() const;
+    virtual wxInt32 GetMaximum() const;
+    virtual wxInt32 GetMinimum() const;
  
     virtual void SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum );
     virtual void SetRange( SInt32 minimum , SInt32 maximum );
 
     bool                ButtonClickDidStateChange() { return true ;}
     void                SetMinimum( wxInt32 v );
     void                SetMaximum( wxInt32 v );
+    wxInt32             GetMinimum() const;
+    wxInt32             GetMaximum() const;
     void                PulseGauge();
     void                SetScrollThumb( wxInt32 value, wxInt32 thumbSize );
 
         - (void)mouseExited:(NSEvent *)event;\
         - (void)keyDown:(NSEvent *)event;\
         - (void)keyUp:(NSEvent *)event;\
+        - (BOOL)performKeyEquivalent:(NSEvent *)event;\
         - (void)flagsChanged:(NSEvent *)event;\
-        - (BOOL) becomeFirstResponder;\
-        - (BOOL) resignFirstResponder;
+        - (BOOL)becomeFirstResponder;\
+        - (BOOL)resignFirstResponder;\
+        - (void)resetCursorRects;
 
-    #define WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION -(void)mouseDown:(NSEvent *)event \
-        {\
-            if ( !impl->DoHandleMouseEvent(event) )\
-                [super mouseDown:event];\
-        }\
-        -(void)rightMouseDown:(NSEvent *)event\
+
+    #define WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION_NO_MOUSEDOWN        -(void)rightMouseDown:(NSEvent *)event\
         {\
             if ( !impl->DoHandleMouseEvent(event) )\
                 [super rightMouseDown:event];\
             if ( !impl->DoHandleMouseEvent(event) )\
                 [super mouseExited:event];\
         }\
+        -(BOOL)performKeyEquivalent:(NSEvent *)event\
+        {\
+            if ( !impl->DoHandleKeyEvent(event) )\
+                return [super performKeyEquivalent:event];\
+            return YES;\
+        }\
         -(void)keyDown:(NSEvent *)event\
         {\
             if ( !impl->DoHandleKeyEvent(event) )\
             if ( r )\
                 impl->DoNotifyFocusEvent( false );\
             return r;\
+        }\
+        - (void) resetCursorRects\
+        {\
+            if ( impl )\
+            {\
+                wxWindow* wxpeer = impl->GetWXPeer();\
+                if ( wxpeer )\
+                {\
+                    NSCursor *cursor = (NSCursor*)wxpeer->GetCursor().GetHCURSOR();\
+                    if (cursor == NULL)\
+                        [super resetCursorRects];\
+                    else\
+                        [self addCursorRect: [self bounds]\
+                            cursor: cursor];\
+                }\
+            }\
         }
-        
+
+    #define WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION -(void)mouseDown:(NSEvent *)event \
+        {\
+            if ( !impl->DoHandleMouseEvent(event) )\
+                [super mouseDown:event];\
+        }\
+        WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION_NO_MOUSEDOWN
+
     #define WXCOCOAIMPL_COMMON_MEMBERS wxWidgetCocoaImpl* impl;
     
     #define WXCOCOAIMPL_COMMON_INTERFACE \
         - (BOOL) isFlipped;\
         WXCOCOAIMPL_COMMON_EVENTS_INTERFACE
 
-    #define WXCOCOAIMPL_COMMON_IMPLEMENTATION WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \
-        - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation\
+    #define WXCOCOAIMPL_COMMON_IMPLEMENTATION_BASE - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation\
         {\
             impl = theImplementation;\
         }\
         {\
             return impl;\
         }\
+
+    #define WXCOCOAIMPL_COMMON_IMPLEMENTATION WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \
+        WXCOCOAIMPL_COMMON_IMPLEMENTATION_BASE \
         - (BOOL) isFlipped\
         {\
             return YES;\
-        }\
+        }
 
-     #define WXCOCOAIMPL_COMMON_IMPLEMENTATION_NOT_FLIPPED WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \
-        - (void)setImplementation: (wxWidgetCocoaImpl *) theImplementation\
-        {\
-            impl = theImplementation;\
-        }\
-        - (wxWidgetCocoaImpl*) implementation\
+    #define WXCOCOAIMPL_COMMON_IMPLEMENTATION_NO_MOUSEDOWN WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION_NO_MOUSEDOWN \
+        WXCOCOAIMPL_COMMON_IMPLEMENTATION_BASE \
+        - (BOOL) isFlipped\
         {\
-            return impl;\
-        }\
+            return YES;\
+        }
+
+
+     #define WXCOCOAIMPL_COMMON_IMPLEMENTATION_NOT_FLIPPED WXCOCOAIMPL_COMMON_EVENTS_IMPLEMENTATION \
+        WXCOCOAIMPL_COMMON_IMPLEMENTATION_BASE \
         - (BOOL) isFlipped\
         {\
             return NO;\
-        }\
+        }
 
     // used for many wxControls
     
 
     virtual void        Enable( bool enable ) = 0;
     virtual void        SetMinimum( wxInt32 v ) = 0;
     virtual void        SetMaximum( wxInt32 v ) = 0;
+    virtual wxInt32     GetMinimum() const = 0;
+    virtual wxInt32     GetMaximum() const = 0;
     virtual void        PulseGauge() = 0;
     virtual void        SetScrollThumb( wxInt32 value, wxInt32 thumbSize ) = 0;
 
 
 
     // implementation only from now on
     void Command(wxCommandEvent& event);
-#if wxOSX_USE_CARBON
-    virtual void MacHandleControlClick( WXWidget control ,
-                                        wxInt16 controlpart ,
-                                        bool mouseStillDown ) ;
-#endif
+    virtual void TriggerScrollEvent( wxEventType scrollEvent ) ;
     virtual bool HandleClicked( double timestampsec );
 protected:
     virtual wxSize DoGetBestSize() const;
 
     void Command(wxCommandEvent& event);
     // osx specific event handling common for all osx-ports
     
-    virtual bool        HandleClicked( double timestampsec );
-    void MacHandleControlClick(WXWidget control, wxInt16 controlpart, bool mouseStillDown);
+    virtual bool HandleClicked( double timestampsec );
+    virtual void TriggerScrollEvent( wxEventType scrollEvent ) ;
 
 protected:
     virtual wxSize DoGetBestSize() const;
 
 
     // implementation
     
-#if wxOSX_USE_CARBON
-    virtual void MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool mouseStillDown ) ;
-#endif
+    virtual void TriggerScrollEvent( wxEventType scrollEvent ) ;
+
     // osx specific event handling common for all osx-ports
     
     virtual bool HandleClicked( double timestampsec );
 
     wxWindowMac *FindItem(long id) const;
     wxWindowMac *FindItemByHWND(WXHWND hWnd, bool controlOnly = false) const;
 
-    virtual void        MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool mouseStillDown ) ;
+    virtual void        TriggerScrollEvent( wxEventType scrollEvent ) ;
     virtual bool        MacDoRedraw( void* updatergn , long time ) ;
 
     // this should not be overriden in classes above wxWindowMac
     // osx specific event handling common for all osx-ports
     
     virtual bool        HandleClicked( double timestampsec );
+    virtual bool        HandleKeyEvent( wxKeyEvent& event );
 protected:
     // For controls like radio buttons which are genuinely composite
     wxList              m_subControls;
 
     if ( !focus )
         return false ;
 
-    bool handled;
     wxKeyEvent event(wxEVT_KEY_DOWN) ;
     MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
 
-    handled = focus->HandleWindowEvent( event ) ;
-    if ( handled && event.GetSkipped() )
-        handled = false ;
-
-#if wxUSE_ACCEL
-    if ( !handled )
-    {
-        wxWindow *ancestor = focus;
-        while (ancestor)
-        {
-            int command = ancestor->GetAcceleratorTable()->GetCommand( event );
-            if (command != -1)
-            {
-                wxEvtHandler * const handler = ancestor->GetEventHandler();
-
-                wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
-                handled = handler->ProcessEvent( command_event );
-
-                if ( !handled )
-                {
-                    // accelerators can also be used with buttons, try them too
-                    command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
-                    handled = handler->ProcessEvent( command_event );
-                }
-
-                break;
-            }
-
-            if (ancestor->IsTopLevel())
-                break;
-
-            ancestor = ancestor->GetParent();
-        }
-    }
-#endif // wxUSE_ACCEL
-
-    return handled ;
+    return focus->HandleKeyEvent(event);
 }
 
 bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
     bool handled;
     wxKeyEvent event( wxEVT_KEY_UP ) ;
     MacCreateKeyEvent( event, focus , keymessage , modifiers , when , wherex , wherey , uniChar ) ;
-    handled = focus->HandleWindowEvent( event ) ;
 
-    return handled ;
+    return focus->HandleKeyEvent(event) ;
 }
 
 bool wxApp::MacSendCharEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey , wxChar uniChar )
 
     verify_noerr( err );
     return peer;
 }
-
-void wxScrollBar::MacHandleControlClick( WXWidget WXUNUSED(control), wxInt16 controlpart, bool mouseStillDown )
-{
-#if wxOSX_USE_CARBON
-
-    int position = m_peer->GetValue();
-    int minPos = 0 ;
-    int maxPos = m_peer->GetMaximum();
-
-    wxEventType scrollEvent = wxEVT_NULL;
-    int nScrollInc = 0;
-
-    // all events have already been reported during mouse down, except for THUMBRELEASE
-    if ( !mouseStillDown && controlpart != kControlIndicatorPart )
-        return;
-
-    switch ( controlpart )
-    {
-    case kControlUpButtonPart:
-        nScrollInc = -1;
-        scrollEvent = wxEVT_SCROLL_LINEUP;
-        break;
-
-    case kControlDownButtonPart:
-        nScrollInc = 1;
-        scrollEvent = wxEVT_SCROLL_LINEDOWN;
-        break;
-
-    case kControlPageUpPart:
-        nScrollInc = -m_pageSize;
-        scrollEvent = wxEVT_SCROLL_PAGEUP;
-        break;
-
-    case kControlPageDownPart:
-        nScrollInc = m_pageSize;
-        scrollEvent = wxEVT_SCROLL_PAGEDOWN;
-        break;
-
-    case kControlIndicatorPart:
-        nScrollInc = 0;
-        if ( mouseStillDown )
-            scrollEvent = wxEVT_SCROLL_THUMBTRACK;
-        else
-            scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
-        break;
-
-    default:
-        wxFAIL_MSG(wxT("unknown scrollbar selector"));
-        break;
-    }
-
-    int new_pos = position + nScrollInc;
-
-    if (new_pos < minPos)
-        new_pos = minPos;
-    else if (new_pos > maxPos)
-        new_pos = maxPos;
-
-    if ( nScrollInc )
-        SetThumbPosition( new_pos );
-
-    wxScrollEvent event( scrollEvent, m_windowId );
-    if ( m_windowStyle & wxHORIZONTAL )
-        event.SetOrientation( wxHORIZONTAL );
-    else
-        event.SetOrientation( wxVERTICAL );
-
-    event.SetPosition( new_pos );
-    event.SetEventObject( this );
-
-    wxWindow* window = GetParent();
-    if (window && window->MacIsWindowScrollbar( this ))
-        // this is hardcoded
-        window->MacOnScroll( event );
-    else
-        HandleWindowEvent( event );
-#endif
-}
\ No newline at end of file
 
     return peer ;
 }
 
-void wxSpinButton::MacHandleControlClick(WXWidget WXUNUSED(control),
-                                         wxInt16 controlpart,
-                                         bool WXUNUSED(mouseStillDown))
-{
-    int inc = 0;
-
-    switch ( controlpart )
-    {
-    case kControlUpButtonPart :
-        inc = 1;
-        break;
-
-    case kControlDownButtonPart :
-        inc = -1;
-        break;
-
-    default:
-        break;
-    }
-    
-    // trigger scroll events
-    
-    wxEventType scrollEvent = wxEVT_NULL;
-    int oldValue = GetValue() ;
-
-    int newValue = oldValue + inc;
-
-    if (newValue < m_min)
-    {
-        if ( m_windowStyle & wxSP_WRAP )
-            newValue = m_max;
-        else
-            newValue = m_min;
-    }
-
-    if (newValue > m_max)
-    {
-        if ( m_windowStyle & wxSP_WRAP )
-            newValue = m_min;
-        else
-            newValue = m_max;
-    }
-
-    if ( newValue - oldValue == -1 )
-        scrollEvent = wxEVT_SCROLL_LINEDOWN;
-    else if ( newValue - oldValue == 1 )
-        scrollEvent = wxEVT_SCROLL_LINEUP;
-    else
-        scrollEvent = wxEVT_SCROLL_THUMBTRACK;
-
-    // Do not send an event if the value has not actually changed
-    // (Also works for wxSpinCtrl)
-    if ( newValue == oldValue )
-        return;
-
-    if ( scrollEvent != wxEVT_SCROLL_THUMBTRACK )
-    {
-        wxSpinEvent event( scrollEvent, m_windowId );
-
-        event.SetPosition( newValue );
-        event.SetEventObject( this );
-        if ((HandleWindowEvent( event )) && !event.IsAllowed())
-            newValue = oldValue;
-    }
-
-    m_peer->SetValue( newValue );
-
-    // always send a thumbtrack event
-    SendThumbTrackEvent() ;
-}
-
 #endif // wxUSE_SPINBTN
 
     {
         wxWindow*  wx = wxFindWindowFromWXWidget(  (WXWidget) control ) ;
         if ( wx )
-            wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ;
+        {   
+            wxEventType scrollEvent = wxEVT_NULL;
+            switch ( partCode )
+            {
+            case kControlUpButtonPart:
+                scrollEvent = wxEVT_SCROLL_LINEUP;
+                break;
+
+            case kControlDownButtonPart:
+                scrollEvent = wxEVT_SCROLL_LINEDOWN;
+                break;
+
+            case kControlPageUpPart:
+                scrollEvent = wxEVT_SCROLL_PAGEUP;
+                break;
+
+            case kControlPageDownPart:
+                scrollEvent = wxEVT_SCROLL_PAGEDOWN;
+                break;
+
+            case kControlIndicatorPart:
+                scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+                // when this is called as a live proc, mouse is always still down
+                // so no need for thumbrelease
+                // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+                break;
+            }
+            wx->TriggerScrollEvent(scrollEvent) ;
+        }
     }
 }
 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ;
     return ::GetControl32BitValue( m_controlRef );
 }
 
-SInt32 wxMacControl::GetMaximum() const
+wxInt32 wxMacControl::GetMaximum() const
 {
     return ::GetControl32BitMaximum( m_controlRef );
 }
 
-/*
 wxInt32 wxMacControl::GetMinimum() const
 {
     return ::GetControl32BitMinimum( m_controlRef );
 }
-*/
 
 void wxMacControl::SetValue( wxInt32 v )
 {
 
     return self;
 }
 
+WXCOCOAIMPL_COMMON_IMPLEMENTATION_NO_MOUSEDOWN
+
+// we will have a mouseDown, then in the native 
+// implementation of mouseDown the tracking code
+// is calling clickedAction, therefore we wire this
+// to thumbtrack and only after super mouseDown 
+// returns we will call the thumbrelease
+
 - (void) clickedAction: (id) sender
 {
     if ( impl )
     {
+        wxEventType scrollEvent = wxEVT_NULL;
+        switch ([self hitPart]) 
+        {
+        case NSScrollerIncrementLine:
+            scrollEvent = wxEVT_SCROLL_LINEDOWN;
+            break;
+        case NSScrollerIncrementPage:
+            scrollEvent = wxEVT_SCROLL_PAGEDOWN;
+            break;
+        case NSScrollerDecrementLine:
+            scrollEvent = wxEVT_SCROLL_LINEUP;
+            break;
+        case NSScrollerDecrementPage:
+            scrollEvent = wxEVT_SCROLL_PAGEUP;
+            break;
+        case NSScrollerKnob:
+        case NSScrollerKnobSlot:
+            scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+            break;
+        case NSScrollerNoPart:
+        default:
+            return;
+        }
+
         wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
         if ( wxpeer )
-            wxpeer->HandleClicked(0);
+            wxpeer->TriggerScrollEvent(scrollEvent);
     }
 }
 
-WXCOCOAIMPL_COMMON_IMPLEMENTATION
+-(void)mouseDown:(NSEvent *)event 
+{
+    if ( !impl->DoHandleMouseEvent(event) )
+        [super mouseDown:event];
+
+    // send a release event in case we've been tracking the thumb
+    NSScrollerPart hit = [self hitPart];
+    if ( impl && (hit == NSScrollerKnob || hit == NSScrollerKnobSlot) )
+    {
+        wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
+        if ( wxpeer )
+            wxpeer->TriggerScrollEvent(wxEVT_SCROLL_THUMBRELEASE);
+    }
+}
 
 @end
 
     {
         return [(wxNSScroller*) m_osxView floatValue] * m_maximum;
     }
+    
+    wxInt32 GetMaximum() const
+    {
+        return m_maximum;
+    }
 protected:
     wxInt32 m_maximum;
 };
 
     return self;
 }
 
+WXCOCOAIMPL_COMMON_IMPLEMENTATION_NO_MOUSEDOWN
+
+// we will have a mouseDown, then in the native 
+// implementation of mouseDown the tracking code
+// is calling clickedAction, therefore we wire this
+// to thumbtrack and only after super mouseDown 
+// returns we will call the thumbrelease
+
 - (void) clickedAction: (id) sender
 {
     if ( impl )
     {
         wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
         if ( wxpeer )
-            wxpeer->HandleClicked(0);
+            wxpeer->TriggerScrollEvent(wxEVT_SCROLL_THUMBTRACK);
     }
 }
 
-WXCOCOAIMPL_COMMON_IMPLEMENTATION
+-(void)mouseDown:(NSEvent *)event 
+{
+    if ( !impl->DoHandleMouseEvent(event) )
+        [super mouseDown:event];
+
+    if ( impl )
+    {
+        wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
+        if ( wxpeer )
+            wxpeer->HandleClicked(0);
+    }
+}
 
 @end
 
 
 @interface wxNSStepper : NSStepper
 {
     WXCOCOAIMPL_COMMON_MEMBERS
+    int formerValue;
 }
 
 WXCOCOAIMPL_COMMON_INTERFACE
 {
     [super initWithFrame:frame];
     impl = NULL;
+    formerValue = 0;
     [self setTarget: self];
     [self setAction: @selector(clickedAction:)];
     return self;
     {
         wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
         if ( wxpeer )
-            wxpeer->HandleClicked(0);
+        {
+            // because wx expects to be able to veto 
+            // a change we must revert the value change
+            // and expose it
+            int currentValue = [self intValue];
+            [self setIntValue:formerValue];
+            int inc = currentValue-formerValue;
+            
+            // adjust for wrap arounds
+            if ( inc > 1 )
+                inc = -1;
+            else if (inc < -1 )
+                inc = 1;
+                
+            if ( inc == 1 )
+                wxpeer->TriggerScrollEvent(wxEVT_SCROLL_LINEUP);
+            else if ( inc == -1 )
+                wxpeer->TriggerScrollEvent(wxEVT_SCROLL_LINEDOWN);
+
+            formerValue = [self intValue];
+        }
     }
 }
 
-WXCOCOAIMPL_COMMON_IMPLEMENTATION
+-(void)mouseDown:(NSEvent *)event 
+{
+    formerValue = [self intValue];
+    if ( !impl->DoHandleMouseEvent(event) )
+        [super mouseDown:event];
+}
+
+WXCOCOAIMPL_COMMON_IMPLEMENTATION_NO_MOUSEDOWN
 
 @end
 
 
 }
 
 - (void)drawRect: (NSRect) rect;
-// TODO should the be moved to COMMON ?
-- (void)resetCursorRects;
 
 WXCOCOAIMPL_COMMON_INTERFACE
 
 - (void)setFloatValue:(float)aFloat;
 - (void)setDoubleValue:(double)aDouble;
 
+- (double)minValue;
+- (double)maxValue;
 - (void)setMinValue:(double)aDouble;
 - (void)setMaxValue:(double)aDouble;
 
 - (id)contentView;
 @end 
 
-long wxOSXTranslateCocoaKey(unsigned short code, int unichar )
+long wxOSXTranslateCocoaKey( int unichar )
 {
-    long retval = code;
+    long retval = unichar;
     switch( unichar )
     {
         case NSUpArrowFunctionKey :
     wxevent.m_controlDown = modifiers & NSControlKeyMask;
     wxevent.m_altDown = modifiers & NSAlternateKeyMask;
     wxevent.m_metaDown = modifiers & NSCommandKeyMask;
-
-    wxString chars;
-    if ( eventType != NSFlagsChanged )
-    {
-        NSString* nschars = [nsEvent characters];
-        if ( nschars )
-        {
-            wxCFStringRef cfchars((CFStringRef)[nschars retain]);
-            chars = cfchars.AsString();
-        }
-    }
-    
-    int unichar = chars.Length() > 0 ? chars[0] : 0;
     
-#if wxUSE_UNICODE
-    wxevent.m_uniChar = unichar;
-#endif
-    wxevent.m_keyCode = wxOSXTranslateCocoaKey( [nsEvent keyCode], unichar ) ;
-//    wxevent.m_rawCode = keymessage;
+    wxevent.m_rawCode = [nsEvent keyCode];
     wxevent.m_rawFlags = modifiers;
     
     wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
         default :
             break ;
     }
+
+    wxString chars;
+    if ( eventType != NSFlagsChanged )
+    {
+        NSString* nschars = [nsEvent characters];
+        if ( nschars )
+        {
+            wxCFStringRef cfchars((CFStringRef)[nschars retain]);
+            chars = cfchars.AsString();
+        }
+    }
+    
+    int unichar = chars.Length() > 0 ? chars[0] : 0;
+    long keyval = wxOSXTranslateCocoaKey(unichar) ;
+    if ( keyval == unichar && ( wxevent.GetEventType() == wxEVT_KEY_UP || wxevent.GetEventType() == wxEVT_KEY_DOWN ) )
+        keyval = wxToupper( keyval ) ;
+
+#if wxUSE_UNICODE
+    wxevent.m_uniChar = unichar;
+#endif
+    wxevent.m_keyCode = keyval;
 }
 
 UInt32 g_lastButton = 0 ;
     }
 }
 
-- (void) resetCursorRects
-{
-    [super resetCursorRects];
-    wxWindow* wxpeer = impl->GetWXPeer();
-    NSCursor *cursor = (NSCursor*)wxpeer->GetCursor().GetHCURSOR();
-    [self addCursorRect: [self bounds]
-          cursor: cursor];
-}
-
 WXCOCOAIMPL_COMMON_IMPLEMENTATION
 
 - (BOOL) canBecomeKeyView
     }
 }
 
+wxInt32 wxWidgetCocoaImpl::GetMinimum() const 
+{
+    if (  [m_osxView respondsToSelector:@selector(getMinValue:)] )
+    {
+        return [m_osxView minValue];
+    }
+    return 0;
+}
+
+wxInt32 wxWidgetCocoaImpl::GetMaximum() const 
+{
+    if (  [m_osxView respondsToSelector:@selector(getMaxValue:)] )
+    {
+        return [m_osxView maxValue];
+    }
+    return 0;
+}
+
 void wxWidgetCocoaImpl::SetBitmap( const wxBitmap& bitmap )
 {
     if (  [m_osxView respondsToSelector:@selector(setImage:)] )
 {
     wxKeyEvent wxevent(wxEVT_KEY_DOWN);
     SetupKeyEvent( wxevent, event );
-    return GetWXPeer()->HandleWindowEvent(wxevent);
+
+    return GetWXPeer()->HandleKeyEvent(wxevent);
 }
 
 bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event)
 
     CacheBestSize(best);
     return best;
 }
+
+void wxScrollBar::TriggerScrollEvent( wxEventType scrollEvent )
+{
+    int position = m_peer->GetValue();
+    int minPos = 0 ;
+    int maxPos = m_peer->GetMaximum();
+    int nScrollInc = 0;
+
+    if ( scrollEvent == wxEVT_SCROLL_LINEUP )
+    {
+        nScrollInc = -1;
+    }
+    else if ( scrollEvent == wxEVT_SCROLL_LINEDOWN )
+    {
+        nScrollInc = 1;
+    }
+    else if ( scrollEvent == wxEVT_SCROLL_PAGEUP )
+    {
+        nScrollInc = -m_pageSize;
+    }
+    else if ( scrollEvent == wxEVT_SCROLL_PAGEDOWN )
+    {
+        nScrollInc = m_pageSize;
+    }
+
+    int new_pos = position + nScrollInc;
+
+    if (new_pos < minPos)
+        new_pos = minPos;
+    else if (new_pos > maxPos)
+        new_pos = maxPos;
+
+    if ( nScrollInc )
+        SetThumbPosition( new_pos );
+
+    wxScrollEvent event( scrollEvent, m_windowId );
+    if ( m_windowStyle & wxHORIZONTAL )
+        event.SetOrientation( wxHORIZONTAL );
+    else
+        event.SetOrientation( wxVERTICAL );
+
+    event.SetPosition( new_pos );
+    event.SetEventObject( this );
+
+    wxWindow* window = GetParent();
+    if (window && window->MacIsWindowScrollbar( this ))
+        // this is hardcoded
+        window->MacOnScroll( event );
+    else
+        HandleWindowEvent( event );
+}
\ No newline at end of file
 
 
  // The dimensions of the different styles of sliders (from Aqua document)
 #ifdef wxOSX_USE_COCOA
-    #define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 25
+    #define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 28
     #define wxSLIDER_DIMENSIONACROSS_ARROW 21
 #else
     #define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 24
     ProcessCommand(event);
 }
 
-void wxSlider::MacHandleControlClick(WXWidget WXUNUSED(control),
-                                     wxInt16 WXUNUSED(controlpart),
-                                     bool WXUNUSED(mouseStillDown))
+void wxSlider::TriggerScrollEvent( wxEventType scrollEvent)
 {
     // Whatever the native value is, we may need to invert it for calling
     // SetValue and putting the possibly inverted value in the event
 
     SetValue( value );
 
-    wxScrollEvent event( wxEVT_SCROLL_THUMBTRACK, m_windowId );
+    wxScrollEvent event( scrollEvent, m_windowId );
     event.SetPosition( value );
     event.SetEventObject( this );
     HandleWindowEvent( event );
 
 bool wxSlider::HandleClicked( double timestampsec )
 {
-    // Whatever the native value is, we may need to invert it for calling
-    // SetValue and putting the possibly inverted value in the event
-    int value = ValueInvertOrNot( m_peer->GetValue() ) ;
-
-    SetValue( value ) ;
-
-    wxScrollEvent event( wxEVT_SCROLL_THUMBRELEASE, m_windowId );
-    event.SetPosition( value );
-    event.SetEventObject( this );
-    HandleWindowEvent( event );
-
-    wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, m_windowId );
-    cevent.SetInt( value );
-    cevent.SetEventObject( this );
-
-    HandleWindowEvent( cevent );
-
+    TriggerScrollEvent(wxEVT_SCROLL_THUMBRELEASE);
+ 
     return true;
 }
 
 
 
 bool wxSpinButton::HandleClicked( double timestampsec )
 {
-#if wxOSX_USE_CARBON
-    // these have been handled by the live action proc already
-#else
-    SendThumbTrackEvent() ;
-#endif
-
+    // all events have already been processed
     return true;
 }
 
     return wxSize( 16, 24 );
 }
 
+void wxSpinButton::TriggerScrollEvent(wxEventType scrollEvent)
+{
+    int inc = 0;
+
+    if ( scrollEvent == wxEVT_SCROLL_LINEUP )    
+    {
+        inc = 1;
+    }
+    else if ( scrollEvent == wxEVT_SCROLL_LINEDOWN )
+    {
+        inc = -1;
+    }
+    
+    // trigger scroll events
+    
+    int oldValue = GetValue() ;
+
+    int newValue = oldValue + inc;
+
+    if (newValue < m_min)
+    {
+        if ( m_windowStyle & wxSP_WRAP )
+            newValue = m_max;
+        else
+            newValue = m_min;
+    }
+
+    if (newValue > m_max)
+    {
+        if ( m_windowStyle & wxSP_WRAP )
+            newValue = m_min;
+        else
+            newValue = m_max;
+    }
+
+    if ( newValue - oldValue == -1 )
+        scrollEvent = wxEVT_SCROLL_LINEDOWN;
+    else if ( newValue - oldValue == 1 )
+        scrollEvent = wxEVT_SCROLL_LINEUP;
+    else
+        scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+
+    // Do not send an event if the value has not actually changed
+    // (Also works for wxSpinCtrl)
+    if ( newValue == oldValue )
+        return;
+
+    if ( scrollEvent != wxEVT_SCROLL_THUMBTRACK )
+    {
+        wxSpinEvent event( scrollEvent, m_windowId );
+
+        event.SetPosition( newValue );
+        event.SetEventObject( this );
+        if ((HandleWindowEvent( event )) && !event.IsAllowed())
+            newValue = oldValue;
+    }
+
+    m_peer->SetValue( newValue );
+
+    // always send a thumbtrack event
+    SendThumbTrackEvent() ;
+}
+
 #endif // wxUSE_SPINBTN
 
 void wxWindowMac::DoCaptureMouse()
 {
     wxApp::s_captureWindow = (wxWindow*) this ;
-#ifdef wxOSX_USE_COCOA
-    // TODO do we really need this ?
-    m_peer->SetFocus() ;
-#endif
     m_peer->CaptureMouse() ;
 }
 
 #endif
 }
 
-void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control),
-                                        wxInt16 WXUNUSED(controlpart),
-                                        bool WXUNUSED(mouseStillDown))
+void wxWindowMac::TriggerScrollEvent( wxEventType WXUNUSED(scrollEvent) )
 {
 }
 
     return wxWindowBase::IsShownOnScreen();
 }
 
+bool wxWindowMac::HandleKeyEvent( wxKeyEvent& event )
+{
+    bool handled = HandleWindowEvent( event ) ;
+    if ( handled && event.GetSkipped() )
+        handled = false ;
+
+#if wxUSE_ACCEL
+    if ( !handled && event.GetEventType() == wxEVT_KEY_DOWN)
+    {
+        wxWindow *ancestor = this;
+        while (ancestor)
+        {
+            int command = ancestor->GetAcceleratorTable()->GetCommand( event );
+            if (command != -1)
+            {
+                wxEvtHandler * const handler = ancestor->GetEventHandler();
+
+                wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
+                handled = handler->ProcessEvent( command_event );
+
+                if ( !handled )
+                {
+                    // accelerators can also be used with buttons, try them too
+                    command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
+                    handled = handler->ProcessEvent( command_event );
+                }
+
+                break;
+            }
+
+            if (ancestor->IsTopLevel())
+                break;
+
+            ancestor = ancestor->GetParent();
+        }
+    }
+#endif // wxUSE_ACCEL
+
+    return handled ;
+}
+
 //
 // wxWidgetImpl 
 //