Posts Tagged ‘gtk’

How libxi broke my system

Thursday, April 3rd, 2014

After some package updates I could no longer log into my Debian/XFCE system. The display manager (gdm3) would start to load but show only a black screen and rotating/spinning cursor. There was no login box – no way for me to get to a desktop. Digging through the logs I saw no errors in Xorg.0.log.  Dmesg and the kernel logs were no help either.  My first clue was found in the /var/log/gdm3/:0-greeter.log.* logs. Each of these logs had just one line:

*** Error in `/usr/bin/gnome-session’: malloc(): memory corruption: 0x000000000207c620 ***

A memtest run showed no errors. Reinstalling gnome-session didn’t fix things. Looking at ~/.xsession-errors I found lots of Gtk and GLib errors among strange things like “Discarding: 6 over 9″ and “** Message: applet now removed from the notification area”. Other errors that might have been related:

polkit-gnome-authentication-agent-1: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.
wicd-client.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

orage: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.
nm-applet: Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

In some log (which I’ve forgotten now) I remember finding more “memory corruption” errors but for applications like nm_applet. I tried switching my display manager to lightdm but I got a similar result. Upon boot, I was greeted with a solid black screen. Logs showed that the x-session was started and the greeter as well. In /var/log/lightdm/x-0-greeter.log I found a familiar error:

*** Error in `/usr/sbin/lightdm-gtk-greeter’: malloc(): memory corruption: 0x00007fe0cd2bcd40 ***

I tried purging and resinstalling the x server but of course, it was working fine. From a console I was able to stop the display manager and invoke an x-session manually with “startx”. In the desktop environment, I noticed my wireless was not connecting automatically and the network manager (nm_applet) and orage icons were missing from by status tray.

I’d like to say I used these clues to determine that the problem was isolated to gtk apps (e.g. lightdm, gdm3, nm_applet, etc.) but I never noticed the connection. I was simply fortunate to stumble upon the solution in this post, courtesy of one dE_logics:

http://forums.gentoo.org/viewtopic-p-6873138.html

While the root cause isn’t described in detail, the simple statement at the end of the post provides the solution: “This’s a bug with libxi. Upgrading it…solves the problem.” I gave it a shot. I found libxi6 in synaptic and upgraded it to the highest version available in Debian’s stable repository. After a reboot, my display managers are working perfectly. My libxi6 version is now 2:1.6.1-1+deb7 according to synaptic.

pyK-Control 2400 version 1.0 alpha released

Thursday, June 20th, 2013

pyK-Control 2400 is a serial port controller and communicator for the Keithley 2400 SourceMeter written in python using the GTK+3 framework.  It’s main purpose is to configure and run current or voltage sweeps from a convenient software interface. The current release, 1.0 alpha, has been tested in Debian GNU/Linux and Windows XP.

More information can be found on the pyK-Control 2400 project page.

GtkGrid alignment issues

Friday, May 17th, 2013

Recently I ran into a problem laying out some controls with a GtkGrid widget that took quite a while to figure out. My controls were contained within a vertical GtkBox with three rows. The first row contained a grid with two columns. The left column housed labels and the right housed the actual controls. The next two rows of the vertical box were similar except the grids within were contained within a frame. The main vertical box itself is in the left column of a 2 column horizontal box. The right column contained a GtkScrolledWindow with a GtkTextView. The scrolled window was set to expand to take up all of the remaining horizontal space in the window. Problem was, the controls on the left weren’t aligned properly. A picture should help the explanation.

Screenshot - 05172013 - 11:48:09 AM

In the image, the vertical box (red) has been enclosed within a GtkFrame (frame13) to show its borders. As you can see, the controls in the yellow grids are aligned to the left and do not fill the cells of the grid. I would like them to be either right aligned or to fill the cells of their parent grids so that the right edge of all controls are aligned. This turned out to be nearly impossible. Most solutions I tried would cause the scrolled window in the adjacent column to shrink for apparently no reason to about 1/3 of the total horizontal area. The image below is an example of one trial solution in which I set the horizontal expand property of the GtkLabel “Loop” to True. The label expands to push the neighboring control (a GtkComboText) to the right side of the vertical box extents. But for some reason, the space outside of the vertical box is allocated to the label’s parent grid instead of the scrolled window.

Screenshot - 05172013 - 11:43:50 AM

