Just over a week ago, I posted a series of [RFC] posts to
the gEDA-user mailing list suggesting six reasonably non-trivial
changes to libgeda and gschem. Although the discussions they started
off weren't quite as productive as I was hoping, they did attract
quite a bit of interest.
I haven't been afraid to put my money where my mouth is. Since
then, I've implemented two of the changes I suggested: a
modification of the way gEDA apps create logfiles, and support for
copying and pasting bits of schematics between gschem windows. I
thought I'd post here to explain the amount of careful design work
that goes into even relatively minor changes to the gEDA suite.
Logging
Historically, gschem (and the other gEDA apps) have created
logfiles in the current working directory when they were
launched. This behaviour quickly resulted in a user's home directory
becoming littered with the files, gschem.log files
especially.
My initial suggestion was to just not create log files by default,
and require users to specifically enable them. However, it was
quickly pointed out that since one of the most common reasons for
gschem failing to start was that a new user had made a mistake in
their configuration file, and that it would be best to carry on
with generating logfiles as the default behaviour.
Instead, it was suggested that the logfiles should be put in a
centralised, out-of-the-way location, and ~/.gEDA/logs/ was
suggested, with the caveat that it would be necessary to make sure
that multiple copies of gschem accessing the directory would have
to be supported safely, even on different machines, but also that a
user could quickly easily find the most recent log file -- so just
adding a random suffix with mktemp wouldn't work either!
Having worked out a way of doing this (a secure algorithm for
generating sequentially numbered, dated log files), I then realised
that on some operating systems, such as Microsoft
Windows, $HOME might not even be defined, and that there
might be platform-specific differences in the standardised place to
keep configuration data. Since the gEDA applications had no
existing way of handling these variations, I ended up abstracting
out the methods for locating the system and user data and
configuration files, and updating all of the gEDA apps to use
them.
All in all, changing the location where log files are stored used
up at least eight hours of development time.
Clipboard copy, cut and paste
For a long time, gschem has supported copying and pasting schematic
data between pages and windows in the same gschem process, but it
was never made clear to users that this mechanism didn't use the X
clipboard, and thus sometimes copying and pasting didn't work when
it would have made sense for it to.
X Window System selections are complicated. There are two
selections normally used by X applications: the PRIMARY selection
and the CLIPBOARD selection. Traditionally, the PRIMARY selection is
contains the most recent piece of text selected by the user with the
mouse, and can be pasted by clicking the middle mouse butten, while
the CLIPBOARD selection is accessed via "copy" and "paste" actions
explicitly invoked by the user. In order to match up with other
applications (and because nothing like the PRIMARY selection is
available on Microsoft Windows or OS X), we decided to use the
CLIPBOARD.
For the same portability reasons (and also because the raw X API is
horrendously complicated), we decided to use the GTK Clipboard API
to manage the clipboard.
A neat feature of clipboards (and X selections in particular) is
that it's possible for the source application to provide the data in
different forms, depending on what the "pasting" application
wants. We needed a format for transferring between gschem instances,
so we decided to use the gEDA schematic format
(application/x-geda-schematic). Fortunately, as part of my
rewrite of the symbol library back in mid 2007, I'd made
libgeda able
to "load" and "save" schematics from memory buffers, so I simply
hooked the clipboard code into that and things started working!
I then, of course, had to work through the boilerplate required to
update the GUI to support it. This took as long as implementing the
actual feature.
I've also been working on some other features, using some code that
I've had floating around for a long time. But more of that another
time!