Skip to content

2004

WinXP Desktop Shell Replacement

A little while back I mentioned some annoyances with virtual desktop software under windows. It occurred to me that the only sane way to implement virtual desktops is to do away with the explorer shell and use something else.

This is not a new idea: GeoShell, LiteStep and BB4win all try to do this kind of thing, with varying degrees of success. I tried to use each of these and found that they all have their rough edges that just made them unusable for me.

So I was frustrated. Motivated by frustration and curiosity, I wrote my own shell replacement for WinXP. It features low resource consumption and a low-clutter interface that I suppose is somewhat similar to the OSX dock, even though that wasn't my original intention.

screenshot full-size.

My shell, dubbed "WezDesk" for want of a better name (EvilDesk!?), implements the following features:

  • Quicklaunch icon bar
  • System Notification area (aka "Tray"), including tray bubbles
  • Clock with day/date
  • No classic taskbar, but "flashing" windows have their icons bounced to get your attention
  • Light-weight icon-free start menu
  • Kludge-free Workspace management; use up to 4 virtual desktops
  • icon-free desktop

If you feel like a change from explorer will also do you some good, then feel free to download and test-drive my latest offering.

Disclaimer : the software is provided as-is in binary form only with no warranty. I am not liable for any bad mojo, be it mental, physical or meta-physical, that arises from its use. By downloading it, you assert that you will not decompile or reverse engineer the software in any way, and that you will not re-distribute it to any third party in any form without my express consent. All rights reserved; All liabilities disclaimed.

Caveat Emptor : when switching desktops, some naughty apps (notably gaim and the MSDN help browser) occasionally get "warped". Restarting the app is one solution, not switching desktops is another. (Running miranda instead of gaim saved several MB of RAM at runtime, runs faster and has no weird interactions that I know of).

Caveat Emptor 2 : tray "bubbles" sometimes miss updates to their text content.

Despite these niggles, I've been happily using the current build for over a month, >15 hours per day and it's been a pleasure to use.

Download wezdesk.msi

Installation

Double click the .msi file to install. Note that installation is non-destructive; it simply installs the app into your start menu. You can then go into:

Start | Programs | Evil, as in Dr | Shell | Set Shell

to register it as your shell. You need to log out and log back in again to use it.

If you want to go back to explorer.exe, call up the start menu (right click on the desktop):

All Programs | Programs | Evil, as in Dr | Shell | Reset Shell

and log out and log back in again.

You'll also find the online docs available in the start menu; in there you'll find out about the various hotkeys available.

What I miss in Thunderbird

Is the ability to display a couple of extra non-standard headers in addition to the usual From, Subject and Date stuff.

I know I can turn on all the headers, but that's just a bit too much noise.

Maybe someone out there can write an extension for that?

