Features/GTK3/Porting: Difference between revisions

Pro-panda (talk | contribs)
No edit summary
Tag: visualeditor-switched
Pro-panda (talk | contribs)
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.


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]]