Features/GTK3/Shell

Daniel Drake started an effort to port the shell to the GTK3 sugar-toolkit. These are the biggest issues identified so far:

Open

Custom tree model for journal

Having trouble reimplementing this. See http://mail.gnome.org/archives/python-hackers-list/2011-December/msg00010.html

Gonzalo provided an initial patch, and Manuq worked over it: http://dev.laptop.org/~manuq/journal_gtk3.patch . Calling Gio.VolumeMonitor.get() crashes Sugar:

 1342801014.701506 DEBUG root: visibility_notify_event_cb <JournalActivity object at 0x3c5fc80 (jarabe+journal+journalactivity+JournalActivity at 0x3672900)>
 1342801014.703394 DEBUG root: visibility_notify_event_cb <JournalActivity object at 0x3c5fc80 (jarabe+journal+journalactivity+JournalActivity at 0x3672900)>
 1342801014.795809 DEBUG root: window_state_event_cb <JournalActivity object at 0x3c5fc80 (jarabe+journal+journalactivity+JournalActivity at 0x3672900)>
 1342801014.797290 DEBUG root: visibility_notify_event_cb <JournalActivity object at 0x3c5fc80 (jarabe+journal+journalactivity+JournalActivity at 0x3672900)>
 TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
 **
 ERROR:/home/manuq/prog/manuqs-shell-port/source/pygobject/gi/_gobject/pygobject.c:946:pygobject_new_full: assertion failed: (tp != NULL)

Custom Icon cell renderer

sugar3.graphics.icon.CellRendererIcon is based on pygtks GenericCellRenderer - needs to be ported

gconf_client_get_list not introspectable

The annotations mark it as non-introspectale.

opened an upstream bug: https://bugzilla.gnome.org/show_bug.cgi?id=681433

similar boxed types fix: https://bugzilla.gnome.org/show_bug.cgi?id=613247

The keyboard is not set up yet because of this as is being called in setup_keyboard_cb in sugar/bin/sugar-session .

gtk_clipboard_set_with_data not introspected

In the annotations it is marked as non-introspectable.

http://www.daa.com.au/pipermail/pygtk/2011-July/019940.html

- check with pygobject devs if the above statement is still the case

gdk_property_change

Is marked as non-introspectable in the annotations.

>>> from gi.repository import Gdk
>>> Gdk.property_change
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/erikos/sources/manuqs-shell-port/install/lib/python2.7/site-packages/gi/module.py", line 266, in __getattr__
    return getattr(self._introspection_module, name)
  File "/home/erikos/sources/manuqs-shell-port/install/lib/python2.7/site-packages/gi/module.py", line 115, in __getattr__
    self.__name__, name))
AttributeError: 'gi.repository.Gdk' object has no attribute 'property_change'

gdk_property_get

The gdk_property_get annotations mark it as introspectable.

Not working:

def _property_get_trapped(window, prop, prop_type):
    Gdk.error_trap_push()

    prop_atom = Gdk.Atom.intern(prop, False)
    type_atom = Gdk.Atom.intern(prop_type, False)

    logging.warning("get prop %s %s %s", window, prop_atom, type_atom)
    prop_info = Gdk.property_get(window, prop_atom, type_atom, 0, 9999, False)
TypeError: Could not caller allocate argument 6 of callable property_get

Port hardcoded styles to the CSS stylesheet

For example in sugar/extensions/cpsection/network/view.py we have things like:

        label_server = gtk.Label(_('Server:'))
        label_server.set_alignment(1, 0.5)
        label_server.modify_fg(gtk.STATE_NORMAL,
                               style.COLOR_SELECTION_GREY.get_gdk_color())

Palettes can't include menu and widgets at the same time

We can use anything like this:


