Index: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m
===================================================================
--- trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m	(revision 182)
+++ trunk/ICeCoffEE/ICeCoffEE/ICeCoffEE.m	(revision 183)
@@ -13,4 +13,5 @@
 #import "ICeCoffEESuper.h"
 #import "ICeCoffEESetServicesMenu.h"
+#import "ICeCoffEETrigger.h"
 
 iccfPrefRec ICCF_prefs;
@@ -59,6 +60,6 @@
 }
 
-iccfURLAction ICCF_KeyboardAction() {
-    unsigned int modifierFlags = [[NSApp currentEvent] modifierFlags];
+iccfURLAction ICCF_KeyboardAction(NSEvent *e) {
+    unsigned int modifierFlags = [e modifierFlags];
     iccfURLAction action;
     action.presentMenu = (modifierFlags & NSAlternateKeyMask) != 0;
@@ -239,6 +240,6 @@
 }
 
-void ICCF_LaunchURL(NSString *string, iccfURLAction action) {
-    OSStatus err;
+BOOL ICCF_LaunchURL(NSString *string, iccfURLAction action) {
+    OSStatus err = noErr;
     long selStart, selEnd;
     unsigned len = [string length];
@@ -273,5 +274,7 @@
     NS_ENDHANDLER
 
-    DisposeHandle(h);    
+    DisposeHandle(h);
+
+    return (err == noErr);
 }
 
@@ -303,5 +306,5 @@
 }
 
-void ICCF_LaunchURLFromTextView(NSTextView *self) {
+void ICCF_LaunchURLFromTextView(NSTextView *self, NSEvent *triggeringEvent) {
     NSCharacterSet *urlLeftDelimiters = nil, *urlRightDelimiters = nil;
     NSRange range = [self selectedRange], delimiterRange;
@@ -371,7 +374,5 @@
         [self display];
 
-        ICCF_LaunchURL([s substringWithRange: range], ICCF_KeyboardAction());
-
-        if (ICCF_prefs.textBlinkEnabled) {
+        if (ICCF_LaunchURL([s substringWithRange: range], ICCF_KeyboardAction(triggeringEvent)) && ICCF_prefs.textBlinkEnabled) {
             for (i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
                 NSRange emptyRange = {range.location, 0};
@@ -500,4 +501,16 @@
 }
 
+static NSEvent *ICCF_MouseDownEventWithModifierFlags(NSEvent *e, BOOL inheritModifierFlags) {
+    return [NSEvent mouseEventWithType: NSLeftMouseDown
+			      location: [e locationInWindow]
+			 modifierFlags: (inheritModifierFlags ? [e modifierFlags] : 0)
+			     timestamp: [e timestamp]
+			  windowNumber: [e windowNumber]
+			       context: [e context]
+			   eventNumber: [e eventNumber]
+			    clickCount: 1
+			      pressure: 0];
+}
+
 
 @interface NSTextView (IC_NSSharing)
@@ -526,5 +539,7 @@
         servicesItem = nil;
     }
-    [[NSApp servicesMenu] update]; // enable keyboard equivalents
+    if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_3) {
+	[[NSApp servicesMenu] update]; // enable keyboard equivalents in Mac OS X 10.3
+    }
 }
 
@@ -547,16 +562,19 @@
     ICLog(@"ICeCoffEE down: %@", e);
 #endif
+    if (ICCF_sharedTrigger != nil) {
+	ICLog(@"%@ cancelling", ICCF_sharedTrigger);
+	[ICCF_sharedTrigger cancel];
+    }
     if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(e)) {
+	BOOL inheritModifierFlags;
 	if ([self respondsToSelector: @selector(selectedRanges)]) {
-	    // discontiguous selection support, Mac OS X 10.4 or later
-	    NSArray *ranges = [self selectedRanges];
-	    ICLog(@"ICeCoffEE selected ranges: %@", ranges);
-	    if ([ranges count] > 1 || [[ranges objectAtIndex: 0] rangeValue].length != 0)
-		goto bypass;
+	    // Command-multiple-click or -drag for discontiguous selection, Mac OS X 10.4 or later
+	    inheritModifierFlags = YES;
 	} else {
 	    // don't want to trigger selection extension or anything else; pass through as a plain click
-	    // (on Panther and earlier, command does not modify behavior)
+	    // (on Mac OS X 10.3, command does not modify behavior)
+	    inheritModifierFlags = NO;
 	}
-        [super mouseDown: [NSEvent mouseEventWithType: NSLeftMouseDown location: [e locationInWindow] modifierFlags: 0 timestamp: [e timestamp] windowNumber: [e windowNumber] context: [e context] eventNumber: [e eventNumber] clickCount: 1 pressure: 0]];
+	[super mouseDown: ICCF_MouseDownEventWithModifierFlags(e, inheritModifierFlags)];
         // we don't actually get a mouseUp event, just wait for mouseDown to return
         NSEvent *upEvent = [[self window] currentEvent];
@@ -566,8 +584,14 @@
         NSAssert([upEvent type] == NSLeftMouseUp, @"NSTextView mouseDown: did not return with current event as mouse up!");
         if (abs(downPt.x - upPt.x) <= kICHysteresisPixels && abs(downPt.y - upPt.y) <= kICHysteresisPixels) {
-            ICCF_LaunchURLFromTextView(self);
+	    if (inheritModifierFlags) {
+		// Mac OS X 10.4 and later: make sure we don't have a command-double-click
+		[ICeCoffEETrigger setTriggerForEvent: e onTarget: self]; // gets stored in ICCF_sharedTrigger; the reason for this weird calling pattern is that we don't want to add methods to NSTextView, and we don't want to add a method call on every mouseDown
+		ICLog(@"%@ set", ICCF_sharedTrigger);
+	    } else {
+		// Mac OS X 10.3
+		ICCF_LaunchURLFromTextView(self, e);
+	    }
         }
     } else {
-bypass:
         [super mouseDown: e];
     }
