Articles

From “power on” to “gtk GUI usable” as fast as possible

In gtk+, Programming, raspberry pi on November 22, 2015 by oli4444

In my Raspberry Pi + Hifiberry-amp + Pitft project I’ve been looking how to speed up the boot process.

[edit] I updated various parts of this post with suggestions from the comments. [/edit]

The original boot process took around 60 seconds from “power on” until my gtk app was visible and responding. I used the original (Wheezy based) raspbian, with autologon on tty1, and in the .bash_profile I called startx. In /home/pi/.xinitrc I started my application without starting a display manager:
#!/bin/sh
PYTHONIOENCODING=utf_8
export PYTHONIOENCODING
exec /usr/bin/python /home/pi/sqgui2.py

(b.t.w. the PYTHONIOENCODING is there otherwise python will give an exception when calling print with a non-ascii unicode character)

By removing a few services from the init process I removed 10 seconds from the boot process. Still 50 seconds. But further options on Raspbian Wheezy are limited.

Next step was to move to Raspbian Jessie, which has systemd. This gave an unwanted side effect: the hifiberry was detected correctly, but did not produce any sound anymore. Removing a line added for the pitft device_tree=bcm2708-rpi-b-plus.dtb from /boot/config.txt fixed this problem. And the pitft is still working.

In systemd I can start X11 as soon as userspace is running. However this generated an error – the touchscreen device has to be available first. The touchscreen input is in udev configured as /dev/input/touchscreen. I created /etc/systemd/system/xinit-login.service with the following content:
[Unit]
Wants=dev-input-touchscreen.device
After=dev-input-touchscreen.device
DefaultDependencies=false
[Service]
Type=simple
ExecStart=/bin/su pi -l -c /usr/bin/xinit -- VT08
WorkingDirectory=/home/pi/
[Install]
WantedBy=local-fs.target

[edit] with suggestions from the comments in now looks like:

[Unit]
Wants=dev-input-touchscreen.device
After=dev-input-touchscreen.device
DefaultDependencies=false
[Service]
Type=simple
ExecStart=/usr/bin/xinit
WorkingDirectory=/home/pi/
User=pi
Group=Users
Environment=PYTHONIOENCODING=utf_8
[Install]
WantedBy=local-fs.target

and .xinitrc is now a hardlink to the gtk application sqgui.py [/edit]

This makes my xinit session start directly after the touchscreen device is available. This reduced the startup time to 28 seconds. Much better! (b.t.w. I haven’t look if all entries in xinit-login.service are correct, perhaps the contents can be improved).

Systemd has a good tool called systemd-analyze which analyzes the boot process. That way you can easily see which parts take too much time. That helped me to strip off another 2 seconds. An interesting question is how the udev config can be improved to create the touchscreen device earlier in the boot process. Another interesting question is how X11 can be configured to start faster, or how python + gtk3 can be configured to start faster. If you have any suggestions please leave them in the comments.

Next thing was to make the system readonly. I installed busybox-syslogd instead of rsyslogd, since it can do in-memory logging. [edit] I now switched to systemd-journald for in memory logging [/edit]

I analyzed which directories changed after a reboot, and moved those to a tmpfs in-memory filesystem. The /etc/fstab now looks like:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,ro 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime,ro 0 1
tmpfs /tmp tmpfs defaults,noatime 0 0
tmpfs /var/lock tmpfs defaults,noatime 0 0
tmpfs /var/lib/dhcpcd5 tmpfs defaults,noatime 0 0
tmpfs /var/log tmpfs defaults,noatime 0 0

Possibly this can be optimized with a single tmpfs mount and symlinks to reduce the mount time of 4 tmpfs filesystems.

[edit] did that, they are all symlinks to /tmp now [/edit]

The only remaining issue that I didn’t solve yet is handling of /etc/resolv.conf when moving the setup to a different network. Because /etc/ is readonly the resolv.conf is now fixed for my local wifi network.

[edit] disabling the UART, and moving from the debian networking scripts to systemd-networkd reduced the boot time to 21 seconds! [/edit]

Articles

A search interface in a 320×240 touchscreen

In gtk+, open source, Programming, raspberry pi on October 24, 2015 by oli4444

Last evenings I spent some time on my raspberry pi + hifiberry amp + piTFT + squeezebox project. Previously I created the interface to load a predefined playlist, and to control basics like volume and time. I also finished the integration of the display in the top of the Mission 731i speaker and placed the pi and amp inside the box (will post some pictures soon).

gui

