<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.sugarlabs.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Humitos</id>
	<title>Sugar Labs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.sugarlabs.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Humitos"/>
	<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/go/Special:Contributions/Humitos"/>
	<updated>2026-05-13T21:31:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83995</id>
		<title>User:Humitos/YumRepository</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83995"/>
		<updated>2012-11-12T18:24:07Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Create our own yum repository =&lt;br /&gt;
&lt;br /&gt;
This will allow us to download just once the package needed to develop on our XO platform.&lt;br /&gt;
&lt;br /&gt;
= Steps on the server =&lt;br /&gt;
&lt;br /&gt;
 sudo yum install nginx createrepo&lt;br /&gt;
 mkdir -P /srv/repo/i686 /srv/repo/armv7hl /srv/repo/noarch&lt;br /&gt;
 ln -s /srv/repo /usr/share/nginx/html&lt;br /&gt;
 sudo service nginx start&lt;br /&gt;
&lt;br /&gt;
= Download packages for all the architectures we want =&lt;br /&gt;
&lt;br /&gt;
I did this by going to each XO (1.5 -i686- and 1.75 -ARM- in my case) and running:&lt;br /&gt;
&lt;br /&gt;
 sudo yum install --assumeyes --nogpg yum-utils&lt;br /&gt;
&lt;br /&gt;
Download all the packages that you consider necessary here:&lt;br /&gt;
&lt;br /&gt;
 ## Common utils that I use&lt;br /&gt;
 sudo yumdownloader --resolve vim git htop emacs-nox multitail screen&lt;br /&gt;
&lt;br /&gt;
 ## Those used to compile sugar / artwork / toolkit&lt;br /&gt;
 sudo yumdownloader --resolve git make alsa-lib-devel gettext-devel \&lt;br /&gt;
    gobject-introspection-devel gtk3-devel intltool libSM-devel \&lt;br /&gt;
    librsvg2-devel pygobject2-devel pygtk2-codegen python-devel \&lt;br /&gt;
    gtk2-devel icon-naming-utils icon-slicer python-empy \&lt;br /&gt;
    xorg-x11-apps gnome-common GConf2-devel gtksourceview3-devel \&lt;br /&gt;
    cairo-gobject&lt;br /&gt;
&lt;br /&gt;
Copy all of the packages downloaded to the server:&lt;br /&gt;
&lt;br /&gt;
 scp *noarch* humitos@192.168.1.101:/srv/repo/noarch&lt;br /&gt;
 scp *armv7hl* humitos@192.168.1.101:/srv/repo/armv7hl&lt;br /&gt;
 scp *i686* humitos@192.168.1.101:/srv/repo/i686&lt;br /&gt;
&lt;br /&gt;
= Create a yum configuration file =&lt;br /&gt;
&lt;br /&gt;
Copy this into a file called: &#039;&#039;/etc/yum.repos.d/local.repo&#039;&#039; (in the XOs)&lt;br /&gt;
&lt;br /&gt;
 [SugarRepo]&lt;br /&gt;
 name=Sugar Repository&lt;br /&gt;
 baseurl=http://192.168.1.101/repo&lt;br /&gt;
 gpgcheck=0&lt;br /&gt;
&lt;br /&gt;
= Last step on the server =&lt;br /&gt;
&lt;br /&gt;
 createrepo /srv/repo&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://ramblings.narrabilis.com/creating-a-yum-repository-repo-and-creating-a-yum-group-to-install-kickstart&lt;br /&gt;
&lt;br /&gt;
Scripts&lt;br /&gt;
&lt;br /&gt;
* http://git.sugarlabs.org/humitos/olpc/blobs/master/scripts/yum/install_local_repo.sh&lt;br /&gt;
* http://git.sugarlabs.org/humitos/olpc/blobs/master/scripts/yum/update_local_repo.sh&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83994</id>
		<title>User:Humitos/YumRepository</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83994"/>
		<updated>2012-11-12T18:23:24Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Download packages for all the architectures we want */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Create our own yum repository =&lt;br /&gt;
&lt;br /&gt;
This will allow us to download just once the package needed to develop on our XO platform.&lt;br /&gt;
&lt;br /&gt;
= Steps on the server =&lt;br /&gt;
&lt;br /&gt;
 sudo yum install nginx createrepo&lt;br /&gt;
 mkdir -P /srv/repo/i686 /srv/repo/armv7hl /srv/repo/noarch&lt;br /&gt;
 ln -s /srv/repo /usr/share/nginx/html&lt;br /&gt;
 sudo service nginx start&lt;br /&gt;
&lt;br /&gt;
= Download packages for all the architectures we want =&lt;br /&gt;
&lt;br /&gt;
I did this by going to each XO (1.5 -i686- and 1.75 -ARM- in my case) and running:&lt;br /&gt;
&lt;br /&gt;
 sudo yum install --assumeyes --nogpg yum-utils&lt;br /&gt;
&lt;br /&gt;
Download all the packages that you consider necessary here:&lt;br /&gt;
&lt;br /&gt;
 ## Common utils that I use&lt;br /&gt;
 sudo yumdownloader --resolve vim git htop emacs-nox multitail screen&lt;br /&gt;
&lt;br /&gt;
 ## Those used to compile sugar / artwork / toolkit&lt;br /&gt;
 sudo yumdownloader --resolve git make alsa-lib-devel gettext-devel \&lt;br /&gt;
    gobject-introspection-devel gtk3-devel intltool libSM-devel \&lt;br /&gt;
    librsvg2-devel pygobject2-devel pygtk2-codegen python-devel \&lt;br /&gt;
    gtk2-devel icon-naming-utils icon-slicer python-empy \&lt;br /&gt;
    xorg-x11-apps gnome-common GConf2-devel gtksourceview3-devel \&lt;br /&gt;
    cairo-gobject&lt;br /&gt;
&lt;br /&gt;
Copy all of the packages downloaded to the server:&lt;br /&gt;
&lt;br /&gt;
 scp *noarch* humitos@192.168.1.101:/srv/repo/noarch&lt;br /&gt;
 scp *armv7hl* humitos@192.168.1.101:/srv/repo/armv7hl&lt;br /&gt;
 scp *i686* humitos@192.168.1.101:/srv/repo/i686&lt;br /&gt;
&lt;br /&gt;
= Create a yum configuration file =&lt;br /&gt;
&lt;br /&gt;
Copy this into a file called: &#039;&#039;/etc/yum.repos.d/local.repo&#039;&#039; (in the XOs)&lt;br /&gt;
&lt;br /&gt;
 [SugarRepo]&lt;br /&gt;
 name=Sugar Repository&lt;br /&gt;
 baseurl=http://192.168.1.101/repo&lt;br /&gt;
 gpgcheck=0&lt;br /&gt;
&lt;br /&gt;
= Last step on the server =&lt;br /&gt;
&lt;br /&gt;
 createrepo /srv/repo&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://ramblings.narrabilis.com/creating-a-yum-repository-repo-and-creating-a-yum-group-to-install-kickstart&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83993</id>
		<title>User:Humitos/YumRepository</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83993"/>
		<updated>2012-11-12T18:09:54Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Create our own yum repository =&lt;br /&gt;
&lt;br /&gt;
This will allow us to download just once the package needed to develop on our XO platform.&lt;br /&gt;
&lt;br /&gt;
= Steps on the server =&lt;br /&gt;
&lt;br /&gt;
 sudo yum install nginx createrepo&lt;br /&gt;
 mkdir -P /srv/repo/i686 /srv/repo/armv7hl /srv/repo/noarch&lt;br /&gt;
 ln -s /srv/repo /usr/share/nginx/html&lt;br /&gt;
 sudo service nginx start&lt;br /&gt;
&lt;br /&gt;
= Download packages for all the architectures we want =&lt;br /&gt;
&lt;br /&gt;
I did this by going to each XO (1.5 -i686- and 1.75 -ARM- in my case) and running:&lt;br /&gt;
&lt;br /&gt;
 sudo yum install --assumeyes --nogpg yumdownloader&lt;br /&gt;
&lt;br /&gt;
Download all the packages that you consider necessary here:&lt;br /&gt;
&lt;br /&gt;
 ## Common utils that I use&lt;br /&gt;
 sudo yumdownloader --resolve vim git htop emacs-nox multitail screen&lt;br /&gt;
&lt;br /&gt;
 ## Those used to compile sugar / artwork / toolkit&lt;br /&gt;
 sudo yumdownloader --resolve git make alsa-lib-devel gettext-devel \&lt;br /&gt;
    gobject-introspection-devel gtk3-devel intltool libSM-devel \&lt;br /&gt;
    librsvg2-devel pygobject2-devel pygtk2-codegen python-devel \&lt;br /&gt;
    gtk2-devel icon-naming-utils icon-slicer python-empy \&lt;br /&gt;
    xorg-x11-apps gnome-common GConf2-devel gtksourceview3-devel \&lt;br /&gt;
    cairo-gobject&lt;br /&gt;
&lt;br /&gt;
Copy all of the packages downloaded to the server:&lt;br /&gt;
&lt;br /&gt;
 scp *noarch* humitos@192.168.1.101:/srv/repo/noarch&lt;br /&gt;
 scp *armv7hl* humitos@192.168.1.101:/srv/repo/armv7hl&lt;br /&gt;
 scp *i686* humitos@192.168.1.101:/srv/repo/i686&lt;br /&gt;
&lt;br /&gt;
= Create a yum configuration file =&lt;br /&gt;
&lt;br /&gt;
Copy this into a file called: &#039;&#039;/etc/yum.repos.d/local.repo&#039;&#039; (in the XOs)&lt;br /&gt;
&lt;br /&gt;
 [SugarRepo]&lt;br /&gt;
 name=Sugar Repository&lt;br /&gt;
 baseurl=http://192.168.1.101/repo&lt;br /&gt;
 gpgcheck=0&lt;br /&gt;
