Mar 032013
 

This isn’t the first time I’ve commented about user interfaces.  This weekend has been particularly wet, and while I did have plans to get out of the house for a few hours, I’ve spent a week-end indoors.

This meant time to go tinker with a few projects, amongst those being my desktop configuration.  In particular, key bindings, and panel placement.

My desktop is largely based on what I was running when I was at university.  At this time, I was mostly limping around with aging Pentium II class laptops with display resolutions of 800×600 pixels.  No space for big spacious panels here.  I was running KDE at the time.

I frequently had a need to move windows around without the use of an external mouse.  The little writing boards that the university provides in its lecture theatres are barely big enough to accommodate a writing pad let along a laptop!  The laptops I had generally had the small track-point type cursor, which while usable, wasn’t great.

That, and small screen real-estate dictated a desktop which was space efficient and mostly keyboard driven.

Now, I could have gone the route of tiling window managers.  I recall trying out Ratpoison at one point, decided it wasn’t for me, and let it go.  I do like a little eye candy!  KDE 3.5 at the time provided a good balance, and wasn’t too bad on these machines.  Crucially, I was able to set up a couple of small panels around the sides of the screen, and set up key bindings to perform most operations.  Some of the common operations I needed were:

Key binding Action
Logo + Shift + M Move a window
Logo + Shift + R Resize a window
Logo + Shift + S Shade (roll up) a window
Logo + Shift + X Maximise a window
Logo + Shift + C Close a window
Logo + Shift + I Iconify (minimise) a window
Logo + Menu (now broken) Bring up launcher menu

You’ll note here I use the term Logo to refer to the additional modifier on some keyboards. Apple users will know this as the Command key. Microsoft users will of course call this the Windows key. On my Yeeloong, the key looks like a house in a white circle. FVWM calls it Mod4. I call it the Logo key because it usually has some sort of OS-vendor-specific logo associated with it.

I use this, rather than Control and Alternate, since most applications bind their operations to those keys, and ignore the Logo key. By requiring the Logo key to be used in command sequences, it leaves Control and Alternate for applications. Control and Alternate of course, still get used in combination with Logo to extend the command set. The key bindings in bold get used the most.

One key stroke did change; originally I had Logo + Menu as the key sequence to bring up the launcher menu. I found KDE 4 broke this, I could no longer assign the Menu key (the one that brings up context menus in Windows) to this action. I haven’t really settled on a suitable substitute, and of course, my current Apple MacBook does not have this key, so I use Logo+Launch instead (what shows the dashboard in MacOS X), a little more of a stretch, but it works.

The layout I settled on was to have a menu and task bar up the top of the screen, then status notification and pager down the right-hand side.  Each panel occupied no more than 16 pixels.  I made extensive use of virtual desktops, configuring 12 virtual desktops and assigning these to each of the function keys. So Logo + F5 meant, go to desktop 5. Logo + Shift + F5 meant, move window to desktop 5.

Thus I could juggle the laptop in my hands, launching applications, moving them between desktops, figuring out where I needed to be next and getting things ready on my way between lectures and tutorials.

Over time, KDE became unsuitable as a full blown desktop due to its memory footprint. I found myself looking around and for a while, I was running FVWM. After a bit of research I figured out how to set up the bindings in much the same way. I managed to get FVWM’s BarButtons to emulate the side panel, but have the panel just lurk in the background and be recalled when necessary. And of course, the root menu and icons shown on the desktop mostly removed the need for a task bar.

This worked well, until I got the MacBook. The MacBook’s keyboard does have function keys, but requires you to hold the Fn key to access them. So the “Move to desktop 3″ operation which I do so commonly, became Logo+Shift+Fn+F3. A real finger-twister. I’ve just put up with it until now.

What’s replaced it? Well I’ve done some re-working. Icons on the desktop for iconified windows is good and well but you’ve got to be able to get at them. That, and getting at the menu with the mouse in one hand proved to be a hassle, so for those tasks, the task-bar is back with its launcher button.

The BarButtons has been given a title bar, and the EWMH working area has been set so that applications do not cover the task bar, or the BarButtons title bar, allowing those to be accessed with the mouse alone. The BarButtons can be raised or lowered with a new key sequence, Logo+Z.

The application switching was always a chore. This is probably the one exception to the Logo for Window manager command rule; I used the very prevalent Alternate+Tab to switch applications. FVWM does this out-of-the-box unsurprisingly. I found with a lot of applications though, going Alt-Tab,Tab,Tab,Tab just a little annoying.

Logo+A brings up the window list and the window list stays there until a choice is made. The windows are numbered with a digit, and one can use arrow keys to select. Much better.

As for the virtual desktops. FVWM has desktops and pages. What I was using as “desktops” before, were just pages of a single desktop. I decided that once again we’d do proper virtual desktops, but only 4 of them, with 4 pages each. That’s 16 “spaces” in total. But how to switch between them? With new key bindings:

Key binding Action
Logo + 1 Jump to Desktop 1
Logo + 2 Jump to Desktop 2
Logo + 3 Jump to Desktop 3
Logo + 4 Jump to Desktop 4
Logo + Q Jump to Page 1
Logo + W Jump to Page 2
Logo + E Jump to Page 3
Logo + R Jump to Page 4
Logo + T Jump to last page
Logo + Backtick Jump to last desktop
Logo + Tab Jump to last desktop and page
Logo + Shift + 1 Move window to Desktop 1
Logo + Shift + 2 Move window to Desktop 2
Logo + Shift + 3 Move window to Desktop 3
Logo + Shift + 4 Move window to Desktop 4
Logo + Shift + Q Move window to Page 1
Logo + Shift + W Move window to Page 2
Logo + Shift + E Move window to Page 3
Logo + Shift + R Move window to Page 4
Logo + Shift + T Move window to last page
Logo + Shift + Backtick Move window to last desktop
Logo + Shift + Tab Move window to last desktop and page

Then there’s the key binding Logo + Escape, which brings up a Jump To menu, where I can just press one of the numeric keys 1-4, which pops up a menu allowing me to select the page 1-4. So to jump to Desktop 4 Page 2, I just hit Logo+Escape, 4, 2. I’m still working on the move bit, while FVWM’s GotoDeskAndPage is documented and works, I’m having trouble with MoveToDeskAndPage, which seems to be undocumented.

We shall see on Monday how the new arrangement goes.

Accessing applications I think will be the next point to work on. I’m thinking about how to code a suitable launcher that can be summoned by FVWM. There are elements of common launchers such as the Windows Start menu, and its replacement, the Start Screen in Windows 8 that are good. The Program Manager was limited by its MDI interface, but the program groups meant there was a hierarchy that the Windows 8 start screen, and indeed, other contemporary launchers, lack.

The FVWM launcher isn’t bad — but it makes it hard to re-arrange items, there the old Program Manager really does shine. Want a new program group? Choose File, New, select Program Group, click OK, done. Want to add an icon to that group? Similar process. Adding and managing applications really does need to be that simple, so the end user can put things where they want them.

That, and keyboard accessibility is a must. FVWM has a little bug which is evident in this screenshot…

FVWM 2.6.5 as I have it now.

FVWM 2.6.3 as I have it now.

If you look at the menu, you’ll notice two things:

  1. There are multiple menu items with the same access key
  2. Where a menu item contains an ampersand, the space following is treated as the access key.

That’s a minor bug with FVWM’s AutomaticHotKeys. Fixable for sure. That particular menu is generated by a Perl script distributed with FVWM; I have a patch that tweaks it to put ampersands in appropriate places to give all the items access key assignments, but I think there are better ways.

In the meantime, those who are interested, my FVWM configuration is here. This will expand into the .fvwm directory.

Feb 172013
 

Well, I was half expecting that it’d happen one day. Gentoo Bug 89744, the bug that saw me promoted to developer on the Gentoo/MIPS team, is now a retirement bug in full swing.

To those in the Gentoo community, I say, thank-you for putting up with me for so long. It is probably time that I moved on though. Real life has meant I’ve got practically no time during my working week to do anything meaningful, and after a week of arguing with computers (largely Ubuntu-based) I come home on a Friday evening not feeling like even looking at a computer. Some weekends, the computer has stayed in my backpack, and not been removed until the following Monday when I return to work.

Thus the time has come, I must be going.

That said, I mostly did enjoy the time I had as a developer. I still remain a Gentoo user, as that seems to be the OS that best fits my usage patterns, and I might pop up from time to time, but I’ll probably maintain a fairly low profile from now on.

I actually didn’t notice the account being shut down, only discovered today in fact, that the redhatter@gentoo.org email address was not working from an Amateur radio colleague. It’s then I thought to have a quick gander and found out what had happened.

This does leave me with two Lemote boxes, that technically no longer belong here.

Remember these? They’re looking for a home now!

I shall enquire, and find out where to send the boxes themselves, or a donation to cover their cost. It is not right that they remain here without some sort of compensation.

This leaves some people without a means of contacting me.  I don’t bother with the instant messengers these days, and definitely not Skype.

Plain old email still works though, you can contact me at stuartl at longlandclan dot yi dot org from now on.  As for the old links on dev.gentoo.org, terribly sorry but that’s outside my control now.


Update:

The Lemote boxes now have a home. Thanks Anthony!

Feb 032013
 

Warning, this is a long post written over some hours. It is a brain dump of my thoughts regarding user interfaces and IT in general.

Technology is a funny beast. Largely because people so often get confused about what “technology” really is. Wind back the clock a few hundred millenia, then the concept of stone tools was all the rage. Then came metallurgy, mechanisation, industrialisation, with successive years comes a new wave of “technology”.

Today though, apparently it’s only these electronic gadgets that need apply. Well, perhaps a bit unfair, but the way some behave, you could be forgiven for thinking this.

What is amusing though, is when some innovation gets dreamt up, becomes widespread (or perhaps not) but then gets forgotten about, and re-discovered. No more have I noticed this, but in the field of user interfaces.

My introduction to computing