[PS: I know this isn't strictly PHP based, but since I spend a lot of time managing the php.net mail server, I guess it could be construed as PHP].

PECL::event

Yesterday I added the product of my weekend-of-hackery to PECL: the event extension.

PECL::event implements an event based scheduling engine that will execute a callback when a particular event is triggered. The various different triggers allowed are:

  • EV_READ - a stream becomes ready to read
  • EV_WRITE - a stream becomes ready to write
  • EV_EXCEP - a stream has out-of-band data available to read
  • EV_TIMEOUT - a certain amount of time has elapsed
  • EV_SIGNAL - a signal was raised

As you might have already guessed, PECL::event is probably most useful for longer-lived scripts that need to perform more than network "operation" without either taking too long (why do one after the other if you can do both at the same time?) or without one blocking the other and making it time out.

I've previously given a talk (or was it a magazine article?) on multiplexing with streams in PHP; this extension takes things a step further by taking the complex scheduling logic out of your script. As a bonus, it can also take advantage of the more scalable IO scheduling interfaces (epoll(4), kqueue, /dev/poll, poll(2) and select(2)) available on various different operating systems. Scalable is one of those phrases that can easily be misinterpreted, so in this context more scalable means lower overhead per file descriptor , which should translate to faster execution time in your script.

In practice, you probably won't notice much difference between the different engines in PECL::event, but you should notice the difference between a userspace implementation using stream_select() and PECL::event.

How do I use it?

<?php
  # our callback
  function readable($stream, $mask, $arg) {
     if ($mask & EV_READ) {
       echo "$arg is readable:\\n";
       echo fread($stream, 8192);
       fwrite($stream, "QUIT\\r\\n");
       fclose($stream);
     }
  }
  # detect and activate the best available scheduling engine  
  event_init();
  # create a new event
  $e = event_new(
       # associate it with an async connection to a gmail MX
       stream_socket_client("tcp://gsmtp171.google.com:25",
          $errno, $errstr, 0,
          STREAM_CLIENT_CONNECT|STREAM_CLIENT_ASYNC_CONNECT),
       # ask the engine to tell us when it is ready to read
       EV_READ,
       # tell it to call the 'readable' function when triggered
       'readable',
       # and pass in the following string as an argument
       'gmail mx');
  # put the event into the scheduling engine   
  event_schedule($e);
  # similarly, create another event, this time connecting
  # to the PHP MX 
  $e = event_new(
       stream_socket_client("tcp://osu1.php.net:25",
          $errno, $errstr, 0,
          STREAM_CLIENT_CONNECT|STREAM_CLIENT_ASYNC_CONNECT),
       EV_READ,
       'readable',
       'php mx');
  event_schedule($e);
  # now service all registered events
  event_dispatch();
  # we get here when both events have been run
?>

If you run this script, you should see it output something like this:

  gmail mx is readable:
  220 mx.gmail.com ESMTP 71si267099rna
  php mx is readable:
  220-PHP  is a widely-used general-purpose scripting language
  220-that is especially suited for Web development and can be
  220-embedded into HTML. If you are new to PHP and want to get
  220-some idea of how it works, try the introductory tutorial.
  220-After that, check out the online manual, and the example
  220-archive sites and some of the other resources available in
  220-the links section.
  220-
  220-Do not send UBE to this server.
  220-
  220 osu1.php.net ESMTP Ecelerity HEAD (r3928) Mon, 13 Dec 2004 17:59:20 -0800

You'll see the osu1 banner a couple of seconds after running the script, because that server deliberately pauses.

What's the point?

The script above connects to two SMTP servers, reads their banners and then gracefully closes the connection. So what? Big deal. I can write a much shorter script that does the same thing using just a couple of lines for each host:

<?php
   $fp = fsockopen('gsmtp171.google.com', 25);
   echo fgets($fp);
   fwrite($fp, "QUIT\\r\\n");
   fclose($fp);
   $fp = fsockopen('osu1.php.net', 25);
   echo fgets($fp);
   fwrite($fp, "QUIT\\r\\n");
   fclose($fp);
?>

That may be the case, but with the PECL::event approach, you're not blocking on each connection (remember, osu1 makes you wait a couple of seconds) and you're not blocking on each read. In fact, you could happily add 10s or perhaps even 100s of machines to monitor and have them all happen concurrently. Neat stuff, huh?

That's all I'm going to write for now, but before I go I'll leave you with a couple of interesting snippets if you're interested in playing with the extension.

  • Events are automatically descheduled after they have run once. To get them to run again, you need to either call event_schedule() again or set the EV_PERSIST flag in your event mask when you call event_new(). You can manually event_deschedule() a persistent event to take it out of the scheduling engine (effectively pausing the event).

  • You can specify a deadline (well, a timeout) for an event when you schedule it; the 2nd and 3rd parameters are seconds and microseconds for the timeout.

  • You can call event_new() with a null stream parameter to create an event that is not associated with a stream. event_schedule() it using a timeout to have that function called after a certain amount of elapsed time.

  • The extension is still beta; docs are pending and bug reports are welcome ;)

Here in USA

So, we're here in Columbia, MD, USA. It's been a hell of a long week; clearing out the house was the hardest part of the whole move, but worth it in the long run.

In the end, we gave away some really nice stuff that nobody wanted (or could afford) to buy; a nearly new office quality desk, Iiyama Vision Master 510 Pro monitor, a box-o-bits including things like a Roland Sound Canvas midi module, WinTV USB etc. Heart-breaking, but it was good to reduce the amount of stuff that we own. Some of the stuff was kinda crappy or useless; for example, I had boxes of things like IO boards for 386/486 machines, ISA and PCI gfx boards, 4 brand new PSUs for the PII generation machines (they came with cases, but were not powerful enough for the PIII processors I was using at the time).

After a gruelling unknown number of hours >= 24, we had loaded up our 6 large suitcases, 2 dogs, 2 dog carriers, Juliette, Xander and myself onto a mini school bus that we had hired to drive us down to the Sheraton Skyline, the only hotel we found in the area that would accept us with our dogs, and had a goodbye meal with some of my family.

