Fork and Rename

Whew, I’m finally back.  Paris is a lovely city to visit, but there’s no place like home!

So, let’s discuss the current situation.  As I said, Quizo did email me and we had a nice conversation which cleared up a number of misunderstandings.  I’m still waiting to hear back from him on a few issues, but here’s the short version of what’s known so far: Due to lack of free time and motivation, Quizo is, for the most part, finished developing QTTabbar.  He was working on a Win 7 compatible version last year, but never completely finished it.  At some point he realized that he would not have the free time to continue, and the recently released 2.0 Beta 2 is simply a cleaned-up version of his latest revision.  He was a little ambiguous as to if he ever plans to release a Beta 3 or above, but he very clearly stated that it was certainly not happening any time soon.  Quizo has agreed to direct users to my project as the version under active development, and the main website has recently been updated to reflect this.

He did have a few requests of me, which I plan to honor.  Mainly, that the internal identifiers and settings location of my project be changed, so that it doesn’t conflict with his version.  This will happen in the next release.

If we’re changing all the internal identifiers anyway, then I’d like to take the opportunity to change another thing: the name.  I undertook this project on the (admittedly presumptuous) assumption that Quizo was gone for good, so I thought of my version was a direct continuation rather than a fork.  But now that there’s this version 2.0 of the original project in the wild, there’s no longer any ambiguity: my project is now a full-blown fork whether I like it or not.  And that means having a different name to differentiate it is pretty much required.

To be honest, I’ve wanted to rename the project for a while now.  I never really liked the name QTTabBar: it’s a little awkward to say, and people are constantly assuming we must have some kind of association with that other Qt.  The two biggest reasons why I haven’t renamed the project are 1) respect to Quizo and 2) I was afraid we’d lose the name-recognition that QTTabBar has established.  But now that Quizo’s given me his blessing and has put a link on his site to my site, both those issues are addressed.

So what should the new name be?  I’m open to suggestions; many people have already done so, but let’s get a few more.  Post them below or email them to me using the Contact link on the right.  I mentioned the possibility of a name-change earlier, and someone suggested “QTabs” as a new name.  I rather like that one: it’s short, it’s catchy, it has some homage to Quzio in there, and we can keep the “QT” prefix that is in use everywhere.  I’m certainly not settled on it though, so feel free to propose a better one (or voice your support for that one).

It was a bit of a bumpy ordeal, but I think it will ultimately be for the better.  I hope to make some serious progress on this project in the coming months, including merging most of the new features of Quizo’s version into my own.

PS: To address some of the comments in the previous post, my assessment of Quizo’s version as “extremely buggy” was based on my own install of it.  It could be that there were conflicts between my version and his that caused the glitches that I encountered.  I certainly didn’t mean to disparage his obvious effort, and as I said, he solved a few problems that I couldn’t.  Looking through the now-public source will provide a great deal of insight, for which I am extremely grateful.

State of QTTabBar

Greetings from Paris!  I have very limited time, so I’ll be brief.  Yesterday QTTabBar was featured on LifeHacker, due to Quizo’s 2.0 version.  Ugh.  This is pretty much exactly what I was afraid of; it’s going to cause a lot of confusion.  I was going to save the full explanation for when I get back (and when I knew a little more; we’re still hammering out a few things) but now due to the LifeHacker posting, I have to post the basic details.  Again, full details will follow in a few days when I return home.

The bottom line is this: Quizo is NOT continuing QTTabBar.  The recently posted 2.0 was posted as a cleaned-up version of his latest revision, once he realized that he would not have time to work on it anymore.  It has very many bugs, and they are not going to be addressed any time soon, if ever.  He has agreed to place a link on the wikidot site directing users to my site as the version under active development, as well as clarification that his version is not.  Hopefully I can get him to do this sooner rather than later, in light of the current circumstances!

Quizo’s back

He’s uploaded a beta of his own 2.0 version on the original site.

On the one hand, he’s fixed a few things that I couldn’t, including the Desktop bar.  Plus the icons have a fresh coat of paint, and the options dialog (while still a little messy) appears to have been redesigned.  However, a lot of other stuff is broken.

