Account Options

  1. Sign in
Google Groups Home
« Groups Home
Message from discussion How Logitech Control Center breaks Growl, and what we can do about it
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Peter Hosey  
View profile  
 More options Apr 14 2008, 11:59 pm
From: Peter Hosey <bore...@gmail.com>
Date: Mon, 14 Apr 2008 20:59:18 -0700
Local: Mon, Apr 14 2008 11:59 pm
Subject: Re: How Logitech Control Center breaks Growl, and what we can do about it
First, how Logitech Control Center breaks Growl. I'll first present a  
user-readable backstory; developers can skip ahead. Please let me  
know if any part of this is unclear.

=== User-readable backstory ===

Mac OS X provides a facility called NSConnection that programs can  
use to communicate with each other.

Applications that support Growl use the Growl framework, which uses  
NSConnection to communicate with the Growl Helper App. GrowlHelperApp  
(GHA) is the program that actually shows notifications on the screen.

Every application has one or more threads, and every thread gets  
(among other things) one NSConnection called the default connection.  
(It can create more NSConnections if it wants them.) Growl Helper  
App, through the current version, uses its default connection to  
listen for notifications from applications.

Every NSConnection has a “root object”, which is the application's  
emissary to other applications. It's like when a country sends an  
ambassador to another country: the root object comes from the  
application, is the ambassador for the application, and represents it  
to other applications. Other apps talk to that object when they want  
the application it came from to do something.

Every NSConnection also has a name, which is like a telephone number:  
you access another application's connection by asking for it by name,  
like dialing the number.

In Growl's case, our root object is the Growl Application Bridge  
pathway. When an application wants to post a Growl notification, the  
framework looks up the connection named  
“GrowlApplicationBridgePathway”, then gets its root object (which  
is supposed to be the pathway), then sends that object some messages  
to tell GHA the notification.

--

Logitech Control Center consists of several parts. One of them is an  
input manager. These are supposed to be used to extend Mac OS X to  
extend new methods of entering text (input). Instead, they're mostly  
abused to add new features to every application or specific  
applications (many Safari “plug-ins” or “extensions” are  
actually input managers).

The reason that this works is that an input manager gets loaded into  
each process (running program), just like a plug-in. Once there, it  
can affect the process any way it wants—usually to add some kind of  
feature. However, this is a high-wire act: an input manager can  
easily break things if it steps on the application's toes in some way.

--

Finally, it's important to remember that GrowlHelperApp is an  
application just like any other. It's a “faceless background  
application” (i.e., it has neither a Dock tile nor a menu-bar), but  
it's still just an application, subject to all the same rules. In  
particular, input managers get loaded into GHA, just as they get  
loaded into any other application.

=== End of user-readable backstory ===

The problem is that, when the application launches, Logitech Control  
Center's input manager gets the default connection and sets its root  
object to its Scroll Enhancer object.

This is a problem for Growl because GHA also uses the default  
connection, and sets its root object at about the same time. But LCC  
does this slightly later, so the root object it sets is the one that  
holds.

So this is what happens in the Growl Helper App process:

1. GHA gets the default connection, sets its root object to the Growl  
Application Bridge pathway object, and registers it under the name  
“GrowlApplicationBridgePathway”.
2. The LCC input manager gets the default connection (same one), sets  
its root object to the LCC Scroll Enhancer object, and registers the  
connection under the name “com.Logitech.Control Center.Scroll  
Enhancer/” followed by the process ID number.

The problem comes from the fact that *one connection* (GHA's default  
connection) is now registered under two names:  
“GrowlApplicationBridgePathway” and “com.Logitech.Control  
Center.Scroll Enhancer/$PID”.

Then, when an application tries to send Growl a notification, it  
looks up the connection for “GrowlApplicationBridgePathway”, and  
gets GHA's default connection. Then it gets its root object to send  
it the necessary messages, but the root object is Logitech's, not  
Growl's, so this fails.

Result: You don't get any notifications.

Important distinction: What we're doing is not wrong. It's perfectly  
OK for an application to get its own default connection, set its root  
object to an object of its own creation, and expect this to work.  
There is no good reason why this should ever break.

Logitech is the party in the wrong here. Input managers should never  
attempt to share any resource with the application. That's borderline  
acceptable when the input manager is actually intending to affect the  
application in some way (e.g., it's borderline acceptable to get the  
app's Edit menu to add a menu item to it), but this was an accident  
(they didn't intend to affect Growl), and it's their fault for using  
the app's default connection rather than creating one of their own.

They assumed that no application would use the default connection (or  
didn't think of the possibility). This assumption is incorrect.

--

So, what can we do about it?

While it's not our bug to fix, and I'm still in favor of telling  
people that LCC breaks things, we *can* work around the problem. I  
see at least two ways:

1. We could move the registration of our default connection to happen  
later (in applicationDidFinishLaunching:, rather than initSingleton:).

I see a couple problems with this. First, we'll need to move a *lot*  
of code that has to happen after it; basically, about half of  
initSingleton: will happen at the start of  
applicationDidFinishLaunching: instead. Second, it's potentially not  
a permanent fix: if LCC changes to also use  
applicationDidFinishLaunching:, or if some other input manager starts  
doing the same thing in that method, we're right back in the same boat.

2. We could create our own connection instead of using  
defaultConnection.

This is basically the “give up defaultConnection to the broken input  
manager” solution. There's nothing wrong with this that I know of,  
and it definitely does work. It also is robust against any new  
breakage that LCC may come up with in the future, unless they decide  
to start actively breaking Growl.

I have this solution ready to commit. It's also a lot smaller than  
#1, which makes it much less likely to regress anything. We could  
even put this into 1.1.3 if we want.

Of course, there's one more thing we can do:

3. Tell users not to use Logitech Control Center.

This is not mutually exclusive with either of the other two. LCC 2.4  
is broken, whether we work around it or not. It's still their bug,  
and it's still possible (maybe even likely) that LCC breaks other apps.

Of course, if we can work around it in Growl, we don't need to be so  
aggressive about warning users against LCC. It'd be possible again to  
use Growl and LCC at the same time, so we wouldn't need to say  
anything like “LCC broke Growl” on login.

Devs: Thoughts?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.