[Git][wxwidgets/wxwidgets][master] 3 commits: Improve wxStatusBar appearance on macOS 11-26

0 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
Sep 7, 2025, 12:00:22 PMSep 7
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • 12dfc19f
    by Václav Slavík at 2025-09-07T09:50:45+02:00
    Improve wxStatusBar appearance on macOS 11-26
    
    Update rendering code to closely match native appearance (i.e. Finder)
    on macOS 11 through 15, and on macOS 26 Tahoe.
    
    Starting with macOS 11, toolbar isn't rendered as part of extended
    window border. Starting with macOS 26, it doesn't even have different
    color and inherits the window's appearance (which is now an effects view
    with subtly changing color under the hood).
    
  • cbb0ab74
    by Václav Slavík at 2025-09-07T14:27:55+02:00
    Don't put wxStatusBar fields into corners on macOS
    
    macOS 26 (and to lesser extent, macOS 11+) uses rounded corners for
    windows and status bar fields were rendered into the corner.
    
    Improve the appearance by offsetting the fields are appropriately to
    look better. Also add a way to customize the offset from user code,
    because the default could be unsuitable when e.g. the window uses larger
    corner radius (possible on macOS 26), or when user code wants to do
    smarter placement of the fields to mimic Finder (which centers the
    statusbar, but not under the entire window, but under the main area sans
    the sidebar).
    
  • df9d6af1
    by Vadim Zeitlin at 2025-09-07T17:30:53+02:00
    Merge branch 'devel/tahoe-statusbar' of github.com:vslavik/wxWidgets
    
    Improve wxStatusBar appearance on macOS 11-26.
    
    See #25766.
    

5 changed files:

