9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] macOS Drawterm patch
@ 2025-01-28 17:23 Nikita Georgiou
  2025-01-28 17:29 ` ori
  2025-01-28 17:48 ` Xiao-Yong Jin
  0 siblings, 2 replies; 3+ messages in thread
From: Nikita Georgiou @ 2025-01-28 17:23 UTC (permalink / raw)
  To: 9front

Hi, I wrote a patch for the macOS version of drawterm that makes it scale accordingly to the user’s scaling preferences. Right now, drawterm renders 1:1 with the monitor resolution which sucks on high DPI displays. This did not used to be the case pre-Metal API. The current fix has been to choose a larger font, which gets us part of the way there but not all the way. This is because window borders, etc. still render as tiny and are cumbersome to interact with. I’ve changed the default behavior to scale with the display (which is what users expect), and added a -S flag that disables this scaling and renders at the monitor resolution as before. 

Patch:

screen.m
diff --git a/gui-cocoa/screen.m b/gui-cocoa/screen.m
index b4e7b2d..74d0746 100644
--- a/gui-cocoa/screen.m
+++ b/gui-cocoa/screen.m
@@ -23,6 +23,7 @@
 #define LOG(fmt, ...) if(DEBUG)NSLog((@"%s:%d %s " fmt), __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
 
 Memimage *gscreen;
+extern int scaleflag;
 
 @interface DrawLayer : CAMetalLayer
 @property id<MTLTexture> texture;
@@ -68,11 +69,18 @@ guimain(void)
 	}
 }
 
+static NSSize
+scaledframesize(void)
+{
+	return (scaleflag) ? myview.frame.size : [myview convertSizeToBacking:myview.frame.size];
+}
+
 void
 screeninit(void)
 {
+	NSSize s;
 	memimageinit();
-	NSSize s = [myview convertSizeToBacking:myview.frame.size];
+	s = scaledframesize();
 	screensize(Rect(0, 0, s.width, s.height), ARGB32);
 	gscreen->clipr = Rect(0, 0, s.width, s.height);
 	LOG(@"%g %g", s.width, s.height);
@@ -285,7 +293,8 @@ mouseset(Point p)
 		if([[myview window] isKeyWindow]){
 			s = NSMakePoint(p.x, p.y);
 			LOG(@"-> pixel  %g %g", s.x, s.y);
-			s = [[myview window] convertPointFromBacking:s];
+			if(!scaleflag)
+				s = [[myview window] convertPointFromBacking:s];
 			LOG(@"-> point  %g %g", s.x, s.y);
 			s = [myview convertPoint:s toView:nil];
 			LOG(@"-> window %g %g", s.x, s.y);
@@ -377,8 +386,11 @@ mainproc(void *aux)
 - (void) windowDidBecomeKey:(id)arg
 {
 	NSPoint p;
-	p = [_window convertPointToBacking:[_window mouseLocationOutsideOfEventStream]];
-	absmousetrack(p.x, [myview convertSizeToBacking:myview.frame.size].height - p.y, 0, ticks());
+	NSSize s; 
+	p = (scaleflag) ? [_window mouseLocationOutsideOfEventStream]
+		: [_window convertPointToBacking:[_window mouseLocationOutsideOfEventStream]];
+	s = scaledframesize();
+	absmousetrack(p.x, s.height - p.y, 0, ticks());
 }
 
 - (void) windowDidResignKey:(id)arg
@@ -594,11 +606,14 @@ evkey(uint v)
 	Point q;
 	NSUInteger u;
 	NSEventModifierFlags m;
+	NSSize s;
 
-	p = [self.window convertPointToBacking:[self.window mouseLocationOutsideOfEventStream]];
+	p = (scaleflag) ? [self.window mouseLocationOutsideOfEventStream] 
+		: [self.window convertPointToBacking:[self.window mouseLocationOutsideOfEventStream]];
 	u = [NSEvent pressedMouseButtons];
 	q.x = p.x;
 	q.y = p.y;
+	s = scaledframesize();
 	if(!ptinrect(q, gscreen->clipr)) return;
 	u = (u&~6) | (u&4)>>1 | (u&2)<<1;
 	if(u == 1){
@@ -609,7 +624,7 @@ evkey(uint v)
 		}else if(m & NSEventModifierFlagCommand)
 			u = 4;
 	}
-	absmousetrack(p.x, [self convertSizeToBacking:self.frame.size].height - p.y, u, ticks());
+	absmousetrack(p.x, s.height - p.y, u, ticks());
 	if(u && _lastInputRect.size.width && _lastInputRect.size.height)
 		[self resetLastInputRect];
 }
