First of all, there are input devices. That's what I started with - when I was working on my Raspberry Pi case, it had an IR receiver. It was connected using lirc and emulated keyboard media key presses using Python and its uinput bindings. I hoped media keys would control mocp, a nice console music player I was accustomed to use, or omxplayer, which is a RPi-specific player making use of hardware acceleration available there. I was wrong but it was a great learning experience about how input devices work. No wonder first thing I did was looking at the existing input devices and incorporating them into my project which desperately needed some input (pun intended). Most input devices I have at home are HID (I've written HID-enabling drivers for those which aren't =) ) This, of course, means that by using HID devices as input device base it is possible to cover most input devices, and make a room for the others by using a standardised interface - therefore the choice. I've got a global input driver taking care of this, it uses evdev - a Linux method of grabbing input device events, and it has nice Python bindings. I've written a wrapper around it which is asynchronous, therefore, everything that connects to this drier is callback-driven. You provide key names and callback functions, then it takes care of the rest. Callback functions are what drives various applications and parts of them such as menus.
Of course, menus have to output themselves somewhere. So every time menu's callback such as move_up, move_down or select_element is called, it has to do something on the screen. That's solved - you guessed it right - by a callback which the driver provides. Now, output drives are more numerous. There are much more HD44780 screen connection ways than there are input device types - just remember about all the ways one can connect an IO expander outputs to those 8 data lines. It's 8!, and sometimes I feel like those people developing cheap I2C HD44780 backpacks have an inside joke of some kind:
-"Let's swap D0 and D1 so that they need to rewrite their Arduino libraries MWAHAHAHA"
-"You thought this library was okay NOW YOUR BACKLIGHT FLASHES AT 20Hz LOL"
-"Oh look garbled characters with that custom library, why don't you use our library IT COMPILES ONLY ON ARDUINO IDE 15 THOUGH WHAT A SHAME"
Anyway, I was saying... There's plenty of ways to output data on a character display. However, I've got a plan on how to write drivers to support most of them, and it's limited only by how much different displays I can get access to - chances are it's got an Arduino library and those are simple to rewrite into Python. I plan to develop wrappers for most popular display ICs, which would contain commands needed to be sent to ICs to display anything, so you needn't redefine all the commands to write a new driver.
Once we've got input and output, the situation is good. As long as we don't need to run more than one thing using it. You could just make one big script which would contain every import there is and give them access directly... And every time there is an unlucky exception, it crashes the whole system. I'm not even talking about how big the file would be. It also would need to run as root, since once the monolith system like this becomes big enough, it is run as root - nobody wants to mess with permissions when you can just type "sudo". Oh, writing your own apps? You'd need to incorporate them into that file. Debugging sure would be hard. It'd be an equivalent of compiling your web browser together with your window manager.
So, we need a window manager of some sort. After a week of hard work, it's finally there, even though very basic - but mostly working. It's all thanks to Pyro4 - an IPC solution for Python objects, really powerful and worth trying if you ever need inter-process communication capable of also providing security features, which IMO is a must in my system. By some clever (and sometimes bruteforcish) principles I've managed to make it work without pulling too much of my hair, and it's clear it's here to stay. Once it's finished, and that is - in a couple of days, I'll be able to write apps. Lots of apps, controlling various aspects of my Linux system - that sure will be the best part to write =)
Oh, but menus... Somebody has to code them, right? So I plan on including every control there can be into an application creation framework. First, menus. That's the only UI design framework element I have by now - but I'll fix that. Menus I have now aren't as flexible as they could be but it's pretty easy to modify them by instantiating and overriding certain functions, you know, that's one of the things I know people and I personally will do. I can also add dialogs, text input fields using keyboards, keypads, T9 and whatever text input facilitation method I can invent or implement, [comboboxes, radiobuttons, buttons] and lists of them, confirmation dialogs, message boxes, warnings and stuff like that. Basically, I won't run out of ideas on what to implement as long as I have an access to any WYSIWYG-capable IDE, such as Visual Studio =)
So far, it's all I've got. There sure are more components, but they are seem more or less optional. The main thing is - it will all be about applications. See, I actually think there are many awesome Linux things, some of them just need an interface to be noticed. Some need an interface to be useable =) By making an interface like this, people are enabled to use their Linux boxes at full power - and what could be better?