Now I’ll admit I’m hardly an old hand in the computing world. Not by a long shot. My days of computing go back to no later than about the late 80′s. My father, working for Telecom Australia (as they were then known) brought home a laptop computer.

A “luggable” by today’s standards, it had no battery and required 240V AC, a smallish monochrome plasma display with CGA graphics. The machine sported a Intel 80286 with a 80287 maths co-processor, maybe 2MB RAM tops, maybe a 10MB HDD and a 3.5″ floppy drive. The machine was about 4 inches high when folded up.

It of course, ran the DOS operating system. Not sure what version, maybe MS-DOS 5. My computing life began with simple games that you launched by booting the machine up, sticking in a floppy disk (a device you now only ever see in pictorial form next to the word “Save”) into the drive, firing up X-Tree Gold, and hunting down the actual .exe file to launch stuff.

Later on I think we did end up setting up QuikMenu but for a while, that’s how it was. I seem to recall at one point my father bringing home something of a true laptop, something that had a monochrome LCD screen and an internal battery. A 386 of some sort, but too little RAM to run those shiny panes of glass from Redmond.

Windows

I didn’t get to see this magical “Windows” later until about 1992 or ’93 or so when my father brought home a brand-new desktop. A Intel 486DX running at 33MHz, 8MB RAM, something like a 150MB HDD, and a new luxury, a colour VGA monitor. It also had Windows 3.1.

So, as many may have gathered, I’ve barely known computers without a command line. Through my primary school years I moved from just knowing the basics of DOS, to knowing how to maintain the old CONFIG.SYS and AUTOEXEC.BAT boot scripts, dealing with WIN.INI, fiddling around with the PIF editor to get contankerous DOS applications working.

Eventually I graduated to QBasic and learning to write software. Initially with only the commands PRINT and PLAY, baby steps that just spewed rubbish on the screen and made lots of noise with the PC speaker, but it was a start. I eventually learned how to make it do useful things, and even dabbled with other variants like CA Realizer BASIC.

My IT understanding entirely revolved around DOS however and the IBM PC clone. I did from time to time get to look at Apple’s offerings, at school there was the odd Apple computer, I think one Macintosh, and a few Apple IIs. With the exception of old-world MacOS, I had not experienced a desktop computer OS lacking a command line.

About this sort of time frame, a second computer appeared. This new one was a AMD Am486DX4 100MHz with I think 16MB or 32MB RAM, can’t recall exactly (it was 64MB and a Am5x86 133MHz by the time the box officially retired). It was running a similar, but different OS, Windows NT Workstation 3.1.

At this point we had a decent little network set up with the two machines connected via RG58 BNC-terminated coax. My box moved to Windows for Workgroups 3.11, and we soon had network file sharing and basic messaging (Chat and WinPopup).

Windows 95

Mid 1996, and I graduated to a new computer. This one was a Pentium 133MHz, 16MB RAM, 1GB HDD, and it ran the latest consumer OS of the day, Windows 95. Well, throw out everything I knew about the Program Manager. It took me a good month or more to figure out how to make icons on the desktop to launch DOS applications without resorting to the Start ? Run ? Browse dance.

After much rummaging through the Help, looking at various tutorials, I stumbled across it quite by accident — the right-click on the desktop, and noticing a menu item called “New”, with a curious item called “Shortcut”.

I later found out some time later that yes, Windows 95 did in fact have a Program Manager, although the way Windows 95 renders minimised MDI windows meant it didn’t have the old feel of the earlier user interface. I also later found out how to actually get at that start menu, and re-arrange it to my liking.

My father’s box had seen a few changes too. His box moved from NT 3.1, to 3.5, to 3.51 and eventually 4.0, before the box got set aside and replaced by a dual Pentium PRO 200MHz with 64MB RAM.

Linux

It wasn’t until my father was going to university for a post-grad IT degree, that I got introduced to Linux.In particular, Red Hat Linux 4.0. Now if people think Ubuntu is hard to use, my goodness, you’re in for a shock.

This got tossed onto the old 486DX4/100MHz box, where I first came to experiment.

Want a GUI? Well, after configuring XFree86, type ‘startx’ at the prompt. I toiled with a few distributions, we had these compilation sets which came with Red Hat, Slackware and Debian (potato I think). First thing I noticed was the desktop, it sorta looked like Windows 95.

The window borders were different, but I instantly recognised the “Start” button. It was FVWM2 with the FVWMTaskBar module. My immediate reaction was “Hey, they copied that!”, but then it was pointed out to me, that this desktop environment was somewhat older than the early “Chicago” releases by at least a year.

The machines at the uni were slightly different again, these ones did have more Win95-ish borders on them. FVWM95.

What attracted me to this OS initially was the games. Not the modern first person shooters, but games like Xbilliard, Xpool, hextris, games that you just didn’t see on DOS. Even then, I discovered there were sometimes ports of the old favourites like DOOM.

The OS dance

The years that followed for me was an oscillation between Windows 3.1/PC DOS 7, Windows 95, Slackware Linux, Red Hat Linux, a little later on Mandrake Linux, Caldera OpenLinux, SuSE Linux, SCO OpenServer 5, and even OS/2.

Our choise was mainly versions of SuSE or Red Hat, as the computer retailer near us sold boxes of them. At the time our Internet connection was via a belovid 28.8kbps dial-up modem link with a charge of about $2/hr. So downloading distributions was simply out of the question.

During this time I became a lot more proficient with Linux, in particular when I used Slackware. I experimented with many different window managers including: twm, ctwm, fvwm, fvwm2, fvwm95, mwm, olvwm, pmwm (SCO’s WM), KDE 1.0 (as distributed with SuSE 5.3), Gnome + Enlightenment (as distributed with Red Hat 6.0), qvwm, WindowMaker, AfterStep.

I got familiar with the long-winded xconfigurator tool, and even getting good at having an educated guess at modelines when I couldn’t find the specs in the monitor documentation. In the early days it was also not just necessary to know what video card you had, but also what precise RAMDAC chip it had!

Over time I settled on KDE as the desktop of choice under Linux. KDE 1.0 had a lot of flexibility and ease of use that many of its contemporaries lacked. Gnome+Enlightenment looked alright at first, but then the inability to change how the desktop looked without making your own themes bothered me, the point and click of KDE’s control panel just suited me as it was what I was used to in Windows 3.1 and 95. Not having to fuss around with the .fvwm2rc (or equivalent) was a nice change too. Even adding menu items to the K menu was easy.

One thing I had grown used to on Linux was how applications install themselves in the menu in a logical manner. Games got stashed under Games, utilities under Utilities, internet stuff under Internet, office productivity tools under Office. Every Linux install I had, the menu was neatly organised. Even the out-of-the-box FVWM configuration had some logical structure to it.

As a result, whenever I did use Windows on my desktop, a good amount of time was spent re-arranging the Start menu to make the menu more logical. Many a time I’d open the Start menu on someone else’s computer, and it’d just spew its guts out right across the screen, because every application thinks itself deserving of a top-level place below “Programs”.

This was a hang-over of the days of Windows 3.1. The MDI-style interface that was Program Manager couldn’t manage anything other than program groups as the top-level, and program items below that. Add to this a misguided belief that their product was more important than anyone elses, application vendors got used to this and just repeated the status quo when Windows 95/NT4 turned up.

This was made worse if someone installed Internet Explorer 4.0. It invaded like a cancer. Okay now your screenful of Start menu didn’t spew out across the screen, it just crammed itself into a single column with tiny little arrows on the top and bottom to scroll past the program groups one by one.

Windows 95 Rev C even came with IE4, however there was one trick. If you left the Windows 95 CD in the drive on the first boot, it’d pop up a box telling you that the install was not done, you’d click that away and IE4 Setup would do its damage. Eject the CD, and you were left with pristine Windows 95. Then when IE5 came around, it could safely be installed without it infecting everything.

Windows 2000

I never got hold of Windows 98 on my desktop, but at some point towards the very end of last century, I got my hands on a copy of Windows 2000 Release Candidate 2. My desktop was still a Pentium 133MHz, although it had 64MB RAM now and few more GB of disk space.

I loaded it on, and it surprised me just how quick the machine seemed to run. It felt faster than Windows 95. That said, it wasn’t all smooth sailing. Where was Network Neighbourhood? That was a nice feature of Windows 95. Ohh no, we have this thing called “My Network Places” now. I figured out how to kludge my own with the quick-launch, but it wasn’t as nice since applications’ file dialogues knew nothing of it.

The other shift was that Internet Explorer still lurked below the surface, and unlike Windows 95, there was no getting rid of it. My time using Linux had made me a Netscape user and so for me it was unneccesary bloat. Windows 2000 did similar Start Menu tricks, including “hiding” applications that it thought I didn’t use very often.

If it’s one thing that irritates me, it’s a computer hiding something from me arbitrarily.

Despite this, it didn’t take as long for me to adapt to it as I did from Windows 3.1 to 95 though, as the UI was still much the same. A few tweaks here and there.

In late 2001, my dinky old Pentium box got replaced. In fact, we replaced both our desktops. Two new dual Pentium III 1GHz boxes, 512MB RAM. My father’s was the first, with a nVidia Riva TNT2 32MB video card and a CD-ROM drive. Mine came in December as a Christmas/18th birthday present, with a ATI Radeon 7000 64MB video card and a DVD drive.

I was to run the old version of Windows NT 4.0 we had. Fun ensued with Windows NT not knowing anything about >8GB HDDs, but Service Pack 6a sorted that out, and the machine ran. I got Linux on there as well (SuSE initially) and apart from the need to distribute ~20GB of data between many FAT16 partitions of about 2GB each (Linux at this time couldn’t write NTFS), it worked. I had drive letters A through to O all occupied.

We celebrated by watching a DVD for the first time (it was our first DVD player in the house).

NT 4 wasn’t too bad to use, it was more like Windows 95, and I quickly settled into it. That said, its tenure was short lived. The momoent anything went wrong with the installation, I found I was right back to square one as the Emergency Repair Disk did not recognise the 40GB HDD. I wrustled up that old copy of Windows 2000 RC2 and found it worked okay, but wouldn’t accept the Windows 2000 drivers for the video card. So I nicked my father’s copy of Windows 2000 and ran that for a little while.