@@ -697,7 +712,8 @@ evkey(uint v)
 
 - (void) reshape
 {
-	NSSize s = [self convertSizeToBacking:self.frame.size];
+	NSSize s; 
+	s = scaledframesize();
 	LOG(@"%g %g", s.width, s.height);
 	if(gscreen != nil){
 		screenresize(Rect(0, 0, s.width, s.height));


cpu.c
diff --git a/cpu.c b/cpu.c
index a271fdb..a3f270e 100644
--- a/cpu.c
+++ b/cpu.c
@@ -28,6 +28,7 @@ static int	norcpu;
 static int	nokbd;
 static int	nogfx;
 static int	nineflag;
+int scaleflag = 1;
 
 static char	*ealgs = "rc4_256 sha1";
 
@@ -248,6 +249,7 @@ usage(void)
 		"[-e 'crypt hash'] [-k keypattern] "
 		"[-p] [-t timeout] "
 		"[-r root] "
+		"[-S]"
 		"[-g geometry] "
 		"[-c cmd ...]\n", argv0);
 	exits("usage");
@@ -294,6 +296,9 @@ cpumain(int argc, char **argv)
 	case 's':
 		secstore = EARGF(usage());
 		break;
+	case 'S':
+		scaleflag = 0;
+		break;
 	case 'e':
 		ealgs = EARGF(usage());
 		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)

