GTK3 code sprint, Rosario (3)

December 9th, 2011

Today was another productive day!

We did finish installing all the rpms on the XO and installed the latest Browse activity who have been ported to GTK3 and Webkit and Read who has been moved to evince with gobject-introspection and to GTK3 as well.

So today we finally put our theme in the XO:

You can see the current status here.

We have two activities for testing, both show the same widgets, one using gtk2 and the other gtk3.

We are facing things that should be done in upstream GTK+3 and gnome-themes-standard before we can use them, like styling the up and down arrows of the spin button, for example. This is needed if we want to preserve the look and the size of the original sugar theme, or even improve it for touch interaction, for example. It seems to be done in git already!

Radio buttons and check buttons have been styled and there are pseudo-classes that can be used to match different states of a widget. For example:

.radio,
.radio row:selected,
.radio row:selected:focused {
    background-image: url("assets/radio-unselected.svg");
}
.radio:active,
.radio row:selected:active,
.radio row:selected:focused:active {
    background-image: url("assets/radio-selected.svg");
}

There are also particular options for the widgets, like this one that sets
the size of the check indicator (and also the radio indicator, because it
inherits from the check):

* {
    -GtkCheckButton-indicator-size: 26; /* $radio_size */
}

The comment in that line is to indicate that we should change that value, 26, for the $radio_size variable in our CSS template.

I did make a quick check if the latest librsvg can be backported in jhbuild, does not seem to be so easy because it depends on the latest libpng (see). I also did a quick check if the new librsvg does provide what we need on the XO. The code in icon.py in the toolkit would be translated to something like this:

from gi.repository import Rsvg
f = open('lala.svg')
icon = f.read()
Rsvg.Handle.new_from_data(icon)
Rsvg.Handle.new_from_file('lala.svg')

I uploaded the Hello-world gtk3 version (version 4) to ASLO some time ago and marked it 0.96 only. However it did not appear when browsing the page. With the help from Aleksey I found out that ASLO is parsing the user agent of the Browser to provide appropriate activity version, if it fails to get the SP version from the agent string, it uses the last stable, which is 0.94 at the moment. A quick hack with adding “Sugar Labs/0.96″ to the user agent string in Browse had the expected result (API refs: webkit-web-view-set-settings, WebKitWebSettings–user-agent).

@@ -386,7 +390,9 @@ class Browser(WebKit.WebView):
     def __init__(self):
         WebKit.WebView.__init__(self)
-
+        s = WebKit.WebSettings()
+        s.props.user_agent = 'Mozilla/5.0 (X11; Linux i686)' \
                              'AppleWebKit/535.4+ (KHTML, like Gecko)' \
                              'Version/5.0 Safari/535.4 Sugar Labs/0.9'
+        self.set_settings(s)

GTK3 code sprint, Rosario (2)

December 9th, 2011

Today we kept on poking at the theme. Gonzalo patched the sugar-toolkit and the theme to allow for the two sugar scaling factors being reflected in the gtk-widgets.css and the setting.ini. We install two themes now and the base activity class checks the ‘SUGAR_SCALING’ environment variable to load the theme accordingly.

GTK3 code sprint, Rosario (1)

December 8th, 2011

Gonzalo, Manuel and myself are here in Rosario (Argentina) having a code sprint for the gtk3 port. We have been lucky in finding a great place for the code sprint, the njambre provides us with perfect working conditions during the next days.

The first day we made a plan what to work on. We decided to focus on the theme and the toolkit in the next days. For the theme we wanted to solve the following issues:

  • find out if it is possible to have a theme independent of the screen resoltion
  • usage of svgs for widgets (e.g. check boxes, radio buttons)
  • make the slider look the same as with the old theme

The first day Gonzalo dived into finding out if the theme can be done in a way independent from the screen resolution. At the moment we are supporting two different scales in Sugar. Sadly this is not possible now, a summary of the evaluation can be found in Gonzalo’s mail.

In the meantime Manuel looked at the usage of svgs for widgets (so called assets), looking at how this is done in the Adwaita theme. The example below uses a svg as the background image for the radio buttons.

from gi.repository import Gtk
from gi.repository import Gdk

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets2.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
                                Gtk.STYLE_PROVIDER_PRIORITY_USER)