&lt;br /&gt;
= Last step on the server =&lt;br /&gt;
&lt;br /&gt;
 createrepo /srv/repo&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
* http://ramblings.narrabilis.com/creating-a-yum-repository-repo-and-creating-a-yum-group-to-install-kickstart&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83992</id>
		<title>User:Humitos/YumRepository</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83992"/>
		<updated>2012-11-12T18:09:43Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Create a yum configuration file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Create our own yum repository =&lt;br /&gt;
&lt;br /&gt;
This will allow us to download just once the package needed to develop on our XO platform.&lt;br /&gt;
&lt;br /&gt;
= Steps on the server =&lt;br /&gt;
&lt;br /&gt;
 sudo yum install nginx createrepo&lt;br /&gt;
 mkdir -P /srv/repo/i686 /srv/repo/armv7hl /srv/repo/noarch&lt;br /&gt;
 ln -s /srv/repo /usr/share/nginx/html&lt;br /&gt;
 sudo service nginx start&lt;br /&gt;
&lt;br /&gt;
= Download packages for all the architectures we want =&lt;br /&gt;
&lt;br /&gt;
I did this by going to each XO (1.5 -i686- and 1.75 -ARM- in my case) and running:&lt;br /&gt;
&lt;br /&gt;
 sudo yum install --assumeyes --nogpg yumdownloader&lt;br /&gt;
&lt;br /&gt;
Download all the packages that you consider necessary here:&lt;br /&gt;
&lt;br /&gt;
 ## Common utils that I use&lt;br /&gt;
 sudo yumdownloader --resolve vim git htop emacs-nox multitail screen&lt;br /&gt;
&lt;br /&gt;
 ## Those used to compile sugar / artwork / toolkit&lt;br /&gt;
 sudo yumdownloader --resolve git make alsa-lib-devel gettext-devel \&lt;br /&gt;
    gobject-introspection-devel gtk3-devel intltool libSM-devel \&lt;br /&gt;
    librsvg2-devel pygobject2-devel pygtk2-codegen python-devel \&lt;br /&gt;
    gtk2-devel icon-naming-utils icon-slicer python-empy \&lt;br /&gt;
    xorg-x11-apps gnome-common GConf2-devel gtksourceview3-devel \&lt;br /&gt;
    cairo-gobject&lt;br /&gt;
&lt;br /&gt;
Copy all of the packages downloaded to the server:&lt;br /&gt;
&lt;br /&gt;
 scp *noarch* humitos@192.168.1.101:/srv/repo/noarch&lt;br /&gt;
 scp *armv7hl* humitos@192.168.1.101:/srv/repo/armv7hl&lt;br /&gt;
 scp *i686* humitos@192.168.1.101:/srv/repo/i686&lt;br /&gt;
&lt;br /&gt;
= Create a yum configuration file =&lt;br /&gt;
&lt;br /&gt;
Copy this into a file called: &#039;&#039;/etc/yum.repos.d/local.repo&#039;&#039; (in the XOs)&lt;br /&gt;
&lt;br /&gt;
 [SugarRepo]&lt;br /&gt;
 name=Sugar Repository&lt;br /&gt;
 baseurl=http://192.168.1.101/repo&lt;br /&gt;
 gpgcheck=0&lt;br /&gt;
&lt;br /&gt;
= Last step on the server =&lt;br /&gt;
&lt;br /&gt;
 createrepo /srv/repo&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
 * http://ramblings.narrabilis.com/creating-a-yum-repository-repo-and-creating-a-yum-group-to-install-kickstart&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83991</id>
		<title>User:Humitos/YumRepository</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/YumRepository&amp;diff=83991"/>
		<updated>2012-11-12T18:08:42Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;= Create our own yum repository =  This will allow us to download just once the package needed to develop on our XO platform.  = Steps on the server =   sudo yum install nginx...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Create our own yum repository =&lt;br /&gt;
&lt;br /&gt;
This will allow us to download just once the package needed to develop on our XO platform.&lt;br /&gt;
&lt;br /&gt;
= Steps on the server =&lt;br /&gt;
&lt;br /&gt;
 sudo yum install nginx createrepo&lt;br /&gt;
 mkdir -P /srv/repo/i686 /srv/repo/armv7hl /srv/repo/noarch&lt;br /&gt;
 ln -s /srv/repo /usr/share/nginx/html&lt;br /&gt;
 sudo service nginx start&lt;br /&gt;
&lt;br /&gt;
= Download packages for all the architectures we want =&lt;br /&gt;
&lt;br /&gt;
I did this by going to each XO (1.5 -i686- and 1.75 -ARM- in my case) and running:&lt;br /&gt;
&lt;br /&gt;
 sudo yum install --assumeyes --nogpg yumdownloader&lt;br /&gt;
&lt;br /&gt;
Download all the packages that you consider necessary here:&lt;br /&gt;
&lt;br /&gt;
 ## Common utils that I use&lt;br /&gt;
 sudo yumdownloader --resolve vim git htop emacs-nox multitail screen&lt;br /&gt;
&lt;br /&gt;
 ## Those used to compile sugar / artwork / toolkit&lt;br /&gt;
 sudo yumdownloader --resolve git make alsa-lib-devel gettext-devel \&lt;br /&gt;
    gobject-introspection-devel gtk3-devel intltool libSM-devel \&lt;br /&gt;
    librsvg2-devel pygobject2-devel pygtk2-codegen python-devel \&lt;br /&gt;
    gtk2-devel icon-naming-utils icon-slicer python-empy \&lt;br /&gt;
    xorg-x11-apps gnome-common GConf2-devel gtksourceview3-devel \&lt;br /&gt;
    cairo-gobject&lt;br /&gt;
&lt;br /&gt;
Copy all of the packages downloaded to the server:&lt;br /&gt;
&lt;br /&gt;
 scp *noarch* humitos@192.168.1.101:/srv/repo/noarch&lt;br /&gt;
 scp *armv7hl* humitos@192.168.1.101:/srv/repo/armv7hl&lt;br /&gt;
 scp *i686* humitos@192.168.1.101:/srv/repo/i686&lt;br /&gt;
&lt;br /&gt;
= Create a yum configuration file =&lt;br /&gt;
&lt;br /&gt;
Copy this into a file called: &#039;&#039;/etc/yum.repos.d/local.repo&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 [SugarRepo]&lt;br /&gt;
 name=Sugar Repository&lt;br /&gt;
 baseurl=http://192.168.1.101/repo&lt;br /&gt;
 gpgcheck=0&lt;br /&gt;
&lt;br /&gt;
= Last step on the server =&lt;br /&gt;
&lt;br /&gt;
 createrepo /srv/repo&lt;br /&gt;
&lt;br /&gt;
= References =&lt;br /&gt;
&lt;br /&gt;
 * http://ramblings.narrabilis.com/creating-a-yum-repository-repo-and-creating-a-yum-group-to-install-kickstart&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingImageViewer&amp;diff=83155</id>
		<title>User:Humitos/PortingImageViewer</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingImageViewer&amp;diff=83155"/>
		<updated>2012-09-25T11:51:05Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;This page is being performed while I&amp;#039;m porting Image Viewer Activity to Gtk3.  There is a [http://bugs.sugarlabs.org/ticket/3958 ticket] with some useful information that I&amp;#039;m ...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Image Viewer Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3958 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Talk:Features/Display_Device&amp;diff=82367</id>
		<title>Talk:Features/Display Device</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Talk:Features/Display_Device&amp;diff=82367"/>
		<updated>2012-08-21T11:45:01Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;* How is going to be the interface for change the brightness? a slider? buttons? * How useful is for kids to take a screenshot?&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* How is going to be the interface for change the brightness? a slider? buttons?&lt;br /&gt;
* How useful is for kids to take a screenshot?&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82148</id>
		<title>User:Humitos/TouchTips</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82148"/>
		<updated>2012-08-10T15:14:41Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Work in progress page to write down some code snippets that I&#039;m finding in the meanwhile.&lt;br /&gt;
&lt;br /&gt;
= Touch and hold =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Browse&#039;&#039;&#039;: Touch and hold to trigger right click palette (for links, downloading, copy etc)&lt;br /&gt;
** http://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventTouch&lt;br /&gt;
&lt;br /&gt;
I think we should use &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; and look for the GDK_TOUCH_BEGIN and take its &#039;&#039;time&#039;&#039;. After that, compare this time with the actual one comming from &#039;&#039;&#039;event.touch.time&#039;&#039;&#039; and show the palette if it is bigger than 1000 milliseconds for example.&lt;br /&gt;
&lt;br /&gt;
The problem that I&#039;m having is that &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; doesn&#039;t tell me about the sequence itself. So, I don&#039;t know what was the GDK_TOUCH_BEGIN.&lt;br /&gt;
&lt;br /&gt;
* from #gtk+&lt;br /&gt;
&lt;br /&gt;
 (20:46:07) Company: humitos3: you can compare them&lt;br /&gt;
 (20:46:24) Company: sequence1 == sequence2&lt;br /&gt;
 (20:46:36) Company: at least it works in C, but i sure hope it does in python, too&lt;br /&gt;
&lt;br /&gt;
 (20:54:08) Flyser__: humitos3: sounds like incomplete bindings. you might want to ask in #python or #introspection&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82147</id>
		<title>User:Humitos/TouchTips</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82147"/>
		<updated>2012-08-10T15:14:26Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Work in progress page to write down some code snippets that I&#039;m finding in the meanwhile.&lt;br /&gt;