Windows XP was newly released, and so I did enquire about a student-license upgrade, but being a high-school student, Microsoft’s resellers would have none of that. Eventually we bought a new “Linux box” with an OEM copy of Windows 2000 with SP2, and I used that. All legal again, and everything worked.

At this point, I was dual-booting Linux and Windows 2000. Just before the move to ADSL, I had about 800 hours to use up (our dial-up account was one that accumulated unused hours) and so I went on a big download-spree. Slackware 8.0 was one of the downloaded ISOs, and so out went SuSE (which I was running at the time) and in went Slackware.

Suddenly I felt right at home. Things had changed a little, and I even had KDE there, but I felt more in control of my computer than I had in a long while. In addition to using an OS that just lets you do your thing, I had also returned from my OS travels, having gained an understanding of how this stuff works.

I came to realise that point-and-click UIs are fine when they work, hell when they don’t. When they work, any dummy can use them. When they don’t, they cry for the non-dummies to come and sort them out. Sometimes we can, sometimes it’s just reload, wash-rinse-repeat.

No more was this brought home to me when we got hold of a copy of Red Hat 8.0. I tried it for a while, but was immediately confronted by the inability to play the MP3s that I had acquired (mostly via the sneakernet). Ogg/Vorbis was in its infancy and I noticed that at the time, there didn’t seem to be any song metadata such as what ID3 tags provided, or at least XMMS didn’t show it.

A bit of time back on Slackware had taught me how to download sources, read the INSTALL file and compile things myself. So I just did what I always did. Over time I ran afoul with the Red Hat Package Manager, and found myself going in cycles doing many RPM solving dependency hell.

On top of this, there was now the need to man-handle the configuration tools that expected things the way the distribution packagers intended them.

Urgh, back to Slackware I go. I downloaded Slackware 9.0 and stayed with that a while. Eventually I really did go my own way with Linux From Scratch, which was good, but a chore.

These days I use Gentoo, and while I do have my fights with Portage (ohh slot-conflict, how I love you!!!), it does usually let me do what I want.

A time for experimentation and learning

During this time I was mostly a pure KDE user. KDE 2.0, then 3.0. I was learning all sorts of tricks reading HOWTO guides on the Linux Documentation Project. I knew absolutely no one around me that used Linux, in fact on Linux matters, I was the local “expert”. Where my peers (in 2002) might have seen it once or twice, I had been using it since 1996.

I had acquired some more computers by this time, and I was experimenting with setting up dial-up routers with proxy servers (Squid, then IP Masquerade), turning my old 386 into a dumb terminal with XDMCP, getting interoperation between the SCO OpenServer box (our old 486DX4/100MHz).

The ability for the Windows boxes to play along steadily improved over this time, from ethernet frames that passed like ships in the night (circa 1996; NetBEUI and IPX/SPX on the Windows 3.1, TCP/IP on Linux) though to begrudging communications with TCP/IP with newer releases of Windows.

Andrew Tridgell’s SAMBA package made its debut in my experimentation, and suddenly Windows actually started to talk sensible things to the Linux boxes and vice versa.

Over time the ability for Linux machines and Windows boxes to interoperate has improved with each year improving on the next layer in the OSI model. I recall some time in 1998 getting hold of an office suite called ApplixWare, but in general when I wanted word processing I turned to Netscape Composer and Xpaint as my nearest equivalent.

It wasn’t until 2000 or so that I got hold of StarOffice, and finally had an office suite that could work on Windows, Linux and OS/2 that was comparable to what I was using at school (Microsoft Office 97).

In 2002 I acquired an old Pentium 120MHz laptop, and promptly loaded that with Slackware 8 and OpenOffice 1.0. KDE 3.0 chugged with 48MB RAM, but one thing the machine did well was suspend and resume. A little while later we discovered eBay and upgraded to a second-hand Pentium II 266MHz, a machine that served me well into the following year.

For high-school work, this machine was fine. OpenOffice served the task well, and I was quite proficient at using Linux and KDE. I even was a trend-setter… listening to MP3s on the 15GB HDD a good year before the invention of the iPod.

Up to this point, it is worth mentioning that the Microsoft world, the UI hadn’t changed all that much in the time between Windows 95 and 2000/ME. Network Neighbourhood was probably the thing I noticed the most. At this time I was usual amongst my peers in that I had more than one computer at home, and they all talked to each other. Hence why Windows 95/98 through to 2000/ME didn’t create such an uproar.

What people DID notice was how poorly Windows ME (and the first release of 98) performed “under the hood”. More so for the latter than the former.

Windows XP

Of course I did mention trying to get hold of Windows XP earlier. It wasn’t until later in 2002 when the school was tossing out a lab of old AMD K6 machines with brand new boxes (and their old Windows NT 4 server for a Novell one) that I got to see Windows XP up close.

The boxes were to run Windows 2000 actually, but IBM had just sent us the boxes preloaded with XP, and we were to set up Zenworks to image them with Windows 2000. This was during my school holidays and I was assisting in the transition. So I fired up a box and had a poke around.

Up came the initial set up wizard, with the music playing, animations, and a little question mark character which at first did its silly little dance telling you how it was there to help you. Okay, if I had never used Windows before, I’d be probably thankful this was there, but this just felt like a re-hash of that sodding paperclip. At least it did eventually shut up and sit in the corner where I could ignore it. That wasn’t the end of it though.

Set up the user account, logged in, and bam, another bubble telling me to take the tour. In fact, to this day that bubble is one of the most annoying things about Windows XP because 11 years on, on a new install it insists on bugging you for the next 3 log-ins as if you’ve never used the OS before!

The machines had reasonable 17″ CRT monitors, the first thing I noticed was just how much extra space was taken up with the nice rounded corners and the absence of the My Computer and My Network Places icons on the desktop. No, these were in the Start menu now. Where are all the applications? Hidden under All Programs of course.

Hidden and not even sorted in any logical order, so if you’ve got a lot of programs it will take you a while to find the one you want, and even longer to find it’s not actually installed.

I took a squiz at the control panel. Now the control panel hadn’t changed all that much from Windows 3.1 days. It was still basically a window full of icons in Windows 2000/ME, albeit since Windows 95, it now used Explorer to render itself rather than a dedicated application.

Do we follow the tradition so that old hands can successfully guide the novices? No, we’ll throw everyone in the dark with this Category View nonsense! Do the categories actually help the novices? Well for some tasks, maybe, but for anything advanced, most definitely not!

Look and feel? Well if you want to go back to the way Windows used to look, select Classic theme, and knock yourself out. Otherwise, you’ve got the choice of 3 different styles, all hard-coded. Of course somewhere you can get additional themes. Never did figure out where, but it’s Gnome 1.0-style visual inflexibility all over again unless you’re able to hack the theme files yourself.

No thank-you, I’ll stick with the less pixel-wasting Classic theme if you don’t mind!

Meanwhile in Open Source land

As we know, it was a long break between releases of Windows XP, and over the coming years we heard much hype about what was to become Vista. For years to come though, I’d be seeing Windows XP everywhere.

My university work horses (I had a few) all exclusively ran Linux however. If I needed Windows there was a plethora of boxes at uni to use, and most of the machines I had were incapable of running anything newer than Windows 2000.

I now was more proficient in front of a Linux machine than any version of Windows. During this time I was using KDE most of the time. Gnome 2.0 was released, I gave it a try, but, it didn’t really grab me. One day I recall accidentally breaking the KDE installation on my laptop. Needing a desktop, I just reached for whatever I had, and found XFCE3.

I ran XFCE for about a month or two. I don’t recall exactly what brought me back to KDE, perhaps the idea of a dock for launching applications didn’t grab me. AfterStep afterall did something similar.

In 2003, one eBay purchase landed us with a Cobalt Qube2 clone, a Gateway Microserver. Experimenting with it, I managed to brick the (ancient) OS, and turned the thing into a lightish door stop. I had become accustomed to commands like `uname` which could tell me the CPU amonst other things.

I was used to seeing i386, i486, i586 and i686, but this thing came back with ‘mips’. What’s this? I did some research and found that there was an entire port. I also found some notes on bootstrapping a SGI Indy. Well this thing isn’t an Indy, but maybe the instructions have something going for them. I toiled, but didn’t get far…

Figuring it might be an idea to actually try these instructions on an Indy, we hit up eBay again, and after a few bids, we were the proud owners of a used SGI Indy R4600 133MHz with 256MB RAM running IRIX 6.5. I toiled a bit with IRIX, the 4DWM seemed okay to use, but certain parts of the OS were broken. Sound never worked, there was a port of Doom, but it’d run for about 10 seconds then die.

We managed to get some of the disc set for IRIX, but never did manage to get the Foundation discs needed to install. My research however, led me onto the Debian/MIPS port. I followed the instructions, installed it, and hey presto, Linux on a SGI box, and almost everything worked. VINO (the video capture interface) was amongst those things that didn’t at the time, but never mind. Sound was one of the things that did, and my goodness, does it sound good for a machine of that vintage!

Needless to say, the IRIX install was history. I still have copies of IRIX 6.5.30 stashed in my archives, lacking the foundation discs. The IRIX install didn’t last very long, so I can’t really give much of a critique of the UI. I didn’t have removable media so didn’t get to try the automounting feature. The shut down procedure was a nice touch, just tap the OFF button, the computer does the rest. The interface otherwise looked a bit like MWM. The machine however was infinitely more useful to me running Linux than it ever was under IRIX.

As I toiled with Debian/MIPS on the Indy, I discovered there was a port of this for the Qube2. Some downloads later and suddenly the useless doorstop was a useful server again.

Debian was a new experience for me, I quite liked APT. The version I installed evidently was the unstable release, so it had modern software. Liking this, I tried it on one of the other machines, and was met with, Debian Stab^Hle. Urgh… at the time I didn’t know enough about the releases, and on my own desktop I was already using Linux From Scratch by this time.

