Visualization of the drug war in Mexico. This guy's blog is awesome, and his code is on github.
Visualization of the drug war in Mexico. This guy's blog is awesome, and his code is on github.
It is Hack Week this week, when all of Novell's hackers work on whatever project they want for the whole week.
The infrastructure for Document-Centric GNOME is coming along just fine. The Zeitgeist hackers are kicking all sorts of ass with the engine and the activity journal — that's what lets you see your work in a nice timeline.
Another part of the document-centric vision is to allow comfortable flow or circulation through your files, which is sorely missing right now.
Let's say you open a document. It doesn't matter how you open it — by double-clicking on it in Nautilus, by clicking on an item in your activity-journal's timeline, or by a File/Open command. The document window you get is something like this:
This document window tells you the title or filename, but it does not let you see where the document is stored. It also does not let you access documents which may be near the place where the original document is stored.
The user interface does not give you any hints about the place in which your document lives. Your document is effectively placeless, you have no way to orient yourself, and you have every reason to feel lost.
What would Christopher Alexander do?
There are several patterns in A Pattern Language that deal with how you move from place to place and how you orient yourself, either in the city or in a building. To solve the problem of disorientation and placeless documents, I think we can grab ideas from these patterns:
Main gateways. "Any part of a town - large or small - which is to be identified by its inhabitants as a precinct of some kind, will be reinforced, helped in its distinctness, marked, and made more vivid, if the paths which enter it are marked by gateways where they cross the boundary. [...] Mark every boundary in the city which has important human meaning - the boundary of a building cluster, a neighborhood, a precinct - by great gateways where the major entering paths cross the boundary."
Circulation realms. "Lay out very large buildings and collections of small buildings so that one reaches a given point inside by passing through a sequence of realms, each marked by a gateway and becoming smaller and smaller, as one passes from each one, through a gateway, to the next. Choose the realms so that each one can be easily named, so that you can tell a person where to go, simply by telling him which realms to go through."
The flow through rooms. "The movement between rooms is as important as the rooms themselves; and its arrangement has as much effect on social interaction in the rooms, as the interiors of the rooms. [...] As far as possible, avoid the use of corridors and passages. Instead, use public rooms and common rooms as rooms for movement and for gathering. To do this, place the common rooms to form a chain, or loop, so that it becomes possible to walk from room to room [...]"
Circulation for your files
File managers like Nautilus let you navigate down in the hierarchy of folders until you reach an actual document. But once you open a document window, you cannot navigate up to look for related files, or even to see the folder in which the document is stored. If you open the document with something other than the file manager, you will have a hard time knowing where the document is.
We can solve this by adding a "Show folder" button to document windows, preferably so that it is close to the document's name or filename.
When you click on that "Show folder" button, it takes you to the document's parent folder. In turn, we can make folder windows in the file manager similar, with a "Show parent" button to go further up in the hierarchy.
By adding a single button that is close to the document's or folder's name, we can let you navigate up in the hierarchy, just as you can currently navigate down with the file manager. This adds circulation and flow to your files.
Every time that I click on a PDF link while I'm browsing the web, the following happens:
The PDF gets downloaded and put somewhere. Sometimes in /tmp, sometimes in ~/Downloads, depending on which button I click in Firefox's "what do you want to do with this file?" nag-window.
Evince opens up to show me the PDF. In a few seconds I can tell if the PDF is something worth keeping.
If I decide to keep or delete the PDF, I cannot move it easily to a good place or to the trash— I have no way to visit the PDF's parent folder so that I can drag it to another place. This would be solved with the "Show folder" button described above.
For some reason, PDFs always seem to have terrible names: presentation.pdf, 2010.pdf, 10.1.1.55.8788.pdf. CiteSeer, I am looking at you. And yet there is no easy way to rename the document right there.
This also happens when someone sends me an email attachment. They give it a crappy name, I want a better one, but there's no easy way to do it right there.
In the mockup screenshots above, you can see that windows for documents and folders actually let you edit the filename right there. Instead of having a static filename in the title bar, you actually have a text entry that you can edit. If I could rename 10.1.1.55.8788.pdf right from Evince as I view the PDF for the first time, my ~/Downloads folder would be a much friendlier place.
This is akin to having physical gateways with big name tags. You always know where you are, and you always know that you can go to a place nearby.
Unfortunately, window managers don't let you customize a window's title bars like that.
The valiant Cody Russell has been working on the client-side-decorations branch of GTK+. With this, you would be able to have a toplevel window and decorate its frame yourself, without the window manager's intervention.
Having control of a window's frame means that we can stick a GtkEntry there for the rename-able filenames, and a GtkButton for the "Show folder" action.
(Yes, this would also let programmers add all sorts of crap to their windows, but apps will shitty UIs will just kill themselves.)
However, having an application paint the window's frame by itself also means that it should paint it exactly in the same way the window manager would, or the window will look out of place.
My Hack Week project is to rip the code from Metacity/Mutter that reads a window manager's theme, and paints the window frames, and make that code reusable for GTK+. This way document windows would look exactly like normal managed windows, but with the addition of the few extra controls we need.
This is the story of two little olives.
Hello, my friend, what have you been doing?
Let me tell you about my deadly battle with a fierce toothpick.
Don't you say! How impressive, what valour!
The toothpick was about this thick.
Tell me no more, I can't bear to hear it!
Now more than ever, we olives have to stand together.
No more toothpicks, only red peppers will pierce our hearts!
Script - Oralia
Puppets - Luciana
Photos - Federico
This is how a GtkBox lays out its children. Yellow is the spacing that you specify in gtk_hbox_new() or gtk_vbox_new(). Beige is padding, which I'll convince you to set to zero. Orange is the actual child widgets inside the box.
In the first example, you see a box with a spacing of 2 (trust me, that yellow is 2 units). The children are thus uniformly spaced, and everything is nice and easy to understand.
In the second example, you see a box with the same spacing of 2 units between children, but each child has a different padding. The leftmost child has a padding of 1 unit, which you see on both sides of that child. The second child has a padding of 2 units, the third child has a padding of 3 units, and the rightmost child has no padding. This is a big mess.
Spacing is the uniform space that GtkBox puts between child widgets.
Padding can be different for each child, and it gets applied on both sides of each child. So each child gets an allocation of at least (padding + requisition + padding).
Other containers like GtkTable also have their own padding parameters for children (GtkTable lets you set different paddings in the X and Y directions).
Summary: if you are using a padding different from zero, you are making a mistake in 99% of cases. Use a good spacing, and a padding of zero. Otherwise you make it really hard to align other widgets in the container hierarchy when someone else has to modify your code. If you really need padding, it's generally better to use a GtkAlignment around your widget and pad that instead of messing up the parent container.
This has been a public service announcement.
Henne Vogelsang pointed me to a great document on applying "A Pattern Language" to online communities.
Go and watch this scary/funny/excellent presentation of turning everything into an online game.
... And now go watch this presentation on why we should use online games to solve real-world problems.
That would be something very cool. Do a little guerrilla gardening? Get +10 points for gardening experience, +5 points for neighborhood-improver, +8 points for community-building if you garden with a neighbor.
Why are you reading, replying to, or posting in foundation-list? Why are you wasting your own time and eveyrone else's? Instead, go and make GNOME better. Fire up that text editor. If you don't "git push" today, your day was a waste of time.
One thing that Seth says is that sometimes designers come up with a design, and then programmers dissect every pixel of it asking for an explanation. Why did you put this here? Why is that a 3-pixel border instead of 4? This is extremely unnerving to designers, as when you are skilled at something, you don't consciously think about all the decisions you make while doing something. Their skill told them that that place is where the thing would look more balanced, or give you the most economy of mouse movement. Their skill told them that 3 pixels looked just right, while 4 pixels would look too fat. I mean, just look — can't you see the difference? (Programmer: no, I can't; that's why I asked you, and 4 is an easier number for me to deal with).
Programmers also tend to burden designers with many questions because it is them, the programmers, who will actually have to go through implementing everything that the designer said. Also, it is very hard to restrain yourself from posting your pet peeves when someone is doing a design — I know, I've done it myself.
For designers, having to justify every decision keeps them from doing good work (or from doing anything at all). Just see what happens with the OpenOffice.org usability train-werck — nobody wants to change the user interface because they would have to go through a bureaucratic process of justifying every single thing they did, write a spec, get it approved, etc.
However, Seth's tongue-in-cheek recommendation of "just trust designers" is not 100% wise. See what happens out there in the physical world when we trust starchitects like Daniel Libeskind and I. M. Pei. They will just jerk off on your city and they will spooge a monstrosity which no one dares to demolish because it was so expensive to build.
|Photo||What||Comments from a programmer|
|An apartment building.||Pretty, unpretentious, respects its surroundings.|
|An apartment building according to Daniel Libeskind.||Yeah, you can live in the pointy end of frozen shark fin's soup.|
|Islamic art.||It's fractal, colorful, and has 1400 years of tradition.|
|Museum where I. M. Pei wants to show Islamic art.||Luciana is getting pretty good at stacking blocks like that.|
Fortunately, human interface designers are not starchitects. They are very reasonable people, trying to build tools that are rewarding to use.
Programmers get annoyed at designers who don't show a hint of knowing how software is implemented. This is like builders who get annoyed at starchitects — yes, mister Gehry, your fucking roof leaks because you designed a surface with a local minimum and no drain. Water will pool in local minima. 2000-year-old fix which you didn't do just to be interesting: cascade of roofs.
A designer who is not involved in the implementation cannot be a good designer, and I will explain why. Designers should not deliver gold-framed drawings drawn with the finest inks on parchment, expecting that the lowlife builders will follow the designs to the letter. Designers need to be involved with the construction. That will teach them what is necessary and what is superfluous, and it will make them better designers. Seth mentions that he and Marco worked very well together when Marco questioned him, because there was an interaction between designer and builder.
You may not be the best programmer or the best designer, but if you work to acquire programming and design skills that are above average, then you have already won.
Design of something as complex as software is best done iteratively. You use the scientific method: design a bit, code a bit, test the outcome. How do you avoid testing mostly screw-ups until you hit the right design? You follow a few rules.
Which rules? Allow me to introduce you to the monumental work of Christopher Alexander.
Introduction: A Pattern Language, or architecture for humans
In the 1970s, Christopher Alexander and other architects at Berkeley went to various places around the world, trying to see if there were reasons for why some places and buildings are comfortable, livable, and nice, and some are not. They distilled their findings into a list of good architectural patterns, and published three books — the first two being The Timeless Way of Building and A Pattern Language.
A Pattern Language is remarkable for several reasons. First, it is immensely practical. If you are building something, you can grab the book and instantly get hundreds of ideas for your project. Second, it is not about a particular style or about superfluous decoration. The book doesn't tell you, "make this shape of flourishes in the handrails"; instead it tells you, "a house should have its rooms placed such that sunlight enters them according to the right time of the day - East for the bedrooms in the morning, West for the living room in the afternoon". Third, you can see a whole philosophy of good living emerge from the book. It advocates a process that allows you to construct an environment that respects your needs as an individual, as a social human being, and as a living being that should not damage its environment.
For us programmers, this book is also interesting because it was the inspiration for Gamma et al's Design Patterns, and a whole slew of pattern-minded thinking that we are used to.
Let's look at five little examples of patterns from the book.
Positive outdoor space. You can feel it in the small, cozy public squares in medieval towns. You can most definitely not feel it in the huge parking lagoons in shopping malls along the highway. Positive space is more or less convex, it is partially enclosed, and it has a definite shape. It is not just leftover space. Here, negative and positive space between buildings (note how old versions of the GIMP were a pain in the ass to use because the program's windows looked like the version on the left):
Light on two sides of every room. This diffuses the light, thus making a more comfortable environment. There is no glare from the window. There is no time of the day when you don't get good sunlight. Here, light on two sides, and light on only one side:
Intimacy gradient. The entrance to your home is semi-public space. The living room is communal space. Your bedroom is private. If you must cross the bedroom to reach the bathroom from the living room, then having visitors will be uncomfortable. So, you design your home so that the connections between rooms form a sequence from public to private.
Structure follows social spaces. Communal areas need to be ample and have high ceilings, and they need to be "in the center of things". Intimate areas like reading alcoves and your study desk need low ceilings and separation from the rest (through doors or half-height walls) to make them private.
Open shelves. Deep cupboards make you put things behind other things, so you can't see them nor reach them. They also have a big footprint. Cupboards that are one-item-deep automatically stay tidy, and you always know where everything is. Things that you use frequently should not be behind doors.
So you can see the essence of design patterns: good, tested recipes that don't constrain your implementation in unnecessary ways.
But where did the patterns come from?
Although the list of patterns is tremendously useful, and universally applicable to urbanism and construction, Alexander was not satisfied. Where did the patterns come from? Can we make new patterns from scratch, or must be we content with what traditional architecture has produced so far? Are patterns necessary at all?
Alexander spent the next twenty years researching these questions. He arrived at the following conclusions:
Nature creates things that all have about 15 properties in common (I'll show you later). This happens solely through natural processes, although it is not quite clear why very different processes produce similar results.
Traditional architectures, or towns which just evolved over time, also have those properties. You can derive all the patterns in A Pattern Language from those properties.
Each property can also describe a transformation to the existing space.
The only way to achieve good design is by using those transformations, one at a time.
This was published in 2003-2004 in four volumes titled The Nature of Order.
The fifteen properties
The first book in The Nature of Order deals with fifteen properties that appear in all natural systems.
You should really look at photos and drawings of the fifteen properties to understand them. I'll just summarize them super-briefly here.
|Levels of scale. There is a balanced range of sizes. You don't have abrupt changes in the sizes of adjacent things.||Strong centers. You can clearly identify parts of the space or structure.||Thick boundaries. Lines delimit things. In living systems, edges are the most productive environments (e.g. all the critters that live at the edge of the water).|
|Alternating repetition. High/low, thick/thin, shape A and shape B. Things oscillate.||Positive space. Space is beautifully shaped, convex, enclosed. It is not leftover space.||Good shape. The sails of a ship, the shell of a snail, the beak of a bird. They attain the optimal shape, which is beautiful.|
|Local symmetries. The world is not symmetrical at large. But small things tend to be symmetrical, because it is easier that way. Your house is not symmetrical, but each window is.||Deep interlock and ambiguity. The crooked streets of old towns. Axons in neurons. Two strong centers are made stronger if a third center is placed between them, so that it belongs to both.||Contrast. You can distinguish where one thing ends and the next one begins, because they don't fade into each other.|
|Gradients. Things fade into each other where they need to. Concentrations in solutions, snow or earth banks, the wires that support a bridge.||Roughness. The world is not frictionless and smooth. Irregularities are good.||Echoes. Things repeat and echo each other. Things are unique in their exact shape, but those shapes repeat over and over.|
|The void. Sometimes you get a big blank area for quietness of form. A lake, a courtyard, a picture window.||Simplicity and inner calm. Things are as simple as possible, but no simpler.||Non-separateness. Everything depends on everything else. You can't separate a fish from the pond and the aquatic plants. You can't separate a column from the base of the building.|
The second book in The Nature of Order describes how each of those properties also defines a transformation. For example:
Thick boundaries. You can sometimes transform something beneficially by adding a boundary to it. You plant a hedge around a garden, which then serves as beauty, as a wind-break, and as a productive system on its own. Scrollable boxes without a GTK_SHADOW_IN frame are hard to distinguish from the window's background. You put a cornice at the top of a building, so you don't get an abrupt transition between the building and the sky.
Local symmetries. Small parts of built things are easier to build symmetrically — because they are turned on a lathe, because they need access from both sides, because they fold like a book. Making things asymmetrical "just to be interesting" takes extra work and it is harder to make them work well.
Positive space. Feeling too exposed when in your desk? Add a waist-high bookshelf beside you to delimit your space, but not to completely close you off.
Each of these is a structure-preserving transformation. You make a change in the existing structure not by tearing it down and remaking it, but by tweaking one thing at a time according to those properties and transformations.
The fundamental process
Over a long argument, Alexander explains why following this process of applying structure-preserving transformations is the only way to achieve a good, functional design. This is not just for buildings, but for everything we construct. We mimic nature, but we do it faster.
So, how do you do one step in your design/implementation process?
1. Start with what you have — an empty lot, or an already-built building, or a program that looks ugly and is hard to use.
2. Identify the centers that exist in that space. Find the weakest center or the least coherent.
3. See how to apply one or more of the fifteen structure-preserving transformations to strengthen that weak center. Does it need to be delimited? Does it need to be blended with its surroundings? Does it need more detail? Does it need to be de-cluttered?
4. Find the new centers that are born when you apply the transformation to the old center. Does the new combination make things stronger? Prettier? More functional?
5. Ensure that you did the simplest possible thing.
6. Go back to the beginning for the next step.
A super-short summary could be, "find the bad parts; make them better in the simplest way possible; repeat until it is all good".
What the hell does this have to do with software design?
Let me give you some examples.
Refactoring is just applying structure-preserving transformations. You don't change what the program does; you just change how it is built internally, piece by piece.
You do not rewrite software; you fix the software that exists. Otherwise you lose all that knowledge, even if it looks ugly in its curent state.
You don't design the whole user interface for a big program in a single step. You go from big to small or small to big (levels of scale); you test each part individually until it is good (strong centers); you make sure the parts are not too disconnected from each other (non-separateness). You move a few widgets where they are easier to reach, or where they are closer to the data to which they refer. You remove some frames and separators to reduce clutter.
Free software and cities
We software developers are building cities. I include code hackers, designers, translators, documenters, etc. in the term "developers" — building cities of software programs interconnected with each other through IPC. Each program is a building, large or small, simple or complex, each with a different purpose and layout.
Designing a whole system (kernel, libraries, tools, shell, programs) would be like trying to design a whole city. A good city cannot be designed; it has to emerge from the interactions between its inhabitants, over many years. Good cities are emergent, not designed. Ecosystems emerge from the interactions of living and non-living beings; they are not designed and they always evolve.
Remember that no one can work on all of free software. You cannot design a whole system by yourself, and you cannot make everyone agree on everything for a perfectly consistent design. But if you follow the structure-preserving transformations and the fundamental process, you can build your part of a big system and it will automatically be harmonious with everything else — and you will have fixed the bad parts first, making the overall goodness much better.
So, go forth and design and build and iterate.
New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.
Keep up with the latest Advogato features by reading the Advogato status blog.
If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!