Shadow copying is in,
for those pesky locked Outlook mailboxes and other "in use" files.
There are three big things left to weave into the
program - file system monitoring, new delta copier
and software updates - and the beta is good
to go. A matter of few days now.
If your message box includes the "Don't ask again"
option, just make sure to disable all but one
button, when it checked.
Oddly enough, I don't know a single app that does that.
Feeling creative? Make your own version, save as
a PNG, drop it in a config directory and -
voilà - your systray looks just like you
want it to.
There are two sets of icons on the sprite sheet.
The first three columns is the XP style, which
is a bit puffy and matches well older Windows
styling. The last three columns is a flat version
that goes better with native W7 tray icon style.
Each icon comes in 3 sizes - 16x16, 20x20, 24x24.
This is needed to accommodate 3 common DPI levels,
see
this earlier entry for
details.
"Message pending" indication, whereby a message
can be either an error, a warning or a notice
and these are differentiated with the ! color.
I realize it's not color-blind friendly,
but the goal is to attract the attention and
make user bring the app window up to read the
message --(therefore)--> reflecting the message
type via an icon level is not exactly critical.
W7-ish version as per
a
this hint on Twitter. Not bad at all.
Working on systray icons...
Revised Preferences window a bit.
Added basic control over backup scheduling
and switched from "close to systray" to
"minimize to systray" - the (x) at the
top right corner will now always act as an
Exit, just as it is supposed to.
More of the UI work.
Custom pop-out button that stays nice, flat
and out of the way when idle, but
acts like a regular button otherwise. Not
exactly a UI innovation, but it was nice
to be able to use it in a real project :)
Took out the engine mode switch from the Preferences
and into a dialog of its own. Still need to understand
if it's worth mentioning that there's an engine per se
or just stick to more amorphous "application mode"...
Looked at few options for splitter styling. First
one is final. Tentatively though... heh.
Done with the split-view mode for the main window.
It's one of those things that everyone takes for
granted and that, in reality, maps to quite a bit
of work if done right.
For example, resizing window by the top edge should
resize the top pane and leave the bottom part alone.
Likewise, resizing by the bottom edge should
expand/compress the bottom pane, but not the
top one.
However, if we are compressing window by the top edge
and the top pane is at its minimal height, then we
should the bottom pane starting to compress.
All good so far, but, say, we change our mind and start
expanding the window back (without releasing the mouse
button).
We should see the bottom pane brought back to its original
size first, followed by the expansion of the top part...
even though we are, technically, dragging by the top edge.
This sort of UX detail is something that few people will
notice if it's done right, because it feels natural and
aligns well with expected behavior. But cut some corners -
and you bet everyone will notice.
Going through styling options for the expand/collapse buttons.
Presently leaning towards C or D, because I'm
considering making the text selectable with the
mouse for easy copy- pasting. For that to work
the buttons need to be as unobtrusive as possible.
Still WiP though...
Working on the backup log viewer.
—
Basically the idea for the log is to support
multiple detail levels, each capturing
progressively more context that its parent.
With all details collapsed, the log gives a
quick overview of when the job was running
and if it completed OK or with errors.
Expanding details allows for a drill-down -
to look at the details such as the file and
byte counts, the timing and performance data
and the details of any errors that have
occured.
I'm still going to shuffle things around
the window, e.g. push the -/+ buttons to the
right, tweak the styling too, but the general
hierarchical format will stay. It is a very
convenient way of organizing the log info.
Finished a piece of code that determines
effective timestamp resolution of a file
system.
—
Every file system keeps track of when a file
was created and when it was last modified.
These timestamps are the natural properties
of a file and they are readily available for
inspection in the Windows Explorer or any
file manager of your choice.
The less obvious aspect of timestamping is
that timestamps have resolution. For example,
FAT tracks file modification with a measly 2
second precision. In comparison, NTFS uses
the 100 ns (nano-second) precision.
—
It is very typical for a backup software to
rely on timestamps to determine if a file
has been modified and requires copying. But
if the source file sits on an NTFS volume
and the backup goes onto a FAT disk, then
comparing timestamp directly simply won't
work, because FAT timestamp will be
rounded-up to a 2-second mark.
In other words, the timestamp granularity needs
to be taken into an account when comparing the
timestamps. The question is how to determine
what it is exactly.
—
First of all, the granularity for creation
and modification times can be different.
FAT has them at 10 ms and 2 s respectively,
but NTFS has them both at 100 ns.
To complicate matters, there appears to be
NAS devices that look like NTFS boxes, but
with the granularity that is not 100 ns.
So what I did is added code to probe the file
system and determine effective resolution for
both timestamps. This involves dropping a
temporary file and then trying to set its
timestamps to this, that and 3rd and see what
they end up at. From that it's possible to
deduce the resolution.
In cases when such probing fails, the app
falls back to guessing resolution by the
file system name. It is also possible to
override the resolution values from the
config, just in case.
Done with the backup scheduler. Comes with a
couple of neat improvements over v1.
—
The Go and Stop buttons work almost exactly
as in v1. If the backup is running, click
Stop once to Pause it, click again to Cancel,
click third time to disable the job.
If the job is disabled, click once to enable
it, click again to manually start it. And so
on, you get the idea.
—
First improvement over v1 are the Go!
and Stop! commands that are activated by
holding Ctrl down when clicking on the
toolbar buttons.
Go! moves the job straight into the running
state.
It's the "Run it. NOW!" command.
Stop! stops and disables the job straight away.
It's the "Stop it. NOW!" command.
—
Second improvement is that multiple
jobs can now be run in parallel. Generally,
this has a negative impact on the overall
performance, but there are certain cases
when this is desirable. One example would
be running a smaller backup in parallel
with a much larger and slower one.
There are three ways to do this:
With the Go! command.
With a per-backup setting that makes
the job always run right away, even if
there's another job is running.
With an app-level setting that does the
same, but for all jobs.
—
PS. I considered adding something more
elaborate, e.g. allowing assigning jobs to
"run groups" and then allowing only one
active job per group, but that seemed like
an overkill, so I dropped that.
Another pass over the main window chrome and
layout. The "backup jobs" section is just a
dummy header ... and it is confusing, I think.
Specifically, I want to get rid of the V1's
Summary panel,
trim the information contained in it a bit and fold it
directly into the main window items.
In conjunction with this I'm also considering having two
modes for displaying backup jobs on the list - "terse"
one-liners and "extended" multi-liners. What I still need
to figure out if this should be a per-item preference or
an app-wide setting and how one would switch between these
display modes.
Work in progress, obviously. Any thoughts -
let me know.
Done with a little animation that and switches
main window between a "welcome screen" and the
regular backup list view.
The animation and fading effects can be disabled,
there's a setting for that.
—
Windows comes with a standard
toolbar control,
but it's an overkill if you need just a
couple of buttons at the top of the window.
It basically takes longer to figure out how
to use and customize it compared
to creating a basic window and sticking a
couple of custom buttons on it.
Had I have a need for toolbar ribbons,
docking, on-the-fly customization, etc., then
ToolbarWindow32 makes sense. But if it's
something simple, then there are faster options.
Meet the toolbar.
—
To explain a bit what you see in this masterpiece :) -
The idea is to try and keep the menu/toolbar
area simple and flat, but still provide some
sort of a visual clue that Go and Start are
clickables.
Here are three options compared back to back
to make the differences a bit more obvious -
—
Here are few options that were leading up to the above one:
iOS says Hi
Also, considered disposing off the menu bar and
folding whatever few items it has into the
drop-down menu. But this just looks weird and
too alien on Windows, the app needs a menu bar.
The look of the main window with no backups
configured. Tried using a stock button, but
it looks heavy and dull. Hopefully, this is
a bit more refined.
Trying to understand how to indicate if
a selected path points at a removable storage.
The app tracks storage devices being plugged into
the computer and it adjusts backup paths if a known
device re-appears under a different drive name.
I can, of course, not bother with this at all and
simply spit out a notification when (and if) the
drive change is detected, but then I think it's an
important functionality and it'd better be mentioned
during the setup.
"Work-in-progress" buttons for beta releases.
Correct your input.
† Idea is courtesy of the OS X login screen,
I think. Though I did experiment with concise error
indication quite a bit.
Wrapping up the Periodic Backup configuration
window.
Unlike the v1 that always stored the backup
interval as a number of seconds, the v2 adds
a time unit specifier.
This simplifies quite a few things in the UI
and yet it keeps the configuration flexible
enough to support 1.5 hour backups by allowing
to specify a 90 minute interval.
—
On an unrelated note, killed few hours trying
to utilize native Windows controls for the
interval configuration. The amount of work
required to make them look reasonably
good is as depressing as it is remarkable.
For example, the editbox control doesn't
natively support vertically centering the
input text. It just does not. It is
meant to look like this -
Want "120" aligned to the label on the left?
Sure thing, that'd be 2 hours of plowing
through documentation only to realize that
it must be... drum-roll... a multiline
control that you will then need to manually
pad the right amount at the top to push the
line to the middle.
—
But that's peanuts compared to trying to
beat some sense into the dropdown box. Long
story, but making a box taller and keeping
the line centered requires taking over the
control drawing functions, which in presence
of Windows themes is a delightfully unpleasant
experience.
In any case, turning the top control line
into the bottom one -
costs exactly a day of work, while it really
shouldn't. Welcome to Windows.
Finalized the design of inline hint/tip
widget for input controls.
Initially, it was meant for the config
window that hosts periodic backup settings
(as seen in a couple of posts below), but
having talked to others and slept on the
issue I think that the natural language
input (i.e. requiring to enter "1 week"
or "15 minutes") is not the best option
for this case.
An alternative design is coming up in a bit.
Coded the previous sketch, played with few
parameters and it is starting to get there
... I think. Will make another pass over this
tomorrow and it should be good to go.
For what it's worth I have also gave a try
to the standard
Tooltip Control. In fact,
that's where I started.
—
A regular tooltip looks like this -
It adds another layer to the windows
stack, breaks the visual flow of the
layout and still manages to tuck itself
under the mouse cursor.
There's also a balloon version of the
same, which looks like this -
It is marginally better, but just look at
those lovely
rounded cornersi. Eat that Apple. Real
artists ship.
—
tl;dr - the standard Tooltip Control is
not very good, so I had to come up with
a custom replacement.
Not sure about this one, seems a bit
clumsy and a bit too custom.
This is basically a way to explain what
is expected as an input for a particular
configuration value. There's gotta be a
cleaner way of delivering the same info...
Working through the supporting code for the Settings window.
Done with collapsing/expanding mechanics and respective
fading and moving animations. Still need to revise the
copy for the explanatory bits and massage in the option
for archiving deleted files.
—
Not to pat myself on the back, but I think it came out
looking pretty decent.
That's not to say there's no way to turn off all this
fancy styling and animations, because, you bet your
favourite monochrome flat design, there is.
Another take on Backup Settings window, 4 styling
variations.
Further compacted vertically, but now it appears
to be somewhat cluttered and lacking comfortable
vertical rhythm (to borrow a term from the typography).
I think the original design from the version 1 got
many things right.
It provided a good at-a-glance overview of the
backup configuration, split settings logically
and tucked away the minute details. It did have
one problem - it was tall. So tall, in fact,
that I got several reports that it didn't fit
on screen :-|
—
V2 adds several new options to the backup
config, so this doesn't make things any
easier. After looking at few options, including
paged, tabbed and two-column, screenful layouts,
I circled back to the v1 layout.
To compress it vertically I've done two things -
got rid of the group boxes (frames) and collapsed
radio button groups into a single line with the
current selection.
This gives us the middle screenshot
(pic) that shows
the config window in the "overview" state.
—
Clicking on a "Change ↓" button expands the
radio button group and allows changing the
setting without leaving the page. Latter
is pretty nice to have, because ... well ...
because it's simply faster and more convenient.
Expanding a section gives the screenshot on the
right
(pic).
To collapse the section, there's a little
button in the section header on the right hand
side. I'm not 100% convinced it's really needed
nor that it's the best solution, but that's how
it is at the moment.
—
I forgot the "how to handle deleted files"
section, but it will be in the beta.
Not to worry.
The Backup Engine section - as simple as it looks,
it is fronting a couple of months worth of work
and it's easily one of the most complex part of
the v2. This is what detaches the user interface
from the guts of the program and lets latter run
as a separate process.
—
The Maintenance section -
I figured that with the backup being an important
piece of software, very few users would be interested
in fully automatic updates. Furthermore, quite a few
people like to retain even tighter control over the
software and, for example, do not like it when the
software talks to the Internet whenever it wants.
Hence the new option -
Don't check, but remind to check for updates
It's basically a kitchen timer that goes "Ding!"
every week or two (configurable) and prompts you
to let the app check for a new version. We'll see
how it goes, but I think it's a sensible
compromise between the privacy and functionality.
—
The More button transforms the window into a
comprehensive list of all available options,
close to two dozens now and still counting.
The idea however is to keep the defaults
reasonable so that there won't be much need
to venture into this part of the app.
—
Lastly, note how the Apply/Close buttons change
when the settings are modified. I have no idea
why this is not a standard behavior, because it
really should be.
A message bar is a unobtrusive way to display
one-liner messages that would've otherwise
required poping up a message box.
When a program detects that it was just restarted
with Admin privileges, it has a limited number of
options for communicating this joyous news to its
user.
#1 - A message box. Bluntly put - I hate them. They
are always too sudden,
they steal your attention and stuff whatever they
want to say down your throat. They ... lack manners.
#2 - A system tray notification. This is less intrusive,
but perhaps it's too out of the way. Also, the
systray is a shared area so the program is always
competing with other apps for the same screen real
estate.
#3 - Something else that is right in your field of view
if you are looking at the app, but that doesn't get
in a way of whatever you are doing at the moment.
—
Cue in the message bar, now an integral part of the
Bvckup UI. It is used for displaying various status
notifications right after the launch, after switching
the engine to/from the system service mode, when
discovering software updates and few other things.
I have also tried the self-closing version of the bar
that dismisses itself on a timeout. Like so -
and so -
but having lived with this for a couple of days,
it now seems like a solution in a search of a
problem. So I shelved it for now. If there's any
a real need for this, it'd be very easy to add
later on.
Nailed down the installer flow. A couple of
things of note here.
The most unconventional part of the setup
is how it handles the configuration of the
installation parameters.
The configuration page (see Page 3) is very
bare and focuses on how the program is going
to be used instead of being a mixed
bag of the minute details of the setup.
The target location is made into a secondary
setting with its value controlled by the usage
preference. There's no field for the Start
Menu group name. There's no ever popular
"Run the program after the setup completes"
option either. Instead, exiting the setup
automatically runs the program (see Page 4),
unless the installer window is closed through
an (x) at the top.
This leads to a simpler and more intuitive
setup flow... or at least that's the idea :)
—
The installer supports both privileged
(administrative) and unprivileged (regular
user) installations.
If you are logged in as a regular user and
have no rights to modify C:\Program Files,
there's no reason why you shouldn't still
be able to install a software, just for
yourself.
While other installers routinely ask if to
install the software for everyone or just
for one user, it's a superficial question.
It merely controls if the Start Menu group
is created under All Users or your personal
profile. The program files still go into a
system directory and this requires
administrative privileges.
Bvckup implements true system- and user-
deployment, which is akin to deploying the
program in /usr/bin or ~/bin in Unix terms.
In fact, on a multi-user system it is
perfectly possible to install one instance
of Bvckup for each user and they will all
happily co-exist with each other.
The first page of the installer.
Working through the details of the update mechanism.
This is one of more difficult parts of the application,
even though on the surface it looks uncomplicated. If
we run the installer and it detects that the app is
already installed, it should just update the
installation. How hard could it be?
Let's see.
If the program is not running, then it's indeed a simple
matter of replacing the program file with a newer version.
The fun starts if the program is running.
On Windows, running a program locks its file, preventing
any changes from being made to it. This is not required
per se and there are operating systems that don't do this.
There are also custom
PE
loaders for Windows that can take
an executable and create a running process out of it without
any locking fuss. For example,
bo2k
could do that back in 1999. See its source code for
details if interested.
—
To complicate matters, there might be more than one
process running off the same executable. For example,
if several users are logged into a Windows box and
each runs a copy of a program.
Therefore, the first order of business for any installer is
to shut down all running instances of the program. A
well-behaved installer should also restart all these
instances after it's done with updating.
—
The shutting down part is not a big deal. There's more
than one way to do this and all of them are fairly
straight-forward.
It's the restarting that is contrived.
Not only program instances may be running under different
user accounts, they may also be running with custom
command-line arguments, as Administrators or system
services. Restarting this cornucopia of awesomeness
is not an envious task.
—
Here's how Bvckup works around this mess.
Every Bvckup executable has a corresponding named event in
the Global namespace. The event is created by
the first instance of the program when it's launched, and it
is opened by all other instances.
The name of the event includes the
file ID of the executable file.
This groups running instances by the file they are using,
because, after all, the installer is interested in a
specific executable and nothing else.
For example, the following is an event name used by the
Bvckup installation on my development box -
Global\Bvckup2.e65a96a8001f000000013cba.Update
—
With this in place, the installer starts off by signaling
the event.
In response, a running program makes a temporary copy
of its executable file and starts it in a special
"relauncher" mode. And then it exits.
The "relauncher" process opens the "update" event and
simply spins there, waiting for it to become unsignaled.
Meanwhile the installer waits for the program file to
become unlocked. Once all running instances replace
themselves with the relaunchers, the executable frees
up and the installer proceeds with the update. It then
clears the "update" event and exits.
This releases the relaunchers, they restart program
instances and - ta-da - the update is completed.
—
Techincally, instead of adding a special "relauncher"
mode to the program it's possible just to have a
small standalone relauncher program. It comes down to
a matter of taste. Some people don't like to spawn
from temporary executables, and I like to keep my
file count to a bare minimum. To each his own.
Dotting all i's and crossing all t's, of which there's
plenty now that there's an optional system service
that just begs to be stopped, restarted and deleted
from under app's feet.
Doh... I missed the disabling of the service.
Will add it tomorrow.
This is my first time not using pixel images to
decorate a website. Instead, all icons are saved
in the
SVG
format and converted to a webfont, which is then
used to style regular HTML characters into icons.
For example, here's a font with the above icon set -
VectorIcons.ttf
The advent of webapps like
IcoMoon and
Fontello
not only made the process of building @font-face kits
an absolute no-brainer, it also gave an easy access
to hundreds of existing vector icons, many of
which are free and of production quality.
When coupled with now virtually universal support for
CSS text-shadow, box-shadow and gradients, this almost
completely eliminates the need for raster form of
smaller decorative and nuancing elements.
More or less done with the Features section
on the new website.
Probably missed few things, but that's easy
to add later on. The biggest time sink was
trying to inject some visual hierarchy into
the list, but without going against overall
minimalist look and feel of the site.
Might still revise it after sleeping on it
for a couple of days :) Won't be the first
time.
Plodding through some grunt work with the
new website. An almost equal split between
working on a copy, javascript and styling.
As simple as the screencap looks, it came
with two hurdles that needed solving.
The header font, Alte Haas Grotesk, didn't
display correctly after it was
converted
to the @font-face kit. Specifically, the
lowercase 'o' looked like this:
The font's free, but I couldn't find a copy
of its license, so I started tracking down
font's author to ask a permission to edit
the outlines.
While waiting for a reply, I found another
workaround which involved generating the
webfont kit from OTFs instead of TTFs. Not a
big deal, but it still took over 3 hours to
resolve.
—
The second issue was with the slide-out,
fade-in animation. Sometimes the slide-out
didn't extend all the way down and sometimes
it overshot. This traced back to the fact
that slide-out height was computed before
the OpenSans was fully loaded and the script
fused basic sans-serif to compute the
height.
Again, not too complicated, but, again, cost
an hour to work through.
:-|
Little bit of this, little bit of that -
all unplanned and it all adds up.
Nearly done with the new website design. Here's
a snippet of how the site's header interacts with
scrolling.
Released a small playable test of the directory scanning module.
It appears that using as many threads as there are CPU cores
and traversing the tree in a depth-first fashion (scan child
directories first and sibling directories second) yields the
best scanning times.
2nd sketch for
bvckup2.com redesign.
Larger version is
here.
1st pass over the redesign of
bvckup2.com.
Larger version is
here.
Current design is almost two years old and
it grew steadily disconnected from the simpler
aesthetics I am pushing for now. So it needs
to be redone.
I will probably simplify this even further.
I've been wanting to do a true minimalist
site for a software product for a long time
now and this seems like a real chance to do
just that. Yay.
This is a
sprite
sheet of all raster images that are going into the
run-as-a-service demo.
Interestingly enough, the total size of individual
images saved as 32bit PNGs is 63,127 bytes, while
the size of this sprite sheet (without checkered
backdrop) is 63,829. After factoring in the size
of the code that is needed to parse the sprite sheet,
it really becomes a no brainer to keep every image
in its own file and embed them into .exe's resources
that way.
Added a "crash" handling and reporting facility
that includes several important changes compared to
the original version:
1. The program now differentiates between three types of
errors and handles them slightly differently.
First, there are unexpected operating
system errors, i.e. when a core Windows function
fails in a way that it shouldn't be failing.
Classic example (that everyone is aware of) is
TrackPopupMenu that is declared as returning
boolean, but actually doesn't shy away from
returning an integer under certain
circuimstances.
Secondly, there are inconsistencies in app's own
code, whereby one part assumes certain usage
that is not observed by another part. These are
so-called
"assert" failures. The original version has
three critical issues, all of this particular
kind.
Lastly, there are straight-forward crashes. This
is when a program is trying to operate with data
that is no longer there or corrupted. This is the
worst of them all as it typically indicates a major
screw up on programmer's part, but in some cases
it may also be an indication of failing hardware,
like a faulty memory stick.
—
2. The program now generates a
minidump
- a small-ish
file in a standard Windows format that captures
the context of a failure. Minidump files
dramatically simplify investigation of a
problem on the developer's end.
—
3. Finally, the minidumps can now be uploaded to the
support server right from the error notification
window with one click. The transfer is based on
WinInet API as this is supposed to improve
the chances of getting the report through in
proxied and otherwise "enterprised" environments.
For cases when the upload fails, the error dialog
also offers an option of opening a link in a
regular browser and reporting a problem that way.
64bit version is stored inside of the 32bit
executable, from where it is extracted and
launched to replace the 32bit version if
latter detects that it is being run on a
64bit system.
Pro:
a single executable to distribute
Con:
the exe comes out weighing twice as
much... or does it?
The size of a 32-bit executable can be easily
reduced with the help of tools called
executable packers. They work by turning
the exe file into a self-extracting archive
that also automatically launches the original
exe after the extraction. It may sound simple
but in reality it involves bundling a custom
PE loader with the packed executable (as
it might not be possible to extract the exe
into a temporary file before running it).
In any case, exe packing is routinely used by
developers who care about the size of their
products, with uTorrent being one of most
notable examples. Original Bvckup was also
compressed, owning its tiny size in part to
the magic of
UPX.
—
The problem lies with 64-bit executables.
For a variety of reasons there are presently
no exe packers that support them.
However if we store 64bit binary inside of
the 32bit executable and then pass latter
through a compressor, we end up with both
being compressed. Ta-da!
But there's more.
—
When an .exe is compressed, the compressor
leaves the primary application icon intact.
This is done so that the app would keep its
original appearance in Windows Explorer and
not sport a generic "program" icon.
Starting with Vista, the app is expected to
support a variety of icon sizes that quickly
add up. For example, bvckup's icon weighs
in at about 110KB. That's almost half as
big as the actual code, the code that does
quite a few meaningful things on top of just
looking great :)
So, if we do the 64-in-32bit packaging, we
end up compressing 64bit version in its
entirety, including its icon, and arriving
at a greater size reduction if we were to
compress the exes separately.
Win-win.
A page from the first demo of Bvckup 2.
Working on a shared memory buffer interface,
a part of the
IPC
module, which is what enables
the separation of the engine and the UI.
A bit more humane approach to critical error reporting.
The message is a homage to
NetPositive,
the BeOS browser that pioneered the technique of using
haiku
in error reporting. In fact, the message in option B is from
the NetPoisitive
original list.
The icon is that of a
Zen circle, which
has a plenty of meanings, many of which applicable given the circumstances.
Three-frame animation of engine's heartbeats for the demo.
Test of a fading transition, part of a small library
that deals with supporting UI animations.
Fading animation dissolves a part of a window into
background, in preparation for transitioning the
window to another state, e.g. moving to the next
page in a wizard or resizing the window into a
more compact form.
As simple as it sounds, these sort of animation
is fairly complex to implement on top of the
Windows API.
Windows includes native support for window
transparency in a form of
layered windows,
but it comes with a list of limitations that
aren't exactly practical or easy to work,
except for several specific cases.
The simplest working solution involves taking
a screenshot of the window, creating an overlay
window and then using it as a canvas to render
the transition from an empty background to the
screenshot. All the while making sure that
Windows doesn't sneak in an unsolicited window
refresh that would lead to a flicker, which in
itself is a very "fun" thing to debug.
Every application icon that is exposed to the
operating system must exist in at least nine
sizes.
16, 32, 48, 256 are more or less expected.
These are used in "small", "icon", "tile"
and "extra-large " views in Windows Explorer.
20, 22 and 26 are possible sizes of an icon
used in the window caption. The exact size
depends on screen's DPI level.
And 40 (along with 32 and 48) is the size of
an icon used in Alt-Tab view on W7, again
depending on the screen's DPI.
If you don't provide an appropriately sized
icon, the OS will grab one that is slightly
bigger and shrink it down, ruining the pixel
polish.
Lastly, each icon ideally must be saved in
32, 8 and 4 bits per pixel formats, so to
be compatible... you know... with
EGA cards
It would've not that big of a deal if it
weren't for the size of a resulting .ico
file. For example, the above icon ends up
being ~ 120KB, whereas the actual .exe it
is attached to and that does quite a few
meaningful things sits at around 96KB.
Similarly, every bit of graphics in the app
must be done in at least three different sizes
- one for each common screen DPI level.
DPI stands for dots-per-inch and it's a metric
of a pixel density on the screen. The smaller
the screen, the more pixels are packed into a
square inch, assuming the resolution stays the
same. The difference in DPI between a large
LCD panel and a 12" notebook screen can easily
be a factor of two or more.
This means that if a program renders 9px text
on both screens, on one it will appear twice as
small as on the other one, and might command
a need for a good magnifying glass.
So naturally it's a good idea to make the OS
aware of the actual DPI of the monitor in use.
If it's too high, the OS can do few things to
make things visible with a naked eye again.
Like increase size of the default system font
and make windows generally larger.
This can be done automatically by looking at
the monitor .inf files or by letting the user
configure the DPI manually.
—
XP defaults to 96 DPI and with some difficulty
it can be changed to 120 DPI. Vista and newer
versions are better. They come with four
predefined levels - 96, 120, 144 and 192 -
and they also support custom settings.
This brings us back to needing multiple versions
of every graphic in the app.
—
Vista is the first Windows version to
routinely use monitor-specific DPI values
out of the box. As such 96 is no longer
a dominant DPI level and the apps are now
expected to take the DPI into an account
when rendering their content.
The higher the DPI, the larger the graphics
and the fonts the app should use.
The penalty for not doing this is an automatic
stretching of the app window that inevitably
leads to a blurry appearance and a host of
other lovely issues.
In other words - not complying with OS
expectations is not really an option. Hence
the need for 3+ differently sized copies of
the same pixel art.
The UI sketch for run-as-a-service demo.
Trying to find a balance between using custom
styling and not getting to far away from the
native OS look and feel.
See also
8 other options leading up to this one.
Illustrative icons for the same demo.
First pass over the demo UI.
V2 running as a service,
an actual screenshot for a change.
There are three big things left to weave into the program - file system monitoring, new delta copier and software updates - and the beta is good to go. A matter of few days now.