Features/GTK3/Porting: Difference between revisions
No edit summary Tag: visualeditor-switched |
Merge useful content from https://wiki.sugarlabs.org/go/Features/GTK3/Porting/GetBooks Tag: visualeditor-switched |
||
| 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. | ||
Here are some instances of porting activities, for reference: | |||
* [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() | ||
===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=== | ||
( | (For more detailes, see http://developer.gnome.org/pangomm/2.28/annotated.html) | ||
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. | 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=== | ||
Some necessary changes include: | |||
Using | |||
get_property('window').get_xid() | |||
Instead of | Instead of | ||
window.xid | window.xid | ||
Using | |||
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) | ||
=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 | |||
* Pango documentation: http://developer.gnome.org/pangomm | |||
* Pango documentation | |||
* 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]] | ||