I don’t know what this means for me.  Should our versions merge?  Would he even agree to that?  Should I just keep going and fork the project?  That Quizo released this without so much as a cursory email to me is pretty upsetting.  I have to wonder if he’s mad at me for taking over.

To top it off, this happened at the worst possible time for me; I’m leaving for a trip to France in two days to attend an academic conference.  And now here I am with my head spinning off.  I really just don’t have time to deal with this right now.  I guess all I can do for now is wait to see how things play out while I’m away, and see if I can get any kind of communication going with Quizo.

EDIT: Thanks everyone for the encouraging comments.  Quizo did send me an email and it looks like everything will work out.  I’ll post the full details when I return from my trip.  Au revoir!

QTTabBar 1.5.0.0 Beta 2 Released

EDIT: IMPORTANT!!! If you have not done so already, you MUST manually uninstall Alpha 5 via the Programs & Features window (Add/Remove Programs on XP) before installing this release.  Alpha 5’s installer was misconfigured so it will not uninstall automatically.

EDIT2: If you install Beta 2 and get an error when you launch Explorer, or it fails to overwrite Beta 1, it’s most likely because you haven’t manually uninstalled Alpha 5!

Okay, okay, so that whole “within a week or so” thing I said almost a month ago turned out to be slightly inaccurate.  Thanks for your patience everyone; Beta 2 is ready for download.

I said in a previous post that fixing the Automation bug was a great learning experience for me, and that the experience was providing a lot of insight on other problems.  Well, that’s the reason for the delay: every time I thought I was ready to release it, I thought to myself, “Let me just take a look at one more problem and see if my newfound knowledge applies…”

As a result, the changelog for this release is particularly juicy, with some really major fixes in it.  But the one I’m most excited about (other than the Automation bug fix of course) is massively improved Explorer instance capturing!  It’s not perfect in all cases yet, but for programs that launch Explorer windows The Right Way™, QTTabBar captures them without having to let the window open half-way first.  Which means you’ll be looking at your files even faster than you would be without QTTabBar, since you don’t have to wait for a new window to be created! Seriously, before you install Beta 2, press Windows+E on your keyboard and note how much time it takes before you get a useable Explorer window.  Then install Beta 2, try again, and marvel.

In addition, programs that are supposed to open a folder and select a file now work as expected (again though, only if they’re doing it the officially Microsoft-sanctioned way).  Folders launched the wrong way will still need to be opened half-way before I can do anything about them; I’m still looking for a better way to capture these windows.

Incidentally, launching folders the wrong way will launch additional explorer.exe processes, so it’s bad even outside the context of QTTabBar.  (If you see a new window open half-way before QTTabBar captures it, check your Task Manager, and you’ll see you have multiple explorer.exe’s running!)  So, if your favorite program is opening Explorer windows the wrong way, send the developer an email and tell them to fix it!  For any programmers reading this wondering what the right way is, it’s to call ShellExecute with the target folder (by itself, not after “explorer.exe”) as the lpFile parameter.  To open a folder and select a file, the correct way is to use the SHOpenFolderAndSelectItems function.

Anyway, I’m really happy with this release.  I hope you all will be too.  Unless this release contains a show-stopping bug, I’m probably going to let this one sit for a while so I can work on the new Options dialog for Beta 3.

Happy tabbing!

======= 1.5.0.0 Beta 2 =======
Bugs Fixed:
Fixed scrolling lag buildup when using the ItemsView.
Fixed massive memory leak (!)
Fixed navigation on Homegroup Libraries.
Refined Windows searches no longer show up in the navigation history.
Clearing the Search bar now navigates back, instead of navigating to Libraries.
Middle-clicking on the Navigation Pane now respects the relevant option.
Fixed various problems occuring when Explorer is in single-click mode.
Fixed extension deselect when renaming .zip and .url files on XP.
IFilter-based Plugins, such as Megimo Loader, are no longer unloaded when the Options dialog is closed.
Support for systems with only .NET 4 and not .NET 3.5.
Support for both the x64 and x86 versions of Explorer on Vista x64.

