Saturday, August 13, 2011

A Swipe UX Idea

Over my desk at work I have a sign that says "On my deathbed I would design a better deathbed".

I've been using the N950 now for several weeks and I can't help thinking about how I would do things differently.  This is not meant to criticize Nokia's work on Swipe.  Swipe works well as a universal gesture.  Even if there are issues with it you and I should recognize this is beta software.  I've heard Nokia has already made one change to swipe since my software build and who knows what else might change before release.

I'm just curious about how else things could be done and the effect they might have on the user experience.  I don't think Nokia should immediately drop everything and switch to my idea.  I first would like to see what they come up with in the finished project.  If I still think mine is better?  Oh well.  People think and act differently, especially programmers, and they are probably targeting others.

Swipe UX

I'd recommend these demos for a quick introduction into swipe.  The main swipes will bring you back to the last home screen you used.  When wanting to swipe to a specific screen you swipe back to the home screen you were on, pause to see which it was, and then swipe over.  You can go about it faster by remembering what screen you were on.  I usually think I know where I was but I tend to be wrong leading me to swipe a few more times.

My variant on Swipe UX

My idea centers on a spatial model that spans home screens, the lock screen, and applications.  This could roughly be translated to virtual desktops with rules controlling which desktop different windows get launched on based on the desktop's role.

Launch an app, no matter from what screen?  As it is opening the device also slides home screens over to the task switcher.  Now with the app up a swipe down reveals the task switcher below.  If instead you swipe up the app closes.  Also you can swipe to the right to move to the launcher or left to move to the events feed.
Idea: Swipe up or down from the lock screen to unlock and reveal the feed
The device goes to sleep?  The lock screen is above the events feed.  A swipe up or down reveals the feed below.  Instead a swipe right moves to the task switcher and left for the launcher.

Idea: Swipe left on the lock screen to unlock and move to the launcher
Open up a folder of icons? The subfolder opens up above the launcher.  A swipe up or down to reveals the main launcher below.    This would provide a simple UI for subfolders to be built into the launcher..  Again instead a swipe right moves to the events feed, and left for the task switcher.

Idea: Swipe Right on the lock screen to unlock and move to task switcher
Applications, home screens, and the lock screen would operate on a more consistent set of simpler rules using a spatial model for the home screens rather than most-recently-used.  From where you are you would always know how to get to where you want to be with one swipe without a pause to think of which screen you are on and what direction you need to go to get to where you want or having to keep an accurate mental copy of the device state.

*Note: The images are mockups only and were hacked together from screenshots I found through Google.

Python Packaging for Harmattan

Right now I am taking a break from learning QML.  Instead I've been adding support for Harmattan to my existing QWidget projects.  It might seem pretty pointless because of how aweful QWidget can be with the default theme.  I will at least have the apps available if I need them in a bind.  Also taking working apps and repackaging them rather than new untested apps provides the benefit of controlling the number of variables to debug when things go wrong.

I will be focusing on packaging for OBS seeing as a QWidget-based application isn't worth pushing through OVI.


I had to switch my applications packaging over from my py2deb fork to the distutils-based sdist_maemo.  A big reason is sdist_maemo already has Harmattan support.  I also figured it was a good idea to switch to distutils as it is more "proper" python packaging and because it is pluggable for various target packaging systems.  That last part will allow me to continue to support Maemo 4.1/5 and in the future support regular MeeGo.

So first I've moved all of my files to a proper distutils based layout
  • ./
  • ./LauncherName
  • ./package-name/*.py
  • ./data/package-name.desktop
  • ./data/package-name.png
I try to reuse code and packaging infrastructure between my projects so this means I need an easy way to diff between them, so I added a symlink from "./package-name/" to "./src".

I then wrote my file with an sdist_maemo command configured for each of my target deb-based distributions.  A nice thing to know is that for Maemo 5 the python module will be optified for you.

An annoying thing is each platform has different packaging requirements.  Some examples include:
  • Different ".desktop" file locations
  • Different ways of launching the app from within a desktop file.
  • Everything seems different with the app launcher icon
  • Different icon sizes for the Maemo-Icon-26 field
  • Different .deb sections
  • Different dependency names
  • Aegis file support (not needed for current apps so skipped over)
Already the differences between Maemo 4.1 and Maemo 5 were annoying from a packaging perspective.  This makes the problem even bigger.  One approach I've always rejected was maintaining separate packaging scripts for each distribution requiring me to keep duplicate information like the version number.  The approach I used with py2deb was passing a parameter in to my script to change what was passed to py2deb.  That doesn't seem to jive with distutils.  So I threw in a touch of code-gen using a nifty tool called cog.
To minimize my need for using code-gen my file creates multiple instances of sdist_maemo, one for each platform.

The app icon caused me some problems.  I had assumed it would operate like previous versions of Maemo and desktop Linux, that if you just said "ejpi" or "gonvert" it would look for the appropriate icon size in "/usr/share/icons/hicolor".  I'm glad I found that document explaining otherwise.  As an alternative some of the apps in the OVI Store just hard code an absolute path. When you do make a mistake on this, Harmattan seems to have two different default icons.  The red square came up for me when "ejpi" didn't map to an icon.  The green curved icon came up when I had an absolute path that pointed at nothing.

My makefile creates the needed icons, code-gens my desktop files, code-gens my files, and then runs "setup.*.py sdist_*".

Odds and Ends

I do not believe PyQt is available for Harmattan, so I had to finish adding support for PySide in my applications.  I've made it easy to use both bindings by centralizing all knowledge of the differences between the two.

I've tried to make the switch a couple of times already but each time I came across new bugs that the old bugs prevented me from seeing.  Luckily the PySide people are quick at resolving these issues and by 1.0.5 my applications ran smoothly.

I went ahead and made the simple switch to XDG and Harmattan-style icons though I'm not yet seeking OVI compliance.  I decided to redo the icons.  They weren't all that great, no where near the icon guidelines, and I wanted SVGs so I could use the Harmattan Icon Generator.  Not being an expert at graphics tools, the icon generator definitely saved me a good amount of work.  The main drawback is that basing the icons background gradient on the base icon's content seems to produce results without enough contrast.  I ended up using the "mean" setting to force gray backgrounds.


Now that we have all that wrapped up, time to upload onto the OBS.  The Getting Started Guide has been updated and now is pretty good.  I setup a harmattan-specific subproject due to my code-gen specializing the source-packages per distribution.  Once everything was uploaded to my project, I logged in as root, added my sources, and away I went.

So for the fruit of my work:
Well I guess this means I need to get back to learning QML.


Desktop File: