code: drawterm

Download patch

ref: 0e9b2f46e70a3c775eb541a754d4402c1e454221
parent: 4b2ebe94a265ad7b89cbc9dcc082773451f37a88
author: glenda <cinap_lenrek@felloff.net>
date: Thu Jun 17 03:49:23 EDT 2021

implement simulated mouse buttons for Mac laptops similar to plan9port.

For systems without a three button mouse, the keyboard modifier keys
can be used to modify the effect of the main mouse button. On Mac
systems, the option key changes the main button to button 2, and the
Command key changes it to button 3.
Pressing the key after the button is held down adds the button to
form a chord, so that for example on Macs selecting text with the
trackpad button and then typing Option without letting go of the button
will cause a 1-2 chord, cutting the selection.
These changes were inspired by rsc's plan9port.

--- a/gui-cocoa/screen.m
+++ b/gui-cocoa/screen.m
@@ -364,43 +364,76 @@
 		kbdkey(m, 0);
 }
 
-- (void)flagsChanged:(NSEvent*)event {
-	static NSEventModifierFlags y;
-	NSEventModifierFlags x;
-
-	x = [event modifierFlags];
-	if((x & ~y & NSEventModifierFlagShift) != 0)
-		kbdkey(Kshift, 1);
-	if((x & ~y & NSEventModifierFlagControl) != 0)
-		kbdkey(Kctl, 1);
-	if((x & ~y & NSEventModifierFlagOption) != 0)
-		kbdkey(Kalt, 1);
-	if((x & ~y & NSEventModifierFlagCapsLock) != 0)
-		kbdkey(Kcaps, 1);
-	if((~x & y & NSEventModifierFlagShift) != 0)
-		kbdkey(Kshift, 0);
-	if((~x & y & NSEventModifierFlagControl) != 0)
-		kbdkey(Kctl, 0);
-	if((~x & y & NSEventModifierFlagOption) != 0)
-		kbdkey(Kalt, 0);
-	if((x & ~y & NSEventModifierFlagCapsLock) != 0)
-		kbdkey(Kcaps, 0);
-	y = x;
-}
-
-- (void)mouseevent:(NSEvent*)event
+- (void)sendmouse:(NSUInteger)b
 {
 	NSPoint p;
 	Point q;
-	NSUInteger u;
 
 	p = [self.window mouseLocationOutsideOfEventStream];
-	u = [NSEvent pressedMouseButtons];
 	q.x = p.x;
 	q.y = p.y;
 	if(!ptinrect(q, gscreen->clipr)) return;
-	u = u & ~6 | u << 1 & 4 | u >> 1 & 2;
-	absmousetrack(p.x, self.frame.size.height - p.y, u, ticks());
+	absmousetrack(p.x, self.frame.size.height - p.y, b, ticks());
+}
+
+- (void)flagsChanged:(NSEvent*)event {
+	static NSEventModifierFlags omod;
+	NSEventModifierFlags m;
+	NSUInteger b;
+
+	m = [event modifierFlags];
+	b = [NSEvent pressedMouseButtons];
+	b = b & ~6 | b << 1 & 4 | b >> 1 & 2;
+	if(b){
+		if(m & ~omod & NSEventModifierFlagControl)
+			b |= 1;
+		if(m & ~omod & NSEventModifierFlagOption)
+			b |= 2;
+		if(m & ~omod & NSEventModifierFlagCommand)
+			b |= 4;
+		[self sendmouse:b];
+	}else{
+		if((m & ~omod & NSEventModifierFlagShift) != 0)
+			kbdkey(Kshift, 1);
+		if((m & ~omod & NSEventModifierFlagControl) != 0)
+			kbdkey(Kctl, 1);
+		if((m & ~omod & NSEventModifierFlagOption) != 0)
+			kbdkey(Kalt, 1);
+		if((m & ~omod & NSEventModifierFlagCapsLock) != 0)
+			kbdkey(Kcaps, 1);
+		if((~m & omod & NSEventModifierFlagShift) != 0)
+			kbdkey(Kshift, 0);
+		if((~m & omod & NSEventModifierFlagControl) != 0)
+			kbdkey(Kctl, 0);
+		if((~m & omod & NSEventModifierFlagOption) != 0)
+			kbdkey(Kalt, 0);
+		if((m & ~omod & NSEventModifierFlagCapsLock) != 0)
+			kbdkey(Kcaps, 0);
+	}
+	omod = m;
+}
+
+- (void)mouseevent:(NSEvent*)event
+{
+	NSUInteger b;
+	NSEventModifierFlags m;
+
+	b = [NSEvent pressedMouseButtons];
+	b = b & ~6 | b << 1 & 4 | b >> 1 & 2;
+	if(b==1){
+		m = [event modifierFlags];
+		if(m & NSEventModifierFlagOption)
+			b=2;
+		else if(m & NSEventModifierFlagCommand)
+			b=4;
+		else if(m & NSEventModifierFlagControl)
+			b=8;
+	}else if(b==4){
+		m = [event modifierFlags];
+		if(m & NSEventModifierFlagCommand)
+			b=8;
+	}
+	[self sendmouse:b];
 }
 
 - (void) mouseDown:(NSEvent*)event { [self mouseevent:event]; }