New Features:
Capturing new Explorer instances is now MUCH smoother in most cases, and supports selecting items.
Middle-clicking on Vista and 7’s Breadcrumb Bar will open the target folder in a new tab.

Automation Bug Postmortem

This was certainly fun to write.  I tried to keep it as accessible as possible for non-programmers, but there’s a section at the bottom for those interested in the exact details.

A brief refresher: One operation absolutely essential for QTTabBar to function is hit testing, which means “figuring out what file or folder the mouse is over”. This used to be super easy, but with the advent of the new ItemsView control, it’s no longer trivial. Fortunately, it’s still possible through the use of the UI Automation library. Unfortunately, the ItemsView has a nasty bug in it: every time you make a UI Automation query, something builds up inside the control that introduces a tiny bit of lag, permanently. That means every time I ask what file the mouse is over (which I need to do very often) the lag grows a tiny bit. After many queries, the lag becomes very noticeable, and after a while it becomes excruciating. The lag goes away when Explorer is restarted, so users that restart their computers often probably barely notice this problem at all. But for power users who infrequently restart, or laptop users who always hibernate, it’s a major issue.

My quest to find a workaround would have been completely impossible where it not for Microsoft’s Public Symbol Files. Microsoft supplies debugging files for all important executable files in Windows. These files don’t give you the source code, of course, but they do give you the names and locations of all the internal functions. This was enough for me to attach a debugger to Explorer and (after a lot of digging through assembly code) figure out exactly the bug that was causing the problem.

Every time a UI Automation query is issued, the connection to the ItemsView’s automation object is created anew. Whenever it’s created, the UI Automation library registers for certain event notifications from the ItemsView, such as “notify me when the selection changes,” and other such events. It’s during this event registration process that the lag increases. It seems a little wasteful to create and destroy the connection every time a single hit test query is executed, and indeed, my first idea was to somehow cache it, so that it only needed to be created once. But over the course of trying to do that (which turned out to be futile anyway), I noticed something very critical: before registering the events, the ItemsView automation object is first asked if it is the type of object for which events can be registered. If the object were to reply, “no, I’m not that kind of object,” then the code introducing the lag is skipped right over! Figuring out how to intercept that request and respond with a fake reply was tricky, but once I did, the lag vanished.

Of course, this does introduce another problem: if any UI Automation application was actually counting on those event notifications, then that application wouldn’t get them once my hook was in place. QTTabBar does not use these events, since they are extremely inefficient, and there are better ways of getting the necessary notifications. And honestly, if anyone else is using these events, they shouldn’t be, specifically because of this bug! So, I’m not too worried about that. In the worst case, if I become aware that it is indeed causing a major problem with some other application, I could probably figure out a way to block the event registration only for QTTabBar’s requests, and no others.

Here’s a more technical explanation, for those that found the above explanation lacking in detail. The main function I need for hit testing is IUIAutomation.ElementFromPoint function, which retrieves the element under the mouse. After a long time of stepping through the assembly, I found that the lag was occurring because Automation events were being registered and never unregistered. This registration occurs during the call to UiaReturnRawElementProvider, which oh-so-conveniently includes a pointer to the ItemsView’s IRawElementProviderSimple as a parameter. I saw in the assembly that the element provider’s QueryInterface method is called to get access to its IRawElementProviderAdviseEvents interface, and from there the events are registered. Ahah! I knew immediately that if they were calling QueryInterface, then they will dutifully check the return code to make sure it succeeded. Sure enough, if QueryInterface doesn’t return S_OK, the event registration section is cleanly skipped, without any the loss of any other functionality. Much as I like to rag on Microsoft, I have never been more thankful for their excellent coding practice. It saved us here!

So, with the ever-amazing MinHook library, I placed an API hook on UiaReturnRawElementProvider, which I used to place another hook on the ItemsView’s IRawElementProviderSimple .QueryInterface. Then I can filter out those calls that are asking for IRawElementProviderAdviseEvents and spoof a return of E_NOINTERFACE.