The next day we checked in at LHR terminal 4; checking in with the dogs took over an hour; they handled things pretty well, but were pleased to hop into the pet cargo containers to have somewhere to rest.

The flight itself was delayed for 45 minutes while they replaced a radio, but magically arrived at BWI 20 minutes early. Xander was really well behaved on the flight, and was quite content with playing with the buckle on his car seat for most of the journey, sleeping for most of the rest.

We got to watch Dodgeball while Xander was napping, and thoroughly enjoyed it; not as good as Zoolander (probably my favourite movie), but vastly superior to Starsky and Hutch (which could have been much better).

When we touched down, we were collected from the airport by a friend/client (who lives within a reasonable distance of the airport) and his "Savannah GMC Van of Terror"; a 12 seater van with blacked out windows that gives airport security the heebie-jeebies.

So, here I am now, on Halloween, "borrowing" a neighbors wifi (I'm getting my own sorted out this week) blogging from our somewhat empty apartment. Mom-in-law had previously visited to drop off our car, filled with some kitchen utensils and bedding, and George and Theo have also donated a few items to make the place feel less empty; all these things help, but we're still pretty bare in here.

We're going to have to go shopping for more stuff; there's no rush for most of it, just for the stuff that annoys us the most first. Top of Juliettes list is an electric kettle, which seems to be something of a rarity here. Top of my list... hmmm, something to sit on would be nice.

Really moving to America

A little while back I mentioned that I was Moving to America. It's taken from then until a few days ago to get the magic visa sticker attached to my passport, and now we are finally good to go.

The people shipping our stuff have been here since 9:30am and are just finishing up (it's getting close to 3pm now). I've moved a number of times in the past but this is the first time I've had someone else do the packing for me--I can't stress how much easier it is this way. If I hadn't been up all night sorting stuff into ship and skip piles, I would be feeling pretty good right about now.

Why was I up all night the night before? The answer is that it is impossible to get anything done during the day with Xander running around and, let's face it, no one really wants to pull an all-nighter when it's not essential.

We'll be spending the next couple of days getting rid of the stuff we didn't decide to take with us, and making the house look nice (we still need to sell it!).

We fly on the 29th.

Java: How to Program

I was asked to review this book recently (with an eye on how it equates to PHP), and having just gone through it, I'm quite impressed. It is well written, well structured (taking you from no knowledge and going from there) and teaches you good design principles, without beating you over the head with them.

Having completed my review, it is apparent that PHP 5 has most of the good parts from java, without bogging you down in syntax. I view this as a good thing, making it easier for programmers to drift between the two languages more easily.

If I was asked to recommend a book on java programming, I wouldn't hesitate to recommend this one. I would even consider recommending it to someone new to programming, because most of what it teaches applies equally well to other languages; it serves as a very useful primer, going into the right amount of detail, to make future employees useful regardless of the language that you're going to use.

nVidia nView virtual desktop manager

I've been using this for a while and been annoyed by two things it does:

  • Won't allow you to assign ALT-F4 to switch to desktop 4
  • It's unable to manage win32 console windows

The latter doesn't seem fixable, but I can live with it. The Alt-F4 thing can be solved with a bit of registry hacking. First, turn off nView, so that it saves its state into the registry. Then open up regedit and create the key shown in the picture below (the full registry path can be seen in the status bar). Once you've added it, turn on nView again.

Alt-F4 as a hotkey

I did try VirtuaWin for a while, but it has particularly crappy interaction with the cygwin X server: switching desktops causes most of your xterm windows go into attention grabbing flashing mode. Very annoying.

PHP Marketing War Chest

Marco aims to publish a number of case studies on the adoption of PHP in small, medium, and large businesses (or enterprise, if you will) with the intention of creating a kind of marketing "war chest". The idea is to form a kind of business PHP hub that will help other businesses to make a more informed decision when it comes to adopting PHP.

Marco is looking for people to write case studies in marketing-speak to use there; for more information, read Marco's blog entry.

Xander at play school

xander_zoo.jpg.t Xander had his first half-day at play school today. He was a little unsettled about not having either Juliette or myself near-by, but enjoyed being in the company of other kids his own age.

xander_art He produced his first artistic piece, without the aid of crayons, pictured to the left. The piece features the colour red and his favourite shape--the circle.