Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 859
fossfreedom Avatar asked Dec 30 '12 10:12

fossfreedom


2 Answers

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)
like image 78
fossfreedom Avatar answered Nov 20 '22 00:11

fossfreedom


Using what @qama said about 'on-resize-set-size-request hack', the behavior can be fixed (though in a really hackish way).

Just add a callback:

def keep_size(crt, *args):

    crt.handler_block(crt_notify)
    crt.set_property('width', 100)
    crt.handler_unblock(crt_notify)

And connect it to the CellRendererText:

crt, crp = covers_view.get_cells()
crt_notify = crt.connect('notify', keep_size)

If you add a print crt, args to the callback you can see that it goes there about 10-20 times... dealing both with properties width and wrap-width

like image 29
deinonychusaur Avatar answered Nov 20 '22 00:11

deinonychusaur