We need to adjust the passed for_size to fit into the content allocation
of the widget.
That also means that we can't call gtk_widget_measure(widget) inside
gtk_widget_measure(widget) since now the for_size will be adjusted
twice.
Instead of mentioning the old _get_preferred_xxx functions, mention
measure() and print the for_size value as well. The orientation is given
by printing either "width" for GTK_ORIENTATION_HORIZONTAL or "height"
for GTK_ORIENTATION_VERTICAL.
Add a new ::measure vfunc similar to GtkCssGadget's that widget
implementations have to override instead of the old get_preferred_width,
get_preferred_height, get_preferred_width_for_height,
get_preferred_height_for_width and
get_preferred_height_and_baseline_for_width.
The g_print documentation explicitly says not to do this, since
g_print is meant to be redirected by applications. Instead use
g_message for logging that can be triggered via GTK_DEBUG.
... and API to set and unset it.
It is set when gtk_widget_queue_resize() is called.
It is unset when gtk_widget_get_preferred_width/height() is called.
So far it is not used.
gtk_widget_preferred_size() is only useful if you want to quickly port a
widget from GTK2 sizing code to GTK3 but does not properly work with
height-for-width as used in GTK. So we don't want to encourage people to
use it. In particular we want people to convert to height-for-width
before adding baseline support to their widgets.
If a subclass (say a child of GtkButton) overrides the non-baseline
size request methods we need to call these, rather than the new
get_height_and_baseline_for_width method.
In order to handle this we make the default for this method to be
NULL, and instead check at runtime which method to call. If any
non-baseline vfunc has changed in a class but the baseline one
hasn't, then we can't use the baseline one.
This modifies the size machinery in order to allow baseline support.
We add a new widget vfunc get_preferred_height_and_baseline_for_width
which queries the normal height_for_width (or non-for-width if width
is -1) and additionally returns optional (-1 means "no baseline")
baselines for the minimal and natural heights.
We also add a new gtk_widget_size_allocate_with_baseline() which
baseline-aware containers can use to allocate children with a specific
baseline, either one inherited from the parent, or one introduced due
to requested baseline alignment in the container
itself. size_allocate_with_baseline() works just like a normal size
allocation, except the baseline gets recorded so that the child can
access it via gtk_widget_get_allocated_baseline() when it aligns
itself.
There are also adjust_baseline_request/allocation similar to the
allocation adjustment, and we extend the size request cache to also
store the baselines.
Some functions in gtkstyle.h were overlooked when we added the
GDK_DEPRECATED macros.
Also add IGNORE_DEPRECATIONS to the few remaining callers of those
functions.
This is a quickfix to keep things working.
It turns out GtkWindow assumes it can do sizing operations while not
being visible, or while in the process of show()ing/hide()ing itself.
And commit b495ce54 broke these operations.
Figuring this properly requires some more thinking and restructuring on
my part, so for now we relax the requirement of visiblility enough for
these things to start working again.
We can set for_size to -1 earlier than we did. Doing so makes sure we
only cache one value (as we should in the first place). In GTK 3.6, this
worked properly, but with Previously, this check was moved further up to
avoid interacting with size groups. But after recent refactorings, size
groups are handled way earlier anyway.
... instead of GtkSizeGroupMode. Orientation is what we're interested in
after all. When we need a GtkSizeGroupMode, we can do the translation
where we need it.
With size groups now doing hfw, doing the optimization for CONSTANT_SIZE
was done too early. Size groups need to know that it's a hfw request, so
the other widgets in the size group get the correct behavior.
We compute on-demand for size groups anyway, so we can (in theory, this
patch doesn't do that yet) get around costly cache blowing when
invalidating single widgets of a size group this way.
This ensures that widgets that aren't ported and rely on the style-set
signal being emitted work as well as before. They should not rely on
style-set being emitted however.
Note that this function is a no-op if the initial style has been set
already and is very cheap if it has not been set yet. It only becomes
relevant if the resulting style actually gets used.
https://bugzilla.gnome.org/show_bug.cgi?id=639584
This patch optimizes window resizes by assuming that if a widget
has the same height at a width of 50 as with a width of 150, the
height for width 100 will also be the same.
The patch also further optimizes the cache allocator, now there
are 2 pointer arrays of up to a maximum of 5 requests, the arrays
will only be allocated if a request is ever made in that orientation
and the array will be sparse until each request is made (i.e. if a
label can only wrap to 3 lines, there will only be 3 out of a
possible 5 SizeRequest structures allocated to cache it).
This patch makes contextual height-for-width request caching
optional (the contextual cache is not allocated for widgets that
report GTK_SIZE_REQUEST_CONSTANT_SIZE).
The constant size request mode defines a request mode where
height-for-width geometry is unneeded, thus optimizing GTK+
by reducing the overall amount of requests that need to be
performed and cached while resizing an interface.
Instead of checking if klass->get_request_mode is != NULL from
the gtk_widget_get_request_mode() api, this allows classes to
trust that there is a default implementation and chain up (specifically
added this for gtkmm wrapper objects).
Checks were in place to ensure that widgets never request taller
or wider than screen size. This was there to test a theory about
scrolled window children functioning correctly with dynamic content
however it breaks GtkViewport children which can generally return a
value taller than screen height intentionally, GtkViewport uses this
value to update the adjustments.
Size requests should only ever need to return the screen's width/height
and max. This way, potentially large widgets (tree view or icon view)
don't need to do so many computations, but can stop when their computed
size has reached the screen size.
This allows us to add a check before executing
->get_preferred_height_for_width() to ensure we always
request for at least the minimum required size (and lets
us remove the warning in gtkcontainer.c telling implementors
to do this check manually from thier container implementations).
I.e. Since we are now calling get_preferred_width() to ensure a good 'for_size'
for get_height_for_width() we need to avoid warning about this internal expected
recursion.
alignment/margin vfuncs adjust_size_request/allocation
Now get_height_for_width() will internally update the for_width
before passing it to the real height_for_width() vfunc, allowing
margins and extra space for alignments to be stripped, thus requesting
sufficient height for greater than natural widths (and also accounting
for margins properly). Test case adjusted in testadjustsize to ensure
proper behavior.
The gtkprivate.h header contains GtkWidget-specific private symbols that
are not useful except in a handful of cases. Basically everything
includes gtkprivate.h for the GTK_PARAM_* macros.
https://bugzilla.gnome.org/show_bug.cgi?id=632539
The geometry widget feature of gtk_window_set_geometry_hints() has
never really worked right because the calculation that GTK+ did to
compute the base size of the window only worked when the geometry
widget had a larger minimum size than anything else in the window.
Setup:
* Move the GtkSizeGroup private functions to a new private header
gtksizegroup-private.h
* Add the possibilty to pass flags to _gtk_size_group_queue_resize(),
with the flag GTK_QUEUE_RESIZE_INVALIDATE_ONLY to suppress adding
the widget's toplevel to the resize queue.
* _gtk_container_resize_invalidate() is added to implement that feature
* _gtk_widget_override_size_request()/_gtk_widget_restore_size_request()
allow temporarily forcing a large minimum size on the geometry
widget without creating resize loops.
GtkWindow:
* Compute the extra width/height around the geometry widget
correctly; print a warning if the computation fails.
* Always make the minimum size at least the natural minimum
size of the toplevel; GTK+ now fails badly with underallocation.
* Always set the base size hint; we were failing to set it
properly when the specified minimum size was overriden, but
it's harmless to always set it.
Tests:
* New test 'testgeometry' that replaces the 'gridded geometry' test
from testgtk. The new test is roughly similar but creates a bunch
of windows showing different possibilities.
* The testgtk test is removed. No need to have both.
https://bugzilla.gnome.org/show_bug.cgi?id=68668
It doesn't make sense to keep them separate as GtkSizeRequest requires a
GtkWidget and GtkWidget implements GtkSizeRequest, so you can never have
one without the other.
It also makes the code a lot easier because no casts are required when
calling functions.
Also, the names would translate to gtk_widget_get_width() and people
agreed that this would be a too generic name, so a "preferred" was added
to the names.
So this patch moves the functions:
gtk_size_request_get_request_mode() => gtk_widget_get_request_mode()
gtk_size_request_get_width() => gtk_widget_get_preferred_width()
gtk_size_request_get_height() => gtk_widget_get_preferred_height()
gtk_size_request_get_size() => gtk_widget_get_preferred_size()
gtk_size_request_get_width_for_height() =>
gtk_widget_get_preferred_width_for_height()
gtk_size_request_get_height_for_width() =>
gtk_widget_get_preferred_height_for_width()
... and moves the corresponding vfuncs to the GtkWidgetClass.
The patch also renames the implementations of the vfuncs in widgets to
include the word "preferrred".
This patch changes the 'age' counting previous approach taken
verbatim from clutter and changes it for a counter of validated
caches and an index to the last cached value which we use to
round-robin through the cache if ever a widget is requested
for more than 3 contextual sizes (cache is reduced by 3 * sizeof (int)
per widget private data).
Originally the GtkSizeRequestIface patches left GtkSizeGroup working
only by bumping the minimum sizes - this commit fixes size groups to take
both minimum and natural requests into account.
Use these new methods to handle set_size_request (aka aux_info)
inside gtkwidget.c, instead of having external code mess with it.
The virtual functions can be used for other purposes in the
future. For example, GtkContainer::border_width could be
automatically implemented for all container subclasses.
We are not re-entrant and there is no reason for widgets to
do this, most likely they'll just get unexpected bugs because
the wrappers may modify the request.
Computing the request should logically rely only on the
widget itself, not on any adjustments caused by set_size_request,
size groups, and so forth.
https://bugzilla.gnome.org/show_bug.cgi?id=628829
Now that we have a private data installed directly on
the GtkWidget instance it makes no sense to cache the size
requests on widget qdata. This change will generally make
GTK+ memory less fragmented as well as significantly speed
up the size request process.
Since we have a new mechanism for requesting sizes: GtkSizeRequestIface;
it makes no sense to maintain this cache on the GtkWidget structure...
removing the requisition cache however does not break the old "size-request"
signal which is there for backwards compatability reasons.
In any case widget->requisition should not have been accessed,
gtk_widget_get_child_requisition() would have been the correct way
to consult the cache.
This commit also deprecates the newly added gtk_widget_get_requisition()
API and makes it fallback on gtk_size_request_get_size().
This commit makes a few massive changes to the extended layout
code:
a.) gtkextendedlayout.c --> gtksizerequest.c
b.) _is_height_for_width --> get_request_mode()
c.) get_desired_size(), get_desired_width(), get_desired_height() -->
get_size(), get_width(), get_height()
This is the first partial commit and only effects portions
of the tree that have already been merged in master (in order to
easily cherry pick this commit).
Conflicts:
gtk/Makefile.am
gtk/gtk.h
gtk/gtk.symbols
gtk/gtkextendedlayout.h