Make wxAUI and wxSplitterWindow work properly with wxOverlay under wxGTK2

This Workaround is needed because the DC used to draw on the wxOverlay clips
children by default under wxGTK2. This means that the sash will always appear
behind the sub-windows. making wxOverlay worthless under this platforms.

Notice that calling gdk_gc_set_subwindow() unconditionally in Destroy() is cheap
when DontClipSubWindows() has never been called.
This commit is contained in:
ali kettab 2024-01-25 03:17:45 +01:00 committed by AliKet
parent a38175885c
commit 7491ac5b7a
4 changed files with 52 additions and 16 deletions

View file

@ -122,6 +122,7 @@ public:
PangoFontDescription *m_fontdesc;
void SetUpDC( bool ismem = false );
void DontClipSubWindows();
void Destroy();
virtual void ComputeScaleAndOrigin() override;

View file

@ -146,6 +146,10 @@ void wxDCOverlay::Clear()
#include "wx/window.h"
#if defined(__WXGTK__) && !defined(__WXGTK3__)
#include "wx/gtk/dcclient.h"
#endif
namespace {
class wxOverlayImpl: public wxOverlay::Impl
{
@ -191,6 +195,14 @@ bool wxOverlayImpl::IsOk()
void wxOverlayImpl::Init( wxDC* dc, int x , int y , int width , int height )
{
#if defined(__WXGTK__) && !defined(__WXGTK3__)
// Workaround! to include sub-windows in the final drawing (on the overlay)
// as drawing on a DC under wxGTK2 clips children by default.
const auto dcimpl = static_cast<wxWindowDCImpl *>(dc->GetImpl());
if ( dcimpl )
dcimpl->DontClipSubWindows();
#endif
if (m_bmpSaved.IsOk())
{
if (x != m_x || y != m_y || width != m_width || height != m_height)
@ -241,6 +253,9 @@ void wxOverlayImpl::Clear(wxDC* dc)
void wxOverlayImpl::Reset()
{
m_bmpSaved.UnRef();
if ( m_window )
m_window->Refresh();
}
void wxOverlayImpl::BeginDrawing(wxDC* dc)

View file

@ -454,6 +454,14 @@ void wxWindowDCImpl::SetUpDC( bool isMemDC )
gdk_gc_set_clip_rectangle( m_bgGC, nullptr );
}
void wxWindowDCImpl::DontClipSubWindows()
{
gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
}
void wxWindowDCImpl::DoGetSize( int* width, int* height ) const
{
wxCHECK_RET( m_window, wxT("GetSize() doesn't work without window") );
@ -2018,14 +2026,33 @@ void wxWindowDCImpl::DestroyClippingRegion()
void wxWindowDCImpl::Destroy()
{
if (m_penGC) wxFreePoolGC( m_penGC );
m_penGC = nullptr;
if (m_brushGC) wxFreePoolGC( m_brushGC );
m_brushGC = nullptr;
if (m_textGC) wxFreePoolGC( m_textGC );
m_textGC = nullptr;
if (m_bgGC) wxFreePoolGC( m_bgGC );
m_bgGC = nullptr;
if (m_penGC)
{
gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN );
wxFreePoolGC( m_penGC );
m_penGC = nullptr;
}
if (m_brushGC)
{
gdk_gc_set_subwindow( m_brushGC, GDK_CLIP_BY_CHILDREN );
wxFreePoolGC( m_brushGC );
m_brushGC = nullptr;
}
if (m_textGC)
{
gdk_gc_set_subwindow( m_textGC, GDK_CLIP_BY_CHILDREN );
wxFreePoolGC( m_textGC );
m_textGC = nullptr;
}
if (m_bgGC)
{
gdk_gc_set_subwindow( m_bgGC, GDK_CLIP_BY_CHILDREN );
wxFreePoolGC( m_bgGC );
m_bgGC = nullptr;
}
}
void wxWindowDCImpl::SetDeviceOrigin( wxCoord x, wxCoord y )

View file

@ -42,18 +42,11 @@ void wxScreenDCImpl::Init()
SetUpDC();
gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_brushGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_textGC, GDK_INCLUDE_INFERIORS );
gdk_gc_set_subwindow( m_bgGC, GDK_INCLUDE_INFERIORS );
DontClipSubWindows();
}
wxScreenDCImpl::~wxScreenDCImpl()
{
gdk_gc_set_subwindow( m_penGC, GDK_CLIP_BY_CHILDREN );
gdk_gc_set_subwindow( m_brushGC, GDK_CLIP_BY_CHILDREN );
gdk_gc_set_subwindow( m_textGC, GDK_CLIP_BY_CHILDREN );
gdk_gc_set_subwindow( m_bgGC, GDK_CLIP_BY_CHILDREN );
}
void wxScreenDCImpl::DoGetSize(int *width, int *height) const