Git == awesome

This week I started off by trying to get the item list to render.  Several times along the way I decided that the rendering an item was way too complex for the tools that we had, so I developed some new classes to try to simplify things.

A lot of them had to do with laying out things and in particular laying out things without something to draw to.  I made a class to handle text layout that’s sort of a trimmed down version of pango or NSLayoutManager.  Also, a Font class that gives a few metrics.  A Button class to size native (or non-native on windows) buttons.  And finally a Layout class, which gives a higher level interface to all of the above.

The buttons are working out pretty cool.  On OS X we use a NSButtonCell, so it’s as native as you can get.  On GTK we get the user’s current style then use it to render buttons — I’m pretty sure this is what Firefox 3 is doing.   You could argue that this is not quite “native”, but I can’t tell the difference.  On windows we just render our own, which you could say is native for that platform :)

I got buttons working around Thursday.  On Friday I had to take a trip to DC.  It seems like a lot of folks were talking about git-svn, so I decided to give it a try.  Fetching the source from subversion was a pretty awful experience, but after that things were pretty awesome.  I was committing changesets while driving down route 15, then checking them in to our server when I got an internet connection.

The last tool I developed was a box-packing system for rendering cells.  For a while I was trying to calculate things by hand, but the layout there is really too complicated for that.  Now we use some basic hboxes/vboxes and alignments and it works pretty well.  I’m feeling like the system that is in place now is basically what we need and it’s only going to need tweaking rather than creating new stuff.

The last thing I did was add download progress bars.  They are still a work in progress, but when I first saw the info updating every 0.5 seconds it made me want to jump for joy.

Themes and fonts

The first part of the week I spent working on the finishing touches with the tab list. I did some more backend changes on OS X, then workeded on adding the playlist list and the static tabs list. That went pretty smoothly.

After that I started working on the right hand side. I started working on code to handle switching displays in and out there, but there’s still more work to be done there. Mostly I started working on rendering items in the display. I got pretty far in that before I realized how badly we would interfact with some linux themes.

At that point I sent out an email to the list and tried to come up with some ideas on how we can work things. After thinking about it for a while, I decided to try this system:

1) Whenever the style gets set on our Window object, we check to see if we think our style is compatible with the user’s theme. Right now it’s fairly braindead. It just checks if the background is white or a really light shade of gray. If the check fails, then we don’t modify the style for widgets, and we don’t mess with the background for a widget in the custom drawing code. We do still draw things like the bubbles next to the feed tabs though.

2) When we draw things we pass in the current background color and text color to the drawing code. This lets us use the right color for the theme’s background. It especially helps when the user has a tab on the left-hand side selected.

It’s not the most elegant way of dealing with themes, but it works fine with all but one of my themes on Ubuntu.

The last thing I worked on was text handling. The initial motivation was to deal with the user changing their system font size. Then I realized that we would have to deal with resizing things based on the current font settings. Finally I realized that our text system could be really improved by adding some simple layout management similar to NSLayoutManager or PangoLayout. I just finished that today.

Next week I’m going to keep working on the item list. I think that I’ve finally dealt with all the side issues and can just work on getting everything to look good. I’m also going to be helping Andrew figure out the new system so that he can tweak things here and there.

I keep feeling psyched about the widgets branch. Take a look at this screenshot showing of it resizing the interface based on the user’s large font size. Still need to work on the video controls, but oh well…

Look at that resizing interface!

Data structures are important (or maybe I’ve just wasted my week)

This week I spent the entire time working on the tablist and more generally the table API.  I got drag and drop working after a day or two, then I spent almost all of the rest of the week changing the way we access the data that goes in our TableModel classes.

In some ways that means that I didn’t get much done, but I just kept thinking how important it is that we get a things working really fast.  We want to support things like rendering a feed with 1000 or maybe even 10,000 items in it, so there’s a lot of motivation to make sure that we have fast data structures in place.

