Created wxPanel overpaints a custom background drawn in EVT_PAINT. This behaviour is seen only in wxMSW.
It can be reproduced with this path to minimal sample:
--- a/samples/minimal/minimal.cpp +++ b/samples/minimal/minimal.cpp @@ -63,6 +63,7 @@ public: // event handlers (these functions should _not_ be virtual) void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); + void OnPaint(wxPaintEvent&); private: // any class wishing to process wxWidgets events must use this macro @@ -175,10 +176,19 @@ MyFrame::MyFrame(const wxString& title) CreateStatusBar(2); SetStatusText("Welcome to wxWidgets!"); #endif // wxUSE_STATUSBAR + wxPanel* p = new wxPanel(this); + Bind(wxEVT_PAINT, &MyFrame::OnPaint, this); } // event handlers +void MyFrame::OnPaint(wxPaintEvent&) +{ + wxPaintDC dc(this); + dc.SetBackground(*wxBLUE_BRUSH); + dc.Clear(); + dc.DrawText("abcd", 10, 10); +} void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) {
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
It looks to me as it behaves as expected only on Windows?
The panel is the sole child of the frame (status and menu bars do not count here), so it is expanded to cover the frame's whole client area and therefore anything the frame paints there cannot be visible?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I agree with @PBfordev, I'd expect wxMSW behaviour and I actually don't know how do wxGTK/wxOSX manage to show the parent window through the (non transparent) panel.
We might be able to emulate this under MSW, but do people really expect it to work like this? What about any other window, i.e. if you create just a wxWindow rather than a wxPanel?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
With
new wxWindow(this, wxID_ANY, wxPoint(0, 0), wxSize(200, 100), wxBORDER_RAISED);
instead of
new wxPanel(this);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
And both wxPaneland wxWindow:
wxPanel* p = new wxPanel(this);
new wxWindow(p, wxID_ANY, wxPoint(0, 0), wxSize(200, 100), wxBORDER_RAISED);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Tested your patches with wxQt under Ubuntu and found that it's the same as wxMSW:
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Firstly, the wxFrame docs states (the feature exists as far as I can remember):
wxEVT_SIZE: if the frame has exactly one child window, not counting the status and toolbar, this child is resized to take the entire frame client area.
Secondly, a wxPanel is not transparent by default, at least not on Windows, which is the only platform I am familiar with.
Just curious: Are childless wxPanels being transparent an expected GTK/macOS trait?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
So it looks like all windows are transparent under GTK/OSX but not anywhere else. I'm really not sure what to do about this.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
So it looks like all windows are transparent under GTK/OSX but not anywhere else.
For GTK, I think so, because the background is always (0, 0, 0, 0) for our custom GtkWidget as returned by wxPizza::New()
This patch seems to fix the issue (doesn't work with non-standard/very old themes):
diff --git a/src/gtk/win_gtk.cpp b/src/gtk/win_gtk.cpp index 7c3d768553..d787da58d5 100644 --- a/src/gtk/win_gtk.cpp +++ b/src/gtk/win_gtk.cpp @@ -362,6 +362,9 @@ GtkWidget* wxPizza::New(long windowStyle) pizza->m_windowStyle = windowStyle; #ifdef __WXGTK3__ gtk_widget_set_has_window(widget, true); + + GtkStyleContext* context = gtk_widget_get_style_context(widget); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_BACKGROUND); // use the theme bg #else gtk_fixed_set_has_window(GTK_FIXED(widget), true); #endif
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thanks @AliKet but I'm afraid I just don't understand all the ramifications of changing this :-(
@paulcor What do you think of the patch above?
And, @csomor, would you know if we can do something similar under Mac too, i.e. not make windows transparent by default?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
the translucency of windows and controls is really by design on OSX since many years ago, it would make a rather poor look if we changed this, eg a group box may have different grades of gray as background and the controls on it should reflect that and not overdraw this. I went quite a few miles to make things work properly,
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
What do you think of the patch above?
I'm not sure if it's a good idea, buf if we're going to do it, I'd rather do it like this:
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index b35ad3a995..ee6648c3f7 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -5869,7 +5869,11 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region) const int h = gdk_window_get_height(gdkWindow); #ifdef __WXGTK3__ GtkStyleContext* sc = gtk_widget_get_style_context(m_wxwindow); + gtk_style_context_save(sc); + if (wx_is_at_least_gtk3(14)) + gtk_style_context_add_class(sc, "background"); gtk_render_background(sc, cr, 0, 0, w, h); + gtk_style_context_restore(sc); #else // find ancestor from which to steal background wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
the translucency of windows and controls is really by design on OSX since many years ago, it would make a rather poor look if we changed this, eg a group box may have different grades of gray as background differing by the nesting level and the controls on it should reflect that and not overdraw this. Also eg. if you have a background with a gradient, you cannot simply restart at the top of a subwindow. I went quite a few miles to make things work properly (see also the handling of the different background styles)
So if you want your wxWindow not to have a transparent background, you should set it to something.
Currently, on both OSX and iOS, wxStaticText has a solid background that I cannot get rid of and that looks very wrong. I would like to second that we need to allow transparent backgrounds - if I understand the debate rightly
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
wxStaticText should be transparent, of course, and if it isn't, it's a bug that should be fixed as it is transparent even under MSW. And, to answer Stefan, there is definitely nothing wrong with wxStaticBox being transparent.
But it's really unexpected, IMO, that a plain wxWindow or wxPanel are transparent too. We could allow them to be, but I still think that this shouldn't be the default behaviour.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
So if you want your wxWindow not to have a transparent background, you should set it to something.
So we should just set the background to the solid colour for wxWindow and then reset it to transparent for the controls whose HasTransparentBackground() is overridden to return true?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
wxStaticTextshould be transparent, of course, and if it isn't, it's a bug that should be fixed as it is transparent even under MSW. And, to answer Stefan, there is definitely nothing wrong withwxStaticBoxbeing transparent.But it's really unexpected, IMO, that a plain
wxWindoworwxPanelare transparent too. We could allow them to be, but I still think that this shouldn't be the default behaviour.
I think if we change the default behavior now, then this will change the look of many apps that just use these for grouping controls on macOS for the worse. It's not the background of the static box that is the problem, but the controls that lie within this box, which must all have their background transparent, to get the correct look. When they set their background explicitly then we proceed accordingly.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
So should we just document that you need to set the background colour to get consistent behaviour under different platforms? This doesn't seem ideal but would be better than nothing...
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
What do you think of the patch above?
I'm not sure if it's a good idea, buf if we're going to do it, I'd rather do it like this:
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index b35ad3a995..ee6648c3f7 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -5869,7 +5869,11 @@ void wxWindowGTK::GTKSendPaintEvents(const GdkRegion* region)
const int h = gdk_window_get_height(gdkWindow);
#ifdef WXGTK3
GtkStyleContext* sc = gtk_widget_get_style_context(m_wxwindow);
gtk_style_context_save(sc);if (wx_is_at_least_gtk3(14))
gtk_style_context_add_class(sc, "background"); gtk_render_background(sc, cr, 0, 0, w, h);
gtk_style_context_restore(sc);
#else
// find ancestor from which to steal background
wxWindow *parent = wxGetTopLevelParent((wxWindow *)this);
Thanks, that looks better. But I'm also not sure if this change will affect those who expect the wxPanel or wxWindow to be transparent by default!
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()