sizing policy
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list gnome org
- Cc: timj gtk org
- Subject: sizing policy
- Date: 26 Jun 2001 18:38:46 -0400
Hi,
Posting this (again), outstanding issues are at the end. Can we
please resolve these ASAP so I can implement it in the next couple
days?
Havoc
Goals of this API revision
===
The idea here is to have functions that do what people expect, and do
things people actually want to do. The current mish-mash of "usizes"
and "upositions" and so on is difficult to use and document, and
causes a lot of FAQs. Also, sometimes it's necessary to access
widget->window to get the effects people want, and most code doing
that is broken in some way.
As a side goal, we want to rationalize some of the "magic numbers"
present in the current API. The basic idea here is that only -1 (never
0) can be a magic number, and -1 always means "unset."
Proposed API overview
===
Widget sizing and positioning are left entirely to the GTK container
system. The only thing you can set explicitly is the size request of a
widget. This is done with gtk_widget_set_size_request() (which renames
gtk_widget_set_usize()).
For toplevel windows, you can set three sizes:
- the size request, which determines the default minimum size hint
for the window
- the current size, which is what changes as the user resizes
the window; setter is gtk_window_resize(), getter is
gtk_window_get_size().
- the default size, which is used when initially mapping the
window
Setting the current size before mapping a window overrides any default
size; the rationale is that a user resize also overrides the default
size, and emulating a user resize before mapping the window is
analagous.
Thus gtk_window_resize() can always be used to set window sizes. The
reason to set the default size is that it applies to the geometry
widget rather than the whole window, and that it can be set from a GUI
builder. The "current size" (from gtk_window_resize()) is not exposed
via properties or put in a GUI builder because resizing is an "action"
which isn't guaranteed to work.
gtk_window_move() is a similar action for positioning a window.
gtk_window_get_position() gets the current actual position.
Properties have "_set" variants, because "-1" magic values can't be
implemented consistently for all properties, and because they create a
bad UI in the GUI builder. However the magic -1 values still exist for
convenience if you know about them.
Proposed API in detail
===
gtk_widget_set_size_request ():
- Sets the size that a widget will request, overriding its usual
request. (Renaming of set_usize().)
Passing -1 for width/height unsets that value.
Passing 0 is equivalent to passing 1, because GTK always
allocates at least 1x1 despite a requisition of 0x0;
however we should allow 0 since it's an intuitive number
to pass here.
The magic -1 is only for the function, not the properties.
gtk_window_resize ():
- Resizes the window as if the user had done so, obeying geometry
constraints. Before mapping, overrides (but does not set) the
default size.
Sizes <= 0 g_return_if_fail().
gtk_window_set_default_size ():
- Sets the size of the window to be used on mapping; size will be
clamped to obey geometry constraints. If there's a geometry widget,
specified size is for the geometry widget. Same as default_width,
default_height. Has no effect if gtk_window_resize() has been
called, because gtk_window_resize() emulates a user resize and
thus overrules the default size.
Right now, passing 0 for default size args means to unset that arg,
and -1 means not to modify it. Propose changing this to: size of -1
unsets the size, size of 0 does g_return_if_fail().
This is 99% of the time backward compatible, because almost no one
is using "0" as an arg, and when using "-1" most people are
actually trying to say "do not set the size in that dimension,"
rather than "do not modify whether the size has been set."
The magic -1 is only for the function, not the properties.
gtk_window_get_default_size ():
- Gets the default size values, including -1 if they are unset.
gtk_window_move ():
- Moves the window as if the user had done so, obeying
constraints of e.g. GTK_WIN_POS_CENTER_ALWAYS.
Position is given as the position of the gravity-determined
reference point.
Position can be negative to move windows offscreen.
Position is in root window coordinates, but allowing
E's virtual root hack to work (we don't try to compensate
for how E will offset our configure request, i.e. we ignore
E)
If called before mapping, sets the uposition on the window.
gtk_window_get_size ():
- If mapped, gets actual current size of widget->window
Prior to mapping, tries to predict the window size (looks
at size request, window_resize() values, and geometry constraints)
gtk_window_get_position ():
- Gets the gravity-determined reference point location,
if unmapped, tries to predict window position (looks at
GTK_WIN_POS_*, gtk_window_move() values, falls back
to 0,0 or something)
Position is normally in root window coordinates. (We could offset
it to compensate for E's virtual root hack so that setting the
position from get_position() will give the expected result.)
gtk_window_parse_geometry ():
- Parses a geometry string and sets window position and default size.
GtkWidget::width_request, GtkWidget::height_request:
- Read-write properties, equivalent to set_size_request.
May not be < 0. i.e. the range of the properties is
the same as for gtk_window_set_size_request().
Auto-toggles-on the _set property when written.
GtkWidget::width_request_set, GtkWidget::height_request_set:
- Read-write properties, whether the size request value
is used or not.
GtkWindow::default_width, GtkWindow::default_height:
- still needed so you can set default size in a GUI builder.
equivalent to gtk_window_set_default_size().
These values are only used if default_width_set, default_height_set
are TRUE. The values are never allowed to be less than 1.
For backward compatibility, in the _set_property implementation, we
special-case -1 and 0 and toggle default_width_set,
default_height_set to FALSE instead of modifying the properties
themselves. However reading the property will never return
a value less than 1.
Auto-toggles-on the _set property when written.
GtkWindow::default_width_set, GtkWindow::default_height_set:
- whether default w/h are set
Deprecations:
- gtk_widget_set_uposition() - use gtk_window_move() or
gtk_fixed_move()/gtk_layout_move() instead
- gtk_widget_set_usize() - use widget_set_size_request()
or gtk_window_resize() or set_default_size()
- x/y/width/height properties on GtkWidget
- gtk_window_set_policy() - this is already deprecated in
CVS, we continue with that deprecation, it's replaced
by set_resizable() (allow_grow) and setting size request to 0
(allow_shrink)
- the set_policy() properties are deprecated along with
gtk_window_set_policy(), replaced by the size request properties
and a "resizable" property
General changes:
Size calculation (internal function gtk_window_move_resize()) is
done simply as:
- compute geometry hints.
- set initial size hint (before mapping window) to:
- gtk_window_resize() values if set
- otherwise default_width, default_height if set
- otherwise size request
In all cases, constraining to geometry hints.
- after the window is onscreen, clamp current size to geometry
hints, don't affect current size otherwise.
(Do we need to send a configure request or will the WM
handle the clamping?)
No "hysteresis" - current size has a fixed relationship to the
parameters that have been set and actions users have taken.
allow_shrink is equivalent to calling
gtk_widget_set_size_request (widget, 0, 0).
allow_grow is now the flag set by gtk_window_set_resizeable(). If
TRUE, max size is infinite by default. If FALSE, max size is equal
to the min size by default.
auto_shrink is now ignored. This is reasonably backward
compatible. If the legacy code using the new set_policy() didn't set
allow_grow, then auto_shrink would do nothing, since we now clamp
within min/max size in all cases. with allow_grow=false this means
the window is always shrunk already. if legacy code did set
allow_grow, then the behavior before just made no sense, but
probably they wanted a resizable window.
Geometry hints set with gtk_window_set_geometry_hints() simply
override anything calculated in any other way, e.g. if you set the
min size with geometry hints, it overrides the min size based on the
window's size request.
Notes
===
There's no way to get GtkWidget size/position because there is no
real reason to get those things unless you understand size_allocate
and widget->allocation
Instead of having set_position() not compensate for E and
get_position() compensate for E, we could have get_position() not
compensate for E but set_position() does compensate for E.
In this case, you would call set_position() with root window
coordinates, and internally we would translate those so that E
positions the window properly.
If we did things like this, we'd need a function
gdk_workspace_get_extents() which should be used for the screen
extents instead of (0,0) gdk_screen_width () x gdk_screen_height ()
My bias toward compensating for E in get_position() rather than
set_position() is that it's simpler and doesn't changing apps.
The argument for gdk_workspace_get_extents() would be that
it's a better abstraction than forcing the workspace to
always be (0,0) gdk_screen_width () x gdk_screen_height ()
Outstanding Issues that Impact the Core Proposal
===
A. Is there a "resizable" property or do we just leave it called
"allow_grow" with the function called gtk_window_set_resizable().
I think this is really obvious but Tim asked to have this issue
open. Tim what is the rationale for keeping allow_grow when
set_policy() is already deprecated (as discussed a long time ago
and already in CVS)?
B. Should we have _set properties, or just use magic -1 flags.
The argument for _set is:
- magic values can't be used in all situations
- the same magic value can't be used in all situations
- thus sometimes you need _set properties
- thus you MUST have a working solution where no magic value
is possible
- we should have a consistent solution throughout GTK
- magic values can't always be used, and are always
inconsistent anyway (may be -1, NULL, 0, etc., depending
on context)
- text widget crucially depends on _set properties anyway
- thus magic values are not a candidate for a consistent solution
- thus we should standardize on _set properties.
The argument against was:
- it's broken to auto-toggle-on the _set property when writing
the property
- if you don't auto-toggle-on, then it's inconvenient to write:
g_object_set (object, "foo", 10, "foo_set", TRUE, NULL)
My argument is that both solutions have problems, but auto-toggled
_set properties are optimal for application developers, and also
fairly easy for GUI builders to handle generically by simply
assuming a boolean property "foo_set" is conventionally a toggle
for another property "foo". If just using a convention is too
annoying, we could trivially add a flag to GParamSpec.
In any case, I consider the magic values a non-starter non-solution
because it does not address all the cases where you need the
concept of an "unset" property - it only happens to work by
accident for some properties that have a reasonable unused
magic value.
C. Does setting default size work post-mapping?
The argument is that if you edit the default size in a GUI builder
you might want to see results immediately.
I think this is just conceptually broken; changing the _default_
size doesn't change the _current_ size. So to me this makes
the API more confusing.
D. Does window_resize() modify geometry widget size or window size?
I've amended the proposal to have gtk_window_resize() affect the
window size.
This required re-adding gtk_window_set_default_size() and having
the default size affect the geometry widget, not the window.
This is needed to implement --geometry.
The idea is that most uses of gtk_window_resize() will either be by
people who don't understand geometry widgets anyway, or who are
trying to get exact pixel effects such as filling the whole screen.
E. Should we just remove all special handling of Enlightenment?
I don't really have any objection to this.
F. auto_shrink behavior
Tim said he had to think about this topic, I don't know what the
issue is.
Outstanding Issues that Add Extra API to Core Proposal
===
I believe we can just ignore these until we implement the proposal,
and add them later if people want them.
G. Whether to add a function to get_size_request().
I'm not sure who wanted this. What would this function do?
does it actually gtk_widget_size_request() the child, or does
it look at current widget->requisition?
One problem is that widgets must be associated with a screen before
being size requested, since they need font metrics etc. Which is
just one reason among many that apps calling get_size_request() for
a widget are probably doing something broken.
It would be useful to have example use-cases for when you would do this.
H. Whether to have readonly "x" and "y" properties for GtkWidget
These return widget->allocation.x and widget->allocation.y I
assume?
My question here is again what the use cases are. When do you want
this information? (aside from widget implementations that can just
look at widget->allocation)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]