The main problem is how access each individual row.  I started using the equivelent of GTK’s RowReference class.  This is like an index that gets updated whenever a row gets added or removed.  It’s probably the simplest in terms of what the programmer has to think about, but it’s quite inefficient since we need to update them whenever things are inserted or removed.  The next try was using Tree Paths, which is basically just an index that doesn’t get updated.  This was probably an improvement, but then I realized that GTK implements it’s model classes with linked lists and whenever we used one of the tree paths we were iterating through the list.  So if we wanted to access each row in the list it was O(n^2) time, which is shameful.  Finally I settled on an using Tree iterators, which is basically a pointer to a node in a linked list.  This is the fastest way to access things and I realized that, like RowReferences, they don’t get invalidated when other rows are added/removed.  So it seems like definitely the way to go.

I may spend one more day trying to work on the model classes on OS X.  Unlike GTK we have to roll our own there and the current design could use a couple improvements.

The other thing I did this week was work on those startup tweaks that we talked about.  I made it so that we don’t re-download thumbnails on startup and implemented a queue for updating feeds.  Both changes seem to be working ok so far.

This week I hope to get a lot of visible changes to the widgets branch.  Now that the behind the scenes table code seems pretty complete it means I can work on the fun part of rendering things.

Tablist is so close

Last week I worked on getting the tablist to work right.  I would say I’m about 90% of the way through it.  I have the channel tabs almost working, the only thing needed is drag and drop.  Once I implement that, then I’ll work on getting playlist tabs and the static tabs, neither of those should be very hard since at that point all the platform-specific code will be in place.

One interesting thing is that the more I work with the widgets branch, the more I realize that once we switch over we can simplify the database a lot.  For example, when I was working with drag and drop, I realized a lot of the book-keeping we do in the TabOrder views can just be thrown out.  Also a lot of the data that’s setup in onRestore() isn’t needed anymore (like if a feed is blinking, or if it’s parent is expanded).  I really like that since it can simplify moving to not having the database in memory.

Next week I’m going to finish up on the tab list, then I guess I’ll move to the items list.

Customizing the Controls

This week I mostly spent adding support for custom buttons and sliders to the widget branches.  It went along well enough, right now there’s playback buttons and a progress slider.  I think the volume slider will be trivial to add, I might have it before the dev call.  The system seems like it’s working pretty nice and it’s easy to customize.

Once I get the first pass done, I’m going to take a bit to make sure that they are accessible.  This mostly means making sure they accept focus and respond to keyboard input.  I think this will be very easy on GTK, but I don’t really know how it works on OS X, so that might take a bit of time.

After that I think I’ll work on dialog boxes for a bit, which shouldn’t take long, then move on to the left-hand tab bar.

Overall the widgets port seems to be moving steadily but surely every week.  It’s really satisfying to click on the play button and see my debugging printout.  Also, the new UI looks really nice, I can’t wait to release it to the world.

Widgets widgets widgets

This week I kept chugging along at the widgets branch.  The begining of the week I spent trying to get the windows port to build since I was basically replacing the entire build process.  I also needed to rewrite my GTK/XULRunner focus fixing code in C++.  I’m not sure exactly what went wrong, but when I added a second thread to the mix subclassing windows procedures gave me segfaults.  I think it has to do with the python GIL, but I don’t really know why.

Right now I have code working on all platforms that displays a window with a web browser inside.  Now I’m working on layout code, which mostly means coding vboxes/hboxes/alignments on cocoa.

Also this week I talked with you all and several people on IRC about different ways to make background tasks less noticable.  I’m pretty excited to get that stuff into 1.5, seems like it’s not too much work and it could have a nice payoff in terms of user experience.

Widgets Moving Along

This week I continued my work on the widgets work.  I checked in code to the widgets branch to handle basic startup/shutdown and open a window.  It’s very simple, but it’s pretty cool to see that window pop up and miroguide.com show up.

At the begining of the week I implemented it in portable and on OS X.  The GTK/X11 implementation was about 2 hours or so.  The windows implementation on the other hand is going to be a real pain and requires basically trashing setup.py and rewriting it from the bottom up.