I was considering my own distribution that would target the Indy, amongst other systems. Already formulating ideas, and at one point, I had a mismash of about 3 different distributions on my laptop.

Eventually I discovered Gentoo, along with its MIPS port. Okay, not as much freedom as LFS, but very close to it. In fact, it gives you the same freedom if you can be arsed to write your own portage tree. One by one the machines got moved over, and that’s what I’ve used.

The primary desktop environment was KDE for most of them. Build times for this varied, but for most of my machines it was an overnight build. Especially for the Indy. Once installed though, it worked quite well. It took a little longer to start on the older machines, but was still mostly workable.

Up to this point, I had my Linux desktop set up just the way I liked it. Over the years the placement of desktop widgets and panels has moved around as I borrowed ideas I had seen elsewhere. KDE was good in that it was flexible enough for me to fundamentally change many aspects of the interface.

My keybindings were set up to be able to perform most window operations without the need of a mouse (useful when juggling the laptop in one’s hands whilst figuring out where the next lecture was), notification icons and the virtual desktop pager were placed to the side for easy access. The launcher and task bar moved around.

Initially down the bottom, it eventually wound up on the top of the screen much like OS/2 Warp 4, as that’s also where the menu bar appears for applications — up the top of the window. Thus minimum mouse movement. Even today, the Windows 7 desktop at work has the task bar up the top.

One thing that frustrated me with Windows at the time was the complete inability to change many aspects of the UI. Yes you could move the task bar around and add panels to it, but if you wanted to use some other keystroke to close the window? Tough. ALT-F4 is it. Want to bring up the menu items? Hit the logo key, or failing that, CTRL-ESC. Want to maximise a window? Either hit ALT-Space, then use the arrows to hit Maximise, or start reaching for the rodent. Far cry from just pressing Logo-Shift-C or Logo-Shift-X.

Ohh, and virtual desktops? Well, people have implemented crude hacks to achieve something like it. In general, anything I’ve used has felt like a bolt-on addition rather than a seamless integration.

I recall commenting about this, and someone pointing out this funny thing called “standardisation”. Yet, I seem to recall the P in PC standing for personal. i.e. this is my personal computer, no one else uses it, thus it should work the way I choose it to. Not what some graphic designer in Redmond or Cupertino thinks!

The moment you talk about standardisation or pining for things like Group Policy objects, you’ve crossed the boundary that separates a personal computer from a workstation.

Windows Vista

Eventually, after much fanfare, Microsoft did cough up a new OS. And cough up would be about the right description for it. It was behind schedule, and as a result, saw many cut backs. The fanciful new WinFS? Gone. Palladium? Well probably a good thing that did go, although I think I hear its echoes in Secure Boot.

What was delivered, is widely considered today a disaster. And it came at just the wrong time. Just as the market for low-end “netbook” computers exploded, just the sort of machine that Windows Vista runs the worst on.

Back in the day Microsoft recommended 8MB RAM for Windows 95 (and I can assure you it will even run in 4MB), but no one in their right mind would tollerate the constant rattle from the paging disk. The same could be said for Windows NT’s requirement of 12MB RAM and a 486. Consumers soon learned that “Windows Vista Basic ready” meant a warning label to steer clear of, or insist on it coming with Windows XP.

A new security feature, UAC, ended up making more of a nuisance of itself, causing people to do the knee-jerk reaction of shooting the messenger.

The new Aero interface wastes even more screen pixels than the “Luna” interface of Windows XP. And GPU cycles to boot. The only good thing about it was that the GPU did all the hard work putting windows on the screen. It looked pretty, when the CPU wasn’t overloaded, but otherwise the CPU had trouble keeping up and the whole effect was lost. Exactly what productivity gains one has by having a window do three somersaults before landing in the task bar on minimise is lost on me.

Windows Vista was the last release that could do the old Windows 95 style start menu. The newer Vista one was even more painful than the one in XP. The All Programs sub-menu opened out much like previous editions did (complete with the annoying “compress myself into a single column”). In Vista, this menu was now entrapped inside this small scrolling window.

Most of Vista’s problems were below the surface. Admittedly Service Pack 1 fixed a lot of the problems, it was already too late. No one wanted to know.

Even with the service packs, it still didn’t perform up to par on the netbooks that were common for the period. The original netbook for what it’s worth, was never intended to run any version of Windows, the entire concept came out of the One Laptop Per Child project, which was always going to be Linux based.

Asus developed the EeePC was one of the early candidates for the OLPC project. When another design got selected, Asus simply beefed up the spec, loaded on Xandros and pushed it out the door. Later models came with Windows XP, and soon, other manufacturers pitched in. This was a form factor with specs that ran Windows XP well, unfortunately Vista’s Aero interface was too much for the integrated graphics typically installed, and the memory requirements had the disk drive rattling constantly, sapping the machine of valuable kilojoules when running from the battery.

As to my run-in with Vista? For my birthday one year I was given a new laptop. This machine came pre-loaded with it, and of course, the very first task I did was spend a good few hours making the recovery discs then uninstalling every piece of imaginable crap that manufacturers insist on prebloating their machines with.

For what I needed, I actually needed Linux to run. The applications I use and depend on for university work, whilst compatible with Windows, run as second class citizens due to their Unix heritage. Packages like The Gimp, gEDA, LaTeX, git, to name a few, never quite run as effortlessly on Windows. The Gimp had a noticable lag when using my Wacom tablet, something that put my handwriting way off.

Linux ran on it, but with no support for the video card, GUI related tasks were quite choppy. In the end, it proved to be little use to me. My father at the time was struggling along with his now aging laptop using applications and hardware that did not support Windows Vista. I found a way to exorcise Windows Vista from the machine, putting Windows XP in its place.

The bloat becomes infectious

What was not lost on me, was that each new iteration of full desktops like KDE brought in more dependencies. During my latter years at University, I bought myself a little netbook. I was doing work for Gentoo/MIPS with their port of Linux, and thus a small machine that would run what I needed for university, and could serve as a test machine during my long trips between The Gap and Laidley (where I was doing work experience for Eze Corp) would go down nicely. So I fired off an email and a telegraphic money transfer over to Lemote in China, and on the doorstep turned up a Yeeloong netbook.

I dual booted Debian and Gentoo on this machine, in fact I still do. Just prior to buying this machine, I was limping along with an old Pentium II 300MHz laptop. I did have a Pentium 4M laptop, but a combination of clumsiness and age slowly caused the machine’s demise. Eventually it failed completely, and so I just had to make do with the PII which had been an earlier workhorse.

One thing, KDE 3.0 was fine on this laptop. Even 3.5 was okay. But when you’ve only got 300MHz of CPU and 160MB RAM, the modern KDE releases were just a bit too much. Parts of KDE were okay, but for the main desktop, it chugged along. Looking around, I needed a workable desktop, so I installed FVWM. I found the lack of a system tray annoyed me, so in went stalonetray. Then came maintaining the menu. Well, modern FVWM comes with a Perl script that automates this, so in that went.

Finally, a few visual touches, a desktop background loader, some keybinding experiments and I pretty much had what KDE gave me, that started in a fraction of the time, and built much faster. When the Yeeloong turned up and I got Gentoo onto there, the FVWM configuration here was the first thing to be installed on the Yeeloong, and so I had a sensible desktop for the Yeeloong.

Eventually I did get KDE 4 working on the Yeeloong, sort of. It was glitchy on MIPS. KDE 3.5 used to work without issue but 4.0 never ran quite right. I found myself using FVWM with just the bits of KDE that worked.

As time went on, university finished, and the part-time industrial experience became full-time work. My work at the time revolved around devices that needed Windows and a parallel port to program them. We had another spare P4 laptop, so grabbed that, tweaked Windows XP on there to my liking, and got to work. The P4 “lived” at Laidley and was my workstation of sorts, the Yeeloong came with me to and from there. Eventually that work finished, and through the connections I came to another company (Jacques Electronics). In the new position, it was Linux development on ARM.

The Windows installation wasn’t so useful any more. So in went a copy of the gPartED LiveCD, told Windows to shove, followed by a Gentoo disc and a Stage 3 tarball. For a while my desktop was just the Linux command line, then I got X and FVWM going, finally as I worked, KDE.

I was able to configure KDE once again, and on i686 hardware, it ran as it should. It felt like home, so it stayed. Over time the position at Jacques finished up, I came to work at VRT where I am to this day. The P4 machine stayed at the workplace, with the netbook being my personal machine away from work.

It’s worth pointing out that at this point, although Windows 7 had been around for some time, I was yet to actually come to use it first hand.

My first Apple

My initial time at VRT was spent working on a Python-based application to ferry metering data from various energy meters to various proprietary systems. The end result was a package that slotted in along side MacroView called Metermaster, and forms one of the core components in VRT’s Wages Hub system. While MacroView can run on Windows, and does for some (even Cygwin), VRT mainly deploys it on Ubuntu Linux. So my first project was all Linux based.

During this time, my new work colleagues were assessing my skills, and were looking at what I could work on next. One of the discussions revolved around working on some of their 3D modelling work using Unity3D. Unity3D at the time, ran on just two desktop OSes. Windows, and MacOS X.

My aging P4 laptop had a nVidia GeForce 420Go video device with 32MB memory. In short, if I hit that thing with a modern 3D games engine, it’d most likely crap itself. So I was up for a newer laptop. That got me thinking, did I want to try and face Windows again, or did I want to try something new?

MacOS was something I had only fleeting contact with. MacOS X I had actually never used myself. I knew a bit about it, such as its basis was on the FreeBSD userland, the Mach microkernel. I saw a 2008 model MacBook with a 256MB video device inbuilt, going cheap, so I figured I’d take the plunge.

My first impressions of MacOS X 10.5 were okay. I had a few technical glitches at first, namely MacOS X would sometimes hang during boot, just showing nothing more than an Apple logo and a swirling icon. Some updates refused to download, they’d just hang and the time estimate would blow out. Worst of all, it wouldn’t resume, it’d just start at the beginning.

