Search code examples
pythongtk3pygobject

What causes the different display behaviour for a GtkIconView between different GTK versions?


Pictures will explain the title:

Under LMDE & Ubuntu 12.04 my GtkIconView looks like this - its correct in terms of the spacing between the icons:

Spacing Ubuntu 12 04 RB 96

Under Ubuntu 12.10, 13.04 & Fedora 17 the same code displays as follows:

Spacing Ubuntu 12 10 RB 97

N.B. - This is a rhythmbox python plugin - source code is here on GitHub

I've checked the following GtkIconView attributes - they are exactly the same between Ubuntu 12.04 and in the incorrectly displayed 12.10 version.

  • item-padding
  • row-spacing
  • column-spacing
  • item-width

This display behaviour occurs immediately when I set either the text_column or the markup_column (the text under the icons) to be a visible column i.e. changing the value from -1 to the column number.

If the text column/markup column is hidden (i.e. a value of -1) then the display is correct on all distro's.

Since its the same code running on exactly the same music collection - I can only surmise that the newer GTK libraries in Fedora 17/Ubuntu 12.10/13.04 are behaving differently.

My google-fu has only found this reference which sounds identical. However examining the ubuntu-accomplishment-viewer source code hasnt really enlightened me.

Has anybody else encountered this? Any suggestions on the best way to investigate further?


Ok - I've tried to reduce this to the bare essentials - this simple glade file with this simple code produces this issue. However I'm still non-the-wiser what is causing this visual effect :/

#!/usr/bin/env python

from gi.repository import Gtk, GdkPixbuf

window = Gtk.Window()
window.connect('delete_event', Gtk.main_quit)

ui = Gtk.Builder()
ui.add_from_file('reproduce.ui')

page = ui.get_object('main_box')
window.add(page)

ls = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
icon = GdkPixbuf.Pixbuf.new_from_file_at_size(
    str("/usr/share/icons/gnome/48x48/actions/zoom-out.png"), 90, 90)

for i in range(15):
    ls.append(['Item %d' % i, icon])

covers_view = ui.get_object('covers_view')
covers_view.set_model(ls)
covers_view.set_text_column(0)
covers_view.set_pixbuf_column(1)
covers_view.set_item_width(100)

# These lines make it easier to see the problem
crt, crp = covers_view.get_cells()
crt.set_property('background', '#000')
crt.set_property('foreground', '#AAA')
print crt.get_request_mode()

window.set_default_size(600,400)
window.show_all()
Gtk.main()

and the glade - http://pastebin.com/uvQ9mWeg


From a suggestion by deinonychusaur I looked at gtkparasite

FYI - I used the ready made PPA from AnthonyWong for both Ubuntu 12.04 and 12.10.

The results for both versions were identical. Experimenting changing the IconView properties using the apps did not really resolve this.

The next suggestion from deinonychusaur looks very interesting and I can confirm - i.e.

The IconView CellRendererText is 2x the size of the IconView Pixbuf in Fedora 17/12.10/13.04 but 1x the size of the IconView Pixbuf in 12.04.


Solution

  • Reason for the observation.

    Upstream GTK developers decided to change the algorithm as to how to calculate the width of the TextRenderer cell of the IconView.

    Here we go with the same old guess, try the icon size and set double the size of the first icon found in the list, naive but works much of the time

    This change was committed after the older GTK version in Ubuntu 12.04 & LMDE. It found its way into the later GTK versions found in Ubuntu 12.10 & 13.04 & Fedora 17.

    bug or no bug

    Since this issue has been occuring for well over a year now since Ubuntu 12.04 was released, it seems this is not a bug but a design decision.

    Perhaps a little odd - on Bugzilla this was reported for another application (Pitivi video editor) but at the time of writing this is still at the unconfirmed state.

    workaround

    What was useful in that link was an attachment giving a workaround where you create a CellRendererText and assign this to the IconView BEFORE the markup/text column is defined.

    Below is my interpretation of the workaround

    cover_size=100
    markup_text="some text"
    
    self._text_renderer = Gtk.CellRendererText()
    self._text_renderer.props.alignment = Pango.Alignment.CENTER
    self._text_renderer.props.wrap_mode = Pango.WrapMode.WORD
    self._text_renderer.props.xalign = 0.5
    self._text_renderer.props.yalign = 0
    self._text_renderer.props.width = cover_size
    self._text_renderer.props.wrap_width = cover_size
    self._cover_view.pack_end(self._text_renderer, False)
    self._cover_view.add_attribute(self._text_renderer, 'markup', markup_text)