&lt;br /&gt;
= Touch and hold =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Browse&#039;&#039;&#039;: Touch and hold to trigger right click palette (for links, downloading, copy etc)&lt;br /&gt;
** http://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventTouch&lt;br /&gt;
&lt;br /&gt;
I think we should use &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; and look for the GDK_TOUCH_BEGIN and take its &#039;&#039;time&#039;&#039;. After that, compare this time with the actual one comming from &#039;&#039;&#039;event.touch.time&#039;&#039;&#039; and show the palette if it is bigger than 1000 milliseconds for example.&lt;br /&gt;
&lt;br /&gt;
The problem that I&#039;m having is that &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; doesn&#039;t tell me about the sequence itself. So, I don&#039;t know what was the GDK_TOUCH_BEGIN.&lt;br /&gt;
&lt;br /&gt;
** from #gtk+&lt;br /&gt;
&lt;br /&gt;
 (20:46:07) Company: humitos3: you can compare them&lt;br /&gt;
 (20:46:24) Company: sequence1 == sequence2&lt;br /&gt;
 (20:46:36) Company: at least it works in C, but i sure hope it does in python, too&lt;br /&gt;
&lt;br /&gt;
 (20:54:08) Flyser__: humitos3: sounds like incomplete bindings. you might want to ask in #python or #introspection&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82105</id>
		<title>User:Humitos/TouchTips</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/TouchTips&amp;diff=82105"/>
		<updated>2012-08-09T23:37:07Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;Work in progress page to write down some code snippets that I&amp;#039;m finding in the meanwhile.  = Touch and hold =  * &amp;#039;&amp;#039;&amp;#039;Browse&amp;#039;&amp;#039;&amp;#039;: Touch and hold to trigger right click palette (f...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Work in progress page to write down some code snippets that I&#039;m finding in the meanwhile.&lt;br /&gt;
&lt;br /&gt;
= Touch and hold =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Browse&#039;&#039;&#039;: Touch and hold to trigger right click palette (for links, downloading, copy etc)&lt;br /&gt;
** http://developer.gnome.org/gdk3/stable/gdk3-Event-Structures.html#GdkEventTouch&lt;br /&gt;
&lt;br /&gt;
I think we should use &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; and look for the GDK_TOUCH_BEGIN and take its &#039;&#039;time&#039;&#039;. After that, compare this time with the actual one comming from &#039;&#039;&#039;event.touch.time&#039;&#039;&#039; and show the palette if it is bigger than 1000 milliseconds for example.&lt;br /&gt;
&lt;br /&gt;
The problem that I&#039;m having is that &#039;&#039;&#039;event.touch.sequence&#039;&#039;&#039; doesn&#039;t tell me about the sequence itself. So, I don&#039;t know what was the GDK_TOUCH_BEGIN.&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81896</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81896"/>
		<updated>2012-08-02T15:22:58Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing / problematic things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch PATCH]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Port to Gtk3 -&amp;gt; Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = \&lt;br /&gt;
     self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state,&lt;br /&gt;
                                          self.active_group)&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* I used a HACK related to Pango fonts and DPI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Set correct DPI for Rsvg and Screen&lt;br /&gt;
 from gi.repository import PangoCairo&lt;br /&gt;
&lt;br /&gt;
 def _get_screen_dpi():&lt;br /&gt;
     xft_dpi = Gtk.Settings.get_default().get_property(&#039;gtk-xft-dpi&#039;)&lt;br /&gt;
     dpi = float(xft_dpi / 1024)&lt;br /&gt;
     logging.debug(&#039;Setting dpi to: %f&#039;, dpi)&lt;br /&gt;
     # HACK: if the DPI detected is 200.0 it seems we are on an XO, so&lt;br /&gt;
     # we return 133 because the XO manage its resolution in a complex&lt;br /&gt;
     # way. More information here:&lt;br /&gt;
     #     http://wiki.laptop.org/go/Display&lt;br /&gt;
     if 200 == int(dpi):&lt;br /&gt;
         return 133&lt;br /&gt;
     return dpi&lt;br /&gt;
&lt;br /&gt;
 dpi = _get_screen_dpi()&lt;br /&gt;
 font_map_default = PangoCairo.font_map_get_default()&lt;br /&gt;
 font_map_default.set_resolution(dpi)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* SHIFT and ALT GR keys do not show the correct keys&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81890</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81890"/>
		<updated>2012-08-02T14:00:21Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch PATCH]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Port to Gtk3 -&amp;gt; Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = \&lt;br /&gt;
     self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state,&lt;br /&gt;
                                          self.active_group)&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* I used a HACK related to Pango fonts and DPI:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 # Set correct DPI for Rsvg and Screen&lt;br /&gt;
 from gi.repository import PangoCairo&lt;br /&gt;