In the end I wandered down to the NextByte store in the city, bought a copy of MacOS X 10.6. I bought the disc on April 1st, 2011, and it’s the one and only disc the DVD drive in the MacBook won’t accept. The day I bought it I was waiting at the bus stop, figured I’d have a look and see what docs there are. I put the disc in, hear a few noises, it spits the disc out again. So I put it back in again, and out it comes. Figuring this was a defective disc, I put the disc back in and march back down to the shop, receipt in one hand, cantankerous laptop in the other. So much for Apple kit “just working”.

Then the laptop decided it liked the pussy cat disc so much it wouldn’t give it back! Cue about 10 minutes in the service bay getting the disc to eject. Finally the machine reneged and spat the disc out. That night it tried the same tricks, so I grabbed an external DVD drive and did the install that way. Apart from this, OSX 10.6 has given me no problems in that regard.

As for the interface? I noticed a few things features that I appreciated from KDE, such as the ability to modify some of the standard shortcuts, although not all of them. Virtual desktops get called Spaces in MacOS X, but essentially the same deal.

My first problem was identifying what the symbols on the key shortcuts meant. Command and Shift were simple enough, but the symbol used to denote “Option” was not intuitive, and I can see some people getting confused for the one for Control. That said, once I found where the Terminal lived, I was right at home.

File browsing? Much like what I’m used to elsewhere. Stick a disc in, and it appears on the desktop. But then to eject? The keyboard eject button didn’t seem to work. Then I remembered a sarcastic comment one of my uncles made about using a Macintosh, requiring you to “throw your expensive software in the bin to eject”. So click the CD icon, drag to the rubbish bin icon, voilà, out it comes.

Apple’s applications have always put the menu bar of the application right up the top of the screen. I found this somewhat awkward when working with multiple applications since you find yourself clicking on one (or command-tabbing over to) one window, access the menu there, then clicking (or command-tabbing) to the other, access the menu up the top of the screen.

Switching applications with Command-Tab works by swapping between completely separate applications. Okay if you’re working with two completely separate applications, not so great if you’re working on many instances of the same application. Exposé works, probably works quite well if the windows are visually distinct when zoomed out, but if they look similar, one is reminded of Forrest Gump: “Life’s like a box of chocolates, you never know what you’re gonna get!”

The situation is better if you hit Command-Tab, then press a down-arrow, that gives you an Exposé of just the windows belonging to that application. A far cry from hitting Alt-Tab in FVWM to bring up the Window List and just cycling through. Switching between MacVim instances was a pain.

As for the fancy animations. Exposé looks good, but when the CPUs busy (and I do give it a hiding), the animation just creeps along at a snail’s pace. I’ll tolerate it if it’s over and done with within a second, but when it takes 10 seconds to slowly zoom out, I’m left sitting there going “Just get ON with it!” I’d be fine if it just skipped the animation and just switched from normal view to Exposé in a single frame. Unfortunately there’s nowhere to turn this off that I’ve found.

The dock works to an extent. It suffers a bit if you have a lot of applications running all at once, there’s only so much screen real-estate. A nice feature though is in the way it auto-hides and zooms.

When the mouse cursor is away from the dock, it drops off the edge of the screen. As the user configures this and sets up which edge it clings to, this is a reasonable option. As the mouse is brought near the space where the dock resides, it slowly pops out to meet the cursor. Not straight away, but progressively as the proximity of the cursor gets closer.

When fully extended, the icons nearest the cursor enlarge, allowing the rest to remain visible, but not occupy too much screen real-estate. The user is free to move the cursor amongst them, the ones closest zooming in, the ones furtherest away zooming out. Moving the cursor away causes the dock to slip away again.

Linux on the MacBook

And it had to happen, but eventually Linux did wind up on there. Again, KDE initially, but I again, found that KDE was just getting too bloated for my liking. It took about 6 months of running KDE before I started looking at other options.

FVWM was of course where I turned to first, in fact, it was what I used before KDE was finished compiling. I came to the realisation that I was mostly just using windows full-screen. So I thought, what about a tiling window manager?

Looking at a couple, I settled on Awesome. At first I tried it for a bit, didn’t like it, reverted straight back to FVWM. But then I gave it a second try.

Awesome works okay, it’s perhaps not the most attractive to look at, but it’s functional. At the end of the day looks aren’t what matter, it’s functionality. Awesome was promising in that it uses Lua for its configuration. It had a lot of the modern window manager features for interacting with today’s X11 applications. I did some reading up on the handbook, did some tweaking of the configuration file and soon had a workable desktop.

The default keybindings were actually a lot like what I already used, so that was a plus. In fact, it worked pretty good. Where it let me down was in window placement. In particular, floating windows, and dividing the screen.

Awesome of course works by a number of canned window layouts. It can make a window full screen (hiding the Awesome bar) or near full-screen, show two windows above/below each other or along side. Windows are given numerical tags which cause those windows to appear whenever a particular tag is selected, much like virtual desktops, only multiple tags can be active on a screen.

What irritated me most was trying to find a layout scheme that worked for me. I couldn’t seem to re-arrange the windows in the layout, and so if Awesome decided to plonk a window in a spot, I was stuck with it there. Or I could try cycling through the layouts to see if one of the others was better. I spent much energy arguing with it.

Floating windows were another hassle. Okay, modal dialogues need to float, but there was no way to manually override the floating status of a window. The Gimp was one prime example. Okay, you can tell it to not float its windows, but it still took some jiggery to get each window to sit where you wanted it. And not all applications give you this luxury.

Right now I’m back with the old faithful, FVWM.

FVWM

FVWM, as I have it set up on Gentoo

Windows 7

When one of my predecessors at VRT left to work for a financial firm down in Sydney, I wound up inheriting his old projects, and the laptop he used to develop them on. The machine dual-boots Ubuntu (with KDE) and Windows 7, and seeing as I already have the MacBook set up as I want it, I use that as my main workstation and leave the other booted into Windows 7 for those Windows-based tasks.

Windows 7 is much like Windows Vista in the UI. Behind the scenes, it runs a lot better. People aren’t kidding when they say Windows 7 is “Vista done right”. However, recall I mentioned about Windows Vista being the last to be able to do the classic Start menu? Maybe I’m dense, but I’m yet to spot the option in Windows 7. It isn’t where they put it Windows XP or Vista.

So I’m stuck with a Start menu that crams itself into a small bundle in one corner of the screen. Aero has been turned off in favour of a plain “classic” desktop. I have the task bar up the top of the screen.

One new feature of Windows 7 is that the buttons of running applications by default only show the icon of the application. Clicking that reveals tiny wee screenshots with wee tiny title text. More than once I’ve been using a colleague’s computer, he’ll have four spreadsheets open, I’ll click the icon to switch to one of them, and neither of us can figure out which one we want.

Thankfully you can tell it to not group the icons, showing a full title next to the icon on the task bar, but it’s an annoying default.

Being able to hit Logo-Left or Logo-Right to tile a window on the screen is nice, but I find more often than not I wind up hitting that when I mean to hit one of the other meta keys, and thus I have to reach for the rodent and maximise the window again. This is more to do with the key layout of the laptop than Windows 7, but it’s Windows 7′s behaviour and the inability to configure it that exacerbates the problem.

The new start menu I’d wager, is why Microsoft saw so many people pinning applications to the task bar. It’s not just for quick access, in some cases it’s the only bleeding hope they’d ever find their application again! Sure, you can type the name of the application, but circumstance doesn’t always favour that option. Great if you know exactly what the program is called, not so great if it’s someone else’s computer and you need to know if something is even there.

Thankfully most of the effects can be turned off, and so I’m left with a mostly Spartan desktop that just gets the job done. I liken using Windows to a business trip abroad, you’re not there for pleasure, and there’s nothing quite like home sweet home.

Windows 8

Now, I get to this latest instalment of desktop Operating Systems. I have yet to actually use it myself, but looking at a few screenshots, a few thoughts:

  • “Modern”: apart from being a silly name for a UI paradigm (what do you call it when it isn’t so “modern” anymore?), looks like it could really work well on the small screen. However, it relies quite heavily on gestures and keystrokes to navigate. All very well if you set these up to suit how you operate yourself, but not so great when forced upon you.
  • Different situations will call for different interface methods. Sometimes it is convenient to reach out and touch the screen, other times it’ll be easier to grab the rodent, other times it’ll be better to use the keyboard. Someone should be able to achieve most tasks (within reason) with any of the above, and seamlessly swap between these input methods as need arises.
  • “Charms” and “magic corners” makes the desktop sound like it belongs on the set of a Harry Potter film
  • Hidden menus that jump out only when you hit the relevant corner or edge of the screen by default without warning will likely startle and confuse
  • A single flat hierarchy of icons^Wtiles for all one’s applications? Are we back to MS-DOS Executive again?
  • “Press the logo key to access the Start screen”, and so what happens if the keyboard isn’t in convenient reach but the mouse is?
  • In a world where laptops are out-numbering desktops and monitors are getting wider faster than they’re getting taller, are extra-high ribbons really superior to drop-down menus for anyone other than touch users?

Apparently there’s a tutorial when you first start up Windows 8 for the first time. Comments have been made about how people have been completely lost working with the UI until they saw this tutorial. That should be a clue at least. Keystrokes are really just a shortened form of command line. Even the Windows 7 start menu, with its search bar, is looking more like a stylised command line (albeit one with minimal capability).

Are we really back to typing commands into pseudo command line interfaces?

The Command line: what is old is new again

The Command line: what is old is new again

I recall the Ad campaigns for Windows 7, on billboards, some attractive woman posing with the caption: “I’m a PC and Windows 7 was my idea”

Mmm mmm, so who’s idea was Windows 8 then? There’s no rounded rectangles to be seen, so clearly not Apple’s. I guess how well it goes remains to be seen.

It apparently has some good improvements behind the scenes, but anecdotal evidence at the workplace suggests that the ability to co-operate with a Samba 3.5-based Windows Domain is not among them. One colleague recently bought herself a new ultrabook running Windows 8.