drawterm.1
diff --git a/drawterm.1 b/drawterm.1
index 347fa40..9cc7970 100644
--- a/drawterm.1
+++ b/drawterm.1
@@ -20,6 +20,8 @@ drawterm  \- connection to cpu, fs, and auth servers
 .B -s
 .I secstore
 ] [
+.B -S
+] [
 .B -e
 \fR'\fIcrypt hash\fR'
 ] [
@@ -91,6 +93,12 @@ server. If the -s option is absent,
 .IR secstore (1)
 will attempt to dial tcp!$auth!secstore (or the otherwise specified auth server).
 
+.TP
+.B -S
+(macOS only) Disables scaling. By default, drawterm will scale window graphics on high DPI displays
+to a proportional size. If this isn't desirable, this flag will render graphics 1:1 with the display
+resolution.
+
 .TP
 .B -e \fR'\fIcrypt hash\fR'
 Specifies the \fR'\fIcrypt hash\fR'

Let me know if you need anything else. 

Nikita

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [9front] macOS Drawterm patch
  2025-01-28 17:23 [9front] macOS Drawterm patch Nikita Georgiou
@ 2025-01-28 17:29 ` ori
  2025-01-28 17:48 ` Xiao-Yong Jin
  1 sibling, 0 replies; 3+ messages in thread
From: ori @ 2025-01-28 17:29 UTC (permalink / raw)
  To: 9front

tip, if you write your email as you would a commit message, it can
be applied directly with git/import:

	git/import /mail/fs/mbox/$messageid

which makes it easier to track attribution.

Quoth Nikita Georgiou <nikitageorgiou@gmail.com>:
> Hi, I wrote a patch for the macOS version of drawterm that makes it scale accordingly to the user’s scaling preferences. Right now, drawterm renders 1:1 with the monitor resolution which sucks on high DPI displays. This did not used to be the case pre-Metal API. The current fix has been to choose a larger font, which gets us part of the way there but not all the way. This is because window borders, etc. still render as tiny and are cumbersome to interact with. I’ve changed the default behavior to scale with the display (which is what users expect), and added a -S flag that disables this scaling and renders at the monitor resolution as before. 
> 
> Patch:
> 
> screen.m
> diff --git a/gui-cocoa/screen.m b/gui-cocoa/screen.m
> index b4e7b2d..74d0746 100644
> --- a/gui-cocoa/screen.m
> +++ b/gui-cocoa/screen.m
> @@ -23,6 +23,7 @@
>  #define LOG(fmt, ...) if(DEBUG)NSLog((@"%s:%d %s " fmt), __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
>  
>  Memimage *gscreen;
> +extern int scaleflag;
>  
>  @interface DrawLayer : CAMetalLayer
>  @property id<MTLTexture> texture;
> @@ -68,11 +69,18 @@ guimain(void)
>  	}
>  }
>  
> +static NSSize
> +scaledframesize(void)
> +{
> +	return (scaleflag) ? myview.frame.size : [myview convertSizeToBacking:myview.frame.size];
> +}
> +
>  void
>  screeninit(void)
>  {
> +	NSSize s;
>  	memimageinit();
> -	NSSize s = [myview convertSizeToBacking:myview.frame.size];
> +	s = scaledframesize();
>  	screensize(Rect(0, 0, s.width, s.height), ARGB32);
>  	gscreen->clipr = Rect(0, 0, s.width, s.height);
>  	LOG(@"%g %g", s.width, s.height);
> @@ -285,7 +293,8 @@ mouseset(Point p)
>  		if([[myview window] isKeyWindow]){
>  			s = NSMakePoint(p.x, p.y);
>  			LOG(@"-> pixel  %g %g", s.x, s.y);
> -			s = [[myview window] convertPointFromBacking:s];
> +			if(!scaleflag)
> +				s = [[myview window] convertPointFromBacking:s];
>  			LOG(@"-> point  %g %g", s.x, s.y);
>  			s = [myview convertPoint:s toView:nil];
>  			LOG(@"-> window %g %g", s.x, s.y);
> @@ -377,8 +386,11 @@ mainproc(void *aux)
>  - (void) windowDidBecomeKey:(id)arg
>  {
>  	NSPoint p;
> -	p = [_window convertPointToBacking:[_window mouseLocationOutsideOfEventStream]];
> -	absmousetrack(p.x, [myview convertSizeToBacking:myview.frame.size].height - p.y, 0, ticks());
> +	NSSize s; 
> +	p = (scaleflag) ? [_window mouseLocationOutsideOfEventStream]
> +		: [_window convertPointToBacking:[_window mouseLocationOutsideOfEventStream]];
> +	s = scaledframesize();
> +	absmousetrack(p.x, s.height - p.y, 0, ticks());
>  }
>  
>  - (void) windowDidResignKey:(id)arg
> @@ -594,11 +606,14 @@ evkey(uint v)
>  	Point q;
>  	NSUInteger u;
>  	NSEventModifierFlags m;
> +	NSSize s;
>  
> -	p = [self.window convertPointToBacking:[self.window mouseLocationOutsideOfEventStream]];
> +	p = (scaleflag) ? [self.window mouseLocationOutsideOfEventStream] 
> +		: [self.window convertPointToBacking:[self.window mouseLocationOutsideOfEventStream]];
>  	u = [NSEvent pressedMouseButtons];
>  	q.x = p.x;
>  	q.y = p.y;
> +	s = scaledframesize();
>  	if(!ptinrect(q, gscreen->clipr)) return;
>  	u = (u&~6) | (u&4)>>1 | (u&2)<<1;
>  	if(u == 1){
> @@ -609,7 +624,7 @@ evkey(uint v)
>  		}else if(m & NSEventModifierFlagCommand)
>  			u = 4;
>  	}
> -	absmousetrack(p.x, [self convertSizeToBacking:self.frame.size].height - p.y, u, ticks());
> +	absmousetrack(p.x, s.height - p.y, u, ticks());
>  	if(u && _lastInputRect.size.width && _lastInputRect.size.height)
>  		[self resetLastInputRect];
>  }
> @@ -697,7 +712,8 @@ evkey(uint v)
>  
>  - (void) reshape
>  {
> -	NSSize s = [self convertSizeToBacking:self.frame.size];
> +	NSSize s; 
> +	s = scaledframesize();
>  	LOG(@"%g %g", s.width, s.height);
>  	if(gscreen != nil){
>  		screenresize(Rect(0, 0, s.width, s.height));
> 
> 
> cpu.c
> diff --git a/cpu.c b/cpu.c
> index a271fdb..a3f270e 100644
> --- a/cpu.c
> +++ b/cpu.c
> @@ -28,6 +28,7 @@ static int	norcpu;
>  static int	nokbd;
>  static int	nogfx;
>  static int	nineflag;
> +int scaleflag = 1;
>  
>  static char	*ealgs = "rc4_256 sha1";
>  
> @@ -248,6 +249,7 @@ usage(void)
>  		"[-e 'crypt hash'] [-k keypattern] "
>  		"[-p] [-t timeout] "
>  		"[-r root] "
> +		"[-S]"
>  		"[-g geometry] "
>  		"[-c cmd ...]\n", argv0);
>  	exits("usage");
> @@ -294,6 +296,9 @@ cpumain(int argc, char **argv)
>  	case 's':
>  		secstore = EARGF(usage());
>  		break;
> +	case 'S':
> +		scaleflag = 0;
> +		break;
>  	case 'e':
>  		ealgs = EARGF(usage());
>  		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
> 
> drawterm.1
> diff --git a/drawterm.1 b/drawterm.1
> index 347fa40..9cc7970 100644
> --- a/drawterm.1
> +++ b/drawterm.1
> @@ -20,6 +20,8 @@ drawterm  \- connection to cpu, fs, and auth servers
>  .B -s
>  .I secstore
>  ] [
> +.B -S
> +] [
>  .B -e
>  \fR'\fIcrypt hash\fR'
>  ] [
> @@ -91,6 +93,12 @@ server. If the -s option is absent,
>  .IR secstore (1)
>  will attempt to dial tcp!$auth!secstore (or the otherwise specified auth server).
>  
> +.TP
> +.B -S
> +(macOS only) Disables scaling. By default, drawterm will scale window graphics on high DPI displays
> +to a proportional size. If this isn't desirable, this flag will render graphics 1:1 with the display
> +resolution.
> +
>  .TP
>  .B -e \fR'\fIcrypt hash\fR'
>  Specifies the \fR'\fIcrypt hash\fR'
> 
> Let me know if you need anything else. 
> 
> Nikita


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [9front] macOS Drawterm patch
  2025-01-28 17:23 [9front] macOS Drawterm patch Nikita Georgiou
  2025-01-28 17:29 ` ori
@ 2025-01-28 17:48 ` Xiao-Yong Jin
  1 sibling, 0 replies; 3+ messages in thread
From: Xiao-Yong Jin @ 2025-01-28 17:48 UTC (permalink / raw)
  To: 9front


> On Jan 28, 2025, at 11:23 AM, Nikita Georgiou <nikitageorgiou@gmail.com> wrote:
> 
> Hi, I wrote a patch for the macOS version of drawterm that makes it scale accordingly to the user’s scaling preferences. Right now, drawterm renders 1:1 with the monitor resolution which sucks on high DPI displays. This did not used to be the case pre-Metal API. 

I guess it's good to have a choice. The choice for me was bad rendering vs small UI elements, and I chose good font rendering. The 1.5x scaling on one of my screen was comical.

Another option would be to surgically change all UI elements to automatically scale up 2x, as what is done in plan9port. Perhaps it would be worth the effort once we have 3x or more dense native pixels.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-01-28 17:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-28 17:23 [9front] macOS Drawterm patch Nikita Georgiou
2025-01-28 17:29 ` ori
2025-01-28 17:48 ` Xiao-Yong Jin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).