On 11 October 2017 at 19:34, Eric Cashon via gtk-perl-list <gtk-perl-list@gnome.org> wrote:
I think there's some confusion, here, about the role of a GdkWindow and rendering… > This is something that I have had some trouble with at the app level. In > GTK3, how drawing is done, has changed a bit between minor versions in GTK3. > In order to get CSS, transparency, OpenGL and modern drawing techniques > working well,,, things have changed. Here is an article about container > windows. I have always considered containers not to have windows to draw on > but that may not be true anymore. > > https://blog.gtk.org/2017/05/24/container-secrets/ Widgets do not need windows to draw any more. It hasn't been true for years, even if the transition happened during the 3.x API series. A GdkWindow itself doesn't mean that a real windowing system surface is used to render its contents; this has been true since the 2.x days. A GtkWidget has a GdkWindow for rendering *only* if Gtk.Widget.set_has_window() is called with `TRUE`; additionally, a GtkWidget can add more GdkWindows for separate rendering and input handling, assuming it calls Gtk.Widget.register_window(), to let the toolkit know. Rendering starts from the top-level, and each widget will be traversed, with the draw() virtual function being called with a Cairo context. The nature of the Cairo context is entirely inconsequential, so you should *never* assume anything about its state. You're only supposed to draw your widget using the allocated size as the size of the surface; if you want to make sure to avoid overdraw, in case you're not using widgets but you're rendering your own objects, you can also query the size of the clip, and avoid rendering things outside of that region. I wrote a blog post about how GTK+ renders last year, for the development blog: https://blog.gtk.org/2016/06/15/drawing-in-gtk/ > Some widgets might use the background window. For example a label or even a > plug inside a socket. You can always try a GtkEventBox if you need a window > to draw on behind a widget if it doesn't have it's own window. You can also use Gtk.DrawingArea and call Gtk.Widget.set_has_window(); the drawing area widget will then create a GdkWindow for you inside its realize() implementation. > A GtkDrawingArea has it's own window to draw on. No, it really doesn't. Of course, unless you call Gtk.Widget.set_has_window(), which is not the default. The default behaviour of GtkDrawingArea, in GTK+ 3.22, is to use the parent's window. In a typical GTK application, this means it'll render on the top-level window, which ideally should be the only native windowing system surface in use for rendering. Incidentally, for GTK+ 4.0 we're cleaning up this mess, and the only windowing system surface for both rendering and input will be the one created by GtkWindow; everything else will render on that, and input will be handled by the GTK widget hierarchy. > If you put a drawing area > over the main window and draw on both with transparency you can see this. This is not really correct. Transparency is done via opacity groups in Cairo and GTK; if a widget has a different opacity than its parent, and its parent also has a different opacity than 1.0, it'll be rendered into an intermediate surface, and then composited at the parent's opacity, to avoid blending errors. > How GTK draws the layout using cairo and the compositor might be a different > argument though. Cairo contexts are the same. Yes, the Cairo context is the same because the Cairo context is propagated through the widget hierarchy, assuming that the surface used as the target is the same. That's how we can implement semi-transparent widgets, or how we can do things like border shadows in CSS. This is also why it's fundamental to always draw using the Cairo context given to you by GTK itself, and never call gdk_cairo_create(). If you want to draw into an intermediate surface you should create your own Cairo surface, render into it, and then use that surface as the source on the Cairo context inside the draw() implementation. Ciao, Emmanuele. -- https://www.bassi.io [@] ebassi [@gmail.com] _______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-perl-list