main_box = Gtk.VBox()
window.add(main_box)
box = Gtk.HBox()
main_box.add(box)
item1 = Gtk.RadioButton.new_with_label_from_widget(None, "One")
item2 = Gtk.RadioButton.new_with_label_from_widget(item1, "Two")
item3 = Gtk.RadioButton.new_with_label_from_widget(item1, "Three")
box.pack_start(item1, False, False, 5)
box.pack_start(item2, False, False, 5)
box.pack_start(item3, False, False, 5)
box2 = Gtk.HBox()
main_box.add(box2)
checkbutton = Gtk.CheckButton('Check')
box2.pack_start(checkbutton, False, False, 5)
window.show_all()
Gtk.main()

In the style sheet we define to display the svg as the background image for all the widgets defining the class ‘radio’.

.radio {
    background-image: url("assets/lala.svg");
}

I did package our current repos for the gtk3 port to be able to run it on the XO with Peter’s latest F17 build. The shell package containing the changes to make sugar-activity independent of sugar-toolkit GTK versions, the gtk2 toolkit with the changes needed for the shell change, the new gtk3 toolkit and the gtk3 theme (sugar-artwork).

gobject-introspection with pylint/pyflakes

November 30th, 2011

So, I have been using pylint quite a lot in the last years to find the ‘easy-errors’ in the code and it has been a great tool since then. We are currently moving Sugar to gobject-introspection/gtk3 and from what I can see pylint does not support dealing with gobject-introspection:


************* Module test
C: 1: Missing docstring
E: 1: No name 'Gtk' in module 'gi.repository'
W: 1: Unused import Gtk

I googled a bit around and did a quick grep over the pylint code but they don’t seem to support it. I came across pyflakes (as well the name of the Fedora package) and give it a quick try. The output looks promissing so far. Will keep on testing a bit and ask the pylint devs what their plans are…

Update: sent a mail to the pylint devs

Epiphany: open link in new tab

November 29th, 2011

I have been using epiphany under GNOME 3 now for a while to see how a webkit based browser compares to Firefox. The web experience is great so far, here is a work-flow issue that I tried to fix this morning:

By default epiphany opens a new link (for example you click on in a mail) in a new window. There is a configuration you can set to enable to open the link in a new tab in the already existing window. Today epiphany is using gsettings, so you should be able to do “gsettings set org.gnome.Epiphany new-windows-in-tabs true” or use the dconf-editor (org/gnome/empathy).

After setting the config the link si still opened in a new tab, looking at the code it should work :) Would be great to hear from somebody for whom that works if I miss something…

Update: Actually, I figured out that the setting was about something else than I had thought: It means that popup windows are opened in a new tab, an example is here: http://dev.laptop.org/~erikos/wanted.html.

I still wonder why opening in a new window is the defauly behavior in the GNOME shell for Epiphany (this makes window management very hard), Firefox is doing the right thing and open it in a new tab.

GTK+ 3 theme: style your applications (2)

November 24th, 2011

After the first introduction yesterday, let’s go through more of the examples on the GtkCssProvider page and try them out.

Instead of applying a style to a widget type (e.g. GtkButton) we would like to specify a style for one specific button now, our from GtkButton derrived Button.

from gi.repository import Gtk
from gi.repository import Gdk

class MyButtonClass(Gtk.Button):
    __gtype_name__ = 'MyButton'
    def __init__(self, label):
        Gtk.Button.__init__(self, label)

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets3.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
                                Gtk.STYLE_PROVIDER_PRIORITY_USER)

box = Gtk.VBox()
window.add(box)
button = Gtk.Button('go-next')
box.pack_start(button, False, False, 0)
mybutton = MyButtonClass('go-next')
box.pack_start(mybutton, False, False, 0)

window.show_all()
Gtk.main()

In the style sheet we define the style for that specific button, we use the gtype name for that. The ordering of the rules is important here. The more specific rule (MyButton) must come after the general one (GtkButton).

GtkButton, GtkEntry {
    color: #ff00ea;
    font: Comic Sans 12
}

MyButton {
    color: #00ffea;
    font: Comic Sans 8
}

The next example will handle Style classes. Widgets may define style classes , which can be used for matching. In the next example we will have two widgets both defining the ‘entry’ style class, GtkEntry and GtkSpinButton. First the test application:

from gi.repository import Gtk
from gi.repository import Gdk

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets4.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
                                Gtk.STYLE_PROVIDER_PRIORITY_USER)

box = Gtk.VBox()
window.add(box)

adj = Gtk.Adjustment(1.0, 1.0, 31.0, 1.0, 5.0, 0.0)
button = Gtk.SpinButton.new(adj, 0, 0)
box.pack_start(button, False, False, 0)

entry = Gtk.Entry()
box.pack_start(entry, False, False, 0)

window.show_all()
Gtk.main()

Now, let’s look at the style sheet: Both widgets should have the same background color but the entry color should be different. So we define that all widgets defining the class entry should have the same ‘background-color’ and the same ‘color’. Then in the next rule we define that the GtkSpinbutton’s color should be different. Syntax: when used in a selector, style classes must be prefixed with a ‘.’ character.

/* Theme all widgets defining the class entry */
.entry {
    background-color: #d7d4d4;
    color: #457ede;
}

/* Theme spinbuttons' entry */
GtkSpinButton.entry {
    color: #e51331
}

The next section in the GtkCssProvider examples handles pseudo-classes: “In complicated widgets like e.g. a GtkNotebook, it may be desirable to style different parts of the widget differently. To make this possible, container widgets may define regions, whose names may be used for matching in selectors.

Some containers allow to further differentiate between regions by applying so-called pseudo-classes to the region. For example, the tab region in GtkNotebook allows to single out the first or last tab by using the :first-child or :last-child pseudo-class. When used in selectors, pseudo-classes must be prefixed with a ‘:’ character.

Refer to the documentation of individual widgets to learn which regions and pseudo-classes they define and see the section called “Style classes and regions” for a list of all regions used by GTK+ widgets.”

Here is an example using a GtkNotebook:

from gi.repository import Gtk
from gi.repository import Gdk

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets5.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
                                Gtk.STYLE_PROVIDER_PRIORITY_USER)

box = Gtk.VBox()
window.add(box)

nb = Gtk.Notebook()
box.pack_start(nb, False, False, 0)

for i in range(5):
    bufferf = "Prepend Frame %d" % (i+1)
    bufferl = "Page %d" % (i+1)

    frame = Gtk.Frame()
    frame.set_border_width(10)
    frame.set_size_request(100, 75)
    label = Gtk.Label(bufferf)
    frame.add(label)
    label.show()

    label2 = Gtk.Label(bufferl)
    nb.append_page(frame, label2)
    frame.show()

window.show_all()
Gtk.main()

The style sheet looks like this:

/* Theme any label within a notebook */
GtkNotebook GtkLabel {
    color: #f90192;
}

/* Theme labels within notebook tabs */
GtkNotebook tab GtkLabel {
    color: #703910;
}

/* Theme labels in the any first notebook
 tab, both selectors are equivalent */
GtkNotebook tab:nth-child(first) GtkLabel,
GtkNotebook tab:first-child GtkLabel {
    color: #89d012;
}

GTK+ 3 theme: style your applications

November 23rd, 2011

The GTK+ 3 theme works a bit differently then the old one. The theming information is written in a CSS-like format that can be passed to a GtkCssProvider.

Here are two simple example to style the widgets in your GTK+ 3 application using the GtkCssProvider and GtkStyleContext.

The first example sets the background color of the GtkWindow, we do get the GtkStyleContext from the widget and set it’s style then using the ‘add_provider’ method which we pass the GtkCssProvider that read in the stylesheet.

from gi.repository import Gtk

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)
style_context = window.get_style_context()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets1.css')

style_context.add_provider(css_provider,
                           Gtk.STYLE_PROVIDER_PRIORITY_USER)

window.show()
Gtk.main()

The style sheet for the first example looks like this, the background of the GtkWindow is set.

GtkWindow {
    background-color: #ff00ea;
}

In the second example we do set the global style for all of the screen, in the first example we did only set the style for one widget.

from gi.repository import Gtk
from gi.repository import Gdk

def _destroy_cb(widget, data=None):
    Gtk.main_quit()

window = Gtk.Window()
window.connect("destroy", _destroy_cb)

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('gtk-widgets2.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
                                Gtk.STYLE_PROVIDER_PRIORITY_USER)

box = Gtk.VBox()
window.add(box)
button = Gtk.Button('go-next')
box.pack_start(button, False, False, 0)

