Friday, November 25, 2005

Update

You may have noticed that the posts got rare in the last weeks - it's not that I don't want to write updates, but while I'm working on the app_server, it's hard to report the actual progress.

In fact, I completed the new event dispatching system today - it took longer than I thought as I had to work on several different components to make it work. For instance, our current (and soon to be thrown away) BMessage implementation was not able to deliver messages to the preferred handler, it forgot "preferred" and set "none" - the message dispatching code in BLooper/BWindow was written around this "feature", as if it were given (messages will always get delivered to a looper, and will then be distributed to the looper's handler objects - a BView is such a handler for a BWindow).

I also spend some time on the input_server that solved some things in too complicated and partially broken ways. For example, it has an internal queue where the input devices add their messages to - this was a standard port, so every message had to be flattened, written to the port, read from the port, and unflattened again for processing. Since the input devices run in the same team as the rest of the input_server that was a pretty large overhead - besides the fact that those messages (all of them) were never deleted and thus leaked memory with every mouse move.

It's not that I only had to fix bugs in other people's code - I also fixed a stupid bug in the kernel and in BFS (in the Haiku-only version), and I guess those fall into my responsibility :-)

To cut a long story short: as a side effect of working on the event handling, we now have a more stable Haiku we probably ever had before. Instead of crashing, the app_server now likes to deadlock - which is an improvement, if you ask me. It's not surprising that it does so, as we don't have a locking model in the app_server: everyone can be locked, and everyone locks everyone without thinking twice. That's one of the things I will be working on next.

The other thing is to continue refactoring the code, and fix the broken Layer class hierarchy. The basic problem is that RootLayer (a subclass of Layer) does too much, and is therefore, but not only therefore known to its super class and other layer dependants - if you're familiar with class design you will know that that's a good indicator for a redesign. I call it refactoring.

In other news, I will continue my work for Haiku until the end of December this year - thanks for your kind and generous donations to make this possible.

Monday, November 14, 2005

Event handling

The font stuff is still not completed, but it works good enough to leave it as is for now. Missing is foremost work on the font cache - I haven't done anything in this regard yet.

In the last days I've mostly fixed bugs, and cleaned up things - there are still enough bugs left, but overall things are improving. Next topic I'd like to work on is the event handling in the app_server.

While I haven't got a detailed plan yet, the basic idea is to make it more flexible and move it out of the class currently taking care of it (RootLayer). While that probably wouldn't keep me busy for too long, I will also try to move as much functionality as possible to the client. The app_server will only make sure the right window gets the event - the rest is mostly up to the client. An exception to this rule are views that are using the BView::SetEventMask() feature; they need special care as they may demand getting events even if they don't have focus and are not below the mouse cursor.

I will also attack a problem that is mostly visible when using Haiku in Qemu or when an application becomes unresponsive: the mouse cursor visually hangs and makes navigation quite hard. The reason for this is quite simple: every mouse move is sent to the window below the mouse cursor - if that one is currently busy, the app_server waits a bit until it gives up sending the message: and that delay is what's responsible for the hanging mouse cursor.

The solution to this problem is the decoupling of the "mouse moved" messages and the updating of the cursor on screen as BeOS does it for ages. A high priority thread will do nothing else than waiting for notifications that the mouse cursor has been moved - these notifications are not sent over ports, but use shared memory to cause as little delay as possible between the physical mouse move and the visual feedback on screen. Now the window can take as long as it wants to read its messages, it won't impact the cursor movement anymore.
Jérôme has already laid the foundation to this, and I will move this into the new event handling design and make sure it'll work.

Tuesday, November 08, 2005

Mmmh Fonts.

In the last couple of days, I worked mainly on the font sub-system in the app_server. I didn't think I would spend that much time on it, and I haven't even touched the FreeType backend other than temporarily fixing threaded access to it, as explained earlier.

On BeOS, when starting up, the app_server will scan the well-known font directories, and makes all fonts it finds and supports available to end-user applications. When you install a new font, you have to launch the Fonts preferences application, and press its "Rescan" button. And while you're at it, you can also specify the amount of memory the app_server uses for font caching.

On Haiku, this will work a little bit differently: on startup, the app_server will only make some fonts available - those that we're used the most during the last session. The app_server just stores a short list of those fonts and where they can be found on disk. It doesn't know about other fonts before you ask for one; if you ask for a font the app_server doesn't know yet, or ask for a list of all fonts, the app_server will scan the well-known directories for fonts for the first time. This makes the system boot time completely independent from the number of installed fonts. As a graphics designer, or just a collector, you can now serve your font needs without penalty.

This method does also work in a multi-user scenario: the user font directories are only added to the app_server when you log in - and they, too, are scanned the first time it's necessary, and not just always. Each user will only see the fonts he can really access, the font manager is able to present different font lists for each user.

