[Git][wxwidgets/wxwidgets][master] 19 commits: Use a single wxSize instead of (w,h) pair in wxBufferedDC

2 views
Skip to first unread message

Vadim Zeitlin (@_VZ_)

unread,
Nov 28, 2025, 11:16:32 AMNov 28
to wx-commi...@googlegroups.com

Vadim Zeitlin pushed to branch master at wxWidgets / wxWidgets

Commits:

  • 2a9d97d2
    by Vadim Zeitlin at 2025-11-21T15:45:11+01:00
    Use a single wxSize instead of (w,h) pair in wxBufferedDC
    
    No real changes, just replace a pair of int parameters with a single
    wxSize one. This makes the code a bit more readable.
    
  • 28eaad75
    by Vadim Zeitlin at 2025-11-21T15:55:03+01:00
    Don't reinvent wxAutoBufferedPaintDC in wxAuiTabContainer code
    
    Remove code in wxAuiTabContainer::Render() which was basically doing the
    same thing as wxAutoBufferedPaintDC does except without using shared
    buffer optimization.
    
    This code predates wxAutoBufferedPaintDC appearance, so it made sense
    originally but it doesn't make sense since a very long time any more.
    
  • b7323939
    by Vadim Zeitlin at 2025-11-21T16:07:28+01:00
    Use 24bpp backing store bitmap in wxMSW to speed up drawing on it
    
    Avoid the overhead of converting the backing store bitmap to DIB and
    back when drawing bitmaps with alpha on it in AlphaBlt(), which may be
    very significant, by using 24bpp bitmap: as it doesn't have alpha, it
    doesn't need to be adjusted after drawing on it.
    
    This is ugly and it would be better to have a better implementation of
    AlphaBlt(), but it's not clear how to do it, and for now this fixes a
    real user-visible problem.
    
    See #14403.
    
    Closes #23841.
    
  • e496728d
    by ali kettab at 2025-11-23T21:51:39+01:00
    wxQt: Refer to base class type by a shorter name
    
    No real changes.
    
  • a0d73364
    by ali kettab at 2025-11-23T21:51:39+01:00
    wxQt: Revert commit 6ead206
    
    Added in 2019-02-11 (Fix wxQT wxTreeCtrl drawing issues under Linux)
    
    The warnings are already fixed by the recent changes to the wxQt code.
    
  • d970a1bc
    by ali kettab at 2025-11-23T23:02:51+01:00
    wxQt: Fix a potential crash when destroying a wxTreeCtrl in edit mode
    
    Closes #24693
    
  • 4915a719
    by ali kettab at 2025-11-24T08:35:21+01:00
    wxQt: Always accept when a wxTreeCtrl item remains unchanged after editing
    
  • 602b80d8
    by Alex Shvartzkop at 2025-11-25T22:54:09+01:00
    Support EGL 1.4 instead of previously required 1.5
    
    Check for the availability of eglCreatePlatformWindowSurfaceEXT() if EGL
    version is < 1.5 and use it if it's available, as it allows applications
    using wxGLCanvasEGL to work on some (many?) systems without EGL 1.5
    support.
    
    Closes #22325.
    
    Co-authored-by: Vadim Zeitlin <va...@wxwidgets.org>
    
  • 8f008d73
    by Vadim Zeitlin at 2025-11-25T22:54:19+01:00
    Translate the error about too low EGL version
    
    This error is user-visible and so should be translated.
    
    Also remove the unnecessary call to wxString::Format().
    
  • b2615451
    by Lauri Nurmi at 2025-11-26T01:16:07+01:00
    Do not log bogus system error in wxRenameFile()
    
    There is no failed system call at this point, so there is no relevant
    system error available either.
    
    Closes #25985.
    
  • 03608709
    by Vadim Zeitlin at 2025-11-26T20:33:55+01:00
    Fix initial scale of wxGLCanvas under EGL/Wayland
    
    The scale of the canvas was set up correctly only once we received
    "size-allocate" signal from GTK, but this doesn't necessarily happen
    when the window is first shown and after its scale factor is actually
    known.
    
    Ensure that we use the correct scale by catching the notification about
    its change too. This makes buffer scale factor correct from the very
    beginning, without having to wait for a resize.
    
    See #23733, #25465.
    
  • c3d9bd95
    by Vadim Zeitlin at 2025-11-26T20:33:55+01:00
    Make wxGLCanvasEGL friend function a normal member one
    
    No real changes, it's just not necessary to have wxEGLUpdatePosition()
    friend function any more as it's only called from wxEGLUpdateGeometry()
    which is itself a friend function and so can call normal private member
    functions.
    
    This hopefully makes things a bit more clear.
    
  • 881f4fe1
    by ali kettab at 2025-11-28T01:14:38+01:00
    wxQt: Fix wxWindow::SetSize() for toplevel windows - revisited
    
    No real changes, just a revision of this commit 846502ec5b (Fix
    wxWindow::SetSize() for toplevel windows, 2024-10-01) to test for
    WA_PendingResizeEvent instead of storing m_pendingSize variable.
    
  • 445f6619
    by ali kettab at 2025-11-28T01:14:38+01:00
    wxQt: Test for pending client size using WA_PendingResizeEvent attribute
    
    No real changes, just make the test more clear that m_pendingClientSize is
    only set when the resize event is pending as reported by the Qt kernel.
    
  • 04843dd3
    by Vadim Zeitlin at 2025-11-28T16:58:23+01:00
    Merge branch 'avoid-slow-alphablt'
    
    Avoid slow drawing of bitmaps with alpha in wxAUI.
    
    See #25983.
    
  • 468667c1
    by Vadim Zeitlin at 2025-11-28T16:59:41+01:00
    Merge branch 'support-egl-1.4'
    
    Support EGL 1.4 instead of previously required 1.5.
    
    See #25986.
    
  • 4fa70c7f
    by Vadim Zeitlin at 2025-11-28T17:01:44+01:00
    Merge branch 'qt-treectrl-fix' of github.com:AliKet/wxWidgets
    
    wxQt: Fix potential crash when destroying a wxTreeCtrl in edit mode.
    
    See #25987.
    
  • 842c5288
    by Vadim Zeitlin at 2025-11-28T17:02:52+01:00
    Merge branch 'egl-fix-initial-scale'
    
    Fix initial scale of wxGLCanvas under EGL/Wayland.
    
    See #25994.
    
  • 71619e9f
    by Vadim Zeitlin at 2025-11-28T17:03:52+01:00
    Merge branch 'qt-pending-resize' of github.com:AliKet/wxWidgets
    
    wxQt: Improve handling pending resize.
    
    See #25995.
    