That brings me to one thing I want to talk about on the call.  If I’m going to be basically starting over with our setup script, I’d like to talk about using mingw as our main C compiler.  I’ve been thinking about how much of a pain it was to add support for the vista function calls and how it would have been a ton easier if we were using mingw. I’m pretty sure mingw has supported the calls for quite a while, and if it hadn’t it’s so much easier to upgrade it’s win32api package than it is to install a new microsoft SDK.  It’s been especially on my mind because I tried to install visual c++ 2008 express and it completely ruined my build environment.  I’d love so much to get rid of microsoft tools and just use free ones.

The main reason that we’re not using it is that the python docs say you should use the visual c++ 2003 to build python extensions.  I’ve done a ton of reading about it and it seems like the reason is complications from using a different C runtime DLL.  Python uses msvcr71.dll, but things compiled from mingw use msvcrt.dll.  Using different C runtimes can cause problems in a couple of ways.  The main one is trying to share data (for example a FILE pointer) from one runtime to another will cause very bad things to happen.  Then there’s more subtle errors, for example atexit() callbacks will only fire from one runtime.  However, all of the errors don’t seem to happen in practice so often. It seems like the main reason that people try not to mix compilers for peace of mind.  But the gtk DLLs are linked to msvcrt.dll, so it seems like we can’t get total peace of mind in any case.

Anyways, I’m not really sure of the ramifications, I’d love to talk on the call about what people think about this.

Cocoa’s been blowing my mind

This week I spent most of my coding time trying to wrap my brain around Cocoa and pyobjc.  I figured it was going to be at least somewhat similar to GTK, but actually it’s completely different.  I’ve just been trying to get a window to pop up that displays miroguide.com, but there’s still quite a bit over my head.  Hopefully I’ll get it working in a few days, I think this first step is going to be the hardest.

In addition to coding, I’ve been spending tons of time trying to figure out how we’re going to make native widgets work.  Mostly it’s been pretty exciting for me though, since I realized that NSOutline/GTKTreeView work on very similar models and are actually much more flexible than I though.  I think they could work great for the item lists and tab lists and be super-snappy.
Lastly, I’ve been working on getting my unaccepted bugs down.  I think I’m finally in single digits now, this week is the week I finally get bugzilla to stop pestering me!

Knee Deep in Browsers

This week I’ve been up to my neck in web browser code.  XULRunner, WebKit, gtkmozembed, you name it.

My main goal was to get an embedded web browser working on windows, so that we can move forward with the widgets program.  The only one I could get working was XULRunner.  I thought XULRunner was a dead end for a long time, because I couldn’t understand the focus issues, but now I finally do and I’m able to get it working pretty much 100%.

When I had given up on XULRunner, I spent a while trying to get WebKit for windows to work, but I was never able to get it working.  I had a couple talks with folks on #webkit, and it seems to me that the windows port is not quite ready for prime time at this point.

There was a time when I was really worried that neither embedded XULRunner, nor webkit was going to work so I started thinking of alternatives.  The main ones I came up with were 100% XULRunner or embedded XULRunner using MFC.  I’m not really interested in either of those, but I guess it’s good to keep in mind.

The other timesink this week was another browser ploblem.  Drag and Drop stopped working on linux with xulrunner 1.9, mostly because they started doing error checking for the bogus values we passed in.  I spent a ton of time trying to get a good workaround, but in the end I ended up just checking in a patch that made our bogus values just a little less bogus.

Web Browsers Clicking

This week I kept working on embedding xulrunner on windows with PyGTK.  I thought it was only going to take a couple days, and in fact I was almost there after two days, but then I ran into a huge tangle of focus problems.  Basically the focus is totally broken on my tests, it takes some random amount of clicking on the window to get the focus right, and I have no idea why.

I looked at the gtkmozembed source and remembered that they have a ton of hacks to get focus right.  Then I checked the moz-dev-embedding lists, and found out that most of those hacks don’t work on windows.  I’m trying to get in contact with some mozilla people, but in the meantime I’m pretty much stuck on the focus issues.

I think I’m going to just forge ahead and ignore this problem for now.  Hopefully I’ll get a good response and have a straightforward fix.  Otherwise, I can look into more radical measures like webkit, or just using XULRunner for all the UI stuff.  I don’t know, but right now I’m sick of trying to get those clicks working, so I need to move on.