[Git][wxwidgets/wxwidgets][master] add key events for iphone (#25844)

2 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
Sep 30, 2025, 12:57:04 PMSep 30
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • abe52cb3
    by Stefan Csomor at 2025-09-30T18:49:44+02:00
    add key events for iphone (#25844)
    
    

3 changed files:

Changes:

  • include/wx/defs.h
    ... ... @@ -2801,6 +2801,7 @@ DECLARE_WXCOCOA_OBJC_CLASS(NSPasteboard);
    2801 2801
     DECLARE_WXCOCOA_OBJC_CLASS(WKWebView);
    
    2802 2802
     
    
    2803 2803
     typedef WX_NSWindow WXWindow;
    
    2804
    +typedef WX_NSEvent WXEvent;
    
    2804 2805
     typedef WX_NSView WXWidget;
    
    2805 2806
     typedef WX_NSImage WXImage;
    
    2806 2807
     typedef WX_NSMenu WXHMENU;
    
    ... ... @@ -2819,11 +2820,14 @@ DECLARE_WXCOCOA_OBJC_CLASS(UIView);
    2819 2820
     DECLARE_WXCOCOA_OBJC_CLASS(UIFont);
    
    2820 2821
     DECLARE_WXCOCOA_OBJC_CLASS(UIImage);
    
    2821 2822
     DECLARE_WXCOCOA_OBJC_CLASS(UIEvent);
    
    2823
    +DECLARE_WXCOCOA_OBJC_CLASS(UIPress);
    
    2824
    +DECLARE_WXCOCOA_OBJC_CLASS(UIKey);
    
    2822 2825
     DECLARE_WXCOCOA_OBJC_CLASS(NSSet);
    
    2823 2826
     DECLARE_WXCOCOA_OBJC_CLASS(EAGLContext);
    
    2824 2827
     DECLARE_WXCOCOA_OBJC_CLASS(UIPasteboard);
    
    2825 2828
     
    
    2826 2829
     typedef WX_UIWindow WXWindow;
    
    2830
    +typedef WX_UIEvent WXEvent;
    
    2827 2831
     typedef WX_UIView WXWidget;
    
    2828 2832
     typedef WX_UIImage WXImage;
    
    2829 2833
     typedef WX_UIMenu WXHMENU;
    

  • include/wx/osx/iphone/private.h
    ... ... @@ -112,6 +112,7 @@ public :
    112 112
         bool                EnableTouchEvents(int WXUNUSED(eventsMask)) { return false; }
    
    113 113
     
    
    114 114
         virtual void        DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow);
    
    115
    +    virtual void        SetupKeyEvent(wxKeyEvent &wxevent, WXEvent event, UIPress* press, NSString* charString = nullptr);
    
    115 116
     
    
    116 117
         // thunk connected calls
    
    117 118
     
    
    ... ... @@ -119,6 +120,7 @@ public :
    119 120
         virtual void        touchEvent(WX_NSSet touches, WX_UIEvent event, WXWidget slf, void* _cmd);
    
    120 121
         virtual bool        becomeFirstResponder(WXWidget slf, void* _cmd);
    
    121 122
         virtual bool        resignFirstResponder(WXWidget slf, void* _cmd);
    
    123
    +    virtual void        keyEvent(WX_NSSet presses, WXEvent event, WXWidget slf, void* _cmd);
    
    122 124
     
    
    123 125
         // action
    
    124 126
     
    

  • src/osx/iphone/window.mm
    ... ... @@ -22,6 +22,39 @@
    22 22
     
    
    23 23
     #include <objc/runtime.h>
    
    24 24
     
    
    25
    +#define TRACE_FOCUS "focus"
    
    26
    +#define TRACE_KEYS  "keyevent"
    
    27
    +
    
    28
    +// ----------------------------------------------------------------------------
    
    29
    +// debugging helpers
    
    30
    +// ----------------------------------------------------------------------------
    
    31
    +
    
    32
    +// These functions are called from the code but are also useful in the debugger
    
    33
    +// (especially wxDumpNSView(), as selectors can be printed out directly anyhow),
    
    34
    +// so make them just static instead of putting them in an anonymous namespace
    
    35
    +// to make it easier to call them.
    
    36
    +
    
    37
    +static wxString wxDumpSelector(SEL cmd)
    
    38
    +{
    
    39
    +    return wxStringWithNSString(NSStringFromSelector(cmd));
    
    40
    +}
    
    41
    +
    
    42
    +static wxString wxDumpUIView(UIView* view)
    
    43
    +{
    
    44
    +    wxWidgetImpl* const impl = wxWidgetImpl::FindFromWXWidget(view);
    
    45
    +    if ( !impl )
    
    46
    +        return wxStringWithNSString([view description]);
    
    47
    +
    
    48
    +    return wxString::Format("%s belonging to %s",
    
    49
    +                            wxStringWithNSString([view className]),
    
    50
    +                            wxDumpWindow(impl->GetWXPeer())
    
    51
    +                            );
    
    52
    +}
    
    53
    +
    
    54
    +// ----------------------------------------------------------------------------
    
    55
    +// Focus
    
    56
    +// ----------------------------------------------------------------------------
    
    57
    +
    
    25 58
     WXWidget wxWidgetImpl::FindFocus()
    
    26 59
     {
    
    27 60
         UIView* focusedView = nil;
    
    ... ... @@ -67,6 +100,11 @@ CGRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const
    67 100
     - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
    
    68 101
     - (void)handleTouchEvent:(NSSet *)touches withEvent:(UIEvent *)event;
    
    69 102
     
    
    103
    +- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event;
    
    104
    +- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event;
    
    105
    +- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event;
    
    106
    +- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event;
    
    107
    +
    
    70 108
     - (BOOL) becomeFirstResponder;
    
    71 109
     - (BOOL) resignFirstResponder;
    
    72 110
     
    
    ... ... @@ -221,6 +259,19 @@ BOOL wxOSX_resignFirstResponder(UIView* self, SEL _cmd)
    221 259
         return impl->resignFirstResponder(self, _cmd);
    
    222 260
     }
    
    223 261
     
    
    262
    +void wxOSX_keyEvent(UIView* self, SEL _cmd, NSSet* presses, UIEvent *event)
    
    263
    +{
    
    264
    +    wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
    
    265
    +    if (impl == nullptr)
    
    266
    +    {
    
    267
    +        wxLogTrace(TRACE_KEYS, "Dropping %s for %s",
    
    268
    +                   wxDumpSelector(_cmd), wxDumpUIView(self));
    
    269
    +        return;
    
    270
    +    }
    
    271
    +
    
    272
    +    impl->keyEvent(presses, event, self, _cmd);
    
    273
    +}
    
    274
    +
    
    224 275
     void wxOSX_drawRect(UIView* self, SEL _cmd, CGRect rect)
    
    225 276
     {
    
    226 277
         wxWidgetIPhoneImpl* impl = (wxWidgetIPhoneImpl* ) wxWidgetImpl::FindFromWXWidget( self );
    
    ... ... @@ -238,6 +289,12 @@ void wxOSXIPhoneClassAddWXMethods(Class c)
    238 289
         class_addMethod(c, @selector(touchesEnded:withEvent:), (IMP) wxOSX_touchEvent, "v@:@@");
    
    239 290
         class_addMethod(c, @selector(becomeFirstResponder), (IMP) wxOSX_becomeFirstResponder, "c@:" );
    
    240 291
         class_addMethod(c, @selector(resignFirstResponder), (IMP) wxOSX_resignFirstResponder, "c@:" );
    
    292
    +
    
    293
    +    class_addMethod(c, @selector(pressesBegan:withEvent:), (IMP) wxOSX_keyEvent, "v@:@@" );
    
    294
    +    class_addMethod(c, @selector(pressesChanged:withEvent:), (IMP) wxOSX_keyEvent, "v@:@@" );
    
    295
    +    class_addMethod(c, @selector(pressesEnded:withEvent:), (IMP) wxOSX_keyEvent, "v@:@@" );
    
    296
    +    class_addMethod(c, @selector(pressesCancelled:withEvent:withEvent:), (IMP) wxOSX_keyEvent, "v@:@@" );
    
    297
    +
    
    241 298
         class_addMethod(c, @selector(drawRect:), (IMP) wxOSX_drawRect, "v@:{_CGRect={_CGPoint=ff}{_CGSize=ff}}" );
    
    242 299
     }
    
    243 300
     
    
    ... ... @@ -623,6 +680,7 @@ void wxWidgetIPhoneImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* ot
    623 680
     
    
    624 681
     typedef void (*wxOSX_DrawRectHandlerPtr)(UIView* self, SEL _cmd, CGRect rect);
    
    625 682
     typedef BOOL (*wxOSX_FocusHandlerPtr)(UIView* self, SEL _cmd);
    
    683
    +typedef void (*wxOSX_PressesHandlerPtr)(UIView* self, SEL _cmd, NSSet* presses, UIEvent* event);
    
    626 684
     
    
    627 685
     bool wxWidgetIPhoneImpl::becomeFirstResponder(WXWidget slf, void *_cmd)
    
    628 686
     {
    
    ... ... @@ -757,6 +815,246 @@ void wxWidgetIPhoneImpl::controlTextDidChange()
    757 815
         }
    
    758 816
     }
    
    759 817
     
    
    818
    +long wxOSXTranslateKey( UIPress* press, int eventType )
    
    819
    +{
    
    820
    +    long retval = 0;
    
    821
    +    UIKey* key = press.key;
    
    822
    +
    
    823
    +    if ( key == nil )
    
    824
    +        return 0;
    
    825
    +
    
    826
    +    UIKeyboardHIDUsage keyCode = [key keyCode];
    
    827
    +    switch( keyCode )
    
    828
    +    {
    
    829
    +        // command key
    
    830
    +        case UIKeyboardHIDUsageKeyboardLeftGUI:
    
    831
    +        case UIKeyboardHIDUsageKeyboardRightGUI:
    
    832
    +            retval = WXK_CONTROL;
    
    833
    +            break;
    
    834
    +        // caps locks key
    
    835
    +        case UIKeyboardHIDUsageKeyboardCapsLock: // Capslock
    
    836
    +            retval = WXK_CAPITAL;
    
    837
    +            break;
    
    838
    +        // shift key
    
    839
    +        case UIKeyboardHIDUsageKeyboardLeftShift: // Left Shift
    
    840
    +        case UIKeyboardHIDUsageKeyboardRightShift: // Right Shift
    
    841
    +            retval = WXK_SHIFT;
    
    842
    +            break;
    
    843
    +        // alt key
    
    844
    +        case UIKeyboardHIDUsageKeyboardLeftAlt: // Left Alt
    
    845
    +        case UIKeyboardHIDUsageKeyboardRightAlt: // Right Alt
    
    846
    +            retval = WXK_ALT;
    
    847
    +            break;
    
    848
    +        // ctrl key
    
    849
    +        case UIKeyboardHIDUsageKeyboardLeftControl: // Left Ctrl
    
    850
    +        case UIKeyboardHIDUsageKeyboardRightControl: // Right Ctrl
    
    851
    +            retval = WXK_RAW_CONTROL;
    
    852
    +            break;
    
    853
    +        // clear key
    
    854
    +        case UIKeyboardHIDUsageKeyboardClear:
    
    855
    +            retval = WXK_CLEAR;
    
    856
    +            break;
    
    857
    +        // tab key
    
    858
    +        case UIKeyboardHIDUsageKeyboardTab:
    
    859
    +            retval = WXK_TAB;
    
    860
    +            break;
    
    861
    +
    
    862
    +        // numpad enter key End-of-text character ETX U+0003
    
    863
    +        case UIKeyboardHIDUsageKeypadEnter:
    
    864
    +            retval = WXK_NUMPAD_ENTER;
    
    865
    +            break;
    
    866
    +        // backspace key
    
    867
    +        case UIKeyboardHIDUsageKeyboardDeleteOrBackspace :
    
    868
    +            retval = WXK_BACK;
    
    869
    +            break;
    
    870
    +        case UIKeyboardHIDUsageKeyboardUpArrow :
    
    871
    +            retval = WXK_UP;
    
    872
    +            break;
    
    873
    +        case UIKeyboardHIDUsageKeyboardDownArrow :
    
    874
    +            retval = WXK_DOWN;
    
    875
    +            break;
    
    876
    +        case UIKeyboardHIDUsageKeyboardLeftArrow :
    
    877
    +            retval = WXK_LEFT;
    
    878
    +            break;
    
    879
    +        case UIKeyboardHIDUsageKeyboardRightArrow :
    
    880
    +            retval = WXK_RIGHT;
    
    881
    +            break;
    
    882
    +        case UIKeyboardHIDUsageKeyboardInsert  :
    
    883
    +            retval = WXK_INSERT;
    
    884
    +            break;
    
    885
    +        case UIKeyboardHIDUsageKeyboardDeleteForward  :
    
    886
    +            retval = WXK_DELETE;
    
    887
    +            break;
    
    888
    +        case UIKeyboardHIDUsageKeyboardHome  :
    
    889
    +            retval = WXK_HOME;
    
    890
    +            break;
    
    891
    +        case UIKeyboardHIDUsageKeyboardEnd  :
    
    892
    +            retval = WXK_END;
    
    893
    +            break;
    
    894
    +        case UIKeyboardHIDUsageKeyboardPageUp  :
    
    895
    +            retval = WXK_PAGEUP;
    
    896
    +            break;
    
    897
    +       case UIKeyboardHIDUsageKeyboardPageDown  :
    
    898
    +            retval = WXK_PAGEDOWN;
    
    899
    +            break;
    
    900
    +       case UIKeyboardHIDUsageKeyboardHelp  :
    
    901
    +            retval = WXK_HELP;
    
    902
    +            break;
    
    903
    +        case UIKeyboardHIDUsageKeyboard0:
    
    904
    +            retval = '0';
    
    905
    +            break;
    
    906
    +        default:
    
    907
    +            if ( keyCode >= UIKeyboardHIDUsageKeyboardA && keyCode <= UIKeyboardHIDUsageKeyboardZ ) {
    
    908
    +                retval = 'a' + (keyCode - UIKeyboardHIDUsageKeyboardA );
    
    909
    +            } else if ( keyCode >= UIKeyboardHIDUsageKeyboard1 && keyCode <= UIKeyboardHIDUsageKeyboard9 ) {
    
    910
    +                retval = '1' + (keyCode - UIKeyboardHIDUsageKeyboard1 );
    
    911
    +            } else if ( keyCode >= UIKeyboardHIDUsageKeyboardF1 && keyCode <= UIKeyboardHIDUsageKeyboardF12 ) {
    
    912
    +                retval = WXK_F1 + (keyCode - UIKeyboardHIDUsageKeyboardF1 );
    
    913
    +            }
    
    914
    +            break;
    
    915
    +    }
    
    916
    +
    
    917
    +    // Check for NUMPAD keys.  For KEY_UP/DOWN events we need to use the
    
    918
    +    // WXK_NUMPAD constants, but for the CHAR event we want to use the
    
    919
    +    // standard ascii values
    
    920
    +    if ( eventType != wxEVT_CHAR )
    
    921
    +    {
    
    922
    +        switch( [key keyCode] )
    
    923
    +        {
    
    924
    +            case UIKeyboardHIDUsageKeypadSlash: // /
    
    925
    +                retval = WXK_NUMPAD_DIVIDE;
    
    926
    +                break;
    
    927
    +            case UIKeyboardHIDUsageKeypadAsterisk: // *
    
    928
    +                retval = WXK_NUMPAD_MULTIPLY;
    
    929
    +                break;
    
    930
    +            case UIKeyboardHIDUsageKeypadHyphen: // -
    
    931
    +                retval = WXK_NUMPAD_SUBTRACT;
    
    932
    +                break;
    
    933
    +            case UIKeyboardHIDUsageKeypadPlus: // +
    
    934
    +                retval = WXK_NUMPAD_ADD;
    
    935
    +                break;
    
    936
    +            case UIKeyboardHIDUsageKeypadPeriod: // .
    
    937
    +                retval = WXK_NUMPAD_DECIMAL;
    
    938
    +                break;
    
    939
    +            case UIKeyboardHIDUsageKeypad0: // 0
    
    940
    +                retval = WXK_NUMPAD0;
    
    941
    +                break;
    
    942
    +            case UIKeyboardHIDUsageKeypad1: // 1
    
    943
    +                retval = WXK_NUMPAD1;
    
    944
    +                break;
    
    945
    +            case UIKeyboardHIDUsageKeypad2: // 2
    
    946
    +                retval = WXK_NUMPAD2;
    
    947
    +                break;
    
    948
    +            case UIKeyboardHIDUsageKeypad3: // 3
    
    949
    +                retval = WXK_NUMPAD3;
    
    950
    +                break;
    
    951
    +            case UIKeyboardHIDUsageKeypad4: // 4
    
    952
    +                retval = WXK_NUMPAD4;
    
    953
    +                break;
    
    954
    +            case UIKeyboardHIDUsageKeypad5: // 5
    
    955
    +                retval = WXK_NUMPAD5;
    
    956
    +                break;
    
    957
    +            case UIKeyboardHIDUsageKeypad6: // 6
    
    958
    +                retval = WXK_NUMPAD6;
    
    959
    +                break;
    
    960
    +            case UIKeyboardHIDUsageKeypad7: // 7
    
    961
    +                retval = WXK_NUMPAD7;
    
    962
    +                break;
    
    963
    +            case UIKeyboardHIDUsageKeypad8: // 8
    
    964
    +                retval = WXK_NUMPAD8;
    
    965
    +                break;
    
    966
    +            case UIKeyboardHIDUsageKeypad9: // 9
    
    967
    +                retval = WXK_NUMPAD9;
    
    968
    +                break;
    
    969
    +            default:
    
    970
    +                //retval = [event keyCode];
    
    971
    +                break;
    
    972
    +        }
    
    973
    +    }
    
    974
    +    return retval;
    
    975
    +}
    
    976
    +void wxWidgetIPhoneImpl::SetupKeyEvent(wxKeyEvent &wxevent , UIEvent* nsEvent, UIPress* press, NSString* charString)
    
    977
    +{
    
    978
    +    UIPressPhase pressPhase = press.phase;
    
    979
    +
    
    980
    +    wxevent.SetTimestamp( static_cast<long>([press timestamp] * 1000) ) ;
    
    981
    +
    
    982
    +    long keyval = 0;
    
    983
    +
    
    984
    +    if ( press.key )
    
    985
    +    {
    
    986
    +        UIKeyModifierFlags modifiers = [press.key modifierFlags];
    
    987
    +
    
    988
    +        wxevent.m_shiftDown = modifiers & UIKeyModifierShift; // UIKeyModifierAlphaShift for capslock
    
    989
    +        wxevent.m_rawControlDown = modifiers & UIKeyModifierControl;
    
    990
    +        wxevent.m_altDown = modifiers & UIKeyModifierAlternate;
    
    991
    +        wxevent.m_controlDown = modifiers & UIKeyModifierCommand;
    
    992
    +        wxevent.m_rawCode = (wxUint32) ([press.key keyCode]);
    
    993
    +        wxevent.m_rawFlags =(wxUint32) modifiers;
    
    994
    +
    
    995
    +    }
    
    996
    +
    
    997
    +    if (wxevent.GetEventType() != wxEVT_CHAR)
    
    998
    +    {
    
    999
    +        keyval = wxOSXTranslateKey(press, wxevent.GetEventType()) ;
    
    1000
    +        switch (pressPhase)
    
    1001
    +        {
    
    1002
    +            case UIPressPhaseBegan :
    
    1003
    +                wxevent.SetEventType( wxEVT_KEY_DOWN )  ;
    
    1004
    +                break;
    
    1005
    +            case UIPressPhaseStationary:
    
    1006
    +                wxevent.SetEventType( wxEVT_KEY_DOWN )  ;
    
    1007
    +                wxevent.m_isRepeat = true;
    
    1008
    +                break;
    
    1009
    +            case UIPressPhaseEnded :
    
    1010
    +                wxevent.SetEventType( wxEVT_KEY_UP )  ;
    
    1011
    +                break;
    
    1012
    +            default :
    
    1013
    +                break ;
    
    1014
    +        }
    
    1015
    +    }
    
    1016
    +    else
    
    1017
    +    {
    
    1018
    +        long keycode = wxOSXTranslateKey( press, wxEVT_CHAR );
    
    1019
    +        if ( (keycode > 0 && keycode < WXK_SPACE) || keycode == WXK_DELETE || keycode >= WXK_START )
    
    1020
    +        {
    
    1021
    +            keyval = keycode;
    
    1022
    +        }
    
    1023
    +    }
    
    1024
    +
    
    1025
    +    wxevent.m_keyCode = keyval;
    
    1026
    +
    
    1027
    +    wxWindowMac* peer = GetWXPeer();
    
    1028
    +    if ( peer )
    
    1029
    +    {
    
    1030
    +        wxevent.SetEventObject(peer);
    
    1031
    +        wxevent.SetId(peer->GetId()) ;
    
    1032
    +    }
    
    1033
    +}
    
    1034
    +
    
    1035
    +void wxWidgetIPhoneImpl::keyEvent( NSSet *presses, UIEvent* event, WXWidget slf, void *_cmd)
    
    1036
    +{
    
    1037
    +    wxLogTrace(TRACE_KEYS, "Got %s for %s",
    
    1038
    +               wxDumpSelector((SEL)_cmd), wxDumpUIView(slf));
    
    1039
    +
    
    1040
    +    if ( !m_wxPeer->IsEnabled() )
    
    1041
    +        return;
    
    1042
    +
    
    1043
    +    wxKeyEvent wxevent;
    
    1044
    +
    
    1045
    +    bool handled = false;
    
    1046
    +
    
    1047
    +    for (UIPress *press in (NSSet<UIPress *> *) presses)
    
    1048
    +    {
    
    1049
    +        SetupKeyEvent(wxevent, event, press , nil);
    
    1050
    +        m_wxPeer->OSXHandleKeyEvent(wxevent);
    
    1051
    +    }
    
    1052
    +
    
    1053
    +    if ( !handled ) {
    
    1054
    +        wxOSX_PressesHandlerPtr superimpl = (wxOSX_PressesHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
    
    1055
    +        superimpl(slf, (SEL)_cmd, presses, event);
    
    1056
    +    }
    
    1057
    +}
    
    760 1058
     //
    
    761 1059
     // Factory methods
    
    762 1060
     //
    


View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help Notification message regarding https://gitlab.com/wxwidgets/wxwidgets/-/commit/abe52cb3d56b3492f3f8714bee633b718d9ff0ee at 1759251416

Reply all
Reply to author
Forward
0 new messages