wip/baedert/drawing branch

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

wip/baedert/drawing branch

Timm Bäder
Hi,

I've collected a whole bunch of changes in th wip/baedert/drawing branch.
Here's a little overview of how things work in there, so we can decide
if it's the right way forward.

Internals:
 - gtk_widget_snapshot automatically draws CSS background and border for
   all widgets. It then calls the ->snapshot vfunc so the widget can
   draw contents, then it draws a focus rectangle if
   gtk_widget_get_has_visible_focus returns TRUE.
 - gtk_widget_real_snapshot calls gtk_widget_snapshot_child on all the
   child widgets of the given GtkWidget instance. This makes sense to me
   but it's already been problematic when porting GtkScale and GtkRange
   away from gadgets because GtkRange didn't override ::snapshot so
   GtkScale couldn't just subclass it and chain up, since it would cause
   all child widgets to be drawn twice.
 - gtk_widget_measure cares about CSS min-width/min-height, as well as
   CSS margins, padding and borders. So
   gtk_widget_size_allocate_with_baseline first sets the widget's
   allocation to the given one and then passes the content allocation,
   i.e. the one without CSS margin, border and padding down to the
   size-allocate vfunc. I.e. in the size-allocate implementation,
   widgets receive their new content allocation, not the entire widget
   allocation. If they still need the widget allocation, they can call
   gtk_widget_get_allocation of course since the allocation has been set
   before calling ::size-allocate. There are currently
   gtk_widget_get_margin_allocaiton, _border_allocation and
   _content_allocation implementations private.
 - For clips, all widgets *have to* currently call gtk_widget_set_clip
   at the end of their size-allocate implementation.
   gtk_widget_set_clip will union the given clip with the box-shadow
   size and the widget allocation minus CSS margins.
 - Since we always automatically set the allocation of a widget before
   calling its ::size-allocate vfunc, gtk_widget_set_allocation is gone.

Widgets:
 - GtkSpinButton is now a direct GtkWidget subclass that contains a
   GtkBox that contains a GtkEntry and two GtkButtons. That was easier
   than expected since GtkSpinButton already (partially) implemented
   GtkEditable. It also means that currently the blue focus outline
   around the entire spin button is broken. Dunno if there's some CSS
   magic that would fix this or if that approach for the spinbutton is
   just wrong.
 - GtkRange is not abstract anymore. Not because I really want to but
   because it was needed for GtkScrollbar. Not sure if that's right or
   if we can use it as a general "slider inside trough" widget.
 - GtkScrollbar is now a direct GtkWidget subclass containing a box that
   contains a GtkRange. That works out mostly fine in practice but of
   course people can't call GtkRange API on it anymore, so
   gtk_scrollbar_get_adjustment has to be used, etc. The stepper buttons
   are currently gone but since it contains a GtkBox they should be
   relatively easy to add back, I've just not heard a good solution to
   how we should hide/show them without the style properties.
 - GtkCheckButton is now a GtkBin subclass containing a
   GtkTogglebutton that contains a GtkIcon as indicator and the actual
   bin child. This consequently means that GtkToggleButton API can't be
   used on a GtkCheckButton anymore, which is pretty painfull for
   porters, and there's not really an automatic way of fixing this since
   the old gtk_tool_button_{get,set}_active for example are still valid
   calls.
 - GtkNotebook lost all its gadgets. There's stil some bug triaging to
   be done though. I'm not sure if it doesn't suffer from being unable
   to show/hide widgets in ::size-allocate now.
 - The last remaining gadgets are the progress and icons in GtkEntry as
   well as the handle gadget in GtkPaned, but I'd like to wait for the
   event-delivery branch to get merged to master first.
 - Since GtkPopover looks at the margins manually and considers them in
   its ::measure implementation, popovers are currently slightly higher
   (or wider, depending on the arrow position) than they should be.


Remaining problems/open questions:
 - Both GtkWindow and GtkPopover are special-cased in
   gtk_widget_snapshot to not draw the CSS background and border for
   them, since they are just too special. Getting rid of that special
   case would require porting them away from manual background drawing.
 - There are lots of CSS problems now of course, e.g. GtkRevealer does
   not hide its padding anymore so GtkSearchBar always leaves a few
   pixels of space around, or the 4px margin around GtkMenu which is not
   applied inside the toplevel instead of outside. Also GtkCheckButton
   obviously.
 - Focus outlines work out pretty badly the way they are currently done
   in the branch. Wit gadgets, widgets had pretty fine-grained control
   over which gadget draws the focus outline.
 - I've had to make lots of changes to make clips work the way they do
   now, but it seems like the clip should always default to the
   allocation (like it always did), but then it doesn't consider the box
   shadow.
 - Baselines are pretty screwed up, but they are already broken in
   master and as long as coordinates are in flux, I don't want to look
   in to that just to have them broken again.
 - GtkScale has a ::format-value signal. In the past, this has been
   emitted on every draw (or size-allocate?), when the PangoLayout was
   created. The widget-factory uses that (and returns a g_strdup (" "))
   to hide the value entirely. This does not work anymore on startup,
   because the value is not being displayed in a GtkLabel and we only
   change the label when the adjustment's value changed. So, if you
   first set the adjustment and then connect to ::draw-value, we'd need
   to automatically invoke it once to set up the initial value string.
 - Generally lots of smaller things. I have a list locally, but lots of
   those depend on wip/carlosg/event-delivery getting merged first so
   I don't have to fix them twice.