So in the end, it’s pretty close to the best case scenario. The lag is completely fixed. Hit tests are free again, using a documented method that is unlikely to break in Windows 8. I can finally get rid of all that horrible spaghetti code I was using to minimize the number of hit test operations. And even more importantly, I can incorporate a hit test function into the plugin library, so that anyone who wants to write something that requires hit testing can use it.

This whole ordeal has really been a huge learning experience for me. I’m going to back some other problems I was facing with the ItemsView and saying “oh, that’s easy now that I know how to do this…” And I still feel like I’m just scratching the surface of what’s possible. Figuring out how to bend Explorer to my will is such an addictive puzzle. People sometimes ask me why I submit myself to dealing with Microsoft’s problems instead of just making my own file browser from scratch. There are, of course, some real answers to that question, but my first response is “Because this way is so much more fun!”

Thanks for reading. Beta 2 is on the way!

Scrolling Lag Bug COMPLETELY FIXED!!

Hello everyone,

It’s no secret that I’ve been obsessed with fixing Explorer’s Automation-related unresponsiveness bug.  (Yeah, they made that KB page just for little ol’ me.)  A few months ago, Microsoft’s developer support rep told me that advising users to use the old SysListView32 control instead of the default control was the best solution Microsoft would provide me with.  They will not issue a hotfix for it, but they’ll “look into it” for Windows 8.  To me, that solution is unacceptable.  How can I say to people, “Yeah, QTTabBar makes Explorer so much better, except you also have to make it worse by using an ugly, outdated control as the main component“?

Well, today, I’m thrilled to announce that I have accomplished what others might have called impossible:  I have effectively fixed Microsoft’s bug for them, without access to a single line of source code.  After a lot of painful stepping through assembly code and some cleverly placed API hooks, the scrolling lag is completely and totally gone, even after tens of thousands of queries.  Hotfix?  I don’t need no stinkin’ hotfix!

Needless to say, this calls for a much earlier Beta 2 than anticipated.  I want to test a little longer to make sure the lag is really gone for good, and I’m going to try to get a few more bug fixes in there too, but I plan on releasing within in a week or so.   Stay tuned; I’ll post the gory details of exactly how the hack works in a future blog post.

EDIT: A friend of mine pointed out that this post sounds a little egotistical.  I’d be lying if I said I didn’t feel good about this accomplishment, but just to be clear: the reason for my exuberance in this post isn’t so much that I fixed it, but that it was fixed.  Not so long ago, I was feeling little depressed thinking that we would probably be living with this bug forever.  But now that it’s fixed, I feel like QTTabBar is finally truly compatible with Windows 7.  And that’s what makes me the happiest.

Migemo Loader Plugin fixed

I’ve been keeping track of the QTTabBar thread on the popular Japanese message board 2ch.   (Surprise, 2ch users!  I can read Japanese!  A little!)  It’s always interesting to read their reactions to my endeavors, since, after all, Japan is sort of QTTabBar’s home country.  I’m glad that they support me and what I’m doing.  Apparently, since my name is Paul, I’ve been nicknamed “P-chan” (one up from “Q-chan,” of course!)  I was laughing for quite a while when I first saw that.

Anyway, I found out from that thread that the Migemo Loader plugin is broken.  So, I went ahead and fixed it.  Migemo Loader allows the filter bar to search for kanji using kana or romaji input, so I imagine it’s pretty important for them.  The problem was that the Migemo program can only use either Shift-JIS or UTF-8 encoding, while the plugin was expecting Unicode.  I don’t understand why everyone just can’t use Unicode and be done with this whole encoding mess…

I’ve fixed the plugin so that it expects UTF-8.  Perhaps in a later version I’ll have it so the encoding is selectable via a dropdown box.  The UTF -8 dictionaries are included in the latest version of Migemo, found here.  Download the fixed plugin here.