This time I wanted to extend the user interface with a feature to search and browse in the mp3 collection. But that immediately raised the question: what kind of interface works best for a small screen size (320×240) and touch input (no keyboard, no mouse)? A possibility was a virtual keyboard with a entry or a combo, but my first mockup in glade resulted in 300×140 pixels just for the keyboard – leaving very little space for the search results. So I tried a treeview so the user can quickly scroll through the results. To reduce the number of results I added a combo with a prefix (a-z0-9) to the top.
search gui
The results work reasonably well, but there are some issues to resolve.

First of all the scrolling in the GtkTreeView is not using “kinetic scrolling” (you can’t scroll like you normally do on a touchscreen) although I enabled kinetic scrolling for the GtkScrolledWindow parent in glade. Scrolling using the scrollbar on the side works, but kinetic scrolling would work better.

Second, most touchscreen users kind of expect the context menu when you hold your finger for a while. I hoped this was automatically translated to a right-click, but that doesn’t work. So I have to find a way now to catch these events for the context menu’s (anybody a hint how to do this?).

The last issue I have is not related to the touchscreen. I have some scaling layout issues, sometimes a multiline label with a long text forces some buttons off the screen.
screenshot
So I also have to find out how ellipsize works with multiline labels.

Articles

raspberry pi, hifiberry, piTFT with gtk GUI

In Uncategorized on September 22, 2015 by oli4444

I bought a hifiberry amp (a 2x25W class D amplifier with a fully digital path from the raspberry) and a PiTFT 2.8″ touchscreen. I’m planning to integrate them with my raspberry pi model B inside in a set of Mission 731i speakers. That will give me a set of powered speakers that can stream music over a wifi network, with a touchscreen interface.

First thing to do was to connect both the hifiberry amp and and pitft to the same raspberry. They are designed to run exclusively on top of a raspberry, but they use different pins, except for the 5V power pin. So after wiring them carefully with jumper cables I managed to run them simultaneously.

raspberry-pi-rev2-gpio-pinout-pitft-hifiberry-amp

The raspberry will run squeezelite, so it will act as a squeezebox player. Squeezelite is a headless application, so it does not provide any interface that can be controlled from the touchscreen. The sqeezelite player is controlled by a squeezebox server (also called logitech media server).

I decided to build a GTK app with glade and python to run on the touchscreen (and obviously I’ll use Bluefish to do the python coding). I previously used pygtk or gtk with C, so first I had to learn the new way to use gtk3 in python, but that turned out to be fairly simple. I start the app in .xinitrc without any window manager or decorations, so it runs fullscreen without any possibility to switch to another application. Startx is called from .profile if the tty is tty1, and tty1 is set for auto-logon – so power on means boot, X and then the app.

The app also has to control the squeezelite process. I created an gtk timer callback check_processes() that is called every second and checks if the squeezelite process is still running:

   def start_procsqueezelite(self):
            try:
                    self.procsqueezelite = subprocess.Popen([config['squeezelite'], '-n', 'SqueezeSpeaker'])
            except OSError as err:
                    print 'error starting',config['squeezelite'],err                

    def check_processes(self):
            if (self.procsqueezelite):
                    ret = self.procsqueezelite.poll()
            else:
                    ret = 255
            if (ret != None):
                    self.start_procsqueezelite()
            return 1

Second challenge was to control the squeezebox server from the app. Luckily the squeezebox server uses a very simple protocol, a tcp connection to port 9090 with ascii line based commands and urlencoded results. The next button can simply send the command “aa:bb:cc:dd:ee:ff playlist index +1”, pause sends “aa:bb:cc:dd:ee:ff playlist mode pause”, etc. Basic functionality was working quickly.

However, any squeezebox player can be controlled from any device (smartphone, tablet, etc.), so another device might be changing the volume, pressing pause, etc. and my app should display the new corresponding status. The squeezebox server has a “listen” command for that, this will send any event over the tcp connection, again line based and urlencoded. I chose to open a second tcp connection. To make the application respond quickly, both when doing socket I/O and responding to GUI events, I run the connections in separate threads. The commands are put into a python Queue, and the threads send their results to the mainloop using an idle callback. In the idle callback I use regex matching to find the interesting events and update the GUI accordingly.

Something that took me some time (and then turned out to be very simple) was how to load the album covers in the GTK GUI. The Squeezeserver has them available over http. The dirty approach was to download them, and then load them from file. The nice way is to download them to memory and load them into the widget. The http loading has again a separate thread, which again sends the loaded data with an idle callback to the mainloop. This is the idle callback:

       def artwork_handler(self,imgdata):
                image = self.builder.get_object('coverimage')
                pbl = GdkPixbuf.PixbufLoader()
                pbl.set_size(80,80)
                try:
                        pbl.write(imgdata)
                        image.set_from_pixbuf(pbl.get_pixbuf())
                except:
                        print 'artwork_handler, failed to parse image data'
                pbl.close()
                return 0

