GNOME Bugzilla – Bug 681937
Dialog box is too skinny
Last modified: 2018-04-15 00:17:17 UTC
I was writing an email while not having a network connection, and this dialog came up when I hit Send. The dialog shouldn't be as skinny as possible; it should have some reasonable width.
Created attachment 221303 [details] Screenshot of skinny window
My guess is the dialog needs to use GtkGrid instead of GtkTable.
Unfortunately not, nothing I do on evolution side helps - this is something in gtk, thus I'm reassigning this. I can reproduce the same even if I add wrapped label directly into GtkDialog.
For the record, the dialog is actually using GtkBox's instead of GtkTable. But replacing them with a GtkGrid didn't help. I also tried removing this logic: http://git.gnome.org/browse/evolution/tree/libevolution-utils/e-alert-dialog.c#n256 But then the dialogs just came out square shaped with lots of empty vertical space. So yeah, I couldn't make it work either.
Created attachment 244347 [details] Test case of weird GtkDialog toplevel sizing The exact behavior seen in this dialog is a result of some code in Evolution that I really don't quite understand - the intent seems like it's trying to pick a size that will give a 5/4 ratio to the dialog. But removing that code (as Matthew tried earlier) results in some strange behavior that you can see in the test case I'm attaching here. Basically, unless you make a GtkDialog non-resizable it's not picking a reasonable miminum or default size. The fact that the non-resizable case is working better has to do with in gtkwindow.c:gtk_window_compute_hints(), the line: /* Please use a good size for unresizable widgets, not the minimum one. */ if (!priv->resizable) gtk_window_guess_default_size (window, &requisition.width, &requisition.height);
Exact explanation of the behavior. GtkWindow computes two sizes for the window: * The 'minimum size' - this is the size from gtk_widget_get_preferred_size(), which in this case ends up being a very narrow minimum width and the minimum height at that narrow width. (Calling gtk_label_set_width_chars() makes the very width taller.) * 'A good size' - from gtk_window_guess_default_size() - which in this case is roughly 640 pixels by the minimum height at 640 pixels. If the window is non-resizable, then the minimum size is just overridden by the good size. If the window is resizable, we set the minimum size as the minimum size and the 'good size' as a default size. This doesn't do anything reasonable, since what we get is a window that has a bunch of white space below that we can remove by resizing the window narrower *horizontally* into the narrow strip that is it's minimum size. There's clearly a pretty fundamental problem here in that we can't easily represent the height-for-width nature of GTK+ geometry management to the window manager, so we have to pick *something* as a minimum size. But I think it's pretty problematic that we're combining two different algorithms here - the result is not understandable. If we were just using the gtk_widget_get_preferred_size(), then things would likely be odd by default, it would be pretty obvious how to fix things (set a width), and you wouldn't end up with with incomprehensible blank space. If we were just using the size from gtk_window_guess_default_size(), then we'd end up with more reasonable sizes, but it would be hard to control the minimum width of a window.
Owen is absolutely correct. However, I think we could do much better out of the box by simply making GtkLabel smarter. There was this old rule of thumb that the width of a column of type should be, in picas, between 1 and 2 times the size in points of the type i.e. for a 12-point font, you'd use a column between 12 and 24 picas wide. I think this would make the desired minimum size for GtkLabel pretty obvious: unwrapped labels: ellipsized ? width_of("...") : width_of(label->text) wrapped labels: minimum_width = picas * font_size_in_points preferred_width = 1.5 * picas * font_size_in_points Setting the minimum width of wrapped labels to a *reasonable* minimum (i.e. 1 pica * font_size_in_points) sounds better, I think, than letting the label become as narrow as possible and horribly tall. (If the label has a user-set width, then that overrides everything.) (All of this wouldn't get rid of the extra vertical space given GtkWindow's limitations, as Owen explains them, but it would probably give us a more reasonable size...)
Hmm, or maybe my proposal would yield the same effect of Owen's test program when it has width-chars set, i.e. still prety bad. No idea.
*** Bug 700457 has been marked as a duplicate of this bug. ***
So there's this interesting question: What's the meaning of natural size? Currently, it's treated as "maximum size the widget could use" which is the label in one row. However, that essentially means "minimum width" is equal to "as high as possible" and "natural width" is equal to "as wide as possible" and what you want is "readable", which is what Federico outlined in comment 7 (the nicest rule I know is 60 characters per row, which would be easy to compute and use (ie if (max_width_chars < 0) max_width_chars = 60;) But that would only solve the problem for labels. What size should we request by default for GtkWindow? As wide as possible? As high as possible? Something else? And what size should we request as minimum size?
I think what would be reasonable is to take the default width, calculate the natural height for it, and perhaps take the max of that and the default height. If the default width/height is not specified, substitute some values derived by meditation/magic/screen size+aspect ratio. I don't know that resizable or not should make a difference for how we determine the initial size.
Created attachment 245335 [details] [review] an experiment Here is an experiment. It tries to improve the situation by changing how we find the minimal size. If a default size is given, we make a few attempts to find a minimal size that fits within the default size. You can play with this using the new testwindowsize test in git.
At this point just an aside, but I fixed the Evolution dialog mentioned in the original description. https://git.gnome.org/browse/evolution/commit/?id=5b2ee4af6fafecfff78f15662c94e62470a9a43d
Sorry if I'm missing something, but what is wrong in the allocation algorithm described below? 1) take the child of the toplevel window 2) find out its minimal size at the preferred aspect ratio. That is: 2a) if it does GTK_SIZE_REQUEST_CONSTANT_SIZE, consider declared minimum width and height 2b) if it does GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH, consider natural width and related minimum height 2c) if it does GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT, consider natural height and related minimum width 3) in particular, if it is a container, the size request will be determined recursively, always computing minimum dimensions by following the rule (for child/grandchild widgets which trade dimensions) "consider one natural dimension and the related minimum other one" 4) if the width/height obtained (plus window borders/decorations, obviously) fit into the screen, declare them to the window manager as minimum size for the window 5) if only one dimension overflows the screen, consider the dimension of the screen, consider the widget's related (minimum) other dimension, and declare the two to the window manager as minimum size for the window 6) if both dimensions overflow the screen, there is not much to do, and just declare them to the window manager as minimum size for the window Clearly, the initial size of the window will instead be computed based only on the _natural_ size requested by the child(ren). It is certainly suboptimal in the fact that a user will not be able i.e. to shrink horizontally a window containing a height-for-width child. But at least 1) they can be shrinked in the other dimension, 2) there will be no useless empty space under the child, 3) the natural size of the widget(s) directly determines the natural size of the window, 3a) for instance, the rule suggested by Federico in Comment 7 can be used to determine the natural width of a label. All this would be compatible with just using some "good size" if the window is non-resizable, as shown in Comment 6. (What am I missing?)
Review of attachment 245335 [details] [review]: this was just an experiment
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
As announced a while ago, we are migrating to gitlab, and bugs that haven't seen activity in the last year or so will be not be migrated, but closed out in bugzilla. If this bug is still relevant to you, you can open a new issue describing the symptoms and how to reproduce it with gtk 3.22.x or master in gitlab: https://gitlab.gnome.org/GNOME/gtk/issues/new