I’m guessing sooner or later I’ll be asked to assist with setting up the Cisco VPN client and setting up links to file shares, but another colleague, despite getting the machine to successfully connect to the office Wifi, couldn’t manage to bring up a login prompt to connect to the file server, the machine instead just assuming the local username and password matched the credentials to be used on the remote server. I will have to wait and see.

Where to now?

Well I guess I’m going to stick with FVWM a bit longer, or maybe pull my finger out and go my own way. I think Linus has a point when he describes KDE as a bit “cartoony”. Animations make something easy to sell, but at the end of the day, it actually has to do the work. Some effects can add value to day-to-day tasks, but most of what I’ve seen over the years doesn’t seem to add much at all.

User interfaces are not one-size-fits-all. Never have been. Touch screen interfaces have to deal with problems like fat fingers, and so there’s a balancing act between how big to make controls and how much to fit on a screen. Keyboard interfaces require a decent area for a keypad, and in the case of standard computer keyboards, ideally, two hands free. Mice work for selecting individual objects, object groups and basic gestures, but make a poor choice for entering large amounts of data into a field.

For some, physical disability can make some interfaces a complete no-go. I’m not sure how I’d go trying to use a mouse or touch screen if I lost my eyesight for example. I have no idea how someone minus arms would go with a tablet — if you think fat fingers is a problem, think about toes! I’d imagine the screens on those devices often would be too small to read when using such a device with your feet, unless you happen to have very short legs.

Even for those who have full physical ability, there are times when one input method will be more appropriate at a given time than another. Forcing one upon a user is just not on.

Hiding information from a user has to be carefully considered. One of my pet peeves is when you can’t see some feature on screen because it is hidden from view. There is one thing if you yourself set up the computer to hide something, but quite another when it happens by default. Having a small screen area that activates and reveals a panel is fine, if the area is big enough and there is some warning that the panel is about to fly out.

As for organising applications? I’ve never liked the way everything just gets piled into the “Programs” directory of the Start Menu in Windows. It is just an utter mess. MacOS X isn’t much better.

The way things are in Linux might take someone a little discovery to find where an application has been put, but once discovered, it’s then just a memory exercise to get at it, or shortcuts can be created. Much better than hunting through a screen-full of unsorted applications.

Maybe Microsoft can improve on this with their Windows Store, if they can tempt a few application makers from the lucrative iOS and Android markets.

One thing is clear, the computer is a tool, and as such, must be able to be adapted for how the user needs to use that tool at any particular time for it to maintain maximum utility.

Jan 202013
 

Many moons ago, we acquired an old RolandDG DXY-800A plotter.  This is an early A3 plotter which took 8 pens, driven via either the parallel port or the serial port.

It came with software to use with an old DOS-version of AutoCAD.  I also remember using it with QBasic.  We had the handbook, still do, somewhere, if only I could lay my hands on it.  Either that, or on the QBasic code I used to use with the thing, as that QBasic code did exercise most of the functionality.

Today I dusted it off, wondering if I could get it working again.  I had a look around.  The thing was not difficult to drive from what I recalled, and indeed, I found the first pointer in a small configuration file for Eagle PCB.

The magic commands:

H Go home
Jn Select Pen n (1..8)
Mxxxx,yyyy Move (with pen up) to position xxx.x, yyy.y mm from lower left corner.
Dxxxx,yyyy Draw (with pen down) a line to position xxx.x, yyy.y mm

Okay, this misses the text features, drawing circles and hatching, but it’s a good start.  Everything else can be emulated with the above anyway.  Something I’d have to do, since there was only one font, and I seem to recall, no ability to draw ellipses.

Inkscape has the ability to export HPGL, so I had a look at what the format looks like.  Turns out, the two are really easy to convert, and Inkscape HPGL is entirely line drawing commands.

hpgl2roland.pl is a quick and nasty script which takes Inkscape-generated HPGL, and outputs RolandDG plotter language. It’s crude, only understands a small subset of HPGL, but it’s a start.

It can be used as follows:

$ perl hpgl2roland.pl < drawing.hpgl > /dev/lp0
Jan 052013
 

Those who have met me, might notice I have a somewhat unusual taste in clothing. One thing I despise is having clothes that are heavily branded, especially when the local shops then charge top dollar for them.

Where hats are concerned, I’m fussy. I don’t like the boring old varieties that abound $2 shops everywhere. I prefer something unique.

The mugshot of me with my Vietnamese coolie hat is probably the one most people on the web know me by. I was all set to try and make one, and I had an idea how I might achieve it, bought some materials I thought might work, but then I happened to be walking down Brunswick Street in Brisbane’s Fortitude Valley and saw a shop selling them for $5 each.

I bought one and have been wearing it on and off ever since. Or rather, I bought one, it wore out, I was given one as a present, wore that out, got given two more. The one I have today is #4.

I find them quite comfortable, lightweight, and most importantly, they’re cool and keep the sun off well. They are also one of the few full-brim designs that can accommodate wearing a pair of headphones or headset underneath. Being cheap is a bonus. The downside? One is I find they’re very divisive, people either love them or hate them — that said I get more compliments than complaints. The other, is they try to take off with the slightest bit of wind, and are quite bulky and somewhat fragile to stow.

I ride a bicycle to and from work, and so it’s just not practical to transport. Hanging around my neck, I can guarantee it’ll try to break free the moment I exceed 20km/hr… if I try and sit it on top of the helmet, it’ll slide around and generally make a nuisance.

Caps stow much easier. Not as good sun protection, but still can look good.   I’ve got a few baseball caps, but they’re boring and a tad uncomfortable.  I particularly like the old vintage gatsby caps — often worn by the 1930′s working class.  A few years back on my way to uni I happened to stop by a St. Vinnies shop near Brisbane Arcade (sadly, they have closed and moved on) and saw a gatsby-style denim cap going for about $10. I bought it, and people commented that the style suited me. This one was a little big on me, but I was able to tweak it a bit to make it fit.

Fast forward to today, it is worn out — the stitching is good, but there are significant tears on the panelling and the embedded plastic in the peak is broken in several places. I looked around for a replacement, but alas, they’re as rare as hens teeth here in Brisbane, and no, I don’t care for ordering overseas.

Down the road from where I live, I saw the local sports/fitness shop were selling those flat neoprene sun visors for about $10 each.  That gave me an idea — could I buy one of these and use it as the basis of a new cap?

These things basically consist of a peak and headband, attached to a dome consisting of 8 panels.  I took apart the old faithful and traced out the shape of one of the panels.

Now I already had the headband and peak sorted out from the sun visor I bought, these aren’t hard to manufacture from scratch either.  I just needed to cut out some panels from suitable material and stitch them together to make the dome.

There are a couple of parameters one can experiment that changes the visual properties of the cap.  Gatsby caps could be viewed as an early precursor to the modern baseball cap.  The prime difference is the shape of the panels.

Measurements of panel from old cap

The above graphic is also available as a PDF or SVG image.  The key measurements to note are A, which sets the head circumference, C which tweaks the amount of overhang, and D which sets the height of the dome.

The head circumference is calculated as ${panels}×${A} so in the above case, 8 panels, a measurement of 80mm, means a head circumference of 640mm.  Hence why it never quite fitted (58cm is about my size) me.  I figured a measurement of about 75mm would do the trick.

B and C are actually two of three parameters that separates a gatsby from the more modern baseball cap.  The other parameter is the length of the peak.  A baseball cap sets these to make the overall shape much more triangular, increasing B to about half D, and tweaking C to make the shape more spherical.

As for the overhang, I decided I’d increase this a bit, increasing C to about 105mm.  I left measurements B and D alone, making a fairly flattish dome.

For each of these measurements, once you come up with values that you’re happy with, add about 10mm to A, C and D for the actual template measurements to give yourself a fabric margin with which to sew the panels together.

As for material, I didn’t have any denim around, but on my travels I saw an old towel that someone had left by the side of the road — likely an escapee.  These caps back in the day would have been made with whatever material the maker had to hand.  Brushed cotton, denim, suede leather, wool all are common materials.  I figured this would be a cheap way to try the pattern out, and if it worked out, I’d then see about procuring some better material.

Below are the results, click on the images to enlarge.  I found due to the fact that this was my first attempt, and I just roughly cut the panels from a hand-drawn template, the panels didn’t quite meet in the middle.  This is hidden by making a small circular patch where the panels normally meet.  Traditionally a button is sewn here.  I sewed the patch from the underside so as to hide the edges of it.

Hand-made gatsbyHand-made gatsby (Underside)

Not bad for a first try, I note I didn’t quite get the panels aligned at dead centre, the seam between the front two is just slightly off centre by about 15mm.  The design looks alright to my eye, so I might look around for some suede leather and see if I can make a dressier one for more formal occasions.

Nov 042012
 

Mexico to Apple: You WILL NOT use the name ‘iPhone’ here

We don’ need no stinkin’ badge lawsuits

Apple has lost the right to use the word “iPhone” in Mexico after its trademark lawsuit against Mexican telco iFone backfired.

http://www.theregister.co.uk/2012/11/02/iphone_ifone_mexico_trademark/

Not so nice when the shoe’s on the other foot now is it, Apple? Now if only other law courts had such common sense.

Sep 302012
 

Just thought I’d post this up here for “backup” purposes… lately I’ve been doing a lot of AVR programming, the first step of course was to procure a programmer for the devices.

The following is a schematic for the programmer I have built myself. It can be built out of scrap bits, none of the components are critical in value.

It gets its name as it is essentially identical to the “DASA” serial cables, only all the signals are inverted.  The inverting buffers serve to provide voltage level conversion along with crude tri-state functionality when the AVR device is not being programmed.

Inverted-"DASA" serial programming cable for AVR

Inverted-”DASA” serial programming cable for AVR

The design is released under the TAPR Open Hardware License.

Sep 102012
 