The resulting app looks like this when running on my desktop:
screenshot

I’ll probably use a dark theme when running on the PiTFT. More on this project later, and I’ll publish the full code soon.

Statuses

backwards rendering compatibility

In Bluefish, gtk+, open source, Programming on July 3, 2015 by oli4444

The last year I didn’t keep up with the latest GTK versions. With less time to code, installing new software was not my priority, so I did most of my programming on a machine running Ubuntu LTS.

Last week I had some spare time and I installed the latest Fedora. I installed the same Bluefish version (the latest, 2.2.7) but to my surprise some bits didn’t look as good anymore. Bluefish has a sidebar with several plugins, each in a GtkNotebook tab. This normally looks like this:

small_icons_tabs

But on the latest and greatest Fedora, it looks like this, instead of showing all the icons, only two are visible, unless you make the sidebar extremely wide:

sidebar-new-gtk

This makes me wonder if GTK has something like “backwards rendering compatibility testing”: see if applications that were not developed for the latest GTK release still look good and function properly. I have no idea if this could be done in an automatic way, but there are probably brighter people around that do have an idea how to do this.

b.t.w. I haven’t found a way yet to change my code in such a way that all icons become visible again. If anybody is willing to drop me a hint how to get all icons back in the original space I will be happy 🙂

Statuses

Bluefish 2.2.7 released

In Bluefish, open source on February 6, 2015 by oli4444

Bluefish 2.2.7 is mostly a bug fix release. It fixes rare crashes in the autocompletion, the filebrowser, the htmlbar plugin preferences, in file-load-cancel, and fixes a rare case of broken syntax highlighting after multiple search/replace actions. It furthermore displays better error/warning output when parsing language files. It also finally fixes javascript regex syntax highlighting. The loading of files with corrupt encoding or non-printable characters (such as binary files) has been improved, and project loading over sftp has been improved. Various HTML5 tags have been added, and HTML5 is the default now for php, cfml and other languages that can include html syntax. Saving and loading of UTF-16 encoded files was broken and has been fixed. Various languages have better syntax support, such as javascript, css, html, pascal/deplhi, and html has improved autocompletion. On OSX the charmap plugin is finally included, the keys for tab switching no longer confict with some keyboard layouts, and behavior at shutdown was improved. The upload/download feature has a new option to ignore backup files. The home/end keys now work better on wrapped tekst. And finally the search and replace dialog correctly shows the number of results when searching in files on disk.

Statuses

Cross-platform keyboard issues

In Bluefish, gtk+, Programming on October 5, 2014 by oli4444

