Wednesday, September 17, 2008

SynergyKM Mouse Scrolling Fix

SynergyKM is a very handy little Mac utility that allows you to share one keyboard and mouse across multiple computers. It's based on the utility called Synergy, which runs on many different computer platforms (Mac, Windows, Linux, etc.). So, if you are sitting at a desk with multiple monitors for various systems, you can choose one system as the master and use its sole keyboard and mouse.

Here's an example of using SynergyKM to designate the layout of the various monitors.



Once you define the layout of the various monitors and have Synergy running on all the machines, you can simply move the mouse off of one screen and it will automatically appear on the next screen. You can even share the cut-and-paste buffer across the machines.

All this is very nice, but SynergyKM hasn't been updated since 2006. One problem I've discovered is if you are on a Mac and are using a scroll wheel or trackpad to perform scrolling on a different monitor, the scrolling is super crazy fast.

Fortunately, Synergy is an open source project, so I was able to figure out the problem. SynergyKM is using a deprecated function for generating mouse scrolling events. The problem - for those interested - was the older method for generating a mouse scrolling event was based on scrolling numbers of "lines" of text. However, the values being uses for the scrolling deltas were based on pixel differences, not line differences. The newer method (CGEventCreateScrollWheelEvent) for generating scrolling events can be configured to use either line or pixel counts.

It's only a few lines of code that need changing. Specifically, edit the COSXScreen.cpp file, and search for the function COSXScreen::fakeMouseWheel(). Replace it with this:


void
COSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const
{
CGEventRef my_event;

if (xDelta != 0 || yDelta != 0) {
my_event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 2, mapScrollWheelFromSynergy(yDelta), -mapScrollWheelFromSynergy(xDelta));
CGEventPost(kCGHIDEventTap, my_event);
CFRelease(my_event);
//CGPostScrollWheelEvent(2, mapScrollWheelFromSynergy(yDelta), -mapScrollWheelFromSynergy(xDelta));
}
}


Also, look for the function COSXScreen::mapScrollWheelFromSynergy() and replace it with this:


SInt32
COSXScreen::mapScrollWheelFromSynergy(SInt32 x) const
{
// use server's acceleration with a little boost since other platforms
// take one wheel step as a larger step than the mac does.
// return static_cast(3.0 * x / 120.0);

// No boost in acceleration
return static_cast(x / 120.0);
}


Then, just recompile the project and take the new synergyc file generated and replace the existing synergyc executable on all your client machines. If you are using SynergyKM, synergyc will be located in:

/Library/PreferencePanes/SynergyKM.prefPane/Contents/Resources/Synergyd.app/Contents/Resources/synergyc

(NOTE: you can not replace the file if Synergy is currently running.)

If you'd prefer to not have to recompile the file yourself, you can get my compiled version here. It's about 370K in size (compressed).

15 comments:

Eli said...

Could you compile a version of the synergy server 'synergys' for OSX? I would like to fix the same problem, but I run the server on the Macbook and the client on the PC. Thanks.

Anonymous said...

Thank you for this. Works great. Glad I got this issue taken care of.

Anonymous said...

The pre-compiled binary seems to have gone MIA. Is it possible to get it re-linked? Thanks!

Jonah Dempcy said...

Yes, I would love the precompiled binary as well.

Mostly Torn said...

I've updated the link - it now points to the proper file.

Chris said...

While this is a great fix, I cannot get it to compile with your changes and the precompiled binary errors out after about 1 minute (Bus Error).

I'm running 10.4.11. Any ideas for me?

Irish Eastie said...

This is a great find! But I'm having the issue on my Client WIndows computers. So I'm running the server on OS X, but the clients are on XP and Windows 7. Would you happen to know what parts of the windows client would have to be edited to fix this scrolling issue?

Thanks, Tim

Mr. Gray said...

you are amaze-balls. this totally fixed it for me. thank god, that fast scrolling was driving me NUTS!

you seem smart… any easy script, launchd item, etc to load synergyKM at the login screen?

thank you!

alex gray.

Bailey81 said...
This comment has been removed by the author.
Erin said...
This comment has been removed by the author.
Bailey81 said...

Hmm... I managed to replace my synergyc file with the one you linked to... but scrolling is still pretty fast. Though it seems to be just a bit slower, it's still awkward to use because of the speed.

I'm sharing the keyboard and my magic mouse on my MacBook Pro (OSX 10.6.6) with my Vista machine.... any ideas?

I'm not a programmer (I'm a web designer) so I know nothing about terminal or I'd just use synergy+ instead of synergyKM but the synergy+ folks don't give quite enough of the in between steps for me to figure it out.

Anonymous said...

You are the man!!! Thank you, works perfectly.

Cameron Spear said...

Thank you so much. I use Synergy a lot and that has been driving me crazy! But finally... normal speeds of scrolling.

Thanks again!

Anonymous said...

That's an awesome fix! Thanks so much! Especially for providing the binary in addition to the source!

Anonymous said...

Works great! Don't even need to change code, just copy the synergyc file to the same path (make a backup of your existing copy) and restart synergy!!


All content copyright © 2009  Brian Stormont, unless otherwise noted.   All rights reserved.