GNOME Bugzilla – Bug 671170
GtkTable and GtkGrid alignment problem
Last modified: 2012-03-04 22:29:50 UTC
This problem exists in gtkmm Table and Grid widgets, due to a problem in the underlying gtk+ widgets. For a detailed discussion, please see the thread on the gtkmm reflector, starting with e-mail <4F4C0D06.4080101@gmail.com> dated 27 February, 2012 and entitled "Why does this behave the way it does?". The problem is that size calculations for cells are incorrect when widgets span multiple columns of the table/grid, and when the rightmost column of one widget is more than the leftmost column of another widget. (For example, when one widget spans columns 30..34 and another one spans columns 20..31.) As stated in e-mail <4F4DFBA2.5030709@bredband.net> authored by kjell.ahlstedt@bredband.net: > I looked in the source code of GtkTable, and I think the error is in > gtk_table_size_request_pass3(). It may be of interest that the same author suggested an admittedly ugly workaround in e-mail<4F4E7031.1080601@bredband.net>. The initial e-mail in the thread (<4F4C0D06.4080101@gmail.com>) includes this example code that demonstrates the problem. Here is the entire original e-mail that started the discussion that led to this being uncovered as a bug (I originally assumed that gtk+ was behaving correctly and I simply wasn't understanding something, but investigation by Kjell uncovered that the behaviour at issue is due to this bug): ---- I have been struggling to understand how tables work, and have created a simple program whose behaviour demonatrates my mystification. The program in its entirety, is below. There is one part of the program that may be compiled or left uncompiled depending on whether one writes #if 0 or #if 1 Call the first of these "variant 1" and the second "variant 2". My understanding of what this is supposed to do is as follows: 1. Create a non-resizable window that is 640x400 pixels in size 2. Create a table with 80 columns and 25 rows 3. Put the table into the window 4. Create and populate a couple of textviews with some short text. Variant 1 of the program displays one of the textviews. Variant 2 displays both textviews. What I don't understand: There is one textview that appears in both variants. Why does its width change in the two versions ... the width of the "1234*" textview is larger in variant 2 than in variant 1. Why? Similarly, the enclosing window is wider in variant 2 than in variant 1. Why? In both cases, the increase in width is not desired (nor expected -- obviously there's some part of the documentation that I've missed or misinterpreted); how do I stop it from occurring? Here is the program: ---- /* * gtk-test-1.cpp * */ #include <gtkmm.h> using namespace std; using namespace Gdk; using namespace Gtk; int main(int argc, char *argv[]) { const int N_ROWS = 25; const int N_COLS = 80; const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 400; Gtk::Main INIT(argc, argv); // needed to init gtkmm Gtk::Window window; // the initial window // the table into which we will place textviews Gtk::Table table(N_ROWS, N_COLS, true); // set the main window to the desired size and make it non-resizable window.set_size_request(SCREEN_WIDTH, SCREEN_HEIGHT); window.set_resizable(false); // we want no space in the table table.set_row_spacings(0); table.set_col_spacings(0); // add the table to the window window.add(table); window.show_all_children(); // create and populate two textviews Gtk::TextView * textview_p1 = new Gtk::TextView; Gtk::TextView * textview_p2 = new Gtk::TextView; Gtk::TextView& textview1 = *textview_p1; Gtk::TextView& textview2 = *textview_p2; Pango::FontDescription fdesc("Courier New, medium, 12"); textview1.override_font(fdesc); textview2.override_font(fdesc); // first textview -- width depends on whether second textview is present textview1.override_color(RGBA("White")); textview1.override_background_color(RGBA("Black")); textview1.set_editable(false); textview1.set_cursor_visible(false); textview1.get_buffer()->set_text("1234*"); table.show(); table.attach(textview1, 30, 35, 3, 4); // left, right+1, top, bottom+1 table.show_all_children(); // second textview // variant 1 does not compile the following code; variant 2 does compile it // the size of the window that contains the text "1234*" varies depending // on which variant we execute #if 0 textview2.override_color(RGBA("White")); textview2.override_background_color(RGBA("Black")); textview2.set_editable(false); textview2.set_cursor_visible(false); textview2.get_buffer()->set_text("5678*"); table.attach(textview2, 20, 32, 2, 3); // left, right+1, top, bottom+1 table.show(); table.show_all_children(); #endif // 0 INIT.run(window); // draw the window and its contents return EXIT_SUCCESS; } ----
If this is a GTK+ bug then it needs a GTK+ test case.
Created attachment 208956 [details] Test case, translated from gtkmm to gtk+ Here's a C test case with GtkGrid. Test it with different widths of text string #2. E.g. testgrid (default value: 12; 2 overlapping cols, the window is too wide) testgrid 10 (no overlapping columns, correct window width) testgrid 11 (1 overlapping column, the window is too wide) testgrid 15 (5 overlapping columns, correct window width) I don't understand the links in the bug description. They are no real links to web pages, but strange e-mail addresses. Here are some links to gtkmm-list, where this problem has been discussed. http://mail.gnome.org/archives/gtkmm-list/2012-February/msg00052.html http://mail.gnome.org/archives/gtkmm-list/2012-February/msg00059.html http://mail.gnome.org/archives/gtkmm-list/2012-February/msg00062.html
Thanks for the testcase !
Thanks for the testcase ! The following fix has been pushed: 47c190a grid: Work harder for tight homogeneous allocation
Created attachment 208965 [details] [review] grid: Work harder for tight homogeneous allocation When doing homogeneous allocation in the presence of overlapping spanning children, we need to avoid uneven line allocations, otherwise, the final homogenization will blow up the size request of the grid.