Unfortunately, there’s also bug in QTTabBar that affects this: if you open and close the Options dialog, Migemo Loader will be disabled until you close and re-open the Explorer window.  I’ve already taken care of it, so the fix will be in Beta 2.

QTTabBar 1.5.0.0 Beta 1 Released

Hello, everyone. It’s been a long time coming, but I think the program is finally stable enough where I feel comfortable ditching the Alpha label once and for all.  QTTabBar 1.5 Beta 1 is now ready for download.  Mostly this release is just polish, although there were a few major bugs fixed; see the changelog at the bottom of this post.

One little hiccup is that, due to a misconfiguration of Alpha 5’s installer, the installer for Beta 1 won’t automatically uninstall it Alpha 5.  So when you install Beta 1, you’ll end up with two entries in your Add/Remove Programs list, one for Alpha 5 and one for Beta 1.  So, Alpha 5 must be uninstalled manually.  Sorry!

So, now that we’re finally in Beta, what has to happen before we get out of it?  I have three main goals that I want to meet before taking off the Beta label: redesign the Options dialog, enhance and stabilize the plugin library, and Chrome-ify the tab bar with translucent tabs. I don’t know if I’ll be able to do these three things in three more releases; there will probably be a few bugfix releases along the way there.  But, we’ll get there!

One more note: I said that the language files would break in this release, but when I said that, I thought I was going to be releasing the redesigned Options dialog as well. Since that’s been pushed back, all the language files will still work.  I’m going to try to keep all the text resource changes in one release, so as to minimize the trouble for the translators.  Speaking of which, I’ve added the following languages to the downloads section as well: French, Dutch, German, and Polish.  Sorry it took so long to get them up there.

As always, massive thanks to everyone who submitted bug reports!  Couldn’t have done it without you guys!

EDIT: Oops, forgot the changelog:

======= 1.5.0.0 Beta 1 =======
Bugs Fixed:
Minor tweaks, fixes, and polish all around.
Fixed crash when uninstalling plugins.
Installer installs for all users now, not just a single user.
Fixed Subdirectory Tip display in details mode on Windows XP (for good this time).
Fixed bug where OK/Cancel buttons in Control Panel windows don’t work.
Moved the Exception log from the Desktop to %APPDATA%\QTTabBar.

New Features:
Ctrl-Click on the Folder Tree now opens a new tab.

Windows 7 SP1

Greetings all,

Beta 1 is pretty much ready for release, as the stream of new Trac tickets seems to have dried up.  I’ve been waiting on releasing it though, partly because I’ve been so crazily busy, but also because I wanted to make sure there were no surprises in SP1 that would break us.  I’ve installed SP1 on two computers so far, and I haven’t seen any ill effects.  Alpha 5 seems to work just fine.  However, some people are reporting that QTTB has stopped working after they installed SP1.  So, I’d like to get to the bottom of that.  I’ve you’ve installed SP1, please post whether or not QTTB still works for you so I can get an idea of what’s going on out there.  Here’s the Trac ticket.

Oh, and by the way: SP1 has fixed a total of zero Explorer bugs (that affect us, at least).  Great to know Explorer is so high on Microsoft’s list of priorities…

EDIT: Okay, judging from the responses so far it looks like most people have no problems, so people for whom it’s working can stop posting.  Please only post if it’s not working for you.

QTTabBar 1.5.0.0 Alpha 5 Released

Greetings everyone; I hope you all had a great Christmas.  I’ve got a belated present for you all today: our hopefully-last alpha, QTTabBar 1.5 Alpha 5.  I had grand visions of releasing it on Christmas day, but alas, I ran into some trouble with the new installer.  Oh well.

Difficult as it may have been to get right, the new installer should greatly streamline the process for new users.  The bars are activated upon installation automatically, which should alleviate a lot of confusion.  MSI also provides much better logging then Inno Setup did, so installer problems will be much easier for me to diagnose.  Also, the bars are now automatically hidden on uninstallation, which should effectively solve the problem of the unhideable menu bar.  I noticed that someone left a Thumbs Down on SourceForge because of this “bug,” ruining my perfect score! (For those unfamiliar with this problem, the bug is actually Explorer’s: the menu bar becomes unhideable if any toolbar is uninstalled while still in the “shown” state.)

