wxDataViewListCtrl flickers when its parent wxPanel is moved inside a wxScrolledWindow (regression in 3.3.3 on MSW) (Issue #26750)

27 views
Skip to first unread message

FredCL13

unread,
Jul 29, 2026, 10:53:40 AM (6 days ago) Jul 29
to wx-...@googlegroups.com, Subscribed
FredCL13 created an issue (wxWidgets/wxWidgets#26750)

Environment

  • OS: Windows 11
  • wxWidgets: 3.3.3 (works fine with 3.3.1)
  • Build: MSW, default settings

Description
When several wxPanel children containing a wxDataViewListCtrl are placed inside a wxScrolledWindow, and these panels are moved with the mouse (dragging), the content of the wxDataViewListCtrl starts to flicker and redraw badly.

The flicker appears:

  • only in the child that is being moved,
  • mainly in the wxDataViewListCtrl content (rows, text, icons),
  • and becomes clearly visible when 3–4 children are present.

The background drawing in the wxScrolledWindow (lines from (0,0) to each child position) is stable enough; the problem is the internal repaint of wxDataViewListCtrl when its parent is moved.

With wxWidgets 3.3.1, everything works correctly (no flicker).
With wxWidgets 3.3.3, flicker appears when moving children inside a wxScrolledWindow.

Steps to reproduce

  1. Create a wxFrame with a wxScrolledWindow as main client area.
  2. Add a menu item “Add Child” that creates a datasource panel inside the scrolled window.
  3. Each datasource is a wxPanel containing:
    • a small header wxPanel (red),
    • a wxDataViewListCtrl with a few columns and rows.
  4. The header panel handles mouse events to implement dragging:
    • on left down: start drag, capture mouse,
    • on motion: move the parent panel (Move(pos + delta)),
    • optionally call GetParent()->Refresh() to redraw the background.
  5. The scrolled window has a wxEVT_PAINT handler that:
    • clears the background,
    • draws two diagonal red lines,
    • iterates over its children and draws a line from (0,0) to each child position.
  6. Add 3–4 children via the menu.
  7. Drag one of the children around with the mouse.

Expected behaviour

  • The wxDataViewListCtrl content should remain stable and readable while its parent panel is moved.
  • Only the background and the lines should be redrawn.
  • No heavy flicker inside the child controls.

Actual behaviour

  • The wxDataViewListCtrl inside the moving child flickers heavily:
    • rows are partially redrawn,
    • text and icons “jump” or appear corrupted during movement,
    • the control looks visually broken while dragging.
  • The effect becomes clearly visible when 3–4 children are present.
  • The background and lines are acceptable; the main issue is inside wxDataViewListCtrl.

Minimal sample code
`// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef BORLANDC
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/dataview.h"

#define ID_DATASOURCE 10000
#define ID_PANEL 10001

// Class datasource declaration
class datasource: public wxPanel
{
DECLARE_DYNAMIC_CLASS( datasource )

public:
/// Constructors
datasource();
datasource( wxWindow* parent, wxWindowID id = ID_DATASOURCE, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL );

/// Creation
bool Create( wxWindow* parent, wxWindowID id = ID_DATASOURCE, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL );

/// Destructor
~datasource() {}

void CreateControls();

void OnDragStart(wxMouseEvent& event);
void OnDragMove(wxMouseEvent& event);
void OnDragEnd(wxMouseEvent& event);
void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);

protected:
bool m_Dragging;
wxPoint m_DragStart;
};

#define ID_MAINFRAME 10000
#define ID_PANEL 10001
#define ID_ADDCHILD 10003
#define FRAME_STYLE wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX

// Class MainFrame declaration

class MainFrame: public wxFrame
{
DECLARE_CLASS( MainFrame )
DECLARE_EVENT_TABLE()

public:
/// Constructors
MainFrame( wxWindow* parent, wxWindowID id = ID_MAINFRAME, const wxString& caption = _("MainFrame"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = FRAME_STYLE );

bool Create( wxWindow* parent, wxWindowID id = ID_MAINFRAME, const wxString& caption = _("MainFrame"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = FRAME_STYLE );

/// Destructor
~MainFrame() {}

/// Creates the controls and sizers
void CreateControls();

/// wxEVT_COMMAND_MENU_SELECTED event handler for ID_ADDCHILD
void OnAddchildClick( wxCommandEvent& event );

/// wxEVT_COMMAND_MENU_SELECTED event handler for wxID_EXIT
void OnExitClick( wxCommandEvent& event );

/// wxEVT_SIZE event handler for ID_PANEL
void OnSize( wxSizeEvent& event );

/// wxEVT_PAINT event handler for ID_PANEL
void OnPaint( wxPaintEvent& event );

protected:
wxScrolledWindow* m_Canvas;
wxInt32 m_Child_X;
wxInt32 m_Child_Y;
};

// Class Project1App declaration

class Project1App: public wxApp
{
DECLARE_CLASS( Project1App )

public:
/// Constructor
Project1App() {}

/// Initialises the application
virtual bool OnInit();

/// Called on exit
virtual int OnExit();

};

// Class Project1App implementation

IMPLEMENT_APP( Project1App )

IMPLEMENT_CLASS( Project1App, wxApp )

bool Project1App::OnInit()
{
MainFrame* mainWindow = new MainFrame( NULL );
mainWindow->Show(true);

return true;

}

int Project1App::OnExit()
{
return wxApp::OnExit();
}

// Class datasource implementation

IMPLEMENT_DYNAMIC_CLASS( datasource, wxPanel )

datasource::datasource()
{
m_Dragging = false;
}

datasource::datasource( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
m_Dragging = false;
Create(parent, id, pos, size, style);
}

bool datasource::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
wxPanel::Create( parent, id, pos, size, style );
SetBackgroundColour(*wxLIGHT_GREY);
CreateControls();
return true;
}

void datasource::CreateControls()
{
wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
SetSizer(itemBoxSizer2);

wxPanel* itemPanel2 = new wxPanel( this, ID_PANEL, wxDefaultPosition, wxSize(-1, 20), wxNO_BORDER|wxTAB_TRAVERSAL );
itemPanel2->SetBackgroundColour(*wxRED);
itemPanel2->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
itemBoxSizer2->Add(itemPanel2, 0, wxGROW|wxALL, 5);

wxDataViewListCtrl* itemWindow3 = new wxDataViewListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
itemBoxSizer2->Add(itemWindow3, 1, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5);

itemWindow3->AppendToggleColumn(wxEmptyString, wxDATAVIEW_CELL_ACTIVATABLE, 24, wxALIGN_CENTER);
itemWindow3->AppendIconTextColumn("Link/Field", wxDATAVIEW_CELL_INERT, 83, wxALIGN_LEFT);
itemWindow3->AppendTextColumn("Type", wxDATAVIEW_CELL_INERT, 76, wxALIGN_RIGHT);
itemWindow3->AppendTextColumn("Linked", wxDATAVIEW_CELL_INERT, 0, wxALIGN_LEFT, wxDATAVIEW_COL_HIDDEN);

wxVector<wxVariant> l_itemData;
wxDataViewIconText l_iconText("Field1");

l_itemData.push_back(wxVariant(false));
l_itemData.push_back(wxVariant(l_iconText));
l_itemData.push_back(wxVariant("TEXT"));
l_itemData.push_back(wxVariant(0));
itemWindow3->AppendItem(l_itemData);

l_itemData.clear();
l_iconText.SetText("Field2");
l_itemData.push_back(wxVariant(false));
l_itemData.push_back(wxVariant(l_iconText));
l_itemData.push_back(wxVariant("INTEGER"));
l_itemData.push_back(wxVariant(0));
itemWindow3->AppendItem(l_itemData);

itemPanel2->Bind(wxEVT_LEFT_DOWN, &datasource::OnDragStart, this);
Bind(wxEVT_LEFT_UP,   &datasource::OnDragEnd, this);
Bind(wxEVT_MOTION,    &datasource::OnDragMove, this);
Bind(wxEVT_MOUSE_CAPTURE_LOST,    &datasource::OnMouseCaptureLost, this);

}

void datasource::OnDragStart(wxMouseEvent& event)
{
m_Dragging = true;
m_DragStart = event.GetPosition();
CaptureMouse();
}

void datasource::OnDragMove(wxMouseEvent& event)
{
if (!m_Dragging)
return;

wxPoint pos = GetPosition();
wxPoint delta = event.GetPosition() - m_DragStart;
Move(pos + delta);

if (GetParent())
    GetParent()->Refresh();

}

void datasource::OnDragEnd(wxMouseEvent& event)
{
if (m_Dragging)
{
m_Dragging = false;
if (HasCapture())
ReleaseMouse();
}
}

void datasource::OnMouseCaptureLost(wxMouseCaptureLostEvent& event)
{
if (m_Dragging)
{
m_Dragging = false;
ReleaseMouse();
}
}

// Class MainFrame implementation

IMPLEMENT_CLASS( MainFrame, wxFrame )

BEGIN_EVENT_TABLE( MainFrame, wxFrame )
EVT_MENU( ID_ADDCHILD, MainFrame::OnAddchildClick )
EVT_MENU( wxID_EXIT, MainFrame::OnExitClick )
END_EVENT_TABLE()

MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
m_Child_X = m_Child_Y = 0;

Create( parent, id, caption, pos, size, style );

}

bool MainFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
wxFrame::Create( parent, id, caption, pos, size, style );

CreateControls();
return true;

}

void MainFrame::CreateControls()
{
wxMenuBar* menuBar = new wxMenuBar;
wxMenu* itemMenu3 = new wxMenu;
itemMenu3->Append(ID_ADDCHILD, _("Add Child"), wxEmptyString, wxITEM_NORMAL);
itemMenu3->Append(wxID_EXIT, _("E&xit\tAlt+F4"), wxEmptyString, wxITEM_NORMAL);
menuBar->Append(itemMenu3, _("Test"));
SetMenuBar(menuBar);

wxBoxSizer* itemBoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
SetSizer(itemBoxSizer1);

m_Canvas = new wxScrolledWindow( this, ID_PANEL, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxHSCROLL|wxVSCROLL );
itemBoxSizer1->Add(m_Canvas, 1, wxGROW, 0);
m_Canvas->SetScrollbars(1, 1, 0, 0);

m_Canvas->SetBackgroundStyle(wxBG_STYLE_PAINT);
// Connect events and objects
m_Canvas->Connect(ID_PANEL, wxEVT_SIZE, wxSizeEventHandler(MainFrame::OnSize), NULL, this);
m_Canvas->Connect(ID_PANEL, wxEVT_PAINT, wxPaintEventHandler(MainFrame::OnPaint), NULL, this);

}

void MainFrame::OnAddchildClick( wxCommandEvent& event )
{
m_Child_X += 10;
m_Child_Y += 10;
datasource* l_Dts = new datasource( m_Canvas, wxID_ANY, wxPoint(m_Child_X, m_Child_Y));

l_Dts->Show();
l_Dts->SetSize(wxSize(200, 180));

}

void MainFrame::OnExitClick( wxCommandEvent& event )
{
Close();
}

void MainFrame::OnSize( wxSizeEvent& event )
{
Refresh();
event.Skip();
}

void MainFrame::OnPaint( wxPaintEvent& event )
{
wxPaintDC l_Dc(wxDynamicCast(event.GetEventObject(), wxWindow));
wxSize l_Size = m_Canvas->GetClientSize();

l_Dc.SetBackground(GetBackgroundColour());
l_Dc.Clear();
l_Dc.SetPen(wxPen(*wxRED, 3));
l_Dc.DrawLine(0, 0, l_Size.x, l_Size.y);
l_Dc.DrawLine(l_Size.x, 0, 0, l_Size.y);

for ( wxWindowList::const_iterator l_Idx = m_Canvas->GetChildren().begin(); l_Idx != m_Canvas->GetChildren().end(); ++l_Idx )
{
    datasource* l_Dts = wxDynamicCast(*l_Idx, datasource);
    if ( l_Dts )
    {
        wxPoint l_Pos = l_Dts->GetPosition();
        l_Dc.DrawLine(0, 0, l_Pos.x, l_Pos.y);
    }
}

}
`
Sorry for this long code but attach file failed each times I try.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750@github.com>

VZ

unread,
Jul 30, 2026, 2:15:58 PM (5 days ago) Jul 30
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26750)

The code is mangled, I could fix this but there is really too much of it. Can you please try to reproduce the problem in the dataview sample with the smallest possible patch to it (please see our bug reporting guidelines)? It already has a wxDataViewListCtrl.

Also, I suspect this is related to turning off compositing in 3.3.3, in which case it's a reversal to 3.2 behaviour and not a "real" regression, but please let me know if it's worse than in 3.2 too.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5134616624@github.com>

FredCL13

unread,
Jul 30, 2026, 2:28:59 PM (5 days ago) Jul 30
to wx-...@googlegroups.com, Subscribed
FredCL13 left a comment (wxWidgets/wxWidgets#26750)

mainframe.zip
The complete code is in the zip archive.
I will try this weekend to build a smaller sample based on dataview sample.
I will also try with the version 3.2.11.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5134752541@github.com>

FredCL13

unread,
Aug 1, 2026, 2:59:12 PM (3 days ago) Aug 1
to wx-...@googlegroups.com, Subscribed
FredCL13 left a comment (wxWidgets/wxWidgets#26750)

I've recompile my test file with Visual Studio 2022 (vc++ 14) using 3.2.11 binaries files provided on Github.
Same problem.
To resume:
v3.2.11 => KO flickering
v3.3.1 => OK
v3.3.3 => KO flickering


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5152928133@github.com>

VZ

unread,
Aug 1, 2026, 4:11:21 PM (3 days ago) Aug 1
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26750)

This seems to confirm that the absence of flicker in 3.3.1 was due to the use of compositing there. This had to be reverted due to many other problems with, unfortunately.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5153215410@github.com>

FredCL13

unread,
Aug 1, 2026, 4:44:17 PM (3 days ago) Aug 1
to wx-...@googlegroups.com, Subscribed
FredCL13 left a comment (wxWidgets/wxWidgets#26750)

This seems to confirm that the absence of flicker in 3.3.1 was due to the use of compositing there. This had to be reverted due to many other problems with, unfortunately.

Does that mean no solution will be found, or is another solution needed, like the one in version 3.3.1, but without the disadvantages?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5153339588@github.com>

VZ

unread,
Aug 1, 2026, 4:48:34 PM (3 days ago) Aug 1
to wx-...@googlegroups.com, Subscribed
vadz left a comment (wxWidgets/wxWidgets#26750)

Another (and completely different) solution would need to be found, probably specific to wxDVC.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/26750/5153364561@github.com>

Reply all
Reply to author
Forward
0 new messages