We often receive bugreports from windows or OSX users with keyboard problems. For example on windows changing the keys ” to ¨ and ‘ to ´. Or on OSX the square brackets [] are not possible on a German keyboard layout (see https://bugzilla.gnome.org/show_bug.cgi?id=737547), or curly braces not on AZERTY layout (see https://bugzilla.gnome.org/show_bug.cgi?id=692721).

From what I understood this is caused by gtk handling the keyboard events itself, instead of waiting for the key-value that the operating system provides.

Is there a way how this can be fixed? Either in Bluefish or in GTK?

Articles

Reducing desktop power usage while idle

In Gnome, Linux desktop, open source on July 14, 2014 by oli4444

While remotely monitoring my desktop session with powertop while it was idle (screensaver active) I noticed that a few processes cause a lot of activity, and keeping the CPU from going into the PC7 state (the complete cpu package deepest sleep state). Most notably firefox and it’s plugin-container cause frequent wakeups.

I wrote a short script that listens on dbus for screensaver ActiveChanged messages, and either sends a STOP or a CONT signal to firefox and the plugin-container. This script makes my desktop go from 20W to 19W of power when I am not using it.


import subprocess
import datetime

import dbus, gobject
from dbus.mainloop.glib import DBusGMainLoop

stoplist = ['firefox', 'plugin-container', 'steam']
def msg2_cb(msg):
	dt = datetime.datetime.now()
	if (msg):
		for name in stoplist:
			subprocess.call(["killall", "-STOP", name])
	else:
		for name in stoplist:
			subprocess.call(["killall", "-CONT", name])

if __name__ == '__main__':
	DBusGMainLoop(set_as_default=True)
	bus = dbus.SessionBus()
	bus.add_signal_receiver(msg2_cb, 'ActiveChanged', None, None, '/org/gnome/ScreenSaver')
	mainloop = gobject.MainLoop ()
	mainloop.run ()

The obvious caveat is that any downloads by firefox are also stopped if the screensaver becomes active.

Articles

Computer hardware

In Hardware on May 21, 2014 by oli4444

I built a new computer last week to replace my old one. My computer is running 24h a days, so I focused on low power hardware with good peak performance. Next to a low-power computer I have a computer built for performance (gaming and heavy development). Because the low power computer is always on, I tend to use it for some quick development as well. Switch on the display, change a few lines of Bluefish code and compile.

The old low power computer, an Athlon X2 2700MHz, idles at about 55W. Compiling Bluefish takes 43s. The performance computer, a Core2 duo 3.3GHz idles at about 83W. Compiling Bluefish takes 25s.

The new computer, a Haswell core i5 3.2Ghz with turbo to 3.6GHz idles at about 20W (if I stop a few services I can get it to 16W!). Compiling Bluefish takes 11s. This basically means I can replace two computers at once! It’s much lower power than my low-power computer, but much faster than my performance computer!

For those interested in building a low-power/high-performance computer the build specs:

  • Intel Core i5 4570
  • ASRock B85M Pro4 (see this review for low power haswell boards, text in Dutch, but the graphs speak for themselves)
  • WD Red SATA 6 Gb/s WD30EFRX, 3TB
  • 16Gb Crucial Ballistix Sport DDR3-1600
  • be quiet! Pure Power L8 300W (see this and this review for power supplies that are efficient in the very low power ranges.)
  • Crucial M500 2,5″ 240GB
  • Gelid Solutions Tranquillo Rev.2
  • Fractal Design Core 1000 USB 3.0

Statuses

Engaging developers

In Bluefish, Gnome, gtk+, open source, Programming on March 22, 2014 by oli4444

As Bluefish developer I’m not really tightly involved with gnome and gtk development. However, it is our platform, and although we ship OSX and Windows binaries, most of our users are on Linux, many of them using Gnome. We are as much affected by a gtk bug than any other gnome part. So if we find any, we try to contribute.

However, for some reason it feels that our “outside” contributions are not so welcome. I believe this is not intentional, but still this is not a good thing. So what makes me feel that these contributions are not so welcome? The lack of feedback and results.

An example: In 2012-09-05 I filed a bugreport https://bugzilla.gnome.org/show_bug.cgi?id=683388 with a patch to improve the GList documentation. I noticed that new developers often make trivial mistakes (for example appending in a loop). I got some feedback and reworked the patch, submitted on 2012-09-12. And then nothing happened anymore. For 1 year and 4 months there was a total silence. I was originally planning to work trough all of the glib documentation to make it easier for novice programmers to work with, but this result was not really motivating me to do any more work on glib. Until on 2014-01-20 the bug was closed with “fixed”. A tiny bit of documentation was added, but the majority of the patch was not committed. Perhaps it was considered low quality, but at least tell the contributer! And tell how to improve it!

A second example: Early this year a reproducible way to crash Bluefish was reported. We realized the bug was not in Bluefish but in Gtk, GtkTreeModelFilter to be more specific. Instead of just filing a bugreport with the problem, we tracked down the problem and found how to fix it, and filed that in bugzilla https://bugzilla.gnome.org/show_bug.cgi?id=722058 For us this is a critical bug. It makes Bluefish crash. It’s now three months later, and nothing has happened. I’m afraid that the next major gtk release will still have this bug, and Bluefish will remain a crappy application because it crashes because of this bug in gtk.

We should improve this! This is not the way to attract new developers! On the contrary, this does discourage new developers!

End note: I realize that I am not heavily involved with gtk or gnome. So there might be many valid reasons why the above two examples are completely wrong. Perhaps my complete feeling about the feedback and results is wrong. Perhaps my expectations are completely unrealistic. But if I have this feeling, there might be more occasional contributing developers that have this feeling. So we could at least then try to explain the true situation.

End note 2: I’m not a native English writer. So if my language was blunt or rude in any way to any person: this was really not intentional and I apologize. I don’t want to attack anyone. I don’t want to complain. I just want to send a signal that we can do better and should do better.

Articles

a new running goal

In Uncategorized on February 5, 2014 by oli4444

Since both my daytime job and my open source programming in the evening involves only brain action, I like to do something physical now and then to empty my head. Around home that usually means running.

Previously I mostly ran the same route – something with little traffic, not too many buildings, and not too few plants and trees. Not a lot of choice around my house.

But I have a new goal now: mapping the wireless networks around my house for the Mozilla Location Service. I installed MozStumbler and now I run with my phone. https://github.com/mozilla/MozStumbler/releases

Every day after I have been running I check the map https://location.services.mozilla.com/map#2/15.0/10.0
which makes me feel good about running another time!