window.show_all()
Gtk.main()

The style sheet for the second example looks like this, we set the color and the font of the GtkButton and GtkEntry. We could have used the so called universal selector ‘*’ as well here.

GtkButton, GtkEntry {
    color: #ff00ea;
    font: Comic Sans 12
}

GTK3, gobject-introspection part two

November 4th, 2011

This last weekend we had the GTK-3 hackfest in Prague. Upfront: it was a great success!

It was a meeting of the past in some ways as we had old-time hackers like Tomeu, Marco and Benjamin present. Marco and Benjamin peared up as the ‘Palette People’ and wrapped their had around this delicate issue to port the palettes over, a summary of the current status can be found in this email thread. Benjamin did as well initial work on the theme with Daniel, you can checkout the work in the branch ‘gtk3′ in the mainline sugar-artwork repository containing the new theme work (folder gtk3).

Raul and myself did work in the toolkit porting and did move sugarext to introspection with the help from Tomeu. Raul did as well more ‘wrapping’ work to access X11 window properties. Since the GdkDrawable has been removed in GTK+ 3, activities have to been ported to use Cairo instead. Walter did port TurtleArt and Abacus with Raul to Cairo, good that we had knowledge in the team with Benjamin to figure out bits here and there.

Daniel was as always all over the place, did coordinate the hacking and worked on upstreaming stuff. Tomeu as the link to pygobject helped us to figure the right approaches for several issues and worked on related issues to write a custom widget.

We also had the Freudenbergs at the event, Bert has been working on switching Etoys to use telepathy directly (kill the PS for real!) and Rita and Martin did work in the Sugar with touchscreen area.

If you want to get started as well hacking on this, documentation can be found at the development page of the GTK3 feature page. Instructions for porting activities over to GTK3 can be found at the porting page.

Bridging future gaps – bringing Sugar to Gtk-3

January 19th, 2011

I am currently attending the Python2011 Hackfest in Praha. As Gtk-3 and GNOME 3.0 are approaching quickly a fine group of hackers gathered to identify the issues that may arise for “PyGtk” application developers using the latest GNOME 3.0 platform.

The static python bindings for GTK are replaced by the dynamic bindings gained through introspection – and identifying consumers issues and fixing them is what the hackfest is about.

I am continuing Tomeu’s work on replacing hippo by using standard Gtk.Containers. I bumped into an issue that did not let me use the standard constructor of the Gdk.Window because it had been made abstract. As this has been done by design we decided to map the new constructor to the standard constructor in the override, reflected by 639936. So, close to getting my first patch into the repo ;p

An interesting side effect is that I get to use git bz a tool for integrating the Git command line with the Bugzilla bug-tracking system. This eases the workflow for submitting patches, reviewing them and updating the status, everything can be made from the command line. Would be great to have something similar for trac and Sugarlabs/OLPC.

Point to the gnome bug tracker:

git config bz.default-tracker bugzilla.gnome.org

File the latest commit as a ticket:

git bz file pygobject/introspection HEAD

Apply the patch from ticket 639936:

git bz apply bugzilla.gnome.org:639936

Attach a new patch to ticket 639936:

git bz attach bugzilla.gnome.org:639936 HEAD

Let’s see when I get to know the ‘fixed’ command…

My trip is kindly sponsored by the GNOME Foundation. Collabora was kind enough to sponsor our event as well, and brmlab a hacker place to the cbase in Berlin is hosting our daily hack sessions.

Collabora

Scratch: “flip horizontally”

December 2nd, 2010

We are using Scratch to develop a jump-and-run like game. The first part is to make it possible to control a character with the arrow keys. Combining the block “when key pressed” with the block “change X/Y by value” let’s us easily do this.

The second part was a bit more difficult. When hitting the left arrow key I wanted the character to turn around before moving to make it more realistic. One of my students had a nice idea to accomplish that. In the “Costumes” section for the object you can edit the sprite. There is an option at the top to “flip horizontally”. So you make two versions of your sprite and change the sprite accordingly on key press.

Lesson of today: the learners are a great source for finding solutions!

Amendment from Bert: For computer animated sprites you can set a mode how to let them bounce of the edge. One can set ‘can rotate’ (freely), “only face left-right” and “don’t rotate” for the sprite.