Cheers,
Timm
_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: wip/baedert/drawing branch

Matthias Clasen-2
On Thu, May 18, 2017 at 11:52 AM, Timm Bäder <[hidden email]> wrote:
Hi,

I've collected a whole bunch of changes in th wip/baedert/drawing branch.
Here's a little overview of how things work in there, so we can decide
if it's the right way forward.

Hey Tim, thanks for writing this up.

Let me ask a few questions that are unclear to me, before we discuss the individual things:

- What are the overall goals here ? That would be good to know. My guess would be:
  1) Get rid of gadgets
  2) Full css drawing for all widgets
  anything else ?
 
  - gtk_widget_real_snapshot calls gtk_widget_snapshot_child on all the
   child widgets of the given GtkWidget instance. This makes sense to me
   but it's already been problematic when porting GtkScale and GtkRange
   away from gadgets because GtkRange didn't override ::snapshot so
   GtkScale couldn't just subclass it and chain up, since it would cause
   all child widgets to be drawn twice.

Iirc, we've had this kind of issue with containers in the past. You can't chain up without knowing
details about the parents implementation, and ordering becomes really tricky to get right.

Remaining problems/open questions:
 - Both GtkWindow and GtkPopover are special-cased in
   gtk_widget_snapshot to not draw the CSS background and border for
   them, since they are just too special. Getting rid of that special
   case would require porting them away from manual background drawing.
 - There are lots of CSS problems now of course, e.g. GtkRevealer does
   not hide its padding anymore so GtkSearchBar always leaves a few
   pixels of space around, or the 4px margin around GtkMenu which is not
   applied inside the toplevel instead of outside. Also GtkCheckButton
   obviously.

So this is a case where we deviate from gtk3 theming and introduce Adwaigtk-4.0
 
 - Focus outlines work out pretty badly the way they are currently done
   in the branch. Wit gadgets, widgets had pretty fine-grained control
   over which gadget draws the focus outline.

How _are_ they done now ?


_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: wip/baedert/drawing branch

Timm Bäder
On 18.05, Matthias Clasen wrote:

> On Thu, May 18, 2017 at 11:52 AM, Timm Bäder <[hidden email]> wrote:
> Hey Tim, thanks for writing this up.
>
> Let me ask a few questions that are unclear to me, before we discuss the
> individual things:
>
> - What are the overall goals here ? That would be good to know. My guess
> would be:
>   1) Get rid of gadgets
>   2) Full css drawing for all widgets
>   anything else ?

No, that's it basically.

> >  - Focus outlines work out pretty badly the way they are currently done
> >    in the branch. Wit gadgets, widgets had pretty fine-grained control
> >    over which gadget draws the focus outline.
> >
>
> How _are_ they done now ?

gtk_widget_snapshot just draws it around the widget if
gtk_widget_has_visible_focus returns TRUE for it:
https://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?h=wip/baedert/drawing#n15693

So e.g. dragging on a scale slider means the entire scale gets a focus
rectangle drawn, and entries get a focus rectangle drawn on top of their
normal focus indication (the blue border). Dunno if we can just set
can-focus to FALSE for appropriate (child) widgets and it works itself
out.
_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: wip/baedert/drawing branch

Matthias Clasen-2
On Thu, May 18, 2017 at 3:19 PM, Timm Bäder <[hidden email]> wrote:

> How _are_ they done now ?

gtk_widget_snapshot just draws it around the widget if
gtk_widget_has_visible_focus returns TRUE for it:
https://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?h=wip/baedert/drawing#n15693

So e.g. dragging on a scale slider means the entire scale gets a focus
rectangle drawn, and entries get a focus rectangle drawn on top of their
normal focus indication (the blue border). Dunno if we can just set
can-focus to FALSE for appropriate (child) widgets and it works itself
out.

I think that is not going to work.

What we need here is a way to decouple the actual focus location (ie where key events get sent)
from the focus indication (what to draw the focus rectangle around). With gadgets, this was
separated by having focus location always be the widget, while the rectangle could be drawing
around one of the gadgets inside.

_______________________________________________
gtk-devel-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-devel-list