9 changed files:

Changes:

  • include/wx/dcbuffer.h
    ... ... @@ -90,7 +90,7 @@ public:
    90 90
         {
    
    91 91
             InitCommon(dc, style);
    
    92 92
     
    
    93
    -        UseBuffer(area.x, area.y);
    
    93
    +        UseBuffer(area);
    
    94 94
         }
    
    95 95
     
    
    96 96
         // Blits the buffer to the dc, and detaches the dc from the buffer (so it
    
    ... ... @@ -116,7 +116,7 @@ private:
    116 116
         }
    
    117 117
     
    
    118 118
         // check that the bitmap is valid and use it
    
    119
    -    void UseBuffer(wxCoord w = -1, wxCoord h = -1);
    
    119
    +    void UseBuffer(wxSize size = wxDefaultSize);
    
    120 120
     
    
    121 121
         // the underlying DC to which we copy everything drawn on this one in
    
    122 122
         // UnMask()
    

  • include/wx/qt/window.h
    ... ... @@ -257,9 +257,6 @@ private:
    257 257
     
    
    258 258
         bool m_mouseInside;
    
    259 259
     
    
    260
    -    bool  m_pendingSize = false; // to properly set the size of the TLW if SetSize()
    
    261
    -                                 // is called before the window is shown.
    
    262
    -
    
    263 260
         wxSize  m_pendingClientSize;
    
    264 261
     
    
    265 262
     #if wxUSE_ACCEL
    

  • include/wx/unix/glegl.h
    ... ... @@ -131,6 +131,20 @@ public:
    131 131
         wl_egl_window *m_wlEGLWindow = nullptr;
    
    132 132
     
    
    133 133
     private:
    
    134
    +    // Set correct m_wlSubsurface position.
    
    135
    +    //
    
    136
    +    // This is defined only when using Wayland.
    
    137
    +    void UpdateSubsurfacePosition();
    
    138
    +
    
    139
    +    // Call eglCreatePlatformWindowSurface() when using EGL 1.5 or later,
    
    140
    +    // otherwise try eglCreatePlatformWindowSurfaceEXT() if it's available and
    
    141
    +    // fall back on eglCreateWindowSurface() otherwise.
    
    142
    +    //
    
    143
    +    // This function uses m_display and m_config which must be initialized
    
    144
    +    // before using it and should be passed either m_xwindow or m_wlEGLWindow
    
    145
    +    // depending on whether we are using X11 or Wayland.
    
    146
    +    EGLSurface CallCreatePlatformWindowSurface(void *window) const;
    
    147
    +
    
    134 148
     
    
    135 149
         EGLConfig m_config = nullptr;
    
    136 150
         EGLDisplay m_display = nullptr;
    
    ... ... @@ -147,8 +161,8 @@ private:
    147 161
         // the global/default versions of the above
    
    148 162
         static EGLConfig ms_glEGLConfig;
    
    149 163
     
    
    150
    -    friend void wxEGLUpdatePosition(wxGLCanvasEGL* win);
    
    151
    -    friend void wxEGLSetScale(wxGLCanvasEGL* win, int scale);
    
    164
    +    // Called from GTK callbacks and needs access to private members.
    
    165
    +    friend void wxEGLUpdateGeometry(GtkWidget* widget, wxGLCanvasEGL* win);
    
    152 166
     };
    
    153 167
     
    
    154 168
     // ----------------------------------------------------------------------------
    

  • src/aui/auibook.cpp
    ... ... @@ -901,34 +901,15 @@ void wxAuiTabContainer::RenderButtons(wxDC& dc, wxWindow* wnd,
    901 901
     // Render() renders the tab catalog to the specified DC
    
    902 902
     // It is a virtual function and can be overridden to
    
    903 903
     // provide custom drawing capabilities
    
    904
    -void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
    
    904
    +void wxAuiTabContainer::Render(wxDC* pdc, wxWindow* wnd)
    
    905 905
     {
    
    906
    -    if (!raw_dc || !raw_dc->IsOk())
    
    907
    -        return;
    
    908
    -
    
    909 906
         if (m_rect.IsEmpty())
    
    910 907
             return;
    
    911 908
     
    
    912 909
         size_t i;
    
    913 910
         size_t page_count = m_pages.GetCount();
    
    914 911
     
    
    915
    -#if wxALWAYS_NATIVE_DOUBLE_BUFFER
    
    916
    -    wxDC& dc = *raw_dc;
    
    917
    -#else
    
    918
    -    wxMemoryDC dc;
    
    919
    -
    
    920
    -    // use the same layout direction as the window DC uses to ensure that the
    
    921
    -    // text is rendered correctly
    
    922
    -    dc.SetLayoutDirection(raw_dc->GetLayoutDirection());
    
    923
    -
    
    924
    -    wxBitmap bmp;
    
    925
    -    // create off-screen bitmap
    
    926
    -    bmp.Create(m_rect.GetWidth(), m_rect.GetHeight(),*raw_dc);
    
    927
    -    dc.SelectObject(bmp);
    
    928
    -
    
    929
    -    if (!dc.IsOk())
    
    930
    -        return;
    
    931
    -#endif
    
    912
    +    wxDC& dc = *pdc;
    
    932 913
     
    
    933 914
         // draw background
    
    934 915
         m_art->DrawBackground(dc, wnd, m_rect);
    
    ... ... @@ -1015,13 +996,6 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
    1015 996
         {
    
    1016 997
             m_art->DrawPageTab(dc, wnd, m_pages.Item(active), active_rect);
    
    1017 998
         }
    
    1018
    -
    
    1019
    -
    
    1020
    -#if !wxALWAYS_NATIVE_DOUBLE_BUFFER
    
    1021
    -    raw_dc->Blit(m_rect.x, m_rect.y,
    
    1022
    -                 m_rect.GetWidth(), m_rect.GetHeight(),
    
    1023
    -                 &dc, 0, 0);
    
    1024
    -#endif
    
    1025 999
     }
    
    1026 1000
     
    
    1027 1001
     // Is the tab visible?
    
    ... ... @@ -1409,7 +1383,7 @@ wxRect wxAuiTabCtrl::GetHintScreenRect() const
    1409 1383
     
    
    1410 1384
     void wxAuiTabCtrl::OnPaint(wxPaintEvent&)
    
    1411 1385
     {
    
    1412
    -    wxPaintDC dc(this);
    
    1386
    +    wxAutoBufferedPaintDC dc(this);
    
    1413 1387
     
    
    1414 1388
         if (GetPageCount() > 0)
    
    1415 1389
             Render(&dc, this);
    

  • src/common/dcbufcmn.cpp
    ... ... @@ -44,19 +44,18 @@ public:
    44 44
         virtual bool OnInit() override { return true; }
    
    45 45
         virtual void OnExit() override { wxDELETE(ms_buffer); }
    
    46 46
     
    
    47
    -    static wxBitmap* GetBuffer(wxDC* dc, int w, int h)
    
    47
    +    static wxBitmap* GetBuffer(wxDC* dc, wxSize size)
    
    48 48
         {
    
    49 49
             if ( ms_usingSharedBuffer )
    
    50
    -            return DoCreateBuffer(dc, w, h);
    
    50
    +            return DoCreateBuffer(dc, size);
    
    51 51
     
    
    52 52
             if ( !ms_buffer ||
    
    53
    -                w > ms_buffer->GetLogicalWidth() ||
    
    54
    -                h > ms_buffer->GetLogicalHeight() ||
    
    53
    +                !ms_buffer->GetLogicalSize().IsAtLeast(size) ||
    
    55 54
                     (dc && dc->GetContentScaleFactor() != ms_buffer->GetScaleFactor()) )
    
    56 55
             {
    
    57 56
                 delete ms_buffer;
    
    58 57
     
    
    59
    -            ms_buffer = DoCreateBuffer(dc, w, h);
    
    58
    +            ms_buffer = DoCreateBuffer(dc, size);
    
    60 59
             }
    
    61 60
     
    
    62 61
             ms_usingSharedBuffer = true;
    
    ... ... @@ -77,14 +76,30 @@ public:
    77 76
         }
    
    78 77
     
    
    79 78
     private:
    
    80
    -    static wxBitmap* DoCreateBuffer(wxDC* dc, int w, int h)
    
    79
    +    static wxBitmap* DoCreateBuffer(wxDC* dc, wxSize size)
    
    81 80
         {
    
    82 81
             const double scale = dc ? dc->GetContentScaleFactor() : 1.0;
    
    83 82
             wxBitmap* const buffer = new wxBitmap;
    
    84 83
     
    
    85 84
             // we must always return a valid bitmap but creating a bitmap of
    
    86 85
             // size 0 would fail, so create a 1*1 bitmap in this case
    
    87
    -        buffer->CreateWithLogicalSize(wxMax(w, 1), wxMax(h, 1), scale);
    
    86
    +        size.IncTo(wxSize(1, 1));
    
    87
    +
    
    88
    +        // Explicitly request 24bpp bitmap under MSW to avoid slow down when
    
    89
    +        // drawing bitmaps with alpha channel on 32bpp bitmap: as explained in
    
    90
    +        // AlphaBlt() implementation in src/msw/dc.cpp, we need to manually
    
    91
    +        // reset alpha values in this case, which involves converting the
    
    92
    +        // bitmap to DIB and back and may be very slow. As we don't really care
    
    93
    +        // about the alpha values in the backing store bitmap (everything is
    
    94
    +        // already blended when drawing to it), use 24bpp bitmap to avoid this.
    
    95
    +        constexpr int depth =
    
    96
    +#if defined(__WXMSW__)
    
    97
    +            24;
    
    98
    +#else
    
    99
    +            wxBITMAP_SCREEN_DEPTH;
    
    100
    +#endif
    
    101
    +
    
    102
    +        buffer->CreateWithLogicalSize(size, scale, depth);
    
    88 103
     
    
    89 104
             return buffer;
    
    90 105
         }
    
    ... ... @@ -104,18 +119,18 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxSharedDCBufferManager, wxModule);
    104 119
     // wxBufferedDC
    
    105 120
     // ============================================================================
    
    106 121
     
    
    107
    -void wxBufferedDC::UseBuffer(wxCoord w, wxCoord h)
    
    122
    +void wxBufferedDC::UseBuffer(wxSize size)
    
    108 123
     {
    
    109
    -    wxCHECK_RET( w >= -1 && h >= -1, "Invalid buffer size" );
    
    124
    +    wxCHECK_RET( size.x >= -1 && size.y >= -1, "Invalid buffer size" );
    
    110 125
     
    
    111 126
         if ( !m_buffer || !m_buffer->IsOk() )
    
    112 127
         {
    
    113
    -        if ( w == -1 || h == -1 )
    
    114
    -            m_dc->GetSize(&w, &h);
    
    128
    +        if ( !size.IsFullySpecified() )
    
    129
    +            size = m_dc->GetSize();
    
    115 130
     
    
    116
    -        m_buffer = wxSharedDCBufferManager::GetBuffer(m_dc, w, h);
    
    131
    +        m_buffer = wxSharedDCBufferManager::GetBuffer(m_dc, size);
    
    117 132
             m_style |= wxBUFFER_USES_SHARED_BUFFER;
    
    118
    -        m_area.Set(w,h);
    
    133
    +        m_area = size;
    
    119 134
         }
    
    120 135
         else
    
    121 136
             m_area = m_buffer->GetSize();
    

  • src/common/filefn.cpp
    ... ... @@ -601,7 +601,7 @@ wxRenameFile(const wxString& file1, const wxString& file2, bool overwrite)
    601 601
     
    
    602 602
         if ( !overwrite && wxFileExists(file2) )
    
    603 603
         {
    
    604
    -        wxLogSysError
    
    604
    +        wxLogError
    
    605 605
             (
    
    606 606
                 _("Failed to rename the file '%s' to '%s' because the destination file already exists."),
    
    607 607
                 file1.c_str(), file2.c_str()
    

  • src/qt/treectrl.cpp
    ... ... @@ -20,6 +20,7 @@
    20 20
     #include "wx/qt/private/winevent.h"
    
    21 21
     #include "wx/qt/private/treeitemdelegate.h"
    
    22 22
     
    
    23
    +#include <QtWidgets/QApplication>
    
    23 24
     #include <QtWidgets/QTreeWidget>
    
    24 25
     #include <QtWidgets/QHeaderView>
    
    25 26
     #include <QtWidgets/QScrollBar>
    
    ... ... @@ -175,9 +176,11 @@ private:
    175 176
     
    
    176 177
     class wxQTreeWidget : public wxQtEventSignalHandler<QTreeWidget, wxTreeCtrl>
    
    177 178
     {
    
    179
    +    using BaseClass = wxQtEventSignalHandler<QTreeWidget, wxTreeCtrl>;
    
    180
    +
    
    178 181
     public:
    
    179 182
         wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) :
    
    180
    -        wxQtEventSignalHandler<QTreeWidget, wxTreeCtrl>(parent, handler),
    
    183
    +        BaseClass(parent, handler),
    
    181 184
             m_item_delegate(handler),
    
    182 185
             m_closing_editor(0)
    
    183 186
         {
    
    ... ... @@ -217,14 +220,6 @@ public:
    217 220
                     });
    
    218 221
         }
    
    219 222
     
    
    220
    -    virtual void paintEvent(QPaintEvent* event) override
    
    221
    -    {
    
    222
    -        //QT generates warnings if we try to paint to a QTreeWidget
    
    223
    -        //(perhaps because it's a compound widget) so we've disabled
    
    224
    -        //wx paint and erase background events
    
    225
    -        QTreeWidget::paintEvent(event);
    
    226
    -    }
    
    227
    -
    
    228 223
         virtual void mouseReleaseEvent(QMouseEvent * event) override
    
    229 224
         {
    
    230 225
             const QPoint qPos = event->pos();
    
    ... ... @@ -264,7 +259,7 @@ public:
    264 259
                     }
    
    265 260
             }
    
    266 261
     
    
    267
    -        return wxQtEventSignalHandler<QTreeWidget, wxTreeCtrl>::mouseReleaseEvent(event);
    
    262
    +        return BaseClass::mouseReleaseEvent(event);
    
    268 263
         }
    
    269 264
     
    
    270 265
         wxTextCtrl *GetEditControl()
    
    ... ... @@ -357,6 +352,48 @@ protected:
    357 352
             QTreeView::selectionChanged(selected, deselected);
    
    358 353
         }
    
    359 354
     
    
    355
    +    // Helper class which tries to close any open editor as early as possible
    
    356
    +    // when the application is shutting down to avoid a crash if closeEditor()
    
    357
    +    // pops up any message box. IOW, showing a message/dialog box (using exec())
    
    358
    +    // while the application is closing down is dangerous.
    
    359
    +    // See note in the Qt documentation of QDialog::exec()
    
    360
    +    class SafeEditorCloser : public QObject
    
    361
    +    {
    
    362
    +    public:
    
    363
    +        explicit SafeEditorCloser(wxQTreeWidget* qTreeWidget)
    
    364
    +            : m_qTreeWidget(qTreeWidget)
    
    365
    +        {
    
    366
    +            qApp->installEventFilter(this);
    
    367
    +        }
    
    368
    +
    
    369
    +        ~SafeEditorCloser()
    
    370
    +        {
    
    371
    +            qApp->removeEventFilter(this);
    
    372
    +        }
    
    373
    +
    
    374
    +    protected:
    
    375
    +        bool eventFilter(QObject* obj, QEvent* event) override
    
    376
    +        {
    
    377
    +            if ( event->type() == QEvent::Close )
    
    378
    +            {
    
    379
    +                // Don't try to close the editor if there is any active popup window
    
    380
    +                // (e.g. selecting Quit from the menu) because the application would
    
    381
    +                // hang if closeEditor() pops up any message box.
    
    382
    +                if ( !QApplication::activePopupWidget() )
    
    383
    +                {
    
    384
    +                    // This will close any currently opened editor.
    
    385
    +                    m_qTreeWidget->setCurrentItem(nullptr);
    
    386
    +                }
    
    387
    +            }
    
    388
    +
    
    389
    +            return QObject::eventFilter(obj, event);
    
    390
    +        }
    
    391
    +
    
    392
    +        wxQTreeWidget* const m_qTreeWidget;
    
    393
    +    };
    
    394
    +
    
    395
    +    std::unique_ptr<SafeEditorCloser> m_editorCloser;
    
    396
    +
    
    360 397
         bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) override
    
    361 398
         {
    
    362 399
             // AllEditTriggers means that editor is about to open, not waiting for double click
    
    ... ... @@ -369,6 +406,8 @@ protected:
    369 406
                     return true;
    
    370 407
                 }
    
    371 408
     
    
    409
    +            m_startEditorText = wxQtConvertString(itemFromIndex(index)->text(0));
    
    410
    +
    
    372 411
                 // Allow event handlers to veto opening the editor
    
    373 412
                 wxTreeEvent wx_event(
    
    374 413
                     wxEVT_TREE_BEGIN_LABEL_EDIT,
    
    ... ... @@ -378,7 +417,15 @@ protected:
    378 417
                 if (GetHandler()->HandleWindowEvent(wx_event) && !wx_event.IsAllowed())
    
    379 418
                     return false;
    
    380 419
             }
    
    381
    -        return QTreeWidget::edit(index, trigger, event);
    
    420
    +
    
    421
    +        if ( QTreeWidget::edit(index, trigger, event) )
    
    422
    +        {
    
    423
    +            m_editorCloser.reset(new SafeEditorCloser(this));
    
    424
    +
    
    425
    +            return true;
    
    426
    +        }
    
    427
    +
    
    428
    +        return false;
    
    382 429
         }
    
    383 430
     
    
    384 431
         void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) override
    
    ... ... @@ -390,6 +437,15 @@ protected:
    390 437
             if (guard.IsInside())
    
    391 438
                 return;
    
    392 439
     
    
    440
    +        m_editorCloser.reset(nullptr);
    
    441
    +
    
    442
    +        if (!GetHandler())
    
    443
    +        {
    
    444
    +            // The handler may have already been destroyed, when quitting
    
    445
    +            // the application using Ctrl+Q for example.
    
    446
    +            return;
    
    447
    +        }
    
    448
    +
    
    393 449
             // There can be multiple calls to close editor when the item loses focus
    
    394 450
             const QModelIndex current_index = m_item_delegate.GetCurrentModelIndex();
    
    395 451
             if (!current_index.isValid())
    
    ... ... @@ -400,7 +456,10 @@ protected:
    400 456
                 GetHandler(),
    
    401 457
                 wxQtConvertTreeItem(itemFromIndex(current_index))
    
    402 458
                 );
    
    403
    -        if (hint == QAbstractItemDelegate::RevertModelCache)
    
    459
    +
    
    460
    +        const wxString editor_text = m_item_delegate.GetEditControl()->GetLineText(0);
    
    461
    +
    
    462
    +        if (hint == QAbstractItemDelegate::RevertModelCache || editor_text == m_startEditorText)
    
    404 463
             {
    
    405 464
                 event.SetEditCanceled(true);
    
    406 465
                 EmitEvent(event);
    
    ... ... @@ -408,7 +467,6 @@ protected:
    408 467
             else
    
    409 468
             {
    
    410 469
                 // Allow event handlers to decide whether to accept edited text
    
    411
    -            const wxString editor_text = m_item_delegate.GetEditControl()->GetLineText(0);
    
    412 470
                 event.SetLabel(editor_text);
    
    413 471
                 if (!GetHandler()->HandleWindowEvent(event) || event.IsAllowed())
    
    414 472
                     m_item_delegate.AcceptModelData(editor, model(), current_index);
    
    ... ... @@ -595,7 +653,7 @@ private:
    595 653
         virtual void mouseMoveEvent(QMouseEvent *event) override
    
    596 654
         {
    
    597 655
             const bool wasDragging = state() == DraggingState;
    
    598
    -        wxQtEventSignalHandler<QTreeWidget, wxTreeCtrl>::mouseMoveEvent(event);
    
    656
    +        BaseClass::mouseMoveEvent(event);
    
    599 657
     
    
    600 658
             const bool nowDragging = state() == DraggingState;
    
    601 659
             if ( !wasDragging && nowDragging )
    
    ... ... @@ -643,6 +701,8 @@ private:
    643 701
         typedef std::map<QTreeWidgetItem*,ImageState> ImageStateMap;
    
    644 702
         ImageStateMap m_imageStates;
    
    645 703
     
    
    704
    +    wxString m_startEditorText;
    
    705
    +
    
    646 706
         // Place holder image to reserve enough space in a row
    
    647 707
         // for us to draw our icon
    
    648 708
         QPixmap m_placeHolderImage;
    
    ... ... @@ -697,8 +757,6 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id,
    697 757
     
    
    698 758
     wxTreeCtrl::~wxTreeCtrl()
    
    699 759
     {
    
    700
    -    if ( GetQTreeWidget() )
    
    701
    -        GetQTreeWidget()->deleteLater();
    
    702 760
     }
    
    703 761
     
    
    704 762
     wxQTreeWidget* wxTreeCtrl::GetQTreeWidget() const
    

  • src/qt/window.cpp
    ... ... @@ -1215,14 +1215,6 @@ void wxWindowQt::DoSetSize(int x, int y, int width, int height, int sizeFlags )
    1215 1215
                 height = BEST_SIZE.y;
    
    1216 1216
         }
    
    1217 1217
     
    
    1218
    -    if ( !GetHandle()->isVisible() && QtGetClientWidget() != GetHandle() )
    
    1219
    -    {
    
    1220
    -        if ( width != -1 && height != -1 )
    
    1221
    -        {
    
    1222
    -            m_pendingSize = true;
    
    1223
    -        }
    
    1224
    -    }
    
    1225
    -
    
    1226 1218
         int w, h;
    
    1227 1219
         GetSize(&w, &h);
    
    1228 1220
         if (width == -1)
    
    ... ... @@ -1294,7 +1286,7 @@ void wxWindowQt::DoMoveWindow(int x, int y, int width, int height)
    1294 1286
     
    
    1295 1287
         const auto clientSize = wxQtSetClientSize(qtWidget, width, height);
    
    1296 1288
     
    
    1297
    -    if (!qtWidget->isVisible() && clientSize.x > 0 && clientSize.y > 0)
    
    1289
    +    if ( qtWidget->testAttribute(Qt::WA_PendingResizeEvent) )
    
    1298 1290
         {
    
    1299 1291
             m_pendingClientSize = clientSize;
    
    1300 1292
         }
    
    ... ... @@ -2001,12 +1993,11 @@ bool wxWindowQt::QtHandleShowEvent ( QWidget *handler, QEvent *event )
    2001 1993
         if ( GetHandle() != handler )
    
    2002 1994
             return false;
    
    2003 1995
     
    
    2004
    -    if ( m_pendingSize )
    
    1996
    +    if ( handler != QtGetClientWidget() &&
    
    1997
    +         handler->testAttribute(Qt::WA_PendingResizeEvent) )
    
    2005 1998
         {
    
    2006
    -        const auto frameSize = GetHandle()->geometry().size();
    
    2007
    -        wxQtSetClientSize(GetHandle(), frameSize.width(), frameSize.height());
    
    2008
    -
    
    2009
    -        m_pendingSize = false;
    
    1999
    +        const auto frameSize = handler->geometry().size();
    
    2000
    +        wxQtSetClientSize(handler, frameSize.width(), frameSize.height());
    
    2010 2001
         }
    
    2011 2002
     
    
    2012 2003
         wxShowEvent e(GetId(), event->type() == QEvent::Show);
    

  • src/unix/glegl.cpp
    ... ... @@ -37,8 +37,17 @@
    37 37
     
    
    38 38
     #include <memory>
    
    39 39
     
    
    40
    +namespace
    
    41
    +{
    
    42
    +
    
    40 43
     constexpr const char* TRACE_EGL = "glegl";
    
    41 44
     
    
    45
    +// EGL version initialized by InitConfig().
    
    46
    +EGLint gs_eglMajor = 0;
    
    47
    +EGLint gs_eglMinor = 0;
    
    48
    +
    
    49
    +} // anonymous namespace
    
    50
    +
    
    42 51
     // ----------------------------------------------------------------------------
    
    43 52
     // wxGLContextAttrs: OpenGL rendering context attributes
    
    44 53
     // ----------------------------------------------------------------------------
    
    ... ... @@ -420,10 +429,9 @@ void wxGLCanvasEGL::OnWLFrameCallback()
    420 429
     
    
    421 430
     #ifdef GDK_WINDOWING_WAYLAND
    
    422 431
     
    
    423
    -// Helper declared as friend in the header and so can access m_wlSubsurface.
    
    424
    -void wxEGLUpdatePosition(wxGLCanvasEGL* win)
    
    432
    +void wxGLCanvasEGL::UpdateSubsurfacePosition()
    
    425 433
     {
    
    426
    -    if ( !win->m_wlSubsurface )
    
    434
    +    if ( !m_wlSubsurface )
    
    427 435
         {
    
    428 436
             // In some circumstances such as when reparenting a canvas between two hidden
    
    429 437
             // toplevel windows, GTK will call size-allocate before mapping the canvas
    
    ... ... @@ -432,13 +440,21 @@ void wxEGLUpdatePosition(wxGLCanvasEGL* win)
    432 440
         }
    
    433 441
     
    
    434 442
         int x, y;
    
    435
    -    gdk_window_get_origin(win->GTKGetDrawingWindow(), &x, &y);
    
    436
    -    wl_subsurface_set_position(win->m_wlSubsurface, x, y);
    
    443
    +    gdk_window_get_origin(GTKGetDrawingWindow(), &x, &y);
    
    444
    +    wl_subsurface_set_position(m_wlSubsurface, x, y);
    
    437 445
     }
    
    438 446
     
    
    439
    -// Helper declared as friend in the header and so can access m_wlSurface.
    
    440
    -void wxEGLSetScale(wxGLCanvasEGL* win, int scale)
    
    447
    +// Helper declared as friend in the header and so can access member variables.
    
    448
    +//
    
    449
    +// Used when size or scale factor changes
    
    450
    +void wxEGLUpdateGeometry(GtkWidget* widget, wxGLCanvasEGL* win)
    
    441 451
     {
    
    452
    +    int scale = gtk_widget_get_scale_factor(widget);
    
    453
    +    wl_egl_window_resize(win->m_wlEGLWindow, win->m_width * scale,
    
    454
    +                         win->m_height * scale, 0, 0);
    
    455
    +
    
    456
    +    win->UpdateSubsurfacePosition();
    
    457
    +
    
    442 458
         wl_surface_set_buffer_scale(win->m_wlSurface, scale);
    
    443 459
     }
    
    444 460
     
    
    ... ... @@ -497,17 +513,76 @@ static void gtk_glcanvas_size_callback(GtkWidget *widget,
    497 513
                                            GtkAllocation *,
    
    498 514
                                            wxGLCanvasEGL *win)
    
    499 515
     {
    
    500
    -    int scale = gtk_widget_get_scale_factor(widget);
    
    501
    -    wl_egl_window_resize(win->m_wlEGLWindow, win->m_width * scale,
    
    502
    -                         win->m_height * scale, 0, 0);
    
    516
    +    wxEGLUpdateGeometry(widget, win);
    
    517
    +}
    
    503 518
     
    
    504
    -    wxEGLUpdatePosition(win);
    
    505
    -    wxEGLSetScale(win, scale);
    
    519
    +static void gtk_glcanvas_scale_factor_notify(GtkWidget* widget,
    
    520
    +                                             GParamSpec*,
    
    521
    +                                             wxGLCanvasEGL *win)
    
    522
    +{
    
    523
    +    wxEGLUpdateGeometry(widget, win);
    
    506 524
     }
    
    507 525
     
    
    508 526
     } // extern "C"
    
    509 527
     #endif // GDK_WINDOWING_WAYLAND
    
    510 528
     
    
    529
    +EGLSurface wxGLCanvasEGL::CallCreatePlatformWindowSurface(void *window) const
    
    530
    +{
    
    531
    +    // Type of eglCreatePlatformWindowSurface[EXT]().
    
    532
    +    typedef EGLSurface (*CreatePlatformWindowSurface)(EGLDisplay display,
    
    533
    +                                                      EGLConfig config,
    
    534
    +                                                      void* window,
    
    535
    +                                                      EGLAttrib const* attrib_list);
    
    536
    +
    
    537
    +    if ( gs_eglMajor > 1 || (gs_eglMajor == 1 && gs_eglMinor >= 5) )
    
    538
    +    {
    
    539
    +        // EGL 1.5 or later: use eglCreatePlatformWindowSurface() which must be
    
    540
    +        // available.
    
    541
    +        static CreatePlatformWindowSurface s_eglCreatePlatformWindowSurface = nullptr;
    
    542
    +        if ( !s_eglCreatePlatformWindowSurface )
    
    543
    +        {
    
    544
    +            s_eglCreatePlatformWindowSurface = reinterpret_cast<CreatePlatformWindowSurface>(
    
    545
    +                eglGetProcAddress("eglCreatePlatformWindowSurface"));
    
    546
    +        }
    
    547
    +
    
    548
    +        // This check is normally superfluous but avoid crashing just in case
    
    549
    +        // it isn't.
    
    550
    +        if ( s_eglCreatePlatformWindowSurface )
    
    551
    +        {
    
    552
    +            return s_eglCreatePlatformWindowSurface(m_display, m_config,
    
    553
    +                                                    window,
    
    554
    +                                                    nullptr);
    
    555
    +        }
    
    556
    +    }
    
    557
    +
    
    558
    +    // Try loading the appropriate EGL function on first use.
    
    559
    +    static CreatePlatformWindowSurface s_eglCreatePlatformWindowSurfaceEXT = nullptr;
    
    560
    +    static bool s_extFuncInitialized = false;
    
    561
    +    if ( !s_extFuncInitialized )
    
    562
    +    {
    
    563
    +        s_extFuncInitialized = true;
    
    564
    +
    
    565
    +        if ( IsExtensionSupported("EGL_EXT_platform_base") )
    
    566
    +        {
    
    567
    +            s_eglCreatePlatformWindowSurfaceEXT = reinterpret_cast<CreatePlatformWindowSurface>(
    
    568
    +                eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"));
    
    569
    +        }
    
    570
    +    }
    
    571
    +
    
    572
    +    if ( s_eglCreatePlatformWindowSurfaceEXT )
    
    573
    +    {
    
    574
    +        return s_eglCreatePlatformWindowSurfaceEXT(m_display, m_config,
    
    575
    +                                                   window,
    
    576
    +                                                   nullptr);
    
    577
    +    }
    
    578
    +    else
    
    579
    +    {
    
    580
    +        return eglCreateWindowSurface(m_display, m_config,
    
    581
    +                                      reinterpret_cast<EGLNativeWindowType>(window),
    
    582
    +                                      nullptr);
    
    583
    +    }
    
    584
    +}
    
    585
    +
    
    511 586
     bool wxGLCanvasEGL::CreateSurface()
    
    512 587
     {
    
    513 588
         m_display = GetDisplay();
    
    ... ... @@ -528,8 +603,7 @@ bool wxGLCanvasEGL::CreateSurface()
    528 603
             }
    
    529 604
     
    
    530 605
             m_xwindow = GDK_WINDOW_XID(window);
    
    531
    -        m_surface = eglCreatePlatformWindowSurface(m_display, m_config,
    
    532
    -                                                   &m_xwindow, nullptr);
    
    606
    +        m_surface = CallCreatePlatformWindowSurface(&m_xwindow);
    
    533 607
         }
    
    534 608
     #endif
    
    535 609
     #ifdef GDK_WINDOWING_WAYLAND
    
    ... ... @@ -560,8 +634,7 @@ bool wxGLCanvasEGL::CreateSurface()
    560 634
             wl_surface_set_buffer_scale(m_wlSurface, scale);
    
    561 635
             m_wlEGLWindow = wl_egl_window_create(m_wlSurface, w * scale,
    
    562 636
                                                  h * scale);
    
    563
    -        m_surface = eglCreatePlatformWindowSurface(m_display, m_config,
    
    564
    -                                                   m_wlEGLWindow, nullptr);
    
    637
    +        m_surface = CallCreatePlatformWindowSurface(m_wlEGLWindow);
    
    565 638
     
    
    566 639
             // We need to use "map-event" instead of "map" to ensure that the
    
    567 640
             // widget's underlying Wayland surface has been created.
    
    ... ... @@ -574,8 +647,17 @@ bool wxGLCanvasEGL::CreateSurface()
    574 647
             // Not unmapping the canvas as soon as possible causes problems when reparenting
    
    575 648
             g_signal_connect(m_widget, "unmap",
    
    576 649
                              G_CALLBACK(gtk_glcanvas_unmap_callback), this);
    
    650
    +
    
    651
    +        // We connect to "size-allocate" to update the position of the
    
    652
    +        // subsurface when the toplevel window is moved, which also updates the
    
    653
    +        // scale as a side effect, but we need to also separately connect to
    
    654
    +        // "notify::scale-factor" to catch scale changes, which is especially
    
    655
    +        // important initially, as we don't get a "size-allocate" with the
    
    656
    +        // correct scale when the window is created.
    
    577 657
             g_signal_connect(m_widget, "size-allocate",
    
    578 658
                              G_CALLBACK(gtk_glcanvas_size_callback), this);
    
    659
    +        g_signal_connect(m_widget, "notify::scale-factor",
    
    660
    +                         G_CALLBACK (gtk_glcanvas_scale_factor_notify), this);
    
    579 661
         }
    
    580 662
     #endif
    
    581 663
     
    
    ... ... @@ -626,7 +708,7 @@ void wxGLCanvasEGL::CreateWaylandSubsurface()
    626 708
         wxCHECK_RET( m_wlSubsurface, "Unable to get EGL subsurface" );
    
    627 709
     
    
    628 710
         wl_subsurface_set_desync(m_wlSubsurface);
    
    629
    -    wxEGLUpdatePosition(this);
    
    711
    +    UpdateSubsurfacePosition();
    
    630 712
         m_wlFrameCallbackHandler = wl_surface_frame(surface);
    
    631 713
         wl_callback_add_listener(m_wlFrameCallbackHandler,
    
    632 714
                                  &wl_frame_listener, this);
    
    ... ... @@ -671,22 +753,20 @@ EGLConfig wxGLCanvasEGL::InitConfig(const wxGLAttributes& dispAttrs)
    671 753
             return nullptr;
    
    672 754
         }
    
    673 755
     
    
    674
    -    EGLint eglMajor = 0;
    
    675
    -    EGLint eglMinor = 0;
    
    676
    -    if ( !eglInitialize(dpy, &eglMajor, &eglMinor) )
    
    756
    +    if ( !eglInitialize(dpy, &gs_eglMajor, &gs_eglMinor) )
    
    677 757
         {
    
    678 758
             wxFAIL_MSG("eglInitialize failed");
    
    679 759
             return nullptr;
    
    680 760
         }
    
    681 761
     
    
    682 762
         // The runtime EGL version cannot be known until EGL has been initialized.
    
    683
    -    if ( eglMajor < 1 || (eglMajor == 1 && eglMinor < 5) )
    
    763
    +    if ( gs_eglMajor < 1 || (gs_eglMajor == 1 && gs_eglMinor < 4) )
    
    684 764
         {
    
    685 765
             // Ignore the return value here, we cannot recover at this point.
    
    686 766
             eglTerminate(dpy);
    
    687
    -        wxLogError(wxString::Format(
    
    688
    -            "EGL version is %d.%d. EGL version 1.5 or greater is required.",
    
    689
    -            eglMajor, eglMinor));
    
    767
    +        wxLogError(
    
    768
    +            _("EGL version is %d.%d but version 1.4 or greater is required."),
    
    769
    +            gs_eglMajor, gs_eglMinor);
    
    690 770
             return nullptr;
    
    691 771
         }
    
    692 772
     
    

Reply all
Reply to author
Forward
0 new messages