&lt;br /&gt;
 def _get_screen_dpi():&lt;br /&gt;
     xft_dpi = Gtk.Settings.get_default().get_property(&#039;gtk-xft-dpi&#039;)&lt;br /&gt;
     dpi = float(xft_dpi / 1024)&lt;br /&gt;
     logging.debug(&#039;Setting dpi to: %f&#039;, dpi)&lt;br /&gt;
     # HACK: if the DPI detected is 200.0 it seems we are on an XO, so&lt;br /&gt;
     # we return 133 because the XO manage its resolution in a complex&lt;br /&gt;
     # way. More information here:&lt;br /&gt;
     #     http://wiki.laptop.org/go/Display&lt;br /&gt;
     if 200 == int(dpi):&lt;br /&gt;
         return 133&lt;br /&gt;
     return dpi&lt;br /&gt;
&lt;br /&gt;
 dpi = _get_screen_dpi()&lt;br /&gt;
 font_map_default = PangoCairo.font_map_get_default()&lt;br /&gt;
 font_map_default.set_resolution(dpi)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81889</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81889"/>
		<updated>2012-08-02T13:57:50Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Gdk.Keymap.translate_keyboard_state */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch PATCH]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Port to Gtk3 -&amp;gt; Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = \&lt;br /&gt;
     self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state,&lt;br /&gt;
                                          self.active_group)&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81888</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81888"/>
		<updated>2012-08-02T13:57:08Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch PATCH]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Port to Gtk3 -&amp;gt; Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81887</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81887"/>
		<updated>2012-08-02T13:56:26Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Port to Cairo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch PATCH]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81886</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81886"/>
		<updated>2012-08-02T13:56:06Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3. Here is the [PATCH http://bugs.sugarlabs.org/attachment/ticket/3772/0001-Port-to-Cairo.2.patch]&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
==== Gtk3 version ====&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap.translate_keyboard_state ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
Old way:&lt;br /&gt;
&lt;br /&gt;
 t = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
New way:&lt;br /&gt;
&lt;br /&gt;
 success, keyval, effective_group, level, consumed_modifiers = self.keymap.translate_keyboard_state(key[&#039;key-scan&#039;], self.active_state, self.active_group)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== &#039;expose-event&#039; &amp;amp; &#039;draw&#039; event ==&lt;br /&gt;
&lt;br /&gt;
The new &#039;&#039;draw&#039;&#039; event that refers to the old &#039;&#039;expose-event&#039;&#039; into a Gtk.DrawingArea now receive the widget and the context instead the widget and the event:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;expose-event&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 def expose_cb(self, area, event):&lt;br /&gt;
     self.draw()&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;draw&#039;&#039; event&lt;br /&gt;
&lt;br /&gt;
 def draw_cb(self, area, cr):&lt;br /&gt;
     self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81852</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81852"/>
		<updated>2012-07-31T15:12:28Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* KEY_PRESS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 -    def expose_cb(self, area, event):&lt;br /&gt;
 -        self.draw()&lt;br /&gt;
 +    def draw_cb(self, area, cr):&lt;br /&gt;
 +        self.draw(cr)&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 cr = self.get_window().cairo_create()&lt;br /&gt;
 # README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf&lt;br /&gt;
 # Although this methos is not available in Python&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
* We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&lt;br /&gt;
&lt;br /&gt;
* PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&lt;br /&gt;
&lt;br /&gt;
* Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81845</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81845"/>
		<updated>2012-07-31T10:44:52Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* KEY_PRESS */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gdk/stable/gdk-Keyboard-Handling.html#gdk-keymap-translate-keyboard-state&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkkeymap.html#method-gdkkeymap--translate-keyboard-state&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 cr = self.get_window().cairo_create()&lt;br /&gt;
 # README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf&lt;br /&gt;
 # Although this methos is not available in Python&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
* We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&lt;br /&gt;
&lt;br /&gt;
* PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&lt;br /&gt;
&lt;br /&gt;
* Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/PyGObjectIssues&amp;diff=81780</id>
		<title>User:Humitos/PyGObjectIssues</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/PyGObjectIssues&amp;diff=81780"/>
		<updated>2012-07-27T18:24:17Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are listed all the bugs that we fund into PyGObject while we were porting activities to Gtk3:&lt;br /&gt;
&lt;br /&gt;
* DPI fonts in PangoCairo: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
** Daniel, Martin and I were working on this and Martin told me about trying 133 as the &amp;quot;magic&amp;quot; dpi number. It worked, but Daniel told us that it&#039;s not the right way to move on. So we are trying to change the way that we were creating the Pango Layout using:&lt;br /&gt;
&lt;br /&gt;
 cr = drawable.get_window().cairo_create()&lt;br /&gt;
 drawable.create_pango_layout(cairo_context)&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
 cr = drawable.get_window().cairo_create()&lt;br /&gt;
 pango_layout = PangoCairo.create_layout(cr)&lt;br /&gt;
&lt;br /&gt;
I&#039;m not sure if this is definetly solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Reading an image from XPM data: https://bugzilla.gnome.org/show_bug.cgi?id=651962&lt;br /&gt;
* GtkTreeModelSort: https://bugzilla.gnome.org/show_bug.cgi?id=680009&lt;br /&gt;
* GtkTextIter: https://bugzilla.gnome.org/show_bug.cgi?id=680597&lt;br /&gt;
* Insert a GtkTreeView column with attributes: https://bugzilla.gnome.org/show_bug.cgi?id=679415&lt;br /&gt;
* Vte.get_text https://bugzilla.gnome.org/show_bug.cgi?id=676999 | https://bugzilla.gnome.org/show_bug.cgi?id=677000&lt;br /&gt;
* Webkit: Double scrollbar in Google Apps: https://bugzilla.gnome.org/show_bug.cgi?id=676982&lt;br /&gt;
* It&#039;s already solved but it is not applied on my F17 package (I think): https://bugzilla.gnome.org/show_bug.cgi?id=674968&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/PyGObjectIssues&amp;diff=81779</id>
		<title>User:Humitos/PyGObjectIssues</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/PyGObjectIssues&amp;diff=81779"/>
		<updated>2012-07-27T18:21:07Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;Here are listed all the bugs that we fund into PyGObject while we were porting activities to Gtk3:  * DPI fonts in PangoCairo: https://bugzilla.gnome.org/show_bug.cgi?id=68066...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are listed all the bugs that we fund into PyGObject while we were porting activities to Gtk3:&lt;br /&gt;
&lt;br /&gt;
* DPI fonts in PangoCairo: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
** Daniel, Martin and I were working on this and Martin told me about trying 133 as the &amp;quot;magic&amp;quot; dpi number. It worked, but Daniel told us that it&#039;s not the right way to move on. So we are trying to change the way that we were creating the Pango Layout using:&lt;br /&gt;
&lt;br /&gt;
 cr = drawable.get_window().cairo_create()&lt;br /&gt;
 drawable.create_pango_layout(cairo_context)&lt;br /&gt;
&lt;br /&gt;
instead of:&lt;br /&gt;
&lt;br /&gt;
 cr = drawable.get_window().cairo_create()&lt;br /&gt;
 pango_layout = PangoCairo.create_layout(cr)&lt;br /&gt;
&lt;br /&gt;
I&#039;m not sure if this is definetly solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Reading an image from XPM data: https://bugzilla.gnome.org/show_bug.cgi?id=651962&lt;br /&gt;
* GtkTreeModelSort: https://bugzilla.gnome.org/show_bug.cgi?id=680009&lt;br /&gt;
* GtkTextIter: https://bugzilla.gnome.org/show_bug.cgi?id=680597&lt;br /&gt;
* Insert a GtkTreeView column with attributes: https://bugzilla.gnome.org/show_bug.cgi?id=679415&lt;br /&gt;
* Vte.get_text https://bugzilla.gnome.org/show_bug.cgi?id=676999&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81753</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81753"/>
		<updated>2012-07-27T11:48:59Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing / problematic things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* [&amp;lt;span style=&amp;quot;color: green;&amp;quot;&amp;gt;SOLVED&amp;lt;/span&amp;gt;] &amp;lt;del&amp;gt;This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&amp;lt;/del&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 cr = self.get_window().cairo_create()&lt;br /&gt;
 # README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf&lt;br /&gt;
 # Although this methos is not available in Python&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
 Gdk.cairo_set_source_pixbuf(cr, self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
* We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&lt;br /&gt;
&lt;br /&gt;
* PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&lt;br /&gt;
&lt;br /&gt;
* Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81752</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81752"/>
		<updated>2012-07-27T11:42:29Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing / problematic things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&lt;br /&gt;
&lt;br /&gt;
 cr = self.get_window().cairo_create()&lt;br /&gt;
 # README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf&lt;br /&gt;
 # Although this methos is not available in Python&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
* We should find the correct way to scale Left and Right hands that are drawn over the keyboard, because I just put values that I thought they were correct. We should calculate them according to the screen&lt;br /&gt;
&lt;br /&gt;
* PangoCairo fonts are not being drawn because of this: https://bugzilla.gnome.org/show_bug.cgi?id=680680&lt;br /&gt;
&lt;br /&gt;
* Font Scale is wrong: https://bugzilla.gnome.org/show_bug.cgi?id=680663&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81751</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81751"/>
		<updated>2012-07-27T11:35:48Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
= Missing / problematic things =&lt;br /&gt;
&lt;br /&gt;
* This method, &#039;&#039;set_source_pixbuf&#039;&#039;, is not available.&lt;br /&gt;
&lt;br /&gt;
 cr = self.get_window().cairo_create()&lt;br /&gt;
 # README: http://developer.gnome.org/gdk/stable/gdk-Cairo-Interaction.html#gdk-cairo-set-source-pixbuf&lt;br /&gt;
 # Although this methos is not available in Python&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingTypingTurtle&amp;diff=81750</id>
		<title>User:Humitos/PortingTypingTurtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingTypingTurtle&amp;diff=81750"/>
		<updated>2012-07-27T11:25:29Z</updated>

		<summary type="html">&lt;p&gt;Humitos: moved User:Humitos/PortingTypingTurtle to Features/GTK3/Porting/TypingTurtle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Features/GTK3/Porting/TypingTurtle]]&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81749</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81749"/>
		<updated>2012-07-27T11:25:29Z</updated>

		<summary type="html">&lt;p&gt;Humitos: moved User:Humitos/PortingTypingTurtle to Features/GTK3/Porting/TypingTurtle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81748</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81748"/>
		<updated>2012-07-27T11:21:40Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
== GdkPixbuf.PixbufLoader ==&lt;br /&gt;
&lt;br /&gt;
Change this:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
by:&lt;br /&gt;
&lt;br /&gt;
 pxb_loader = GdkPixbuf.PixbufLoader.new_with_type(&#039;png&#039;)&lt;br /&gt;
&lt;br /&gt;
== KEY_PRESS ==&lt;br /&gt;
&lt;br /&gt;
This should be done by the &#039;&#039;&#039;pygi-convert.sh&#039;&#039;&#039; script.&lt;br /&gt;
&lt;br /&gt;
 gtk.gdk.KEY_PRESS&lt;br /&gt;
 gtk.gdk.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
replaced by&lt;br /&gt;
&lt;br /&gt;
 Gdk.EventType.KEY_PRESS&lt;br /&gt;
 Gdk.EventType.KEY_RELEASE&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81747</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81747"/>
		<updated>2012-07-27T11:13:51Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer ==&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextTag ==&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Keymap ==&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e[0], e[1], e[2]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
 for e in entries:&lt;br /&gt;
     e.keycode, e.group, e.level&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
= Notes =&lt;br /&gt;
&lt;br /&gt;
* I found this chunk of code in the source (&#039;&#039;keyboard.py&#039;&#039; &#039;&#039;&#039;L515&#039;&#039;&#039;) and I didn&#039;t understand what it means&lt;br /&gt;
&lt;br /&gt;
 # Hack to get the current modifier state - which will not be represented by the event.&lt;br /&gt;
 state = gtk.gdk.device_get_core_pointer().get_state(self.window)[1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81746</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81746"/>
		<updated>2012-07-27T11:09:11Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextBuffer =&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = gtk.TextBuffer(self.tagtable)&lt;br /&gt;
 self.lessontext = gtk.TextView(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
== Gdk.Event ==&lt;br /&gt;
&lt;br /&gt;
 event.state&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 event.get_state()&lt;br /&gt;
&lt;br /&gt;
== Rsvg ==&lt;br /&gt;
&lt;br /&gt;
 import rsvg&lt;br /&gt;
 image = rsvg.Handle(file=filename)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 from gi.repository import Rsvg&lt;br /&gt;
 image = Rsvg.Handle.new_from_file(filename)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting&amp;diff=81687</id>
		<title>Features/GTK3/Porting</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting&amp;diff=81687"/>
		<updated>2012-07-27T01:07:48Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Going from Cairo in GTK-2 to Cairo in GTK-3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Porting an existing activity to GTK3=&lt;br /&gt;
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 [http://git.sugarlabs.org/hello-world hello-world] activity as a simple example.&lt;br /&gt;
&lt;br /&gt;
There is another guide written from scratch that uses this one as reference. I was done porting GetBooks Activity [[Features/GTK3/Porting/GetBooks]]&lt;br /&gt;
&lt;br /&gt;
==Preparation==&lt;br /&gt;
Before you start porting your activity you are encouraged to branch off a stable branch. This will allow you to keep on doing stable releases on the stable branch and new releases on the master branch. We highly recommend that you use the &#039;sugar-0.94&#039; as the stable branch name because this will keep the repositories consistent and eases the development work. Let&#039;s step through this with a real life example:&lt;br /&gt;
&lt;br /&gt;
The latest release of hello-world was version 3 (commit 04fb9beb708f1078aae93995da3ec06bac7aa433). We want to branch off at that point. If you did not do any changes after the last stable commit simply create a branch with:&lt;br /&gt;
 git branch sugar-0.94&lt;br /&gt;
&lt;br /&gt;
If you have already made commits after that, you need to go to that commit first and create a branch at that specific point in our case commit 04fb9beb708f1078aae93995da3ec06bac7aa433, there is a command to do that in one go:&lt;br /&gt;
 git checkout -b sugar-0.94 04fb9beb708f1078aae93995da3ec06bac7aa433&lt;br /&gt;
 &lt;br /&gt;
In both cases this has created a local branch, as you can see by running &#039;git branch&#039;; you should see the following (if you did the second command you will have sugar-0.94 already selected):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[erikos@T61 helloworld]$ git branch&lt;br /&gt;
* master&lt;br /&gt;
  sugar-0.94&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;sugar-0.94&#039; branch is only available locally, as you can see by running &#039;git branch -r&#039; which shows the remote branches:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[erikos@T61 helloworld]$ git branch -r&lt;br /&gt;
  origin/HEAD -&amp;gt; origin/master&lt;br /&gt;
  origin/master&lt;br /&gt;
  origin/sucrose-0.84&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only branch available besides the master branch is the &#039;sucrose-0.84&#039; branch. Let&#039;s push now our new branch to the remote repository to make it available for others:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git push origin sugar-0.94&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The branch is now listed as a remote branch. You can verify as well on your [http://git.sugarlabs.org/hello-world/mainline gitorious page].&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[erikos@T61 helloworld]$ git branch -r&lt;br /&gt;
  origin/HEAD -&amp;gt; origin/master&lt;br /&gt;
  origin/master&lt;br /&gt;
  origin/sucrose-0.84&lt;br /&gt;
  origin/sugar-0.94&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can switch now between those branches using &#039;git checkout &amp;lt;branch&amp;gt;&#039;. And you can use &#039;git branch&#039; to see which branch you are on (the one with the * before is the branch you are currently on).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
git checkout sugar-0.94&lt;br /&gt;
git checkout master&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Cleanup, adopt to API changes in sugar-toolkit-gtk3 ==&lt;br /&gt;
&#039;&#039;This should be done only on the master branch&#039;&#039;! In the new sugar-toolkit-gtk3 we have removed old API, you should adjust your activity accordingly:&lt;br /&gt;
* the keep button has been removed completely&lt;br /&gt;
* the old-style toolbar has been removed&lt;br /&gt;
* do not use set_toolbox anymore use set_toolbar_box instead (see in [http://git.sugarlabs.org/~walter/abacus/walter-cairo/commit/6871dd340a89ade3b5361457e1bd1d58276a8efc Abacus])&lt;br /&gt;
* remove import of deprecated ActivityToolbox (see [http://git.sugarlabs.org/hello-world/mainline/commit/22060a3063b2d6fd38d6b1cd8d44946170255af3 hello-world])&lt;br /&gt;
* support for &#039;service_name&#039; and &#039;class&#039; has been removed from the activity.info make sure you are using: &#039;bundle_id&#039; instead of &#039;service_name&#039; and &#039;exec&#039; instead of &#039;class&#039; (see in [http://git.sugarlabs.org/record/mainline/commit/6e8968c71e474e2d8d86886badf5cf7d70217dc5 Record])&lt;br /&gt;
&lt;br /&gt;
==Port the activity from GTK2 to GTK3==&lt;br /&gt;
To start, change the importing instruction for GTK from&lt;br /&gt;
 import gtk&lt;br /&gt;
to&lt;br /&gt;
 from gi.repository import Gtk&lt;br /&gt;
Then you have to change each call that involves Gtk, for example creating a button will look now like this:&lt;br /&gt;
 button = Gtk.Button()&lt;br /&gt;
&lt;br /&gt;
A simple hello world program in GTK3 looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from gi.repository import Gtk&lt;br /&gt;
&lt;br /&gt;
def _destroy_cb(widget, data=None):&lt;br /&gt;
    Gtk.main_quit()&lt;br /&gt;
&lt;br /&gt;
w = Gtk.Window()&lt;br /&gt;
w.connect(&amp;quot;destroy&amp;quot;, _destroy_cb)&lt;br /&gt;
label = Gtk.Label(&#039;Hello World!&#039;)&lt;br /&gt;
w.add(label)&lt;br /&gt;
w.show_all()&lt;br /&gt;
&lt;br /&gt;
Gtk.main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For porting your activity you do have to change your calls for accessing widgets and services in the new GTK3 sugar-toolkit as well. The new namespace is called sugar3, trying to reflect that GTK3 is the underlying technology. For example the import of the base activity class has to be changed from&lt;br /&gt;
 from sugar.activity import activity&lt;br /&gt;
to&lt;br /&gt;
 from sugar3.activity import activity&lt;br /&gt;
&lt;br /&gt;
Make sure you change the setup.py in your activity to point to the new toolkit as well:&lt;br /&gt;
  from sugar3.activity import bundlebuilder&lt;br /&gt;
&lt;br /&gt;
The changes that were needed to port the hello-world activity can be seen in [http://git.sugarlabs.org/hello-world/mainline/commit/508e1c518b56cbde5508e560c8a2ff38a3518583 this commit].&lt;br /&gt;
&lt;br /&gt;
Ok, let&#039;s do these changes now for your activity. Make sure you are in your master branch using the &#039;git branch&#039; command (the master branch should have a &#039;*&#039; before it). Make your changes, commit them (&#039;git commit -a&#039;) and push them to the remote repository (&#039;git push origin master&#039;).&lt;br /&gt;
&lt;br /&gt;
===Tools===&lt;br /&gt;
There are tools to help you do the porting. There is a script in the pygobject repository for porting called [http://git.gnome.org/browse/pygobject/tree/pygi-convert.sh pygi-convert.sh], more info about the script can be found in [http://live.gnome.org/PyGObject/IntrospectionPorting the PyGObject Introspection Porting guide].&lt;br /&gt;
&lt;br /&gt;
Here is a script to automate the rename of the imports &#039;&#039;&#039;sugar&#039;&#039;&#039; to &#039;&#039;&#039;sugar3&#039;&#039;&#039;: [http://dev.laptop.org/~manuq/sugar-convert.sh sugar-convert.sh].&lt;br /&gt;
&lt;br /&gt;
If you are having trouble finding how a particular GTK class/method/constant has been named in PyGI, run [http://dev.laptop.org/~dsd/20110806/pygi-enumerate.py pygi-enumerate.py] and grep the output. (this app lists all identified methods and constants).  Usage example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python pygi-enumerate.py | grep get_selection&lt;br /&gt;
Gtk.AccelLabel.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.Editable.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.Entry.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.IconView.get_selection_mode() (instance method)&lt;br /&gt;
Gtk.Label.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.SelectionData.get_selection() (instance method)&lt;br /&gt;
Gtk.SpinButton.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.TextBuffer.get_selection_bound() (instance method)&lt;br /&gt;
Gtk.TextBuffer.get_selection_bounds() (instance method)&lt;br /&gt;
Gtk.TreeView.get_selection() (instance method)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constructor considerations ===&lt;br /&gt;
&lt;br /&gt;
With PyGI it is possible to use Python-like constructors, or &amp;quot;new&amp;quot; functions e.g. the following are (usually) equivalent:&lt;br /&gt;
 label = Gtk.Button()&lt;br /&gt;
 label = Gtk.Button.new()&lt;br /&gt;
&lt;br /&gt;
However, the first form is preferred: it is more Python-like. Internally, the difference is that Gtk.Label.new() translates to a call to gtk_label_new(), whereas Gtk.Label() (the preferred form) will directly construct an instance of GtkLabel at the GObject level.&lt;br /&gt;
&lt;br /&gt;
If the constructor takes parameters, they &#039;&#039;&#039;must&#039;&#039;&#039; be named. The parameters correspond to GObject properties in the API documentation which are usually marked as &amp;quot;Construct&amp;quot;. For example, the following code will not work:&lt;br /&gt;
&lt;br /&gt;
 expander = Gtk.Expander(&amp;quot;my expander&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The (confusing) error is:&lt;br /&gt;
 TypeError: GObject.__init__() takes exactly 0 arguments (1 given)&lt;br /&gt;
&lt;br /&gt;
The solution is to go to the [http://developer.gnome.org/gtk3/3.2/GtkExpander.html#GtkExpander.properties GtkExpander API documentation] and find the appropriate property that we wish to set. In this case it is &amp;lt;b&amp;gt;label&amp;lt;/b&amp;gt; (which is a Construct property, further increasing our confidence of success), so the code should be:&lt;br /&gt;
&lt;br /&gt;
 expander = Gtk.Expander(label=&amp;quot;my expander&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Combining the two points above, if you wish to call a construct-like function such as gtk_button_new_with_label(), you do have the option of calling Gtk.Button.new_with_label(), however if we check the [http://developer.gnome.org/gtk3/3.2/GtkButton.html#GtkButton.properties GtkButton properties] we see one called &amp;quot;label&amp;quot; which is equivalent. Therefore gtk_button_new_with_label(&amp;quot;foo&amp;quot;) should be called as:&lt;br /&gt;
 button = Gtk.Button(label=&amp;quot;foo&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
=== HBox, VBox, pack_start and pack_end ===&lt;br /&gt;
&lt;br /&gt;
GtkHBox and GtkVBox, commonly used containers in GTK2 code, have pack_start and pack_end methods. These take 4 parameters:&lt;br /&gt;
# The widget to pack into the container&lt;br /&gt;
# &#039;&#039;&#039;expand&#039;&#039;&#039;: Whether the child should receive extra space when the container grows (default True)&lt;br /&gt;
# &#039;&#039;&#039;fill&#039;&#039;&#039;: True if space given to child by the expand option is actually allocated to child, rather than just padding it. This parameter has no effect if expand is set to False. A child is always allocated the full height of a gtk.HBox and the full width of a gtk.VBox. This option affects the other dimension. (default True)&lt;br /&gt;
# &#039;&#039;&#039;padding&#039;&#039;&#039;: extra space in pixels to put between child and its neighbor (default 0)&lt;br /&gt;
&lt;br /&gt;
In PyGTK, the expand, fill and padding parameters were optional: if unspecified, the default values above were used. In PyGI, these parameters are &#039;&#039;&#039;not&#039;&#039;&#039; optional: all 4 must be specified. Hence the rules for adding in the extra parameters are:&lt;br /&gt;
&lt;br /&gt;
# If &#039;&#039;&#039;expand&#039;&#039;&#039; was not set, use value True&lt;br /&gt;
# If &#039;&#039;&#039;fill&#039;&#039;&#039; was not set, use value True. (however, if expand is False, this parameter gets ignored so False is an equally acceptable option when expand=False)&lt;br /&gt;
# If &#039;&#039;&#039;padding&#039;&#039;&#039; was not set, use value 0.&lt;br /&gt;
&lt;br /&gt;
These parameters can be specified either as positional arguments or as named keyword arguments, however all 4 must always be specified. Some developers prefer keyword arguments, arguing that the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;box.pack_start(widget, expand=True, fill=False, padding=4)&amp;lt;/pre&amp;gt;&lt;br /&gt;
is much more readable than:&lt;br /&gt;
&amp;lt;pre&amp;gt;box.pack_start(widget, True, False, 4)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, these functions are called extremely often; any mildly seasoned GTK developer will have memorized the order and meaning of the parameters. Some developers therefore prefer to avoid the extra work of dropping in hundreds of keyword arguments throughout the code and just use the positional ones. This is really up to you.&lt;br /&gt;
&lt;br /&gt;
If you are using pack_start with the default values (expand=True, fill=True and padding=0), you can avoid using pack_start (and the parameter pain that it brings with it) by just using .add for some added cleanliness, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;box.pack_start(widget, True, True, 0)&amp;lt;/pre&amp;gt;&lt;br /&gt;
can be replaced with:&lt;br /&gt;
&amp;lt;pre&amp;gt;box.add(widget)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is as far as you need to go for now. However, in GTK3, GtkVBox and GtkHBox have been deprecated, which means they might be removed in GTK4. The replacement is to use GtkBox directly, and you may wish to make this change now. e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, homogeneous=True, spacing=8)&amp;lt;/pre&amp;gt;&lt;br /&gt;
However, it must be noted that if GtkBox is used directly (instead of using GtkHBox/GtkVBox), the default value of &#039;&#039;&#039;expand&#039;&#039;&#039; is now &#039;&#039;&#039;False&#039;&#039;&#039;. The implications of this are:&lt;br /&gt;
# You need to check your .add() calls, as previously they would behave as pack_start with expand=True, but now they will behave as expand=False (you need to change them to use pack_start with expand=True to retain the old behaviour)&lt;br /&gt;
# Every single pack_start call that has expand=False and padding=0 (and any value of fill) can be converted to .add() for cleanliness&lt;br /&gt;
&lt;br /&gt;
=== GtkAlignment considerations ===&lt;br /&gt;
&lt;br /&gt;
In PyGTK, the gtk.Alignment constructor takes four optional parameters:&lt;br /&gt;
# xalign: the fraction of horizontal free space to the left of the child widget. Ranges from 0.0 to 1.0. Default value 0.0.&lt;br /&gt;
# yalign: the fraction of vertical free space above the child widget. Ranges from 0.0 to 1.0. Default value 0.0.&lt;br /&gt;
# xscale: the fraction of horizontal free space that the child widget absorbs, from 0.0 to 1.0. Default value 0.0.&lt;br /&gt;
# yscale: the fraction of vertical free space that the child widget absorbs, from 0.0 to 1.0. Default value 0.0&lt;br /&gt;
&lt;br /&gt;
In PyGI/GTK3, these parameters are still optional when used in the Gtk.Alignment constructor (as keyword arguments, as explained above). However, the default values have changed. They are now:&lt;br /&gt;
# xalign: default value 0.5&lt;br /&gt;
# yalign: default value 0.5&lt;br /&gt;
# xscale: default value 1&lt;br /&gt;
# yscale: default value 1&lt;br /&gt;
&lt;br /&gt;
If your code was relying on the default value of 0 for any of these parameters in PyGTK, you will now need to explicitly specify that in your constructor. Similarly, if you were previously using construction parameters to select the now-default values, those parameters can be dropped.&lt;br /&gt;
&lt;br /&gt;
Additionally, PyGTK accepted these construction parameters as positional arguments. As explained above, they must now be converted to keyword arguments.&lt;br /&gt;
&lt;br /&gt;
=== Other considerations ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;self.allocation&#039;&#039; property is no longer available.  Please search your code for &amp;quot;self.allocation&amp;quot; and replace it for &amp;quot;self.get_allocation()&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So to get the allocation size:&lt;br /&gt;
&lt;br /&gt;
 self.allocation.width&lt;br /&gt;
 self.allocation.height&lt;br /&gt;
&lt;br /&gt;
should be replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.get_allocated_width()&lt;br /&gt;
 self.get_allocated_height()&lt;br /&gt;
&lt;br /&gt;
==Make a release==&lt;br /&gt;
===Versioning===&lt;br /&gt;
If you do new releases the versioning of the GTK2 and GTK3 release should be different. For GTK2 releases you should use dotted versions for new development releases major versions. Let&#039;s have a look at hello-world as an example. The latest release of hello-world was version 3. Bug fix releases should be named 3.1 then 3.2 and so on. The new releases for the new development branch should be starting with a major number, in the case of hello-world version 4.&lt;br /&gt;
&lt;br /&gt;
To minimise the maintainer overload we highly encourage you to only do bug-fix releases for the GTK2 branch. New features should only go into the new branch that is based on gobject-introspection and GTK3.&lt;br /&gt;
&lt;br /&gt;
== Tips to Activity Developers ==&lt;br /&gt;
&lt;br /&gt;
===Changes to the Clipboard===&lt;br /&gt;
Two things to note:&lt;br /&gt;
&lt;br /&gt;
1. You need to specify a clipboard using get()&lt;br /&gt;
    clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
2. You need to pass a length to set_text()&lt;br /&gt;
    clipboard.set_text(string, len(string))&lt;br /&gt;
&lt;br /&gt;
See [http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html] for more details.&lt;br /&gt;
&lt;br /&gt;
===Changes to Drag-and-Drop===&lt;br /&gt;
Slightly different syntax:&lt;br /&gt;
        self.drag_dest_set(Gtk.DestDefaults.ALL, [],&lt;br /&gt;
                           Gdk.DragAction.COPY)&lt;br /&gt;
        self.drag_dest_set_target_list(None)&lt;br /&gt;
        self.drag_dest_add_text_targets()&lt;br /&gt;
        self.connect(&#039;drag_data_received&#039;, self._drag_data_received)&lt;br /&gt;
&lt;br /&gt;
and:&lt;br /&gt;
        data.get_text()&lt;br /&gt;
or:&lt;br /&gt;
        data.get_image()&lt;br /&gt;
&lt;br /&gt;
See [http://python-gtk-3-tutorial.readthedocs.org/en/latest/drag_and_drop.html] for more details.&lt;br /&gt;
&lt;br /&gt;
===Going from Drawable to Cairo===&lt;br /&gt;
&lt;br /&gt;
GTK-3 does not support gtk Drawable objects, so the first step is to get your activity running under Cairo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import cairo&lt;br /&gt;
&lt;br /&gt;
# From activity.Activity, you inherit a canvas.&lt;br /&gt;
# Create a Cairo context from the window.&lt;br /&gt;
cairo_context = self.canvas.get_window().cairo_create()&lt;br /&gt;
&lt;br /&gt;
# Create an XLib surface to be used for drawing&lt;br /&gt;
xlib_surface = surface.create_similar(cairo.CONTENT_COLOR,&lt;br /&gt;
                                      gtk.gdk.screen_width(),&lt;br /&gt;
                                      gtk.gdk.screen_height())&lt;br /&gt;
&lt;br /&gt;
# You&#039;ll need a Cairo context from which you&#039;ll build a GTK Cairo context&lt;br /&gt;
cairo_context = cairo.Context(xlib_surface)&lt;br /&gt;
cairo_context = gtk.gdk.CairoContext(cairo_context)&lt;br /&gt;
&lt;br /&gt;
# Use this context as you would a Drawable, substituting Cairo commands&lt;br /&gt;
# for gtk commands, e.g.,&lt;br /&gt;
cairo_context.move_to(0, 0)&lt;br /&gt;
cairo_context.line_to(100, 100)&lt;br /&gt;
# Cairo uses floats from 0 to 1 for RGB values&lt;br /&gt;
cairo_context.set_source_rgb(r, g, b)&lt;br /&gt;
cairo_context.rectangle(x, y, w, h)&lt;br /&gt;
cairo_context.fill()&lt;br /&gt;
&lt;br /&gt;
# To invalidate a region to force a refresh, use:&lt;br /&gt;
self.canvas.queue_draw_area(x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
# Handle the expose event&lt;br /&gt;
def do_expose_event(self, event):&lt;br /&gt;
    # Create the cairo context&lt;br /&gt;
    cairo_context = self.canvas.get_window().cairo_create()&lt;br /&gt;
    cairo_context.rectangle(event.area.x, event.area.y,&lt;br /&gt;
                            event.area.width, event.area.height)&lt;br /&gt;
    cairo_context.clip()&lt;br /&gt;
    cairo_context.set_source_surface(xlib_surface)&lt;br /&gt;
    cairo_context.paint()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pango is a bit different when used with Cairo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pango, pangocairo&lt;br /&gt;
&lt;br /&gt;
# Again, from the xlib_surface...&lt;br /&gt;
cairo_context = cairo.Context(xlib_surface)&lt;br /&gt;
&lt;br /&gt;
# Create a PangoCairo context&lt;br /&gt;
cairo_context = pangocairo.CairoContext(cairo_context)&lt;br /&gt;
&lt;br /&gt;
# The pango layout is created from the Cairo context&lt;br /&gt;
pango_layout = cairo_context.create_layout()&lt;br /&gt;
&lt;br /&gt;
# You still use pango to set up font descriptions.&lt;br /&gt;
fd = pango.FontDescription(&#039;Sans&#039;)&lt;br /&gt;
fd.set_size(12 * pango.SCALE)&lt;br /&gt;
&lt;br /&gt;
# Tell your pango layout about your font description&lt;br /&gt;
pango_layout.set_font_description(fd)&lt;br /&gt;
&lt;br /&gt;
# Write text to your pango layout&lt;br /&gt;
pango_layout.set_text(&#039;Hello world&#039;)&lt;br /&gt;
&lt;br /&gt;
# Position it within the Cairo context&lt;br /&gt;
cairo_context.save()&lt;br /&gt;
cairo_context.translate(x, y)&lt;br /&gt;
cairo_context.rotate(pi / 3)  # You can rotate text and images in Cairo&lt;br /&gt;
cairo_context.set_source_rgb(1, 0, 0)&lt;br /&gt;
&lt;br /&gt;
# Finally, draw the text&lt;br /&gt;
cairo_context.update_layout(pango_layout)&lt;br /&gt;
cairo_context.show_layout(pango_layout)&lt;br /&gt;
cairo_context.restore()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To draw a bitmap...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Again, from the xlib_surface...&lt;br /&gt;
cairo_context = cairo.Context(xlib_surface)&lt;br /&gt;
&lt;br /&gt;
# Create a gtk context&lt;br /&gt;
cairo_context = gtk.gdk.CairoContext(cairo_context)&lt;br /&gt;
cairo_context.set_source_pixbuf(pixbuf, x, y)&lt;br /&gt;
cairo_context.rectangle(x, y, w, h)&lt;br /&gt;
cairo_context.fill()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To read a pixel from the xlib surface...&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# create a new 1x1 cairo surface&lt;br /&gt;
cairo_surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1);&lt;br /&gt;
cairo_context = cairo.Context(cairo_surface)&lt;br /&gt;
# translate xlib_surface so that target pixel is at 0, 0&lt;br /&gt;
cairo_context.set_source_surface(xlib_surface, -x, -y)&lt;br /&gt;
cairo_context.rectangle(0,0,1,1)&lt;br /&gt;
cairo_context.set_operator(cairo.OPERATOR_SOURCE)&lt;br /&gt;
cairo_context.fill()&lt;br /&gt;
cairo_surface.flush() # ensure all writing is done&lt;br /&gt;
# Read the pixel&lt;br /&gt;
return (ord(pixels[2]), ord(pixels[1]), ord(pixels[0]), 0)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Going from Cairo in GTK-2 to Cairo in GTK-3===&lt;br /&gt;
&lt;br /&gt;
Not much changes, but...&lt;br /&gt;
&lt;br /&gt;
The Cairo/Pango interaction is a little different:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from gi.repository import Pango, PangoCairo&lt;br /&gt;
&lt;br /&gt;
cairo_context = ...&lt;br /&gt;
pango_layout = PangoCairo.create_layout(cairo_context)&lt;br /&gt;
fd = Pango.FontDescription(&#039;Sans&#039;)&lt;br /&gt;
fd.set_size(12 * Pango.SCALE)&lt;br /&gt;
pango_layout.set_font_description(fd)&lt;br /&gt;
pango_layout.set_text(&#039;Hello World&#039;, -1)&lt;br /&gt;
cairo_context.set_source_rgb(1, 0, 0)&lt;br /&gt;
PangoCairo.update_layout(cairo_context, pango_layout)&lt;br /&gt;
PangoCairo.show_layout(cairo_context, pango_layout)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Taking a screenshot and making a thumbnail===&lt;br /&gt;
To make a screenshot of the window:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
width, height = window.get_width(), window.get_height()&lt;br /&gt;
thumb_surface = Gdk.Window.create_similar_surface(window,&lt;br /&gt;
                                                  cairo.CONTENT_COLOR,&lt;br /&gt;
                                                  width, height)&lt;br /&gt;
&lt;br /&gt;
thumb_width, thumb_height = style.zoom(100), style.zoom(80)&lt;br /&gt;
cairo_context = cairo.Context(thumb_surface)&lt;br /&gt;
thumb_scale_w = thumb_width * 1.0 / width&lt;br /&gt;
thumb_scale_h = thumb_height * 1.0 / height&lt;br /&gt;
cairo_context.scale(thumb_scale_w, thumb_scale_h)&lt;br /&gt;
Gdk.cairo_set_source_window(cairo_context, window, 0, 0)&lt;br /&gt;
cairo_context.paint()&lt;br /&gt;
thumb_surface.write_to_png(png_path_or_filelike_object)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Creating a video widget===&lt;br /&gt;
&lt;br /&gt;
Haven&#039;t gotten this working yet, but some necessary changes include:&lt;br /&gt;
&lt;br /&gt;
Instead of&lt;br /&gt;
 window.xid&lt;br /&gt;
use&lt;br /&gt;
 get_property(&#039;window&#039;).get_xid()&lt;br /&gt;
&lt;br /&gt;
Instead of&lt;br /&gt;
 unset_flags(gtk.DOUBLE_BUFFERED)&lt;br /&gt;
 set_flags(gtk.APP_PAINTABLE)&lt;br /&gt;
use&lt;br /&gt;
 set_double_buffered(False)&lt;br /&gt;
 set_app_paintable(True)&lt;br /&gt;
&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
== Resources ==&lt;br /&gt;
* PyGtk documentation&lt;br /&gt;
** Gtk3: http://python-gtk-3-tutorial.readthedocs.org&lt;br /&gt;
** gtk2: http://www.pygtk.org/docs/pygtk/&lt;br /&gt;
* Reference Manual&lt;br /&gt;
** Gtk3: http://developer.gnome.org/gtk3/3.4/&lt;br /&gt;
* Gdk documentation:&lt;br /&gt;
** Gdk3: http://developer.gnome.org/gdk/2.24/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
&lt;br /&gt;
= More porting wiki pages =&lt;br /&gt;
&lt;br /&gt;
{{Special:PrefixIndex/Features/GTK3/Porting}}&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81665</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81665"/>
		<updated>2012-07-25T16:20:45Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeModelSort.convert_child_iter_to_iter ==&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTreeModelSort.html#gtk-tree-model-sort-convert-child-iter-to-iter&lt;br /&gt;
&lt;br /&gt;
The old way to do this:&lt;br /&gt;
&lt;br /&gt;
 log_iter = \&lt;br /&gt;
     self._treeview.get_model().convert_child_iter_to_iter(None,&lt;br /&gt;
             log.iter)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 success, log_iter = \&lt;br /&gt;
     self._treeview.get_model().convert_child_iter_to_iter(log.iter)&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Look for &#039;&#039;&#039;FIXME&#039;&#039;&#039;s and &#039;&#039;&#039;README&#039;&#039;&#039;s in the code (logviewer.py)&lt;br /&gt;
* Searching in the log is not working due to this bug: https://bugzilla.gnome.org/show_bug.cgi?id=680597&lt;br /&gt;
&lt;br /&gt;
= Useful Links =&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTextIter.html#gtk-text-iter-forward-search&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTreeModelSort.html#gtk-tree-model-filter-convert-child-iter-to-iter&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81664</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81664"/>
		<updated>2012-07-25T16:17:33Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Look for &#039;&#039;&#039;FIXME&#039;&#039;&#039;s and &#039;&#039;&#039;README&#039;&#039;&#039;s in the code (logviewer.py)&lt;br /&gt;
* Searching in the log is not working due to this bug: https://bugzilla.gnome.org/show_bug.cgi?id=680597&lt;br /&gt;
&lt;br /&gt;
= Useful Links =&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTextIter.html#gtk-text-iter-forward-search&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTreeModelSort.html#gtk-tree-model-filter-convert-child-iter-to-iter&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81663</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81663"/>
		<updated>2012-07-25T15:18:16Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;br /&gt;
&lt;br /&gt;
= Useful Links =&lt;br /&gt;
&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTextIter.html#gtk-text-iter-forward-search&lt;br /&gt;
* http://developer.gnome.org/gtk3/3.5/GtkTreeModelSort.html#gtk-tree-model-filter-convert-child-iter-to-iter&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81653</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81653"/>
		<updated>2012-07-25T13:28:03Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Write some text ===&lt;br /&gt;
&lt;br /&gt;
This is the old way to do it:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 layout = self.area.create_pango_layout(title)&lt;br /&gt;
 layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))    &lt;br /&gt;
 size = layout.get_size()&lt;br /&gt;
 tx = x+w/2-(size[0]/pango.SCALE)/2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 self.area.window.draw_layout(gc, tx, ty, layout)&lt;br /&gt;
&lt;br /&gt;
and this is the way that I used to do it with pangocairo:&lt;br /&gt;
&lt;br /&gt;
 title = _(&#039;You finished!&#039;)&lt;br /&gt;
 pango_cr = pangocairo.CairoContext(cr)&lt;br /&gt;
 pango_cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 pango_layout = cr.create_layout()&lt;br /&gt;
 pango_layout.set_font_description(pango.FontDescription(&#039;Serif Bold 16&#039;))&lt;br /&gt;
 pango_layout.set_text(title)&lt;br /&gt;
 size = pango_layout.get_size()&lt;br /&gt;
 tx = x + (w / 2) - (size[0] / pango.SCALE) / 2&lt;br /&gt;
 ty = y + 100&lt;br /&gt;
 pango_cr.move_to(tx, ty)&lt;br /&gt;
 pango_cr.show_layout(pango_layout)&lt;br /&gt;
 pango_cr.stroke()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Draw a line ===&lt;br /&gt;
&lt;br /&gt;
This is the old way:&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_line(gc, int(b.x), int(b.y + b.size / 2), &lt;br /&gt;
                            int(b.x), int(b.y + b.size))&lt;br /&gt;
&lt;br /&gt;
and should be replaced by this new way using cairo&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0, 0, 0)&lt;br /&gt;
 cr.move_to(int(b.x), int(b.y + b.size / 2))&lt;br /&gt;
 cr.line_to(int(b.x), int(b.y + b.size))&lt;br /&gt;
 cr.stroke()&lt;br /&gt;
&lt;br /&gt;
=== Draw an arc ===&lt;br /&gt;
&lt;br /&gt;
Old way to do it (notice the second argument of &#039;&#039;draw_arc&#039;&#039;: &#039;&#039;&#039;filled&#039;&#039;&#039;):&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(b.color[0],b.color[1],b.color[2])&lt;br /&gt;
 self.area.window.draw_arc(gc, True, x-b.size/2, y-b.size/2, b.size, b.size, 0, 360*64)&lt;br /&gt;
&lt;br /&gt;
new way:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(b.color[0], b.color[1], b.color[2])&lt;br /&gt;
 cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; tricks ==&lt;br /&gt;
&lt;br /&gt;
=== Convert cairo.Surface to GdkPixbuf ===&lt;br /&gt;
&lt;br /&gt;
 import StringIO&lt;br /&gt;
&lt;br /&gt;
 surface = cairo.ImageSurface(cairo.FORMAT_RGB24, w, h)&lt;br /&gt;
 cr = cairo.Context(surface)&lt;br /&gt;
&lt;br /&gt;
 [... draw something into the surface ...]&lt;br /&gt;
&lt;br /&gt;
 pixbuf_data = StringIO.StringIO()&lt;br /&gt;
 surface.write_to_png(pixbuf_data)&lt;br /&gt;
 pxb_loader = gtk.gdk.PixbufLoader(image_type=&#039;png&#039;)&lt;br /&gt;
 pxb_loader.write(pixbuf_data.getvalue())&lt;br /&gt;
 temp_pix = pxb_loader.get_pixbuf()&lt;br /&gt;
 pxb_loader.close()&lt;br /&gt;
&lt;br /&gt;
=== Paint a GdkPixbuf into the canvas ===&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_pixbuf(self.backgroundpixbuf, 0, 0)&lt;br /&gt;
 cr.rectangle(x, 0, self.backgroundpixbuf.get_width(),&lt;br /&gt;
              self.backgroundpixbuf.get_height())&lt;br /&gt;
 cr.paint()&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81652</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81652"/>
		<updated>2012-07-25T13:17:14Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Port to Cairo */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 0-65535 and the &#039;&#039;set_source_rgb&#039;&#039; method from cairo are between 0-1, so we have to convert these values as well:&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
Note that the second attributo of &#039;&#039;draw_rectangle&#039;&#039; tells us about if the rectangle is filled or not. In this case is True, so we use &#039;&#039;cr.fill()&#039;&#039; in the new way but if we want just the outside lines of the rectangle we should use &#039;&#039;cr.stroke()&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81651</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81651"/>
		<updated>2012-07-25T13:09:11Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3772 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Port to Cairo =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
== Code Snippets ==&lt;br /&gt;
&lt;br /&gt;
=== Draw a rectangle ===&lt;br /&gt;
&lt;br /&gt;
To draw a rectangle we used to do:&lt;br /&gt;
&lt;br /&gt;
 gc = self.window.new_gc()&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(50000, 50000, 50000)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, True, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
The arguments for &#039;&#039;alloc_color&#039;&#039; are between 1-&lt;br /&gt;
&lt;br /&gt;
now, with cairo we should do something like this&lt;br /&gt;
&lt;br /&gt;
 cr.set_source_rgb(0.762, 0.762, 0.762)&lt;br /&gt;
 cr.rectangle(x, y, w, h)&lt;br /&gt;
 cr.fill()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 gc.foreground = self.area.get_colormap().alloc_color(0, 0, 0)&lt;br /&gt;
 self.area.window.draw_rectangle(gc, False, x, y, w, h)&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;br /&gt;
&lt;br /&gt;
= Useful links =&lt;br /&gt;
&lt;br /&gt;
* http://cairographics.org/documentation/pycairo/2/index.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/pangocairo-class-reference.html&lt;br /&gt;
* http://www.pygtk.org/docs/pygtk/class-gdkdrawable.html&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81442</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81442"/>
		<updated>2012-07-23T13:05:19Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;README&#039;&#039;&#039;: before to port this activity to GTK3, we should port it to Cairo as the first step and then move to GTK3.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81439</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81439"/>
		<updated>2012-07-23T12:30:15Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
= Gdk.Keymap =&lt;br /&gt;
&lt;br /&gt;
 entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 valid, entries = self.keymap.get_entries_for_keyval(keyval)&lt;br /&gt;
&lt;br /&gt;
Every entry was a tuple of (keycode, group, level). Now, this is an object with those attributes.&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81251</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81251"/>
		<updated>2012-07-19T14:25:12Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
 self.lessonbuffer = Gtk.TextBuffer.new(self.tagtable)&lt;br /&gt;
 self.lessontext = Gtk.TextView.new_with_buffer(self.lessonbuffer)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81249</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81249"/>
		<updated>2012-07-19T14:22:30Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;br /&gt;
&lt;br /&gt;
= Gtk.TextTag =&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag(&#039;instructions&#039;)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 instructions_tag = Gtk.TextTag.new(&#039;instructions&#039;)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81248</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81248"/>
		<updated>2012-07-19T14:17:12Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Gtk.DrawingArea ==&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original)&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 self.layout = self.create_pango_layout(&#039;&#039;)&lt;br /&gt;
 self.layout.set_text(self.title_original, len(self.title_original)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81247</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81247"/>
		<updated>2012-07-19T14:05:32Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.Style.fg_gc ==&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg_gc[Gtk.StateType.NORMAL]&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 gc = self.get_style().fg[Gtk.StateType.NORMAL]&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81246</id>
		<title>Features/GTK3/Porting/Typing Turtle</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Typing_Turtle&amp;diff=81246"/>
		<updated>2012-07-19T14:04:13Z</updated>

		<summary type="html">&lt;p&gt;Humitos: Created page with &amp;quot;This page is being performed while I&amp;#039;m porting Typing Turtle Activity to Gtk3.  There is a [ticket] with some useful information that I&amp;#039;m using on the porting and to keep trac...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Typing Turtle Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingLog&amp;diff=81202</id>
		<title>User:Humitos/PortingLog</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=User:Humitos/PortingLog&amp;diff=81202"/>
		<updated>2012-07-18T14:33:25Z</updated>

		<summary type="html">&lt;p&gt;Humitos: moved User:Humitos/PortingLog to Features/GTK3/Porting/Log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Features/GTK3/Porting/Log]]&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81201</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81201"/>
		<updated>2012-07-18T14:33:25Z</updated>

		<summary type="html">&lt;p&gt;Humitos: moved User:Humitos/PortingLog to Features/GTK3/Porting/Log&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81198</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81198"/>
		<updated>2012-07-18T14:15:44Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Missing things */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81197</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81197"/>
		<updated>2012-07-18T14:08:02Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Clipboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Copy button doesn&#039;t work&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81196</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81196"/>
		<updated>2012-07-18T14:07:43Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Clipboard =&lt;br /&gt;
&lt;br /&gt;
* Gtk3: http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html&lt;br /&gt;
** http://developer.gnome.org/gtk3/3.5/GtkTextBuffer.html#gtk-text-buffer-copy-clipboard&lt;br /&gt;
&lt;br /&gt;
To integrate the clipboard of the activity with the &#039;&#039;MAIN&#039;&#039; clipboard (the Sugar one) we should obtain that clipboard:&lt;br /&gt;
&lt;br /&gt;
 # Clipboard of the activity&lt;br /&gt;
 self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)&lt;br /&gt;
&lt;br /&gt;
And then, when the &#039;&#039;Copy&#039;&#039; button is pressed we should call this function (in the callback). The &#039;&#039;self.viewer.&#039;&#039;&#039;&#039;&#039;active_log&#039;&#039;  is a Gtk.TextBuffer&lt;br /&gt;
&lt;br /&gt;
 self.viewer.active_log.copy_clipboard(self.clipboard)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Copy button doesn&#039;t work&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81192</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81192"/>
		<updated>2012-07-18T13:29:14Z</updated>

		<summary type="html">&lt;p&gt;Humitos: /* Code Snippets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
== Gtk.TreeSortable.set_sort_func ==&lt;br /&gt;
&lt;br /&gt;
* http://python-gtk-3-tutorial.readthedocs.org/en/latest/treeview.html#Gtk.TreeSortable.set_sort_func&lt;br /&gt;
&lt;br /&gt;
This function sometimes receives &#039;&#039;user_data&#039;&#039; so we need to add an optional argument to the definition.&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb):&lt;br /&gt;
&lt;br /&gt;
replaced by:&lt;br /&gt;
&lt;br /&gt;
 def _sort_logfile(self, treemodel, itera, iterb, user_data=None):&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Copy button doesn&#039;t work&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81191</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81191"/>
		<updated>2012-07-18T13:22:42Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
* gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
* Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;br /&gt;
&lt;br /&gt;
= Missing things =&lt;br /&gt;
&lt;br /&gt;
* Copy button doesn&#039;t work&lt;br /&gt;
* Look for a &#039;&#039;&#039;FIXME&#039;&#039;&#039; in the code (logviewer.py)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
	<entry>
		<id>https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81190</id>
		<title>Features/GTK3/Porting/Log</title>
		<link rel="alternate" type="text/html" href="https://wiki.sugarlabs.org/index.php?title=Features/GTK3/Porting/Log&amp;diff=81190"/>
		<updated>2012-07-18T13:07:30Z</updated>

		<summary type="html">&lt;p&gt;Humitos: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is being performed while I&#039;m porting Log Activity to Gtk3.&lt;br /&gt;
&lt;br /&gt;
There is a [http://bugs.sugarlabs.org/ticket/3761 ticket] with some useful information that I&#039;m using on the porting and to keep tracking this port. Besides, this wiki page will be useful to write some code snippets about what are the difficulties that I&#039;m having on the port and maybe can be useful for someone else.&lt;br /&gt;
&lt;br /&gt;
I will take [[User:Humitos/PortingGetBooks|this guide]] as reference on the Gtk3 porting.&lt;br /&gt;
&lt;br /&gt;
= Code Snippets =&lt;br /&gt;
&lt;br /&gt;
== Gtk.TextView ==&lt;br /&gt;
&lt;br /&gt;
 * gtk2: http://www.pygtk.org/docs/pygtk/class-gtktextview.html#method-gtktextview--scroll-to-mark&lt;br /&gt;
 * Gtk3: http://developer.gnome.org/gtk3/3.5/GtkTextView.html#gtk-text-view-scroll-to-mark&lt;br /&gt;
&lt;br /&gt;
Gtk.TextView.scroll_to_mark needs all the arguments. In gtk2 version three of them were optional (use_align, xalign, yalign)&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0)&lt;br /&gt;
&lt;br /&gt;
replaced with:&lt;br /&gt;
&lt;br /&gt;
 self._textview.scroll_to_mark(log.get_insert(), 0, use_align=False, xalign=0.5, yalign=0.5)&lt;/div&gt;</summary>
		<author><name>Humitos</name></author>
	</entry>
</feed>