Sean Egan's Blog
Message Display in Pidgin
During the Summer of Code, one of my students, Jeff, wrote:
Prior to 2001, Gaim used GtkHTML, but now conversations are rendered using the GtkIMHtml engine.referring to the GtkHtml widget from GNOME used by Evolution for its message displays.
I told Jeff he was mistaken; Gaim never used GtkHtml. I went on to explain the history of message rendering in Pidgin and promised to make it an interesting blog post. Here, half a year later, it is.
Jeff was right to be confused. The original HTML renderer used by Gaim was called GtkHtml. However, it was of no relation to the one used by GNOME.
The screenshot above is of Gaim 0.10.0, from September 11, 2000. Gaim's GtkHtml supported a bunch of features; you can see colors and links above. It also supported smileys, background colors, italics, bold, and horizontal separators. GtkHtml is built completely from scratch; all the HTML parsing, postitioning, rendering, etc., was all written by Gaim developers.
I don't remember much of GtkHtml, as I personally got involved in Gaim development in late 2000, when GtkHtml's replacement was already underway.
GtkHtml was deemed by Eric, the maintainer at the time, to be nearing the end of its utility. The biggest issue was that the parser was unbearingly slow, and as we tried to add new formatting abilities, it proved a major bottleneck. GtkIMHtml was to be the successor to GtkHtml; it would have a re-written super-fast parser, considerably better drawing code, and then a bunch of other features made possible by the performance improvements.
GtkImHtml also did all its rendering and drawing by hand. Why didn't we just use Mozilla's Gecko to handle all this for us? Gecko was considered way too massive to be a dependency for the little bit we needed. All we needed were some colors, some images, bold, underline, italics, and links. Who in their right minds would ever want frames in their IM windows?
We did eventually learn the price of writing your own HTML parser; a ton of remotely-exploitable denial-of-service attacks (read: Gaim crashes when it receives HTML it isn't expecting) were found in our parser. Send someone "�"? Ka-boom. These were fixed quickly as we worked on this widget from 2001 to 2003, adding features such as sending embedded images over IM.
GtkImHtml version 2
Released in 2003, Gaim 0.60 was our first release to support GTK+ v2, a hugely significant upgrade to the GUI library Gaim uses. GTK+ 2.0 broke compatibilty with older versions of GTK+, and offered a ton of great new functionality, especially in areas such as international support. (GTK+ has never broken backward compatibility since that release. You can run Gaim 0.60 on the current 2.20 versions of GTK+ just as you can run Pidgin 2.3.0 on GTK+ 2.0.0). Since GTK+ broke compatibility, a lot of Gaim's UI code had to be re-written. One of the great additions to GTK2 was GtkTextView, a really powerful rich-text editor with great internationalization support.
Proper international text rendering is really, really, ridiculously hard. The Unicode standard describes how to properly do it. It contains thousands of pages with stuff like:
For the purpose of rendering, the Lao combining marks above (U+0EB1, U+0EB4..U+0EB7, U+0EBB, U+0EC8..U+0ECD) should be displayed outward from the base character they modify, in the order in which they appear in the text. In particular, a sequence containing <U+0EC8 lao tone mai ek, U+0ECD lao niggahita> should be displayed with the niggahita above the mai ek, and a sequence containing <U+0ECD lao niggahita, U+0EC8 lao tone mai ek> should be displayed with the mai ek above the niggahita.
GTK2 included a library called Pango that takes care of international text rendering. GtkTextView used it to do all its layout and drawing, so it was an obvious choice to base Gaim 0.60's GtkImHtml's replacement on. This was, uncreatively, also called GtkImHtml
This screenshot is from Gaim 0.60. This version of GtkImHtml, around since 2003, is still around today. GtkImHtml2 was made by keeping the original GtkImHtml's parser (as it does the job well, and you don't want to make the same security mistakes twice), but fed the results into a form that GtkTextView can understand. On top of that was added all sorts of additions through the years to add all the features we now have: smooth scrolling, animated smileys, full-width background colors, rich-text input, rich-text copy and paste, etc.
However, just as GtkHtml eventually outlived its usefulness, we're now, after 4 years, seeing GtkImHtml do the same. This way we parse HTML ourselves and then pass it into GtkTextView is proving difficult to work with, and we're choosing to work-around potential denial of service attacks rather than attempting to fix them.
For instance, if our parser sees a whole lot of formatting changes in a single message, each of those requires GtkTextView to recalculate its entire contents. A message with a huge number of formatting changes could cause Pidgin to lock up for minutes, and a proper fix would require a considerable rewrite of our parser, so we now strip formatting away from any message with more than 20 formatting changes.
Another issue is that the way we support animated smileys is fairly expensive to GtkTextView. If you have a large number of animated smileys, it can take up all your CPU time, essentially locking your entire computer. To work around this issue, we only animate the last few animated smileys, changing ones scrolled off screen to not animate.
It's becoming obvious that a true HTML widget, with a proper, well-tested parser, and robust layout engine would be better suited for us than our current solution.
I've been working on a plugin to use the GTK+ port of Webkit in Pidgin and to support Adium's message styles with it. This has turned out not to be hard at all to do, and it only took me a few hours to get to a very useable state
This is my plugin loaded in Pidgin using the Glass message style.
It's worth mentioning that Kopete for KDE has supported these styles for a long time. The Google Talk client for Windows and Banter for GNOME also support them to certain degrees. The plugin isn't very useful for most people right now (it depends on development snapshots of both webkit and Pidgin, and is very difficult to configure), but I hope to make it publically releasable within a few weeks (It's here right now if you think you can figure it out) and then once it has feature parity with GtkIMHtml, and when Webkit's GTK+ port is stable enough to depend on, make it part of Pidgin proper.
Reducing Tab Size
In my previous post, where I discussed some of the new UI changes we're experimenting with in Pidgin, I included a screenshot that differs in a few ways from what became 2.1.0. In that screenshot, the tabs are nothing more than text lables, and the #pidgin window in the background has no tab at all.
I claim that the sole purpose tabs have is to organize and allow quick access to multiple conversations. The most important means to this end is to show as many conversations as possible. That status icon, while useful, takes a lot of space: space that could be better used to show more tabs. Tabs are not an appropriate place for a status icon.
Of course, as I've learned many times developing Pidgin, you cannot take away information from someone easily. Regardless of how inappropriate the context might be, someone has grown to depend on that information being there. Because of the feedback we got, we put status icons back for 2.1.0.
For 2.1.1, we're experimenting with removing status icons, but replacing them with text formatting. We're hoping the benefit of more efficient use of space outweighs the cost of a slight new learning curve. And, so far, almost everyone who's seen them has been able to correctly identify what they mean. So far, people seem to agree.
In this screenshot, SmarterChild is online, Mark is away, and John is offline.
You'll also notice that the Sean Egan conversation window has no tabs. After all, if the purpose of tabs is to organize your conversations, you don't need one if there's only one conversation to organize. When we tried this before 2.1.0, the feedback I got was that the slight jitter caused in the conversation when a second conversation was added, creating tabs, was too annoying. In particular, it had a strong tendency to mess up the scrolling.
2.1.0 addded some code to ensure that if the conversation is scrolled to the bottom, it will stay there. Because of that, and the fact that the tabs are smaller, we're trying it again to see if it works any better. This won't happen if you use left tabs or right tabs, as those tabs cause a more obvious jump.
Lastly, you may notice that the close buttons are smaller. The old close buttons were buttons that contained menu-sized icons. They certainly weren't huge, but when you're optimizing for space, every pixel counts. For 2.1.0, I've changed them to actual text multiplication signs. (U+2715 MULTIPLICATION X) which guarantees they're small, sleek, and look good regardless of your theme's font size or color. Of course, you can still turn the close buttons off entirely, if you prefer to close conversations from the menu, keyboard shortcuts, or middle clicking the tabs.
These changes do make a very significant difference (on my machine, at least)! For comparision, here's a shot of Gaim 2.0.0beta3.1 (the only older build I had installed) taken at the same sizes as the conversations above. Where, Gaim 2.0.0beta3.1 could only fit one conversation at its minimum size, the current development code for Pidgin 2.1.1 can hold four (although only three are shown above).
It's too early to say if these changes will make it as-is into 2.1.1, but it seems likely that some of them will. As always, feedback is always welcome.
UI Changes in the Works
Since releasing Pidgin 2.0.0, we've been able to resume our normal rapid release cycle, getting lots of issues addressed quickly, and having time to experiment with different things, to see what works best.
UI changes are the funnest changes to write about, as I can let pictures do the talking, so that's what this post is about.
Our conversation window has had a ton of issues reported about it. Some of the biggest:
- The buddy icons and tooltips all draw over other parts of the Window and generally look bad (506, 1150)
- There are two many items in the toolbar, so that if you want to use the 'Insert Smiley' button, you must have a very wide window just to access it.
- Some features are difficult to access
- I can't fit enough conversations in a window before those pesky arrows show up, and tabs scroll off-screen.
- More information should be available
For 2.1.0, our designer Hylke Bons, has created a new conversation window interface that clears some of these issues up. Right now, it looks like this:
The toolbar has been re-organized into two drop-downs and a "Reset" button. The "Font" dropdown was inspired by Tomboy, a note-taking application:
This organization makes all the features more accessible, even at small window sizes, and doesn't require the toolbar to overlap anything
We've added something we call the "infopane." It's modelled to exactly resemble a buddy list node. It moves the buddy icon to a nice, fixed-size, rounded icon like those found in the buddy list. The status message is included beneath your buddy's name (for chats, it shows the topic). Emblems, such as 'mobile' will likewise appear right on the conversation window. It will have the same tooltip and context menu as the buddy list does, and the conversation's "Send To" menu will be replaced with something analagous to the buddy list's "Expand" menu option.
The infopane also acts as an extension of the tab. In current development code, when there is only one conversation, the tab disappaears entirely, leaving only the infopane to serve as a drag-and-drop point.
The tabs themselves have had the status icons removed, freeing up a lot of room to fit more conversations. The status icon of the current conversation is visible in the infopane.
All of this will, I proimise you, be entirely optional. If you prefer having just two text boxes in your conversations, this won't need to get in the way.
This is all targetted for 2.1.0, which is scheduled to be released tomorrow, but as many of the issues mentioned above are still very much hotly debated (I seem to be the only one who thinks that "more tabs" is better than "status icons of inactive tabs", for instance), there's a chance this release may be postponed.
Status Icon themeing
A bit further down the pipeline, Etan, who doesn't care for the "Green light" available icon has gone and implemented status icon themes!
This works by integrating with GTK+'s stock item themeing, and allows you to easily manage and change the look of your status icons. This work is mostly done, but a few snags have kept it out of 2.1.0.
The "Themes" header in the above screenshot will also have "Smiley Theme" added to it (note it's not one of the tabs above), and I've told him to save room for message styles (eventually), and notification themes.
Guifications has long been one of the most popular plugins for Gaim (and now Pidgin). It creates small, discrete, "toaster" notifications in the corner of your screen to inform you of events in a non-intrusive way.
pidgin-libnotify is a plugin that does the same thing, but uses the 'libnotify' D-Bus protocol to integrate well with modern Linux desktops.
We've decided that this is a feature useful enough to make part of Pidgin proper. The "Sounds" settings in Preferences will become more general "Notifications" settings. We'll expand the list of events to match Guificiations' extensive list of events, and each event will offer two ways of notifying you of them: sound and popup. Pop-ups will be created by libnotify, if available, or otherwise by Guifications. Hylke has created an awesome default theme for notifications
This has been a little glimpse at some of the UI ideas we've been working on. All of this is tentative, all highly debated and contended. It's fun to try lots of different things and see what works and what doesn't, without necessarily turning Pidgin into a science experiment.
The Power of Momentum (continued)
Another good example of the power of momentum is our new name, Pidgin. When we announced our legal troubles and name change, we expected a lot of complaints about the fact that we were forced to secrecy and betrayed some of the core tenets of open-source developemnt. Such complaints would have been entirely valid, and we were ready to apologize profusely to everyone, and beg their understanding. Instead we got comments like:
I don't like the new name. NO ONE will know what the hell "pidgen" is by simply reading the name. Not one person. The name leaves you 100% clueless as to the function of the program. At least "GAIM " gave someone with half a brain a decent chance to figure out what the program might be about. Two thumbs up for a great IM program, two thumbs down for a sucky name change. Irregardless I'll continue to use GAIM and call it GAIM..
For the first few years after we first added support for protocol plugins, we'd hear non-stop repetative complaints about how terrible the name 'Gaim' is. We do so much more than AIM, we should change the name because it's misleading. Of course, we didn't change the name, because we had raised donations to protect the name from a lawsuit by AOL, and were still interesting in keeping it. The name was, however, quite universally panned.
Flash forward a few years. We've reached a settlement regarding the legal disputes. We have a clever new name that alludes to our nature as a multi-protocol client, and lends itself to a neat pigeon mascot (pigeons, of course, being known for carrying messages long distances).
Suddenly, however, Gaim was a great name! How dare we even consider getting rid of it! Whereas years ago, the name misled people into a false sense of what functionality was offered, now it was a perfect description of it! Whereas everyone hated it then, everyone loved it then. Everyone hated Pidgin, but after a few weeks, nobody seems to mind if so much anymore. The momentum has finally died down.
Of course, you can't criticize anything that's open-source without talking about how great Firefox is in comparison, so we got plenty of mention that we should come up with a cool name like Firefox. Of course when Firefox renamed from Firebird, it got comments like:
I still think 'Firefox' stinks. Doesn't roll off the tongue like Mozilla, Firebird, or Phoenix, but I'm sure choosing a name that isn't already taken isn't easy.
Within time, Pidgin will, like Firebird and Gaim, be the greatest name you've ever heard!
The Power of Momentum
After a long wait, we finally launched Pidgin 2.0.0. Surprisingly, almost everything went down exactly as I anticipated. This includes the small, vocal minority who are adamently against our decision to demote what protocols your buddies use to second-class information, giving full attention to their presence information.
I suppose not everything went precisely as I anticipated. I foresaw the inevitable backlash, and wrote this to explain the rationale. I naively thought a lot of people would read the reasoning and be instantly convinced. Maybe they have, but there remains a very strong, vocal, minority convinced that they need to know what protocol their buddies are using. I figured I'd write a little historical background about the issue.
The original versions of Gaim (what Pidgin was called way back when), didn't put any thought into what icons to show. Gaim was originally an AIM-only client, and the AIM servers we used served the icons to us. As such, we had strange icons nobody understood. That gray dot you see above means 'unconfirmed AIM user,' or maybe 'confirmed AIM user.' I have no clue what the icon for "ICQ Alias 1" is supposed to be.
Since we already had four 'available' icons just from the ones AIM provided (confirmed, unconfirmed, AOL user, and Admin), when we added more protocols, it made sense that we might have tons more available icons. As you see above, we had Yahoo, Napster, and Jabber icons to represent their 'available' states. States other than 'available' did not retain protocol information; they used the standard 'away' icons.
This philosophy remained the status quo, even as we got newer (and more sensible) icons. We never really explicitly decided that protocols are important; we just followed the AIM model that the 'available' icon identifies the type of account and that other icons indicate their own state.
We completely re-wrote the Buddy List for version 0.60, the most significant release prior to 2.0.0. With it, we changed the way status icons were generated. Now, the protocol icon was always there, and other states no longer replaced it, but overlay onto it. This change was hugely contended at the time. There was just as similar a vocal minority about introducing protocol icons as first-class citizens as there now is about removing it. People dislike change.
For the past few years, it's been basically impossible to read a discussion about Pidgin or Gaim without someone mentioning that Adium has the best user interface of anything ever imagined by mankind. I've never used it, myself, but I still recommend it to anyone looking for Pidgin on OS X.
Back in November 2005, someone wrote to the gaim-devel mailing list that he doesn't like the large number of icons on his list, and would prefer if buddies only had status icons if they were not 'available.' I wrote back saying that, obviously, the protocol your buddy is using is very important, and something you definitely need to see at a glance.
Within minutes, two Adium developers replied to me, asking why I would ever think that protocol icons are important. I gave the same reasons I've been hearing every day since 2.0.0 was released: protocol features vary greatly, and it's cruical to know what feature set you'll be working with. I even came up with some other valid arguements, some of which I haven't heard regarding Pidgin yet. Anyway, they defended their award-winning UI and eventually I realized I was wrong, and that I truly didn't need to know, at a glance, what protocol my buddies use.
When we started looking for an icon designer to rehaul the visual style of Pidgin, we decided to give that designer as much control as reasonable. The designer we chose, Hylke Bons, realized that overlaying status emblems on top of status icons led to an inconsistent jumble of colors and shapes, and greatly hindered the subtle ability to pick useful information out of it. In fact, all of the designers we talked to recommended this change.
Since the Adium guys managed to convince me I didn't actually need protocol icons as much as I had convinced myself I had, I was ok with the change. Of course, a bunch of the other Pidgin developers were just as convinced as I was. However, within time, everyone has come around to appreciate the change.
So, you can probably see how I anticipated that some people would violently disagree with this change, and this is the power of momentum. When protocol icons were introduced as first-class citizens, they were hated by people who were familiar with the older style. Now that they're gone, their absence is hated just as strongly. And despite the criticisms that our UI should be more like Adium's, we're now criticized for having a UI that is more like Adium's. If we had only the foresight to have never introduced protocol icons to begin with, we wouldn't need to have this debate.
Enter vs. Control-Enter
Another change made in the beta cycle between 1.5.0 and 2.0.0beta7 is in our handling of what key you press to send a message. In 1.5.0 there was an option in the Preferences dialog that let you choose between Enter and Control-Enter. In beta7, that option is removed from the preferences window, leading many to believe you can no longer customize this keybinding. In fact, it still is possible, but the configuration has been delegated elsewhere. Perhaps this shall explain why, but first you'll need to learn a little Korean.
A Korean Lesson
In the Korean alphabet, called Hangul, each character represents a single sylable. My name, "Sean Egan," is three sylables long and is written in Korean as 숀이근. Three sylables, three characters.
Each sylable is composed of between one to four sounds, each sound being represented by a letter. My first name, 숀, is composed of three letters, ㅅ, ㅛ, and ㄴ. These represent the sounds "s," "yo," and "n," respectively. Stack them all on top of each other, and you get "Sean."
This is a really good picture of a Korean keyboard. You can see the first two letters of my name on the T and Y keys. The third letter is on the S key, just out of view. So, to spell my name in Korean, I have to type "TYS," just to create one character. A fairly low-level element in the computer's windowing system called the Input Method is responsible for interpreting these three keystrokes and telling the application "this is the character 숀."
Gaim 1.5.0 (and earlier) offered the ability to configure the "send" (among other) keystrokes from the preferences window. This worked by intercepting these low-level, individual keystrokes (t, y, and s), and saying "is this the enter key?" or "is this ctrl-enter?" and, if so, copy what's in the textbox and send it.
The problem with this is that, since we intercepted the keystrokes as they came in, the input method never received them. This means that, if the input method has not yet 'finished' the character, then it's not in the input box, when we pull it out to send. This should illustrate it nicely:
After typing 근, the input method still doesn't know if this character is done yet (it could potentially be 귽, for instance), and so it doesn't get sent. It remains, uncompleted, in the textbox. This, of course, is not at all unique to Korean, but to any language that requires complex input methods (e.g. Japanese, Chinese, etc.).
For 2.0.0, we've changed this behavior. No longer do we intercept keystrokes before the input method sees them, but we've asked the lower layer (in this case, GTK+, the GUI toolkit we use) to tell us when someone has asked us to "Send." We've also told GTK+ that "Enter" is a reasonable default character to use to trigger this signal. Now, GTK+ receives keyboard input, correctly processes it with the input method, and if it matches its 'Send' command, tells Pidgin to send.
Everything works as it should.
So, since GTK+ now tells us "this person wants to send a message," instead of "this person hit the Enter key," we can't easily make the key to use configurable. Thankfully, GTK+ makes it possible to configure it to anything. See our example gtkrc file to see how to configure keybindings. It's certainly not as straightforward as a checkbox in the preferences dialog, but compared to keeping a huge percentage of the world's population from sending IMs at all, it's a fair sacrifice.
Identity vs. Account Orientation
2.0.0beta7 is out, the final beta before Pidgin 2.0.0. We hired an artist assoicated with the Tango project, Hylke Bons, to do a complete graphical overhaul of the UI, and a logo designer to create a new Pidgin logo, and the results have been astounding. This is the first release the new look appears in. While Pidgin looks visually, much, much better than Gaim ever did, I still suspect some of the new changes will draw some complaints from a few people.
There are two basic approaches that come to mind in developing a multi-protocol IM client like Pidgin. One is the account-oriented approach. This approach allows you to configure all your accounts, and then presents them to you separately. It purposely distinguishes your AIM identity from your XMPP identity from your Yahoo! identity. It says "these are your IM accounts, use them however you wish. These are your XMPP buddies. These are your Yahoo! buddies." This is more-or-less the same as running multiple IM clients separately, but having them all in one window.
The other approach is the identity-oriented approach. This approach says: "I am one person who happens to have several IM accounts. I have one set of friends, who happen to use different services," assumes you don't care about those details, and abstracts them away. While the account-oriented approach shows you a list of your accounts, and then the buddy lists of each account, the identity-oriented approach shows you yourself, and your friends. It aims to make it appear, functionally, as if you only had one IM account.
I, and many (probably most) of the Pidgin developers use Pidgin in this latter way. We're interested in ourself, and in our friends. We typically want to talk to Ethan, rather than start an XMPP conversation with email@example.com. Formally, Gaim (as probably all multi-protocol IM clients) has been inconsistant in which approach it took. In some places it was decidedly account based; you could only view logs with specific IM contacts, rather than with whole "people," (i.e. a collection of IM contacts owned by the same person). Other places were more identity-oriented: buddies from all your accounts were merged together into a single list.
For 2.0.0, a lot of the work has gone into cleaning up this inconsistency. And since we prefer the identity-oriented approach, we've worked towards that direction. You, as an identity, have a single status, and a single buddy icon. And in the final push, revealed in tonight's beta release, your friends are represented primarily by their status, not what protocol they happen to use. When I look at my list right now, I see that I'm "Available" with a nifty Duck Hunt buddy icon, and that Mark is away with his Rugrats icon. No longer do I see that Mark happens to be using AIM, which is good because I never cared about that to begin with. Nor must I drop down the Accounts menu to see what all my accounts are, and what status they're in. I don't have to set each one's icon individually either. If I want to be Invisible, I just hit the status selector and choose Invisible.
While the identity-oriented approach is what best suits me, it's not necessarily one-size-fits-all. We commonly get requests for more account-oriented behavior. We're often asked to separate the buddy lists of different accounts into different groups or tabs. Some people prefer an account-oriented approach, and---while I think most of the feedback we've gotten about Pidgin has been postive---there have certainly been complaints about this shift. The most common such criticism received from earlier betas is---as also seen in this review---that while setting your status on a single account used to be easy, it's now more difficult.
Of course, when viewed in the light that you, as a Pidgin user, are a single person, it makes total sense that you would have only one status. If your MSN account is away cliff diving, it makes sense that your QQ account would be also. If you're just one person, why should you have to check your AIM list for one person and your IRC list for another? The issue that motivates these complaints is that people who prefer an accounts-oriented approach tend to use a multi-protocol IM client as if they are more than one person.
The most common reason (possibly only reason) for I hear supporting the account-oriented approach is: I use AIM at school and Google Talk with parents, and I don't want my parents to know what I'm doing with my friends, or---for older people---I use Sametime at work, and Yahoo! with my friends and I don't want my boss knowing what I'm going with my friends. In both cases, the user isn't a single person, but two people: a straight-laced, wholesome, angel on one account and a drugged up, drunken, vice-crazed sinner on the other :). Even the above review claims this same reasoning for not liking the new identity-oriented status.
So, we've kept it possible, although a bit less obvious, to do these account-oriented things, but in a somewhat identity-oriented manner. We have a system of "saved statuses," accessible from "New..." that allows you to create an "at a frat party" status that happens to lie, and tell your parents "at the library." Instead of setting two different statuses, you set one status that contains both these messages in it. Next time you have to "study," you can reuse it. Additionally, Sadrul's "mystatusbox" plugin can add status boxes for all your accounts, but generally, I think the best way to keep two identities separate is just to run Pidgin twice.
Of course, there are some times where it's important to know what protocol you are using, due to the differing capabilities of the protocols supported by Pidgin. We've kept the protocol icons in Pidgin, but downgraded them to secondary elements. When you know you need, for example, an AIM account to send a file to, you'll always want to find the person first, and then check the protocol. I can't imagine a situation where someone would want to find the protocol first, and then choose a person randomly from that to send a file to.
So, while some people with dual identities might be turned off by some of the changes between 1.5.0 and 2.0.0, I'm betting that most people are indeed one person, and will appreciate how much easier Pidgin makes multi-protocol instant messaging.
No big-picture documentation?Pidgin Planet, you might think that there's no source available for high-quality, general, big-picture documentation about how Pidgin works. That's probably because, despite getting a free copy, Ethan never bothered to read Open Source Messaging Application Development: Building and Extending Gaim, which is still plenty relevant, despite the name change.
System Tray Icon Preference
I just added a preference to Gaim to control when the system tray icon is shown, as discussed in my previous post. Because there was no obvious place in the preferences dialog to add this, I added a new tab and moved some of the Conversations preferences to it.
This has the added benefit of making the dialog smaller, such that it now fits on the screens of older machines with poorer resolution.
- On some Windows systems, beta4 is ridiculously slow. This is caused by a bug in our network detection code, and we have the fix ready to go
- Some people hate---hate---the "system tray icon" flashing. We'll add a check item in the icon's context menu to turn on and off flashing. We'll probably also add an option to control when the tray icon is visible: always, never, only when you have unread messages.
"System Tray" and NetworkManager
Barring some emergency, we should have beta4 out sometime this week. Here are a few more of its features introduced last week
Notification Area Icon
Another very common question I hope to put to rest with beta4: when I close the buddy list window, Gaim should not exit but go to the 'notification area' or 'system tray.'
Gaim users have been able to do this since 1999 by installing a special "applet" version of Gaim, and since 2003, the feature has been available for all Gaim users by loading the 'System Tray Icon' included with Gaim. Last week I removed the plugin and made the feature on for everyone.
There's some controversy behind this change. The guidelines behind the "system trays" on both Windows and UNIX-like operating systems say the function should be used only for temporary, transient notifications. On Windows, applications have avoided it, using the area as a place to provide access to applications without any windows, which many complain has cluttered this area to the point of uselessness.
Despite this, many distributors of Gaim have taken to enable the feature by default, and it remains one of the most commonly requested features by people who have never checked the plugins. Because of this, we've turned the "system tray icon" on for everyone.
Another application that lives in the "system tray," even when it doesn't have any urgent notifications, is NetworkManager. NetworkManager is a really cool system that makes connecting to various networks on Linux really, really easy. It also provides a way for an application to be informed when the network status changes: when a cable is unplugged, when you connect to a wireless networ, etc.
Thanks to work by Paul Betts, Gaim can now talk to NetworkManager when connecting to IM services. Before it logs in, it will make sure you're connected to the network and, if not, connect you as soon as the network comes available. When the network goes away, Gaim will disconnect; when it comes back, it will reconnect.
Another one of those questions I get asked several times a day is "how do I make the font size in the conversation window larger." Like the buddy list indentation I mentioned in earlier post to this blog, this is another thing controlled by an obscure setting that has to be manually set in a text file somewhere.
It turns out that people asking this question almost always want one thing: that when someone IMs them formatted text, that it not appear too small. In the past, people have used the "Ignore incoming font sizes" option in Gaim to ensure their buddies' messages are always legible, but in Gaim 2.0.0, we've replaced this with a "Ignore incoming formatting" option, which also turns off colors and font styles.
I thought about adding a feature to let you easily adjust the size of the conversation font, but today, I submitted some code that I hope solves the root of the problem. In previous versions of Gaim, a "smaller" font was about 83% the size of the normal font, and the "smallest" was about 69%. I've changed these numbers to 95% and 85% respectively.
If you've been bothered by fonts in Gaim being too small before, I hope you give this a try and let me know if this is a good solution.
Following up on my last e-mail, Sadrul wrote me with a more thorough description of gaim-text and the UI library it uses. I'll be posting follow-ups for other Summer of Code projects soon!
Hi! I am Sadrul, and I am going to talk about gaim-text. gaim-text is a text-frontend for Gaim. It uses libgaim for the IM-services, and libgnt for the UI widgets. gaim-text was developed for Google's Summer of Code 2006 program.
I tried to make sure gaim-text looks pretty close to Gaim to make sure a Gaim user can easily use gaim-text without having to go through a steep learning curve. There are buttons, textboxes, windows etc. which closely resemble the same widgets in GTK+ (the toolkit used by Gaim). So a user should feel at home with the environment (more on this later).
When you start gaim-text, it starts with the buddy-list window. You can expand/collapse the selected group or contact by pressing the space-bar. If you want to start a conversation with a buddy, then simply select the buddy and press Return. You can use the menu-key (right-click key) to show a context menu for the selected buddy/contact/chat/group. This context menu allows you to start chat with a buddy, get information about the buddy, add a new buddy/chat in the group etc.
Tooltip for a group
There is a status-selector at the bottom of the buddy-list window which you can use to set your status. Selecting 'New...' will bring up a dialog to set a new custom status. Selecting 'Saved...' will bring up a dialog with all the previously-saved statuses which you can use to change your status.
Each conversation has its own window in gaim-text, unlike Gaim where you can group conversations in tabbed windows. However, in gaim-text, it is possible to write plugins which will manage the conversation windows to closely resemble the same functionality (more on this later).
The textbox in which you type your messages is single-line. Right now, there is no support for entering multi-line messages. However, the text-boxes do have other useful features, like tab-completion, and history (ctrl+up/down to use previous messages).
Tab-completion in entry boxes
You can add, delete or modify accounts from the accounts window, just like Gaim. Take a look at the screenshot:
gaim-text also has a plugin-window where you can enable/disable plugins. Note that there many UI-specific plugins for gaim, which, obviously, will not work in gaim-text. However, there are a lot of UI-independent plugins, which can be used with gaim-text.
There are also a few gnt-plugins which can be use by gaim-text. The gnt-plugins use libgnt for its ui. If you are an interested developer, you should be able to convert many GTK-plugins into gnt-plugins without too much trouble.
Gaim Ncurses Toolkit (GNT) Environment
Now let's talk about the toolkit used by gaim-text. The toolkit is called 'Gaim Ncurses Toolkit', or 'GLib Ncurses Toolkit'. It was developed as part of the Google Summer of Code project along with gaim-text. This toolkit provides a set of UI elements, which you can use with event callbacks, much like how GTK+ widgets are used.
Here's a list of shortcuts that you will find useful while using gaim-text:
- Alt + a: Brings up a list of available actions. You can use this to open the accounts window, plugins window, preferences window etc.
- Alt + w: Brings up a list of open windows to quickly switch between windows.
- Alt + d: Dump the contents of the screen into "dump.html" (that's how the screenshots in this page were created.)
- Alt + m: This allows you to move a window.
- Alt + r: This allows you to resize a window.
- Alt + n: Switch to the next window.
- Alt + p: Switch to the previous window.
- Alt + c: Close the current window.
- Alt + q: Quit.
- Alt + ,: Move the position of the window one place to the left.
- Alt + .: Move the position of the window one place to the right.
- Alt + 1 2 ...0: Jump to the 1st, 2nd ... 10th window.
- Ctrl + o: Bring up the menu for a window if it has one. (Note: currently only the buddylist has a menu).
You can configure some settings in the environment by setting the appropriate options in ~/.gntrc. For example, you can enable shadows in the windows, enable mouse support, use a window manager etc. using the file.
To manage all the windows, libgnt uses a window manager. The default window manager is very naive. However, gaim-text comes with a simple custom window manager as a sample. A custom window manager is able to control the size, position, appearance of the windows. It can also change the default behaviour of the keystrokes, mouse-events etc.
To use a custom window-manager, set the following option in ~/.gntrc:
[general] wm = /path/to/custom/wm.so
You can enable mouse support by setting
[general] mouse = 1in ~/.gntrc. The mouse support will work if your version of ncurses/ncursesw is not too old. The mouse support includes clicking on a window to gain focus, click on buttons to activate, drag-n-drop to move a window etc. Note that although quite useful, the mouse support is still experimental, and patches to improve the functionalities are always welcome.
Do a `man gaim-text` to see how you can add more options in ~/.gntrc.
There are quite a few places in both gaim-text and libgnt that can use improvements. For example, a multi-line input-box can be useful. The mouse support can also be extended. A more robust window-manager would be cool. If you are interested, feel most welcome to jump in and start hacking! There are a few small test applications included that you can take a look at to get started. I will also be happy to reply to any questions you may have about gaim-text or/and libgnt.
Gaim Development Blog
Hi! A lot of people have been e-mailing and IMing me asking for updates about Gaim development: how things are going, what features we're working on, when it 2.0.0 will be released. Rather than responding to them all individually, I decided to start a blog where I can post regularly about what's going on and inform lots of people at once.
I've also set-up a Planet so other Gaim developers can follow suit and post about their own developments.
We'll be releasing a fourth beta of 2.0.0 soon (hopefully this weekend), and here's a glimpse of some of the new stuff we've worked on:
Global Buddy Icon Selector
There are about 5 questions that I get asked over and over and over again, and I've recently been taking steps to keep people from asking them. One of the questions I hear over and over and over is "How do I set my buddy icon?" The answer (Tools ⇨ Accounts ⇨ Modify) is hidden in an account setting and, apparently, very difficult to discover. An additional inconvenience is that people who want to use the same icon for each of their accounts have to set it individually, for each of their accounts.
2.0.0beta4 will introduce a global buddy icon selector in the buddy list. Accounts will now use a single, global, buddy icon (unless otherwise configured), which is visible in the lower-right-hand corner of the buddy list, next to the status selector. Clicking it brings up a file dialog to select an icon, and you can also drag and drop an image onto it to set your icon. If you still want to set your icons individually by account, the Modify Account dialog still allows you to set one to use instead of the global.
Buddy List Group Indenting
Another thing people complain to me about fairly regularly is the indentation of buddies within a group. Some people like to keep their buddy list very narrow and this empty space keeps them from keeping it as narrow as they like. Because this indentation isn't drawn by Gaim directly, but by GTK+ (the library we use to draw our interface), the best answer we've been able to give is to edit the settings of that library. The details of exactly how to do so are tricky, and can vary from machine to machine.
For 2.0.0beta4, we've changed the way we use this library to make the margin very small: as small as the little expander arrow (any smaller started to look funny). With the margin gone, we've given the groups a different background color to (hopefully) make it just as easy to differentiate between them, while making more efficient use of space.
libgaim and gaim-text
I can't take much credit for this one personally, but it's too cool not to mention. 2.0.0beta4 will
be the first official release of
libgaim, the core functionality of Gaim, as a library
for other programs to use. Other IM programs (e.g. Adium X,
Meebo) already exist using incomplete versions of
but 2.0.0beta4 will include a completed version of this library. Hopefully this will inspire even
more programs to take advantage of
Gaim 2.0.0beta4 is actually two programs, both using
libgaim as their backends. In
addition to the standard Gaim graphical UI we have a text version of Gaim, written by Sadrul Chowdhury.
gaim-text is really useful for UNIX users who can login to their computer remotely and
run Gaim in text mode from anywhere. Sadrul's done a great job of making a really usable text-based
application; hopefully he'll post about it some more himself.
We're hoping beta4 will be the final beta before the final release of 2.0.0, but it's always possible one or more will be needed. I can't yet say when 2.0.0 will be released, but we're definitely getting really close. The current development releases are really good, and very stable. If you're here, you're probably interested in Gaim development, so please, install beta4 when it's released and let us know what you think.