Line 2: |
Line 2: |
| This is a guide to porting an existing activity from GTK2 to [http://developer.gnome.org/gtk3/stable/ GTK3]. It also shows the changes to use the new Sugar toolkit that also now uses [[Features/GTK3|GTK3]]. This guide uses the [https://github.com/sugarlabs/hello-world hello-world] activity as a simple example. | | This is a guide to porting an existing activity from GTK2 to [http://developer.gnome.org/gtk3/stable/ GTK3]. It also shows the changes to use the new Sugar toolkit that also now uses [[Features/GTK3|GTK3]]. This guide uses the [https://github.com/sugarlabs/hello-world hello-world] activity as a simple example. |
| | | |
− | There is another guide that uses this one as reference. It was made while porting GetBooks Activity [[Features/GTK3/Porting/GetBooks]]
| + | Here are some instances of porting activities, for reference: |
− | | |
− | If you would like to reference other examples of GTK3 port:
| |
| * [https://github.com/sugarlabs/biorhythm/commit/c16de3b70cce2cc6f8af933e2b062c844a47c144/ Biorhythm] | | * [https://github.com/sugarlabs/biorhythm/commit/c16de3b70cce2cc6f8af933e2b062c844a47c144/ Biorhythm] |
| * [https://github.com/sugarlabs/peru-learns-english-activity/commit/caa2cde526b3823a5a1f7d200a76ad5bc3502b0e Peru Learns English, includes GStreamer and GST update] | | * [https://github.com/sugarlabs/peru-learns-english-activity/commit/caa2cde526b3823a5a1f7d200a76ad5bc3502b0e Peru Learns English, includes GStreamer and GST update] |
| + | * [https://github.com/sugarlabs/jump/commit/b75410d2879d9829df942726f5465b7cf5a9d98d Port of Jump Activity] |
| + | * [https://github.com/sugarlabs/iknowMadagascar/commit/44ba42645ac4fcd9e06b4add7fa3b6ce2e0d9c3d Port of I-know-Madagascar] |
| + | |
| + | =Steps to Port an Activity to Gtk3= |
| + | #Read the [http://wiki.sugarlabs.org/go/Features/GTK3 Sugar Official Wiki] |
| + | #Resolve any existing pull requests before porting to avoid conflicts at a later stage. |
| + | #Run this [http://git.gnome.org/browse/pygobject/tree/pygi-convert.sh script] that will convert automatically things as much as it can. This is to avoid some stressful manually conversions that a "simple script" can do using ''sed'' :) |
| + | #Convert all the <code>from sugar.* import</code> to <code>from sugar</code>'''3'''<code>.* import</code> using [http://dev.laptop.org/~manuq/sugar-convert.sh this script] |
| + | #Follow the [[Development Team/Code guidelines|Code Guidelines]] during all the porting process |
| + | #Make the API changes in sugar-toolkit-gtk3 |
| + | #Write comments on the code, by adding '''# README:''', '''# TODO:''' and '''# FIXME:''' explaining what are the problems that you are having with that chunk of code. Put a link if it's necessary |
| + | Note: If you are considering to fix some ''pep8'' or ''pylint'' errors/warnings, please create two separate patch files (one for the port and one for the pylint/pep8 changes). If we follow this way it is easier to check the port patches, if not the information about the port itself it's difficult to follow |
| | | |
| ==Cleanup, adopt to API changes in sugar-toolkit-gtk3 == | | ==Cleanup, adopt to API changes in sugar-toolkit-gtk3 == |
Line 14: |
Line 24: |
| * remove import of deprecated ActivityToolbox (see [http://git.sugarlabs.org/hello-world/mainline/commit/22060a3063b2d6fd38d6b1cd8d44946170255af3 hello-world]) | | * remove import of deprecated ActivityToolbox (see [http://git.sugarlabs.org/hello-world/mainline/commit/22060a3063b2d6fd38d6b1cd8d44946170255af3 hello-world]) |
| * support for 'service_name' and 'class' has been removed from the activity.info make sure you are using: 'bundle_id' instead of 'service_name' and 'exec' instead of 'class' (see in [http://git.sugarlabs.org/record/mainline/commit/6e8968c71e474e2d8d86886badf5cf7d70217dc5 Record]) | | * support for 'service_name' and 'class' has been removed from the activity.info make sure you are using: 'bundle_id' instead of 'service_name' and 'exec' instead of 'class' (see in [http://git.sugarlabs.org/record/mainline/commit/6e8968c71e474e2d8d86886badf5cf7d70217dc5 Record]) |
| + | * <code>sugar3.activity.Activity</code> doesn't have the ''window'' attribute. Use the <code>.get_window()</code> method instead. |
| | | |
| ==Port the activity from GTK2 to GTK3== | | ==Port the activity from GTK2 to GTK3== |
Line 193: |
Line 204: |
| The Gtk.Menu.popup function now works slightly differently. | | The Gtk.Menu.popup function now works slightly differently. |
| The user supplied positioning function now takes different parameters. These are menu, x, y, push_in and user_data. | | The user supplied positioning function now takes different parameters. These are menu, x, y, push_in and user_data. |
− |
| |
− |
| |
| === Gdk === | | === Gdk === |
| Previously, gdk was an attribute of the gtk module, which means that it can be called through gtk. For example, if we want to use color_parse(): | | Previously, gdk was an attribute of the gtk module, which means that it can be called through gtk. For example, if we want to use color_parse(): |
Line 233: |
Line 242: |
| gtk.JUSTIFY_CENTER became Gtk.Justification.CENTER | | gtk.JUSTIFY_CENTER became Gtk.Justification.CENTER |
| gtk.RELIEF_NONE became Gtk.ReliefStyle.NONE | | gtk.RELIEF_NONE became Gtk.ReliefStyle.NONE |
− |
| |
| | | |
| === Pixbufs === | | === Pixbufs === |
Line 242: |
Line 250: |
| | | |
| GdkPixbuf.Pixbuf.new_from_file() | | GdkPixbuf.Pixbuf.new_from_file() |
− |
| |
− | ==Releasing activities (for maintainers)==
| |
− | Once an activity is ported, a new release can be made. The major version should be greater than the existing one.
| |
− |
| |
− | Please follow [https://github.com/sugarlabs/sugar-docs/blob/master/src/contributing.md#checklist---maintainer this] guide for releasing a new version
| |
− |
| |
− | ==Port to Python 3==
| |
− | We are migrating towards Python 3. Python 3 does not support GTK+ 2. Hence, once the activity is ported to GTK+ 3, please also continue porting the activity from Python 2 to Python 3.
| |
− |
| |
− | Ref: [https://github.com/sugarlabs/sugar-docs/blob/master/src/python-porting-guide.md Guide to port activities to Python 3]
| |
− |
| |
− | == Tips to Activity Developers ==
| |
| | | |
| ===Changes to the Clipboard=== | | ===Changes to the Clipboard=== |
Line 391: |
Line 387: |
| ===Going from Cairo in GTK-2 to Cairo in GTK-3=== | | ===Going from Cairo in GTK-2 to Cairo in GTK-3=== |
| | | |
− | (See http://developer.gnome.org/pangomm/2.28/annotated.html for more details) | + | (For more detailes, see http://developer.gnome.org/pangomm/2.28/annotated.html) |
− | Not much changes, but...
| |
| | | |
| The Cairo/Pango interaction is a little different: | | The Cairo/Pango interaction is a little different: |
Line 414: |
Line 409: |
| | | |
| ==== Replacing pixmaps with Cairo ==== | | ==== Replacing pixmaps with Cairo ==== |
− | You need to replace your pixmaps with Cairo in GTK3. See http://developer.gnome.org/gtk3/3.5/ch24s02.html#idp129615008 for example code. | + | You need to replace your pixmaps with Cairo in GTK3. For an example on how this is done, see: http://developer.gnome.org/gtk3/3.5/ch24s02.html#idp129615008 |
| | | |
| ===Taking a screenshot and making a thumbnail=== | | ===Taking a screenshot and making a thumbnail=== |
Line 436: |
Line 431: |
| ===Creating a video widget=== | | ===Creating a video widget=== |
| | | |
− | Haven't gotten this working yet, but some necessary changes include:
| + | Some necessary changes include: |
| + | |
| + | Using |
| + | get_property('window').get_xid() |
| | | |
| Instead of | | Instead of |
| window.xid | | window.xid |
− | use
| + | Using |
− | get_property('window').get_xid() | + | set_double_buffered(False) |
− | | + | set_app_paintable(True) |
| Instead of | | Instead of |
| unset_flags(gtk.DOUBLE_BUFFERED) | | unset_flags(gtk.DOUBLE_BUFFERED) |
| set_flags(gtk.APP_PAINTABLE) | | set_flags(gtk.APP_PAINTABLE) |
− | use
| |
− | set_double_buffered(False)
| |
− | set_app_paintable(True)
| |
| | | |
− | A more basic question is whether or not we migrate to gstreamer-1.0. If we do, some helpful documentation is found here [https://wiki.ubuntu.com/Novacut/GStreamer1.0].
| + | =Hacks to help in porting= |
| + | |
| + | === Use the same keyboard and mouse === |
| + | If you have an XO, I'm sure you want to take a look at [[User:Humitos/x2x|this]]... |
| + | ===Use Extended Python debugger=== |
| + | '''epdb''' library is useful to inspect the code while the Activity is running. |
| + | sudo yum install python-epdb |
| + | After that I put some trace point in the code where I can stop and make my tests by doing this: |
| + | import epdb;epdb.set_trace() |
| + | Finally I run Get Books Activity from the Terminal Activity to be able to write some code on a shell. This is the command that I use: |
| + | sugar-launch org.laptop.sugar.GetBooksActivity |
| + | See also [[Development Team/Debugging]]. |
| + | ===Check logs with ''multitail''=== |
| + | Here is a really useful command to open new logs automatically: [[User:Humitos/MultiTail]] |
| + | ===Use the pygobject code as example=== |
| + | [https://live.gnome.org/PyGObject pygobject] is what we use to make Gtk3 activities. So, it's really useful to take a look at the code examples that are there. Even more, you can run some demo application that show how to use something specific about the library. |
| + | *Clone the code: |
| + | git clone git://git.gnome.org/pygobject |
| + | *Run an example |
| + | cd pygobject |
| + | cd demos/gtk-demo/demos |
| + | python pixbuf.py |
| + | *Grep the code to search for something useful |
| + | cd pygobject |
| + | git grep GdkPixbuf |
| + | ===Monitoring DBus=== |
| + | Not sure how this command works, but it can give us an interesting information. If you run this command and plug an USB drive you will see useful information |
| + | dbus-monitor --system |
| + | |
| + | =Port to Python 3= |
| + | We are migrating towards Python 3. Python 3 does not support GTK+ 2. Hence, once the activity is ported to GTK+ 3, please consider porting the activity from Python 2 to Python 3. |
| + | |
| + | Ref: [https://github.com/sugarlabs/sugar-docs/blob/master/src/python-porting-guide.md Guide to port activities to Python 3] |
| + | |
| + | =Releasing activities (for maintainers)= |
| + | Once an activity is ported, a new release can be made. The major version should be greater than the existing one. |
| + | |
| + | Please follow [https://github.com/sugarlabs/sugar-docs/blob/master/src/contributing.md#checklist---maintainer this] guide for releasing a new version |
| + | |
| + | =Notes= |
| + | These are the changes implemented by developers while porting activities |
| + | *<code>Gtk.Widget.hide_all()</code> does not exist anymore. We should use just <code>.hide</code> |
| + | **Ref: http://developer.gnome.org/gtk3/3.5/GtkWidget.html#gtk-widget-hide |
| | | |
− | == Resources == | + | *If the code creates some own object, and it defines some properties, you should use '''__gproperties__''' dictionary: http://python-gtk-3-tutorial.readthedocs.org/en/latest/objects.html#GObject.GObject.__gproperties__ |
− | PyGI Documentation: https://lazka.github.io/pgi-docs/ | + | *<code>Gtk.ListStore</code> doesn't have the method '''.reorder'''. There is a [https://bugzilla.gnome.org/show_bug.cgi?id=677941 ticket] reported upstream about this. |
| + | *I replaced the use of <code>dbus</code> by [http://developer.gnome.org/gio/unstable/pt02.html Gio] to monitor the (dis)connection of pen drives |
| + | *Migrate custom signals: |
| + | **If you have defined custom gtk objects with custom signal you should migrate them to [http://python-gtk-3-tutorial.readthedocs.org/en/latest/objects.html the new way] to do this. You should replace this: from gobject import signal_new, TYPE_INT, TYPE_STRING, TYPE_BOOLEAN, \ TYPE_PYOBJECT, TYPE_NONE, SIGNAL_RUN_LAST signal_new('extlistview-modified', gtk.TreeView, SIGNAL_RUN_LAST, TYPE_NONE, ()) by adding the signal definition inside the object that you are creating using the <code>__gsignals__</code> dictionary like this (in this case Gtk.TreeView is the class that our object inherits): from gi.repository import GObject class ExtListView(Gtk.TreeView): __gsignals__ = { 'extlistview-modified': (GObject.SignalFlags.RUN_LAST, None, ()), } The last argument of the signal definition are the argument types that the callback will receive. |
| + | * Change the mouse cursor |
| + | ** Example use case: When the activity is working and we want to show a ''work in progress'' cursor. |
| + | ** Replace this: |
| + | self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) |
| + | with: |
| + | from gi.repository import Gdk |
| + | self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.WATCH)) |
| + | =Resources= |
| + | *PyGI Documentation: https://lazka.github.io/pgi-docs/ |
| + | *PyGtk documentation |
| + | **Gtk3: [http://python-gtk-3-tutorial.readthedocs.org/ http://python-gtk-3-tutorial.readthedocs.org] |
| + | **gtk2: http://www.pygtk.org/docs/pygtk/ |
| + | *Reference Manual |
| + | **Gtk3: http://developer.gnome.org/gtk3/3.4/ |
| + | *Gdk documentation: |
| + | **Gdk3: http://developer.gnome.org/gdk/2.24/ |
| + | *OLPC Documentation: http://wiki.laptop.org/go/Activities/PortingToGtk3 |
| + | *Used to know the arguments of <code>GdkPixbuf.Pixbuf.save_to_bufferv</code> https://mail.gnome.org/archives/javascript-list/2011-March/msg00001.html |
| | | |
− | gtk2: http://www.pygtk.org/docs/pygtk/
| + | * Pango documentation: http://developer.gnome.org/pangomm |
− | * Reference Manual
| |
− | :: Gtk3: http://developer.gnome.org/gtk3/3.4/
| |
− | * Gdk documentation:
| |
− | :: Gdk3: http://developer.gnome.org/gdk/2.24/
| |
− | * Pango documentation: | |
− | :: GTK3: http://developer.gnome.org/pangomm
| |
− | * Gst-1.0 documentation
| |
− | :: Gst-1: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/index.html
| |
− | * Gst-1.0 porting hints
| |
− | :: https://wiki.ubuntu.com/Novacut/GStreamer1.0
| |
| | | |
| + | * Gst-1.0 documentation: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/index.html |
| | | |
| + | * Gst-1.0 porting hints: https://wiki.ubuntu.com/Novacut/GStreamer1.0 |
| [[Category:Developer]] | | [[Category:Developer]] |
| | | |