Rapid GNOME Development with Mono
Mono is an open-source implementation of the .NET development platform, a powerful and now open development platform. Mono contains a number of components: a Common Language Infrastructure (CLI) virtual machine, a C# compiler and a set of class libraries. Mono implements the C# language and runtime environment according to ECMA standards 334 and 335, respectively.
Mono—which is the word for monkey in Spanish—provides various class libraries, including an open-source implementation of the .NET Framework SDK. In this article, however, we discuss one of Mono's brightest assets: its GNOME support, in the form of Gtk#.
Gtk# is a .NET language binding for the Gtk+ toolkit and various other GNOME libraries. More than a simple wrapper, Gtk# provides a powerful platform for developing GUI software in the GNOME environment. Gtk#'s language bindings utilize good object-oriented principles and C#-style design to make GNOME development easy and natural, yet flexible and powerful.
In this article, we investigate the construction of a simple C# application, starting with a trivial “Hello, World” application and building it into a basic Wikipedia search tool. Our only dependencies will be Mono and Gtk#. Packages are available for most distributions—see the on-line Resources.
Let's start by constructing the most basic Mono application possible, which prints “Hello, World!” to the console:
using System;
class first {
public static void Main (string[] args)
{
Console.WriteLine ("Hello, World!");
}
}
Fire up your favorite editor, enter this code and save it as first.cs. We can then compile the program into an executable image with the following:
$ mcs first.cs
Finally, we can run it via the following command:
$ mono first.exe Hello, World!
This application implements the first class. Every application needs an entry point, an initial function inside of the class for the Mono runtime to jump to and begin the program's execution. As with C and C++, this is the Main function. The prototype of this function is:
public static void Main (string[] args)
In our program's Main, we invoke a single function, WriteLine, which is found inside the Console class. This function, similar to printf(), writes a line of text to the console. It can be used to output the values of variables too:
int x = 5;
String s = "wolf";
Console.WriteLine ("x={0} s={1}", x, s);
This gives us:
x=5 s=wolf
We do not, however, have to confine our “Hello, World!” to the console; with Gtk#, we can build a trivial GUI dialog to hoist our message onto the world:
using System;
using Gtk;
class Two {
static void WindowDelete (object o, DeleteEventArgs args)
{
Application.Quit ();
}
static void InitGui ()
{
Window w = new Window ("My Window");
HBox h = new HBox ();
h.BorderWidth = 6;
h.Spacing = 6;
w.Add (h);
VBox v = new VBox ();
v.Spacing = 6;
h.PackStart (v, false, false, 0);
Label l = new Label ("Hello, World!");
l.Xalign = 0;
v.PackStart (l, true, true, 0);
w.DeleteEvent += WindowDelete;
w.ShowAll ();
}
public static void Main (string[] args)
{
Application.Init ();
InitGui ();
Application.Run ();
}
}
As before, enter the code via your favorite editor. This time, save it as two.cs. To compile this program, we need to tell the Mono compiler that we want to use the Gtk# assembly:
$ mcs two.cs -pkg:gtk-sharp
Running it, however, is the same:
$ mono two.exe
The application creates a small window, titled My Window, and writes “Hello, World!” into the window (Figure 1). The window is a GtkWindow, the label a GtkLabel. Gtk lays out windows via boxes. Boxes are invisible widgets—existing solely for the purpose of layout—into which other widgets are packed. The arrangement of widgets within a box determines the physical layout of the widgets within the window. Although it is possible in Gtk to arrange widgets using tables, most programmers prefer boxes for their flexibility and power—plus, once you get the hang of them, they are not difficult to use.

Figure 1. My Window
Gtk provides two types of boxes: vertical and horizontal. A vertical box, called a vbox, defines the vertical arrangement of widgets—vboxes arrange widgets into columns. A horizontal box, known as an hbox, defines the horizontal arrangement of widgets, by arranging them into rows. Widgets are packed into boxes, boxes are packed into other boxes, and the boxes are added to windows.
A new hbox is created via:
HBox h = new HBox ();
And a new vbox is created via:
VBox v = new VBox ();
The new objects representing the boxes have various properties that one can set to manipulate the look and feel of the box. In our previous example, we set two properties on the hbox:
h.BorderWidth = 6; h.Spacing = 6;
Here, we set the border of and the spacing around the hbox to six pixels each. This provides a net spacing of 12 pixels around the hbox. Coincidentally, for purposes of aesthetics and consistency, the GNOME HIG (Human Interface Guideline) dictates a minimum spacing of 12 pixels between widgets—thus the six and six pixels in this example are perfect.
To add a box to a window, the Add() member function is called on the window in question and provided to the box:
w.Add (h);
To pack a widget into a box, the PackStart() member function is called on the box in question:
public void PackStart (Widget child,
bool expand,
bool fill,
uint padding)
In our example, we did:
v.PackStart (l, true, true, 0);
This call packs our label into our vbox. If the expand parameter is true, the widget child expands to fill all available space within the box. If the fill parameter is true, the widget consumes all of its space for rendering; otherwise, if false, the widget uses superfluous space for padding. The padding parameter allows for the addition of extra spacing around the widget, within the box, beyond any padding already provided.
Starting our application is simple. We perform three simple steps:
Application.Init (); InitGui (); Application.Run ();
Application.Init() initializes Gtk# and the application's GUI. It should be one of the first functions that a Gtk# application invokes. After executing this function, applications set up their GUI, create and arrange their widgets, and draw the initial windows and other UI elements. In our program, we do this in the InitGui() function. Once everything is complete and ready to roll, the program calls Application.Run() and the race is off. Our main window pops up because we exposed it, back in InitGui(), via:
w.ShowAll ();
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Designing Electronics with Linux
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Dynamic DNS—an Object Lesson in Problem Solving
- Linux Systems Administrator
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Using Salt Stack and Vagrant for Drupal Development
- Reply to comment | Linux Journal
4 hours 41 min ago - Dynamic DNS
5 hours 15 min ago - Reply to comment | Linux Journal
6 hours 14 min ago - Reply to comment | Linux Journal
7 hours 4 min ago - Not free anymore
11 hours 6 min ago - Great
14 hours 53 min ago - Reply to comment | Linux Journal
15 hours 1 min ago - Understanding the Linux Kernel
17 hours 16 min ago - General
19 hours 45 min ago - Kernel Problem
1 day 5 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
Mono IDE
Nowadays you don't have to worry about coding your GTK interface! :)
Monodevelop is the official IDE of Mono. It is an IDE just like MS Visual Studio/VB Express... Drag your widgets onto a window, assign them signals and the IDE automatically puts the interface code into your project. Just fill in the blanks with your code and you have a GTK program!
Small addition
Thanks for the article. More than that, thanks for you work on other projects (especially NetworkManager).
The Wikipedia sample application doesn't allow for spaces in the text box, I added the following just before the Gnome.Url.Show(s) call:
s = s.Replace(' ', '+');
Lovely article!
Dear Robert, thanks for yet another lovely article!
I'm reading your book, "Linux Kernel Development" these days as well, and it is an absolute pleasure to read.