Unfortunately, the new installer means that this update will be a bit rough for existing users.  Please note that Alpha 4 must be manually uninstalled and Explorer must be restarted before installing Alpha 5. I’ve tried to include some code to check for this, but apparently it doesn’t work on x64.  So I guess I’ll just post it here and hope for the best.

One thing I’m beginning to realize is how much this “Alpha” label is hurting.  My original plan was to make some massive (but time-consuming) improvements for the next release, but now I think it’s more important that we shed this Alpha label as soon as possible.  So, I’ve decided that this release will essentially be the release candidate for Beta 1, and all the new stuff I’d planned will go to Beta 2.  If there turns out to be some massively destabilizing bug, I may release another Alpha, but otherwise, I’ll just add a little more polish and release Beta 1.

As always, thanks for everyone’s constant support, and extra-special thanks for those who have donated.

Here’s the changelog for this release:

======= 1.5.0.0 Alpha 5 =======
Bugs Fixed:
    Many random crashes involving navigation fixed
    Fixed a few random crashes involving the search bar
    Broken Drag/Drop on XP fixed
    Dragging files from the SysListView into other applications doesn't double the action anymore.
    "Close all but this" and similar menu items fixed
    In XP, SubDirTips no longer disappear if the mouse is moved off file label
    Desktop Tool is not registered on Windows 7, as it doesn't work yet.
    SysListView no longer behaves strangely when attempting to navigate to a folder unsuccessfully
    OK/Cancel buttons on Control Panel dialogs now function as expected
    Header In All Views functionality reimplemented using a more reliable method; won't mess with icon sizes now
    Dragging files over folders now respects SubDirTip settings
    Fixed crash induced by Windows Search on XP
    Escape key now clears the search box, as expected
    Search box now clears upon refresh without introducing duplicate items
    Automatic renaming of ambiguous tabs is now case-insensitive
    Installer activates TabBar and ButtonBar automatically
    Installer deactivates TabBar and ButtonBar before removing them, working around Explorer's menu bar hiding bug

New Features:
    Brand new MSI-based installer
    Middle-click on the Folder Tree opens the folder in a new tab on Vista/7

Greetings everyone; I hope everyone had a great Christmas. I’ve got a belated present for you all today: our hopefully-last alpha, QTTabBar 1.5 Alpha 5. I had grand visions of releasing it on Christmas day, but alas, I ran into some trouble with the new installer. Oh well.

Difficult as it may have been to get right, the new installer should greatly streamline the process for new users. The bars are activated upon installation automatically, which should alleviate a lot of confusion. MSI also provides much better logging then Inno Setup did, so installer problems will be much easier for me to diagnose. Also, the bars are now automatically hidden on uninstallation, which should effectively solve the problem of the unhideable menu bar. I noticed that someone left a Thumbs Down on SourceForge because of this “bug,” ruining my perfect score! (For those unfamiliar with this problem, the bug is actually Explorer’s: the menu bar becomes unhideable if any toolbar is uninstalled while still in the “shown” state.)

Unfortunately, the new installer means that this update will be a bit rough for existing users. Please note that Alpha 4 must be manually uninstalled and Explorer must be restarted before installing Alpha 5. I’ve tried to include some code to check for this, but apparently it doesn’t work on x64. So I guess I’ll just post it here and hope for the best.

One thing I’m beginning to realize is how much this “Alpha” label is hurting. My original plan was to make some massive (but time-consuming) improvements for the next release, but now I think it’s more important that we shed this Alpha label as soon as possible. So, I’ve decided that this release will essentially be the release candidate for Beta 1, and all the new stuff I’d planned will go to Beta 2. If there turns out to be some massively destabilizing bug, I may release another Alpha, but otherwise, I’ll just add a little more polish and release Beta 1.

As always, thanks for everyone’s support, and extra-special thanks for those who have donated.