class SugarMenuItem(gtk.EventBox):

    __gsignals__ = {
        'clicked': (gobject.SIGNAL_RUN_FIRST, None, [])
    }

    def __init__(self, icon_name, label_text):
        gtk.EventBox.__init__(self)
        self._sensitive = True
        vbox = gtk.VBox()
        hbox = gtk.HBox()
        vbox.set_border_width(style.DEFAULT_PADDING)
        self.icon = Icon()
        self.icon.props.icon_name = icon_name
        hbox.pack_start(self.icon, expand=False, fill=False,
                padding=style.DEFAULT_PADDING)
        align = gtk.Alignment(xalign=0.0, yalign=0.5, xscale=0.0, yscale=0.0)
        text = '<span foreground="%s">' % style.COLOR_WHITE.get_html() + \
                    label_text + '</span>'
        self.label = gtk.Label()
        self.label.set_use_markup(True)
        self.label.set_markup(text)
        align.add(self.label)
        hbox.pack_start(align, expand=True, fill=True,
                padding=style.DEFAULT_PADDING)
        vbox.pack_start(hbox, expand=False, fill=False,
                padding=style.DEFAULT_PADDING)
        self.add(vbox)
        self.id_bt_release_cb = self.connect('button-release-event',
                self.__button_release_cb)
        self.id_enter_notify_cb = self.connect('enter-notify-event',
                self.__enter_notify_cb)
        self.id_leave_notify_cb = self.connect('leave-notify-event',
                self.__leave_notify_cb)
        self.modify_bg(gtk.STATE_NORMAL, style.COLOR_BLACK.get_gdk_color())
        self.show_all()
        self.set_above_child(True)

    def __button_release_cb(self, widget, event):
        self.emit('clicked')

    def __enter_notify_cb(self, widget, event):
        self.modify_bg(gtk.STATE_NORMAL,
                style.COLOR_BUTTON_GREY.get_gdk_color())

    def __leave_notify_cb(self, widget, event):
        self.modify_bg(gtk.STATE_NORMAL, style.COLOR_BLACK.get_gdk_color())

    def set_icon(self, icon_name):
        self.icon.props.icon_name = icon_name

    def set_label(self, label_text):
        text = '<span foreground="%s">' % style.COLOR_WHITE.get_html() + \
                    label_text + '</span>'
        self.label.set_markup(text)

    def set_sensitive(self, sensitive):
        if self._sensitive == sensitive:
            return

        self._sensitive = sensitive
        if sensitive:
            self.handler_unblock(self.id_bt_release_cb)
            self.handler_unblock(self.id_enter_notify_cb)
            self.handler_unblock(self.id_leave_notify_cb)
        else:
            self.handler_block(self.id_bt_release_cb)
            self.handler_block(self.id_enter_notify_cb)
            self.handler_block(self.id_leave_notify_cb)
            self.modify_bg(gtk.STATE_NORMAL, style.COLOR_BLACK.get_gdk_color())

And add them to a vbox:


        # TODO: private!!!
        self._content.set_border_width(0)
 
        self._play_pause_button = SugarMenuItem('player_play',
                _('Say selected text'))
        self._play_pause_button.connect('clicked', self.__play_clicked_cb)
        vbox_menu.add(self._play_pause_button)

To do the SegurMenuItem take all the width in the palette, we need set the border_width in _content to zero, but that is a private member. Then we need to look if we add a method to set the it, or change the api to make the first container (where is the menu today) useful for other type of widgets.

A handful of NMClient issues

See http://mail.gnome.org/archives/python-hackers-list/2011-August/msg00003.html and the other posts in the thread. Some problems resolved, some probably still pending.


Done

Can't call gdk_window_set_user_data()

In the latest implementation we don't use set_user_data anymore AFAIK. http://mail.gnome.org/archives/python-hackers-list/2011-September/msg00006.html


do_forall not working in pygobject

Needs:

cant call gdkwindow.raise()

Needs:

can not listen to signals in subclassed subclasses

ActivityIcon.do_draw never called, see http://bugs.sugarlabs.org/ticket/3386

Needs:

set_data/get_data not available anymore

More background info in: https://bugzilla.gnome.org/show_bug.cgi?id=641944

Needs:

libxklavier

This is how Anaconda is using libxklavier in Python (found when coming across this bug, Colin enabled introspection for libxklavier).

You have to use Xkl.Engine.get_instance(display) instead of the constructor. Manuq made sure the API we use is there. This testcase was useful.