The behavior is the result of the GtkGrid inheriting the hexpand property its child, the “Loop” label, and so on up the chain. The vertical box doesn’t appear expanded, but it is allocated the space anyway. To override this reverse inheritance behavior, one must set the hexpand property of the parent container (the vertical box in this case) to False. I’m designing in Glade and by default, this property is “No” for all widgets. This is not the same as setting the property to False. The workaround is to add a line of code to force the property to be false. I have unfortunately not found a fix that can be applied within Glade. The line looks something like this:

    builder = Gtk.Builder()
    builder.get_object('verticalBox').set_hexpand(False)

From there, setting the horizontal expand on the labels pushes the controls to the right, but no space is allocated outside of the vertical box parent. The successful alignment, with frame13 removed and some column spacing added between the controls and the scrolled window looks like this:

Screenshot - 05172013 - 12:11:45 PM

This project is being developed in Python 2.7+ using the Gtk+3 framework. The UI is designed in Glade 3.

Saving the image drawn with Cairo on a GtkLayout or GtkDrawingArea using a pixbuf

Wednesday, May 8th, 2013

In my previous post, I discussed how to get the draw() event to fire for Gtk3 widgets in order to draw on them using cairo, specifically the GtkLayout and GtkDrawingArea widgets. Since that time I’ve had some success writing code to plot data from a connected source meter (through the RS232 port) in real time. I got stuck again trying to save the image drawn on the GtkLayout to a file. Most of the material I found on the internet wasn’t up to date and not relevant for the GTK3 framework. Finally I figured out how to save the image and it’s pretty easy to do too.

The solution is to get a GdkPixbuf from the widget’s GdkWindow and use the GdkPixbuf’s .savev() method to write the image to disk. For some reason, when I use the .get_window() method of GtkWidget’s, I don’t get a GdkWindow returned but rather a GdkX11Window object (gtk.gdk.X11Window). I’m not sure why there’s a difference but it seems to be ok to feed this into the Gdk.pixbuf_get_from_window() function. Please note that you must use the .savev() method of the pixbuf. Most sources online use the .save() method but that seems to be gone in Gtk3 (or perhaps there is no python binding?).

For example, assume you have a GtkLayout stored in the variable layout (I find mine with layout = self.builder.get_object(‘mylayout’) – because I’m using Glade). To capture an image of the layout and whatever you’ve drawn on it, you would do the following:

pixbuf = Gdk.pixbuf_get_from_window(layout.get_window(), 0, 0, width, height)
pixbuf.savev("foobar.png","png", [], [])

In this example, width and height need to be the width and height of the widget. The rectangular area defined by (0,0) to (width, height) is saved. In my case, I did something like this:

rect = layout.get_allocation()
width = rect.width
height = rect.height

In the .savev() method, the first argument is the file name, the second is the type, and the third and forth options are arrays of options and their settings. I pass empty arrays because I don’t set any options.

Note that this works with GtkLayout and should work with GtkDrawingArea and GtkWindow. For other widgets, the window returned by .get_window() seems to be that of the parent GtkWindow. If you want to capture an image of those wigdets, you’ll need to specify the x,y position of their top left corners in the Gdk.pixbuf_get_from_window() call.

layout

Drawing to GtkLayout and GtkDrawingArea with Python

Monday, May 6th, 2013

This one took me several hours to figure out. I’m writing an application that will include a graph of some data collected from the serial port (using the pySerial library). I’m writing the application in Python (2.7.2+) using the GTK 3 framework. UI design is being done in Glade 3. To make the graph, I wanted the base object to be a GtkLayout widget because this widget can be scrolled (inside a GtkScrolledWindow), can contain other widgets, has a fixed layout, and can be directly drawn to.

The problem was, I couldn’t get the draw event for the GtkLayout to trigger no matter what I did. The problem was worsened by the fact that most of the information online is not relevant for Gtk 3, or if it is, it uses the GtkDrawingArea widget instead. But, even when I gave up and went with a GtkDrawingArea widget, I still failed to trigger the draw event.

Finally, after reading everything ever written on the internet, I found the answer in a forum (link below). I was missing the python-gi-cairo package (Debian package) which has the python cairo bindings. After installing this package, the draw event triggers as expected and I’m able to draw to both the GtkLayout and GtkDrawingArea widgets. I didn’t even have to add another “import” line to my script, which is nice, but the dependency still exists.

Link: http://python.6.x6.nabble.com/pygi-gtk-drawingarea-doesn-t-work-td4981920.html

A GtkDrawingArea example: https://git.gnome.org/browse/pygobject/tree/demos/gtk-demo/demos/drawingarea.py