Changes:

  • include/wx/generic/statusbr.h
    ... ... @@ -87,6 +87,9 @@ protected:
    87 87
         // returns the position and the size of the size grip
    
    88 88
         wxRect GetSizeGripRect() const;
    
    89 89
     
    
    90
    +    // returns the width available for fields drawing given total width
    
    91
    +    virtual int GetAvailableWidthForFields(int width) const;
    
    92
    +
    
    90 93
         // common part of all ctors
    
    91 94
         void Init();
    
    92 95
     
    

  • include/wx/osx/statusbr.h
    ... ... @@ -28,14 +28,23 @@ public:
    28 28
         // Implementation
    
    29 29
         virtual void MacHiliteChanged() override;
    
    30 30
         void OnPaint(wxPaintEvent& event);
    
    31
    +    virtual bool GetFieldRect(int i, wxRect& rect) const override;
    
    32
    +
    
    33
    +    void MacSetCornerInset(int inset);
    
    34
    +    int MacGetCornerInset() const { return m_cornerInset; }
    
    31 35
     
    
    32 36
     protected:
    
    33 37
         virtual int GetEffectiveFieldStyle(int WXUNUSED(i)) const override { return wxSB_NORMAL; }
    
    34 38
     
    
    35 39
         virtual void InitColours() override;
    
    36 40
     
    
    41
    +    void InitCornerInset();
    
    42
    +
    
    43
    +    virtual int GetAvailableWidthForFields(int width) const override;
    
    44
    +
    
    37 45
     private:
    
    38
    -    wxColour m_textActive, m_textInactive;
    
    46
    +    int m_cornerInset;
    
    47
    +    wxColour m_textActive, m_textInactive, m_bgActive, m_bgInactive, m_separator;
    
    39 48
     
    
    40 49
         wxDECLARE_DYNAMIC_CLASS(wxStatusBarMac);
    
    41 50
         wxDECLARE_EVENT_TABLE();
    

  • src/generic/statusbr.cpp
    ... ... @@ -177,13 +177,19 @@ void wxStatusBarGeneric::SetStatusWidths(int n, const int widths_field[])
    177 177
         DoUpdateFieldWidths();
    
    178 178
     }
    
    179 179
     
    
    180
    +int wxStatusBarGeneric::GetAvailableWidthForFields(int width) const
    
    181
    +{
    
    182
    +    if ( ShowsSizeGrip() )
    
    183
    +        width -= GetSizeGripRect().width;
    
    184
    +
    
    185
    +    return width;
    
    186
    +}
    
    187
    +
    
    180 188
     void wxStatusBarGeneric::DoUpdateFieldWidths()
    
    181 189
     {
    
    182 190
         m_lastClientSize = GetClientSize();
    
    183 191
     
    
    184
    -    int width = m_lastClientSize.x;
    
    185
    -    if ( ShowsSizeGrip() )
    
    186
    -        width -= GetSizeGripRect().width;
    
    192
    +    const int width = GetAvailableWidthForFields(m_lastClientSize.x);
    
    187 193
     
    
    188 194
         // recompute the cache of the field widths if the status bar width has changed
    
    189 195
         m_widthsAbs = CalculateAbsWidths(width);
    

  • src/osx/carbon/frame.cpp
    ... ... @@ -128,7 +128,14 @@ wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
    128 128
     void wxFrame::SetStatusBar(wxStatusBar *statbar)
    
    129 129
     {
    
    130 130
         wxFrameBase::SetStatusBar(statbar);
    
    131
    -    m_nowpeer->SetBottomBorderThickness(statbar ? GetMacStatusbarHeight() : 0);
    
    131
    +    if ( WX_IS_MACOS_AVAILABLE(11, 0) )
    
    132
    +    {
    
    133
    +        // textured borders are unwanted, statusbar renders w/o them
    
    134
    +    }
    
    135
    +    else
    
    136
    +    {
    
    137
    +        m_nowpeer->SetBottomBorderThickness(statbar ? GetMacStatusbarHeight() : 0);
    
    138
    +    }
    
    132 139
     }
    
    133 140
     
    
    134 141
     void wxFrame::PositionStatusBar()
    

  • src/osx/carbon/statbrma.cpp
    ... ... @@ -25,9 +25,6 @@
    25 25
     #include "wx/osx/private.h"
    
    26 26
     #include "wx/osx/private/available.h"
    
    27 27
     
    
    28
    -// Margin between the field text and the field rect
    
    29
    -#define wxFIELD_TEXT_MARGIN 2
    
    30
    -
    
    31 28
     
    
    32 29
     wxBEGIN_EVENT_TABLE(wxStatusBarMac, wxStatusBarGeneric)
    
    33 30
         EVT_PAINT(wxStatusBarMac::OnPaint)
    
    ... ... @@ -69,13 +66,52 @@ bool wxStatusBarMac::Create(wxWindow *parent, wxWindowID id,
    69 66
         SetWindowVariant( wxWINDOW_VARIANT_SMALL );
    
    70 67
     
    
    71 68
         InitColours();
    
    69
    +    InitCornerInset();
    
    72 70
     
    
    73 71
         return true;
    
    74 72
     }
    
    75 73
     
    
    76 74
     void wxStatusBarMac::InitColours()
    
    77 75
     {
    
    78
    -    if ( WX_IS_MACOS_AVAILABLE(10, 14) )
    
    76
    +    if ( WX_IS_MACOS_AVAILABLE(26, 0) )
    
    77
    +    {
    
    78
    +        if ( wxSystemSettings::GetAppearance().IsDark() )
    
    79
    +        {
    
    80
    +            m_textActive = wxColour(0x9B, 0x9F, 0x9F);
    
    81
    +            m_textInactive = wxColour(0x59, 0x5F, 0x60);
    
    82
    +            // native separator uses hairline black plus some shading,
    
    83
    +            // this approximates it well visually:
    
    84
    +            m_separator = wxColour(0x18, 0x18, 0x18);
    
    85
    +        }
    
    86
    +        else
    
    87
    +        {
    
    88
    +            m_textActive = wxColour(0x80, 0x80, 0x80);
    
    89
    +            m_textInactive = wxColour(0xB8, 0xB8, 0xB8);
    
    90
    +            m_separator = wxColour(0xD9, 0xD9, 0xD9);
    
    91
    +        }
    
    92
    +    }
    
    93
    +    else if ( WX_IS_MACOS_AVAILABLE(11, 0) )
    
    94
    +    {
    
    95
    +        if ( wxSystemSettings::GetAppearance().IsDark() )
    
    96
    +        {
    
    97
    +            m_textActive = wxColour(0xB1, 0xB2, 0xB2);
    
    98
    +            m_textInactive = wxColour(0x68, 0x69, 0x6A);
    
    99
    +            m_bgActive = wxColour(0x35, 0x36, 0x36);
    
    100
    +            m_bgInactive = wxColour(0x27, 0x28, 0x29);
    
    101
    +            // native separator uses hairline black plus some shading,
    
    102
    +            // this approximates it well visually:
    
    103
    +            m_separator = wxColour(0x18, 0x18, 0x18);
    
    104
    +        }
    
    105
    +        else
    
    106
    +        {
    
    107
    +            m_textActive = wxColour(0x73, 0x74, 0x74);
    
    108
    +            m_textInactive = wxColour(0xA5, 0xA6, 0xA6);
    
    109
    +            m_bgActive = wxColour(0xF3, 0xF3, 0xF3);
    
    110
    +            m_bgInactive = wxColour(0xE6, 0xE6, 0xE6);
    
    111
    +            m_separator = wxColour(0xCC, 0xCC, 0xCC);
    
    112
    +        }
    
    113
    +    }
    
    114
    +    else if ( WX_IS_MACOS_AVAILABLE(10, 14) )
    
    79 115
         {
    
    80 116
             if ( wxSystemSettings::GetAppearance().IsDark() )
    
    81 117
             {
    
    ... ... @@ -90,7 +126,6 @@ void wxStatusBarMac::InitColours()
    90 126
         }
    
    91 127
         else // 10.10 Yosemite to 10.13:
    
    92 128
         {
    
    93
    -
    
    94 129
             m_textActive = wxColour(0x40, 0x40, 0x40);
    
    95 130
             m_textInactive = wxColour(0x4B, 0x4B, 0x4B);
    
    96 131
         }
    
    ... ... @@ -118,7 +153,27 @@ void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event))
    118 153
                 break;
    
    119 154
         }
    
    120 155
     
    
    121
    -    // Don't paint any background, that's handled by the OS. Only draw text:
    
    156
    +    if ( WX_IS_MACOS_AVAILABLE(26, 0) )
    
    157
    +    {
    
    158
    +        // don't paint the background, handled by the OS
    
    159
    +    }
    
    160
    +    else if ( WX_IS_MACOS_AVAILABLE(11, 0) )
    
    161
    +    {
    
    162
    +        // we _do_ need to paint the background on Big Sur up to Tahoe
    
    163
    +        // to match Finder's appearance:
    
    164
    +        dc.SetBackground(tlw == keyWindow ? m_bgActive : m_bgInactive);
    
    165
    +        dc.Clear();
    
    166
    +    }
    
    167
    +    // else: background is rendered by OS, it is part of NSWindow border
    
    168
    +
    
    169
    +    // Draw horizontal separator above the status bar:
    
    170
    +    if ( WX_IS_MACOS_AVAILABLE(11, 0) )
    
    171
    +    {
    
    172
    +        dc.SetPen(m_separator);
    
    173
    +        dc.DrawLine(0, 0, GetSize().x, 0);
    
    174
    +    }
    
    175
    +
    
    176
    +    // Draw the text:
    
    122 177
     
    
    123 178
         dc.SetTextForeground(tlw == keyWindow ? m_textActive : m_textInactive);
    
    124 179
     
    
    ... ... @@ -131,6 +186,38 @@ void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event))
    131 186
             DrawField(dc, i, textHeight);
    
    132 187
     }
    
    133 188
     
    
    189
    +void wxStatusBarMac::InitCornerInset()
    
    190
    +{
    
    191
    +    if ( WX_IS_MACOS_AVAILABLE(26, 0) )
    
    192
    +        m_cornerInset = 8;
    
    193
    +    else if ( WX_IS_MACOS_AVAILABLE(11, 0) )
    
    194
    +        m_cornerInset = 4;
    
    195
    +    else
    
    196
    +        m_cornerInset = 0;
    
    197
    +}
    
    198
    +
    
    199
    +void wxStatusBarMac::MacSetCornerInset(int inset)
    
    200
    +{
    
    201
    +    m_cornerInset = inset;
    
    202
    +    // force recalculation of the fields:
    
    203
    +    m_lastClientSize = wxDefaultSize;
    
    204
    +    Refresh();
    
    205
    +}
    
    206
    +
    
    207
    +int wxStatusBarMac::GetAvailableWidthForFields(int width) const
    
    208
    +{
    
    209
    +    return wxStatusBarGeneric::GetAvailableWidthForFields(width) - 2 * m_cornerInset;
    
    210
    +}
    
    211
    +
    
    212
    +bool wxStatusBarMac::GetFieldRect(int i, wxRect& rect) const
    
    213
    +{
    
    214
    +    if ( !wxStatusBarGeneric::GetFieldRect(i, rect) )
    
    215
    +        return false;
    
    216
    +
    
    217
    +    rect.x += MacGetCornerInset();
    
    218
    +    return true;
    
    219
    +}
    
    220
    +
    
    134 221
     void wxStatusBarMac::MacHiliteChanged()
    
    135 222
     {
    
    136 223
         Refresh();
    

Reply all
Reply to author
Forward
0 new messages