And when you install a new font, it will be picked up immediately, using node monitoring; it's really surprising how few system components make use of this nice and handy feature in BeOS. That situation is greatly different in Haiku: we are keen to get rid of all those "restart" and "rescan" buttons the BeOS UI present you in one place or another, and node monitoring plays a big role in achieving this.

But let's come back to the Fonts preferences application for a moment: have you ever changed the cache settings there? Have you felt good about it? Did you know what you were doing? Did you notice any change? If you're like me, you can answer with a honest "no" to most of these questions. I think it's a bad option to put into a user accessible preferences application. The app_server should be able to figure out a good value by itself, and maybe even make the cache size dynamic, adapting it to the current work load. For this reason, you won't find that setting anymore in the Haiku Fonts preferences - I took the liberty and removed it.

The app_server font cache is still under construction, and I'll write something about how it will work in one of the next posts.

Thursday, November 03, 2005

Workspaces

Most of us are used to how BeOS handles multiple workspaces: each workspace represents a configuration for the screen, including resolution, colours, and desktop background. The visual appearance, that is UI colours, scroll bar design, etc. is maintained per desktop, though - all workspaces share the same properties in this regard.

It's maybe not so obvious that every workspace also knows which windows are open on it, and in what order they are. When you switch between workspaces the position and order of the windows is usually preserved. There are exceptions when it comes to windows that are visible on multiple workspaces, but I never quite understood why this is and how it is working. Adi Oanca has implemented a similar behaviour for the Haiku app_server, and I hope that he figured out how it worked or even found a better way how these windows are handled.

Anyway, there can be up to 32 different workspaces for each user. And that makes 32 workspaces for each desktop, too. The desktop class manages the list of workspaces - it makes sure that every time you log into your computer, your workspace configuration is restored.

The Haiku app_server extends the idea of workspaces to multiple physical screens. How does that work? Every workspace will not only store the configuration of one physical screen, but all physical screens that are or were once attached to your computer. So in one workspace, you can have the second head of your graphics card (or even your second graphics card) configured to deliver a nice TV out signal, while in another workspace, it's configured to feed your second TFT panel right beside the first one. Of course, you would still need to switch the cables yourself in case you don't have a KVM switch :-)
Unlike the situation found in other famous operating systems, the screen settings are not lost if you change the screens attached to your computer (and not even if you don't change it) - or the graphics card for that matter. The configuration of each screen is preserved: if you only attach the video projector to your laptop during lectures, the app_server is supposed to recognize this and restore the configuration you had used for this output device. We'll see how well that works in reality - in R2, though, I'd guess.

In any way, the desktop spans over all physical screens, they share a single coordinate system. If a window asks for the screen size, it will only get the size of the screen it is asking for, though - if it wants to span over all screens attached, it needs to be adapted to know about multiple screens. This is even possible without any API extension, the BScreen class already covers this use completely.

Tuesday, November 01, 2005

Introducing The Desktop

Since it would probably be boring if I just wrote which bugs I fixed in the app_server today, or which function I renamed to make it easier on the eyes, I think I can better use this forum to introduce some app_server concepts, in varying detail, and in small steps.

The first concept I will introduce you to is the Desktop. Not the Desktop you see as part of your daily (?) computer experience, but the Desktop as the app_server manages it. Every user logged into your system will get a different Desktop object. Every user? Well, for now, this is just you - but the app_server can manage as many desktops as needed. If you notice this for R1 remains yet to be seen, but the chances for this are not too bad.

Anyway, every desktop has certain input devices, and output devices assigned. It will also manage all applications of its user, and the workspaces configurations the user has defined. The desktop also knows all screens visible on screen and their order. If a desktop object is deleted, it will also quit all applications the user had running, and that will also close all windows those applications had opened before.
Your physical screen(s) as well as all the mice and keyboards connected to your computer will typically be owned by the desktop object. Of course, if you happen to have two of everything, these resources could also be shared between concurrently logged in users. The input or output devices may also be connected via the network, even though it's not very likely that this will be supported in R1.

Right now, when a BApplication is created, the application will first ask the app_server for a desktop object, and when the application got this object, it will then have the desktop create the server part of the BApplication, which is currently called ServerApp. That's usually about all an application will talk to the desktop - even if it's the main actor, it will also stay in the background, and delegate most features to other classes.

A desktop object is only created, if an application asks for it - and that will be the moment when you'll need to authorize yourself to be able to open anything on screen. Right now, the app_server doesn't care about passwords, though. The desktop object is the app_server's key to multi-user support - even if it is currently not really used that way, it lays the foundation for R2 and beyond.