Over the years I’ve used many a desktop environment or window manager for my graphical desktop. In the beginning it was FVWM (1.x), a later update brought me AnotherLevel (basically Red Hat’s branded FVWM), I also toyed with OLVWM, WindowMaker, AfterStep, CTWM and a few others.

KDE was one of the few that I’ve used long-term. I loved KDE 1.0 when it was first released. Gnome 1.0 came out, and I soon switched over, but it was only a matter or a month or two and I was back to KDE. Likewise with XFCE, did try it for a little while, but then I returned. Lately, KDE has been getting a bit bloaty for my liking. Thus, I’ve been on the window manager trail, and for now, I’m back with FVWM.

This has worked well, except for one bug bear; I could not get the compose key to work. So I did some digging, and came up with the following:

setxkbmap -option compose:rwin

Add that to your .xinitrc, or you can do what I did, and add it to the FVWM start up scripts:
AddToFunc InitFunction
# Load the X Setup Scripts setting if we use it
+ I Exec [ -f $HOME/.xinitrc-fvwm ] && sh $HOME/.xinitrc-fvwm
+ I Exec exec awsetbg -a -r /home/stuartl/backdrops
+ I Exec exec kmix
+ I Exec exec klipper
+ I Exec exec blueman-manager
+ I Exec exec xscreensaver
+ I Exec exec setxkbmap -option compose:rwin

When you re-start your session, you should find the right logo key (“Windows” key, or in my case “Command” key, yes my machine is that fruity) will deliver the dead-key magic.

Aug 082012
 

I’ll be posting up a series of notes on various aspects of OpenERP. This is largely as a brain-dump for my own reference, but might prove interesting for others who may be facing the same problems I have faced in my maintenance of my work’s OpenERP instance.

OpenERP’s mail gateway system is a generic interface for manipulating objects according to the reception of incoming emails. The system can either receive emails via a script ran by the mail server, or by periodic collection of a POP3/IMAP mail account. Each dedicated account is allocated for processing of one kind of object. You can also configure outbound email SMTP servers for sending email traffic — these can be accessed and utilised by any object.

Sending emails from OpenERP objects

Configuring outbound email

Configuring outbound email is a fairly straightforward affair. After installing the ‘mail’ module (or one of its dependents) you should be able to see “Outgoing Mail Servers” under Settings/Configuration/Email.

The configuration here is not much different to any email client you might otherwise configure; give the host name of the SMTP server, port and connection security options, click save and you’re done. Unless you’ve got a fairly specialised set-up, you should only need to configure the one mail server.

Sending arbitrary messages: mail.message

As the saying goes, there is more than one way to skin a cat, and here is no different. There are in fact, two interfaces for sending emails. The first of these is mail.message, which is useful for sending arbitrary messages. It defines a method, schedule_with_attach which, as the name suggests, schedules an email for delivery, optionally with an attachment or two.

def schedule_with_attach(self, cr, uid, email_from, email_to, subject,
        body, model=False, email_cc=None, email_bcc=None,
        reply_to=False, attachments=None, message_id=False,
        references=False, res_id=False, subtype='plain', headers=None,
        mail_server_id=False, auto_delete=False,
        context=None):
    """ Schedule sending a new email message, to be sent the next time the
        mail scheduler runs, or the next time :meth:`process_email_queue` is
        called explicitly.

    :param string email_from: sender email address
    :param list email_to: list of recipient addresses (to be joined with commas)
    :param string subject: email subject (no pre-encoding/quoting necessary)
    :param string body: email body, according to the ``subtype`` (by default, plaintext).
        If html subtype is used, the message will be automatically converted
        to plaintext and wrapped in multipart/alternative.
    :param list email_cc: optional list of string values for CC header (to be joined with commas)
    :param list email_bcc: optional list of string values for BCC header (to be joined with commas)
    :param string model: optional model name of the document this mail is related to (this will also
        be used to generate a tracking id, used to match any response related to the
        same document)
    :param int res_id: optional resource identifier this mail is related to (this will also
        be used to generate a tracking id, used to match any response related to the
        same document)
    :param string reply_to: optional value of Reply-To header
    :param string subtype: optional mime subtype for the text body (usually 'plain' or 'html'),
        must match the format of the ``body`` parameter. Default is 'plain',
        making the content part of the mail "text/plain".
    :param dict attachments: map of filename to filecontents, where filecontents is a string
        containing the bytes of the attachment
    :param dict headers: optional map of headers to set on the outgoing mail (may override the
        other headers, including Subject, Reply-To, Message-Id, etc.)
    :param int mail_server_id: optional id of the preferred outgoing mail server for this mail
    :param bool auto_delete: optional flag to turn on auto-deletion of the message after it has been
        successfully sent (default to False)"""

So in your method, you might call it with something like this:

def send_mail(cr, uid, ids, ... context=None):
    if not isinstance(ids, list):
        ids = [ids]

    msg_pool = self.pool.get('mail.message')
    for object in self.browse(cr, uid, ids, context=context):
        # Constructing the body text. This can be done a variety of ways
        body_text = '''An example email body using some fields from the object.
Object name: %s
Object ID: %s
''' % (object.name, object.id)

        msg_pool.schedule_with_attach(cr, uid, email_from='some@email.address',
                email_to=[  'a@list.of',
                            'people@for.the',
                            'to@list' ],
                subject='Your Spam',
                body=body_text, # Constructed above
                email_cc=['same@deal'], # or False for no CCs
                email_bcc=['etc@somewhere'],
                ..., context=context)

If you trigger this method, then look in your outbound message queue (Settings/Email/Messages) you’ll see the message queued for delivery. At some point the scheduler in OpenERP will send this message to the destination address. This is done every few minutes or so.

Sending templated messages: email.template

This sort of hard-coded message is all very well, but they aren’t pretty, and they certainly aren’t user customisable. The project module gets around the user customisability by providing fields for a header and footer with a fixed set of fields, but if you want to do something nicer, you’re out of luck. We had a need to be able to notify people when tasks were assigned to them, or whenever the task was closed. I initially used the above approach, but then investigated the email.template method.

Under “Settings/Configuration/Email/Templates” you’ll see a list of such templates. Essentially you can fill any field from the source object in, at any position. In each field, any text inside ${ } blocks is executed as Python code. There seems to be more options here for formatting, but so far that’s what I definitely know. The object being formatted gets passed in as object, and the context dict is exposed as ctx. You’ve got the ability to customise both HTML and plain-text versions, and to attach a report or existing files if you so choose.

So for my project task notification, I took the following approach. Firstly, to save me a lot of messy code, I augmented the task object with a function field which enumerated all the people that were to be notified. The idea was to enhance the “Warn Manager”/”Warn Customer”, replacing that implementation with this one. So in a custom module, I code up a derived model like so:

class project_task(osv.osv):
    '''
    Project Task notification hooks.  This allows us to send an email
    when a task is created or updated.
    '''
    _name = "project.task"
    _inherit = "project.task"

    def _get_mailing_list(self, cr, uid, ids, field_name, arg, context=None):
        '''Fetch the list of email addresses that will be sent notifications.'''

        ret = {}
        for task in self.browse(cr, uid, ids, context=context):
            mail_list = set()

            if task.user_id and task.user_id.notify_on_task \
                    and task.user_id.user_email:
                mail_list.add(task.user_id.user_email)

            if task.manager_id and (task.manager_id.notify_on_task or      \
                     (task.project_id and task.project_id.warn_manager))  \
                        and task.manager_id.user_email:
                mail_list.add(task.manager_id.user_email)

            if task.project_id and task.project_id.warn_customer:
                for partner in filter(lambda p : p, [task.partner_id,
                        task.project_id.partner_id]):
                    if partner.address and partner.address[0].email:
                        mail_list.add(partner.address[0].email)

            # We have a set of relevant email addresses, convert to a sorted
            # list and put it in the returned output.
            ret[task.id] = u','.join(sorted(mail_list))
        return ret

    _columns = {
        'notification_mailing_list': fields.function(_get_mailing_list, type='text',
                string='Email addresses to notify', store=False),
    }

You’ll notice that here, res.users has an additional field; notify_on_task, this is a per-user flag, configurable in the user preferences that lets users decide whether they’ll personally get nagged or not. I use a set, as we only want to add each address once.

We can now use this field in the template to populate the To: field, rather than a very messy lambda expression to do the same.

Next, we create the template. Now, you can (and I did) create this in the user interface, the following shows how to do it inside the XML files for a module. This was lifted from the edi demo and tweaked.

    <!-- Mail template and workflow bindings are done in a NOUPDATE block
         so users can freely customize/delete them -->
    <data noupdate="1">
        <!--Email template -->
        <record id="email_template_task" model="email.template">
            <field name="name">Automated Task Update Notification Mail</field>
            <field name="email_from">${ctx.get('uid_email') or 'no-body@localhost.localdomain'}</field>
            <field name="subject">Task #${object.id}: ${object.name} [${object.state.title()}]</field>
            <field name="email_to">${object.notification_mailing_list}</field>
            <field name="model_id" ref="project.model_project_task"/>
            <field name="body_html"><![CDATA[
            <p>Hello, The following task has recently been updated:</p>
            <ul>
                <li>${'<i>(Updated)</i> ' if 'name' in ctx.get('changed_fields',[]) else ''}Name: ${object.name} [Task ID #${object.id}]</li>
                <li>${'<i>(Updated)</i> ' if 'state' in ctx.get('changed_fields',[]) else ''}State: ${object.state.title()}</li>
                <li>${'<i>(Updated)</i> ' if 'project_id' in ctx.get('changed_fields',[]) else ''}Project: ${object.project_id.name if object.project_id else 'No project'}</li>
                <li>${'<i>(Updated)</i> ' if 'user_id' in ctx.get('changed_fields',[]) else ''}Assignee: ${object.user_id.name if object.user_id else 'Nobody'}</li>
                <li>Manager: ${object.manager_id.name if object.manager_id else 'Nobody'}</li>
                <li>${'<i>(Updated)</i> ' if 'total_hours' in ctx.get('changed_fields',[]) else ''}Total Hours: ${object.total_hours}.
                        ${'<i>(Updated)</i> ' if 'remaining_hours' in ctx.get('changed_fields',[]) else ''}Remaining Hours: ${object.remaining_hours}
                        Progress: ${object.progress}%</li>
                <li>${'<i>(Updated)</i> ' if 'date_start' in ctx.get('changed_fields',[]) else ''}Start Date: ${object.date_start or 'None'}</li>
                <li>${'<i>(Updated)</i> ' if 'date_end' in ctx.get('changed_fields',[]) else ''}End Date: ${object.date_end or 'None'}</li>
                <li>${'<i>(Updated)</i> ' if 'date_deadline' in ctx.get('changed_fields',[]) else ''}Deadline: ${object.date_deadline or 'None'}</li>
            </ul>
            <h2>${'<i>(Updated)</i> ' if 'description' in ctx.get('changed_fields',[]) else ''}Description:</h2>
            <pre>${object.description or ''}</pre>
            <h2>${'<i>(Updated)</i> ' if 'notes' in ctx.get('changed_fields',[]) else ''}Notes:</h2>
            <pre>${object.notes or ''}</pre>
            ]]></field>
            <field name="body_text"><![CDATA[
Hello, The following task has recently been updated:

 * ${'(Updated) ' if 'name' in ctx.get('changed_fields',[]) else ''}Name: ${object.name} [Task ID #${object.id}]
 * ${'(Updated) ' if 'state' in ctx.get('changed_fields',[]) else ''}State: ${object.state.title()}
 * ${'(Updated) ' if 'project_id' in ctx.get('changed_fields',[]) else ''}Project: ${object.project_id.name if object.project_id else 'No project'}
 * ${'(Updated) ' if 'user_id' in ctx.get('changed_fields',[]) else ''}Assignee: ${object.user_id.name if object.user_id else 'Nobody'}
 * Manager: ${object.manager_id.name if object.manager_id else 'Nobody'}
 * ${'(Updated) ' if 'total_hours' in ctx.get('changed_fields',[]) else ''}Total Hours: ${object.total_hours}  ${'(Updated) ' if 'remaining_hours' in ctx.get('changed_fields',[]) else ''}Remaining Hours: ${object.remaining_hours}  Progress: ${object.progress}%
 * ${'(Updated) ' if 'date_start' in ctx.get('changed_fields',[]) else ''}Start Date: ${object.date_start or ''}
 * ${'(Updated) ' if 'date_end' in ctx.get('changed_fields',[]) else ''}End Date: ${object.date_end or ''}
 * ${'(Updated) ' if 'date_deadline' in ctx.get('changed_fields',[]) else ''}Deadline: ${object.date_deadline or ''}

${'(Updated) ' if 'description' in ctx.get('changed_fields',[]) else ''}Description:
${object.description or ''}

${'(Updated) ' if 'notes' in ctx.get('changed_fields',[]) else ''}Notes:
${object.notes or ''}
            ]]></field>
        </record>

You’ll notice I use ctx.get('uid_email') for the From address. When I call the template up, I can pass in the From address via the context, calling the key uid_email, and it will be filled in. I also have a list of fields that have changed; changed_fields — this is as simple as grabbing vals.keys() from within a write method. To whistle up the template and send the email, I defined a method which I can call.

    def _send_email(self, cr, uid, ids, context=None):
        '''
        Send an email relating to the given task IDs.
        '''
        if not context:
            context = {}

        # Grab the tasks
        tasks = self.browse(cr, uid, ids, context=context)

        # Filter out the tasks for which no emails will be sent.
        tasks = filter(lambda t : \
                (t.user_id and t.user_id.notify_on_task) or \
                (t.manager_id and t.manager_id.notify_on_task) or \
                (t.project_id and \
                    (t.project_id.warn_manager or \
                     t.project_id.warn_customer)), tasks)
        if not tasks:
            # If we've eliminated them all, stop here.
            return None

        # Mail message template handler
        model_pool = self.pool.get('ir.model')
        template_pool = self.pool.get('email.template')
        template_id = template_pool.search(cr, uid, [
            ('model_id','in',model_pool.search(cr, uid,
                                               [('model','=',self._name)],
                                               context=context)),
        ], context=context)
        if template_id:
            # Use the first one
            template_id = template_id.pop(0)

            # Get the current user's email address
            user_pool = self.pool.get('res.users')
            user = user_pool.browse(cr, uid, uid, context=context)
            context['uid_email'] = user.user_email

            # Send the emails for each task
            map(lambda t : template_pool.send_mail(cr, uid, template_id, \
                        t.id, context=context), tasks)

This method performs the following steps:

  1. It filters out the tasks for which no emails will be sent; if no one has elected to receive notifications for a task, then let’s not waste our time.
  2. We then look for the template used to format tasks. To do this, we must first know what ID corresponds to a project.task, so we do a search, then
    use its result in the domain expression to search the templates.
  3. If we find a template ID; there should only be one, so we pick the first of the list. searchalways returns a list.
  4. We look up the current user, and try to find their email address, so that the email will be sent from the person making the changes.
  5. The map function passes each individual task in to the send_mail method.

The send_mail method of email.template has the following structure:

    def send_mail(self, cr, uid, template_id, res_id, force_send=False, context=None):
        """Generates a new mail message for the given template and record,
           and schedules it for delivery through the ``mail`` module's scheduler.

           :param int template_id: id of the template to render
           :param int res_id: id of the record to render the template with
                              (model is taken from the template)
           :param bool force_send: if True, the generated mail.message is
                immediately sent after being created, as if the scheduler
                was executed for this message only.
           :returns: id of the mail.message that was created 
        """

Above, res_id was passed the ID of the task. We also do some magic injecting values into context so they’ll appear in the template. The final step in our mail template integration is to actually make use of the new method. I wanted to send an email when the task was updated, much like Bugzilla’s updates. So I hooked the create and write methods of project.task:

    # Override the action handlers so that we can slip our email out.
    def create(self, cr, uid, vals, context=None):
        id = super(vrt_project_task, self).create(cr, uid, vals, context=context)
        self._send_email(cr, uid, [id], context=context)
        return id

    # What fields do we notify on?  TODO: make this configurable?
    NOTIFY_ON   =   {   'user_id':  lambda val : True,
                        'state':    lambda val : val in ('cancelled','done'),
    }

    def write(self, cr, uid, ids, vals, context=None):
        res = super(vrt_project_task, self).write(cr, uid, ids,
                vals, context=context)
        notify = False
        for field, do_check in self.NOTIFY_ON.iteritems():
            if (field in vals) and do_check(vals[field]):
                # We found a field of interest
                notify = True
                break

        # Send an email describing what changed
        if notify:
            if not context:
                context = {}
            else:
                context = context.copy()
            # List the fields that changed so we can highlight them
            # in the email.
            context['changed_fields'] = vals.keys()
            if isinstance(ids, (int,long)):
                ids = [ids]
            self._send_email(cr, uid, ids, context=context)
        return res

If you process the tasks one-by-one, it is possible to read the state of the task first, do the write, then send an email off for that message telling the recipients how everything changed, but that was not necessary here, thus hasn’t been implemented. One thing that irritates me is the hard-coded list of notification fields, but it’ll do for now.

Receiving emails in OpenERP

Sending emails is only half the story however. It’d be nice, for example, to have a form on a website that people can use to contact sales staff and make enquiries, and for this form to turn into a lead. One such approach would be to use one of many off-the-shelf form posting scripts, and to parse the email within OpenERP. The approach I am specifically looking at, is using Python-code Server Actions to parse the email.

For now I’ve focussed my attention on bringing the email in to OpenERP and doing some processing on it without actually creating leads, as this is more an exploration of how the processing all works.

Setting up the inbound email account

To start off with, you must have a dedicated email address that will receive these notifications. OpenERP then checks this via IMAP or POP3 periodically, and for each new message, will either create a new document or run a server action.

Under “Settings/Configuration/Email/Incoming Mail Servers”, configure a new account, specifying the usual login details. Below this, you’ll notice the fields below the heading “Actions to Perform on Incoming Mails”. This is where OpenERP is told what to do. “Create a new record” defines what sort of object is to be processed.

I used mail.message initially, then discovered I got some funny errors. For everything to work, the object chosen needs to inherit mail.thread. In fact, for testing you can even use mail.thread, and this is what I later used. For CRM stuff, crm.lead inherits mail.thread so I’ll probably use that in the final implementation.

Creating the server action

When the server creates the object it can trigger a server action at the same time. This server action can take a number of forms, but the one of most interest is the Python Code server action. As a test, I made a server action that took a mail.thread, then posted a response email for each message seen, a bit like the autoanswer alias on vger.kernel.org. Creating the server action, I specified mail.thread as the object and used the following Python code:

if context.get('active_id'):
    thread = self.browse(cr, uid, context.get('active_id'), context=context)
    for msg in thread.message_ids:
        msg_body = '''Test server action -- email received:
From: %s
To: %s
CC: %s
Subject: %s
Headers:
  %s
TEXT:
  %s
HTML:
  %s
''' % (
    msg.email_from,
    msg.email_to,
    msg.email_cc,
    msg.subject,
    msg.headers,
    msg.body_text,
    msg.body_html,
)
        pool.get('mail.message').schedule_with_attach(cr, uid, (msg.email_to or 'me@mydomain.com.au').split(',')[0], [msg.email_from or 'me@mydomain.com.au'], 'Test email reply [Re: %s]' % msg.subject, msg_body, context=context)

Probably worth noting, I suspect the self.browse() bit and the context.get('active_id') bit is not necessary, as that is what I’d imagine object is for, but initially I didn’t have the right model chosen, so I suspect that bit of code could be re-worked.

The plan now, is to use the YAML module to parse the message body so that the fields can be sent from the website in a human-readable and unambiguous form.

I’ll be doing some further experimentation, but for now that’s where I’ve gotten. No doubt, there’ll be updates as I discover more about what goes on here.