unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* macOS (Cocoa) alpha-background
@ 2024-01-23  0:54 Jon Rubens
  2024-01-23  3:21 ` Po Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Rubens @ 2024-01-23  0:54 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 10706 bytes --]

I’ve been jealous of the alpha-background feature for Cairo builds so
I took it upon myself to try and implement the same on my macOS build.

I’ve got it working to some extent and I’m looking for someone with
some experience to help finish this implementation.

What isn’t working yet:
- Main window face background is solid. I messed around in
  src/macfont.m and did achieve transparency but it also caused a
  bunch of strange behavior. I don’t understand the CoreGraphics
  implementation well. I don’t know why the modeline text is
  implemented differently from the window text. I almost think the NS
  build is wildly outdated.
- I do not know if what I changed is done in an effective way, I’m not
  a developer to any extent just someone who is too impatient to wait
  for someone else to add this feature. This also means that my patch
  file is invalid in some way because I’m teaching myself as I go
  along.


---
 src/nsfns.m  |  9 ++++-----
 src/nsfont.m |  2 +-
 src/nsterm.h |  2 +-
 src/nsterm.m | 44 ++++++++++++++++++++++++--------------------
 4 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/src/nsfns.m b/src/nsfns.m
index b0281aac257..705c8e5aab7 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -282,7 +282,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   [f->output_data.ns->foreground_color release];
   f->output_data.ns->foreground_color = col;

- FRAME_FOREGROUND_PIXEL (f) = [col unsignedLong];
+ FRAME_FOREGROUND_PIXEL (f) = [[col colorWithAlphaComponent: f->alpha_background] unsignedLong];

  if (FRAME_NS_VIEW (f))
    {
@@ -301,7 +301,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   struct face *face;
   NSColor *col;
   NSView *view = FRAME_NS_VIEW (f);
- EmacsCGFloat alpha;
+ EmacsCGFloat alpha = f->alpha_background;

  block_input ();
  if (ns_lisp_to_color (arg, &col))
@@ -315,12 +315,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   [f->output_data.ns->background_color release];
   f->output_data.ns->background_color = col;

- FRAME_BACKGROUND_PIXEL (f) = [col unsignedLong];
- alpha = [col alphaComponent];
+ FRAME_BACKGROUND_PIXEL (f) = [[col colorWithAlphaComponent: alpha] unsignedLong];

  if (view != nil)
    {
- [[view window] setBackgroundColor: col];
+ [[view window] setBackgroundColor: [col colorWithAlphaComponent: alpha]];

  if (alpha != (EmacsCGFloat) 1.0)
      [[view window] setOpaque: NO];
diff --git a/src/nsfont.m b/src/nsfont.m
index 1205fbe5263..9da964956e1 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1185,7 +1185,7 @@ is false when (FROM > 0 || TO < S->nchars).  */
 	{
 	  if (s->hl != DRAW_CURSOR)
 	    [(NS_FACE_BACKGROUND (face) != 0
- ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+ ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background]
  ,----
  | FRAME_BACKGROUND_COLOR (s->f)) set];
  `----

  else
    [FRAME_CURSOR_COLOR (s->f) set];
diff --git a/src/nsterm.h b/src/nsterm.h
index c2965cfcc0f..7b0a1db601d 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1017,7 +1017,7 @@ #define FRAME_NS_WINDOW(f) ((f)->output_data.ns->window_desc)
 #define FRAME_NATIVE_WINDOW(f) FRAME_NS_WINDOW (f)

 #define FRAME_FOREGROUND_COLOR(f) ((f)->output_data.ns->foreground_color)
-#define FRAME_BACKGROUND_COLOR(f) ((f)->output_data.ns->background_color)
+#define FRAME_BACKGROUND_COLOR(f) ([(f)->output_data.ns->background_color colorWithAlphaComponent: f->alpha_background])

 #define NS_FACE_FOREGROUND(f) ((f)->foreground)
 #define NS_FACE_BACKGROUND(f) ((f)->background)
diff --git a/src/nsterm.m b/src/nsterm.m
index 518b38658d1..1fd7ea54dae 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2618,8 +2618,9 @@ Hide the window (X11 semantics)

block_input ();
ns_focus (f, &r, 1);
- [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
- (FACE_FROM_ID (f, DEFAULT_FACE_ID))] set];
+ [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+ (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+ colorWithAlphaComponent: f->alpha_background] set];
  NSRectFill (r);
  ns_unfocus (f);

@@ -2647,7 +2648,7 @@ Hide the window (X11 semantics)

r = NSIntersectionRect (r, [view frame]);
ns_focus (f, &r, 1);
- [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+ [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];

  NSRectFill (r);

@@ -2751,7 +2752,7 @@ Hide the window (X11 semantics)
         return;

ns_focus (f, NULL, 1);
- [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+ [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
  NSRectFill (NSMakeRect (0, margin, width, border));
  NSRectFill (NSMakeRect (0, 0, border, height));
  NSRectFill (NSMakeRect (0, margin, width, border));
@@ -2802,7 +2803,7 @@ Hide the window (X11 semantics)
           NSRect r = NSMakeRect (0, y, FRAME_PIXEL_WIDTH (f), height);
           ns_focus (f, &r, 1);

- [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+ [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
  NSRectFill (NSMakeRect (0, y, width, height));
  NSRectFill (NSMakeRect (FRAME_PIXEL_WIDTH (f) - width,
  			y, width, height));
@@ -2966,8 +2967,7 @@ Hide the window (X11 semantics)
   if (! NSIsEmptyRect (clearRect))
     {
       NSTRACE_RECT ("clearRect", clearRect);
- 

- [[NSColor colorWithUnsignedLong:face->background] set];
+ [[[NSColor colorWithUnsignedLong:face->background] colorWithAlphaComponent: f->alpha_background] set];
    NSRectFill (clearRect);
  }

@@ -2994,7 +2994,7 @@ Hide the window (X11 semantics)
       if (!p->cursor_p)
         bm_color = [NSColor colorWithUnsignedLong:face->foreground];
       else if (p->overlay_p)
- bm_color = [NSColor colorWithUnsignedLong:face->background];
+ bm_color = [[NSColor colorWithUnsignedLong:face->background] colorWithAlphaComponent: f->alpha_background];
  else
    bm_color = f->output_data.ns->cursor_color;

@@ -3491,7 +3491,7 @@ larger if there are taller display elements (e.g., characters
   if (s->face->use_box_color_for_shadows_p)
     color = [NSColor colorWithUnsignedLong: s->face->box_color];
   else
- color = [NSColor colorWithUnsignedLong: s->face->background];
+ color = [[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background];

  if (s->hl == DRAW_CURSOR)
    color = FRAME_CURSOR_COLOR (s->f);
@@ -3719,7 +3719,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
     {
       ns_draw_box (r, abs (hthickness), abs (vthickness),
- [NSColor colorWithUnsignedLong:face->box_color],
+ [[NSColor colorWithUnsignedLong:face->box_color] colorWithAlphaComponent: s->f->alpha_background],
  		 left_p, right_p);
    }
  else
@@ -3757,8 +3757,10 @@ Function modeled after x_draw_glyph_string_box ().
             {
               if (s->hl != DRAW_CURSOR)
                 [(NS_FACE_BACKGROUND (face) != 0
- ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+ ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+ colorWithAlphaComponent: s->f->alpha_background]
  ,----
  | FRAME_BACKGROUND_COLOR (s->f)) set];
  `----
+ else if (face && (NS_FACE_BACKGROUND (face)
  		  == [(NSColor *) FRAME_CURSOR_COLOR (s->f)
  				  unsignedLong]))
@@ -3902,7 +3904,7 @@ Function modeled after x_draw_glyph_string_box ().
      otherwise, since we composite the image under NS (instead of mucking
      with its background color), we must clear just the image area.  */

- [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+ [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background] set];

  if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
     s->img->mask    s->img->pixmap == 0    s->width != s->background_width)
@@ -3972,7 +3974,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->hl == DRAW_CURSOR)
     {
       [FRAME_CURSOR_COLOR (s->f) set];
- tdCol = [NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)];
+ tdCol = [[NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background];
    }
  else
    tdCol = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (face)];
@@ -4066,10 +4068,10 @@ Function modeled after x_draw_glyph_string_box ().
 		face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
 	      prepare_face_for_display (s->f, face);

- [[NSColor colorWithUnsignedLong: face->background] set];
+ [[[NSColor colorWithUnsignedLong: face->background] colorWithAlphaComponent: s->f->alpha_background] set];
    }
  else
- [[NSColor colorWithUnsignedLong: s->face->background] set];
+ [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];
        NSRectFill (NSMakeRect (x, y, w, h));
      }
  }
@@ -4095,7 +4097,7 @@ Function modeled after x_draw_glyph_string_box ().
 	  if (s->hl == DRAW_CURSOR)
 	    [FRAME_CURSOR_COLOR (s->f) set];
 	  else
- [[NSColor colorWithUnsignedLong: s->face->background] set];
+ [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];

    NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
  }
@@ -8374,8 +8376,9 @@ - (void)toggleFullScreen: (id)sender
   w = (EmacsWindow *)[self window];
   onFirstScreen = [[w screen] isEqual:[[NSScreen screens] objectAtIndex:0]];
   f = emacsframe;
- col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
- (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+ col = [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+ (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+ colorWithAlphaComponent: f->alpha_background];

  if (fs_state != FULLSCREEN_BOTH)
    {
@@ -9171,8 +9174,9 @@ - (instancetype) initWithEmacsFrame: (struct frame *) f

f->border_width = [self borderWidth];

- col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
- (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+ col = [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+ (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+ colorWithAlphaComponent: f->alpha_background];
  [self setBackgroundColor:col];
  if ([col alphaComponent] != (EmacsCGFloat) 1.0)
    [self setOpaque:NO];
-- 
2.39.3 (Apple Git-145)


Thanks,

-- 
Jon

[-- Attachment #1.2: Type: text/html, Size: 31403 bytes --]

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

* Re: macOS (Cocoa) alpha-background
  2024-01-23  0:54 macOS (Cocoa) alpha-background Jon Rubens
@ 2024-01-23  3:21 ` Po Lu
  2024-01-23  4:17   ` Jon Rubens
  0 siblings, 1 reply; 11+ messages in thread
From: Po Lu @ 2024-01-23  3:21 UTC (permalink / raw)
  To: Jon Rubens; +Cc: emacs-devel

Jon Rubens <jonathan.rubens@gmail.com> writes:

> I’ve been jealous of the alpha-background feature for Cairo builds so
> I took it upon myself to try and implement the same on my macOS build.
>
> I’ve got it working to some extent and I’m looking for someone with
> some experience to help finish this implementation.
>
> What isn’t working yet:
>
> * Main window face background is solid. I messed around in
>  src/macfont.m and did achieve transparency but it also caused a
>  bunch of strange behavior. I don’t understand the CoreGraphics
>  implementation well. I don’t know why the modeline text is
>  implemented differently from the window text. I almost think the NS
>  build is wildly outdated.
> * I do not know if what I changed is done in an effective way, I’m not
>  a developer to any extent just someone who is too impatient to wait
>  for someone else to add this feature. This also means that my patch
>  file is invalid in some way because I’m teaching myself as I go
>  along.

Thanks, but it is rather difficult for anyone to help improve your patch
when much of it has been encoded into HTML, rendering it impossible to
apply.  Please send the patch as an attachment instead.



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

* Re: macOS (Cocoa) alpha-background
  2024-01-23  3:21 ` Po Lu
@ 2024-01-23  4:17   ` Jon Rubens
  2024-01-24 23:25     ` Jon Rubens
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Rubens @ 2024-01-23  4:17 UTC (permalink / raw)
  To: Po Lu, Jon Rubens; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 97 bytes --]

> Please send the patch as an attachment instead.
Sorry, my bad. Patch attached.

-- 
Jon Rubens

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Attempt-at-adding-alpha_background-functionality-to-.patch --]
[-- Type: text/x-patch, Size: 10296 bytes --]

From f43b79979b5bb7077b37c78b183160e007454088 Mon Sep 17 00:00:00 2001
From: Jon Rubens <jonrubens@jon-mbp.lan>
Date: Mon, 22 Jan 2024 16:26:09 -0800
Subject: [PATCH] Attempt at adding alpha_background functionality to NS

---
 src/nsfns.m  |  9 ++++-----
 src/nsfont.m |  2 +-
 src/nsterm.h |  2 +-
 src/nsterm.m | 44 ++++++++++++++++++++++++--------------------
 4 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/src/nsfns.m b/src/nsfns.m
index b0281aac257..705c8e5aab7 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -282,7 +282,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   [f->output_data.ns->foreground_color release];
   f->output_data.ns->foreground_color = col;
 
-  FRAME_FOREGROUND_PIXEL (f) = [col unsignedLong];
+  FRAME_FOREGROUND_PIXEL (f) = [[col colorWithAlphaComponent: f->alpha_background] unsignedLong];
 
   if (FRAME_NS_VIEW (f))
     {
@@ -301,7 +301,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   struct face *face;
   NSColor *col;
   NSView *view = FRAME_NS_VIEW (f);
-  EmacsCGFloat alpha;
+  EmacsCGFloat alpha = f->alpha_background;
 
   block_input ();
   if (ns_lisp_to_color (arg, &col))
@@ -315,12 +315,11 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   [f->output_data.ns->background_color release];
   f->output_data.ns->background_color = col;
 
-  FRAME_BACKGROUND_PIXEL (f) = [col unsignedLong];
-  alpha = [col alphaComponent];
+  FRAME_BACKGROUND_PIXEL (f) = [[col colorWithAlphaComponent: alpha] unsignedLong];
 
   if (view != nil)
     {
-      [[view window] setBackgroundColor: col];
+      [[view window] setBackgroundColor: [col colorWithAlphaComponent: alpha]];
 
       if (alpha != (EmacsCGFloat) 1.0)
           [[view window] setOpaque: NO];
diff --git a/src/nsfont.m b/src/nsfont.m
index 1205fbe5263..9da964956e1 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1185,7 +1185,7 @@ is false when (FROM > 0 || TO < S->nchars).  */
 	{
 	  if (s->hl != DRAW_CURSOR)
 	    [(NS_FACE_BACKGROUND (face) != 0
-	      ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+	      ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background]
 	      : FRAME_BACKGROUND_COLOR (s->f)) set];
 	  else
 	    [FRAME_CURSOR_COLOR (s->f) set];
diff --git a/src/nsterm.h b/src/nsterm.h
index c2965cfcc0f..7b0a1db601d 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1017,7 +1017,7 @@ #define FRAME_NS_WINDOW(f) ((f)->output_data.ns->window_desc)
 #define FRAME_NATIVE_WINDOW(f) FRAME_NS_WINDOW (f)
 
 #define FRAME_FOREGROUND_COLOR(f) ((f)->output_data.ns->foreground_color)
-#define FRAME_BACKGROUND_COLOR(f) ((f)->output_data.ns->background_color)
+#define FRAME_BACKGROUND_COLOR(f) ([(f)->output_data.ns->background_color colorWithAlphaComponent: f->alpha_background])
 
 #define NS_FACE_FOREGROUND(f) ((f)->foreground)
 #define NS_FACE_BACKGROUND(f) ((f)->background)
diff --git a/src/nsterm.m b/src/nsterm.m
index 518b38658d1..1fd7ea54dae 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2618,8 +2618,9 @@ Hide the window (X11 semantics)
 
   block_input ();
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-			    (FACE_FROM_ID (f, DEFAULT_FACE_ID))] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+                                 colorWithAlphaComponent: f->alpha_background] set];
   NSRectFill (r);
   ns_unfocus (f);
 
@@ -2647,7 +2648,7 @@ Hide the window (X11 semantics)
 
   r = NSIntersectionRect (r, [view frame]);
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
 
   NSRectFill (r);
 
@@ -2751,7 +2752,7 @@ Hide the window (X11 semantics)
         return;
 
       ns_focus (f, NULL, 1);
-      [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+      [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (NSMakeRect (0, margin, width, border));
       NSRectFill (NSMakeRect (0, 0, border, height));
       NSRectFill (NSMakeRect (0, margin, width, border));
@@ -2802,7 +2803,7 @@ Hide the window (X11 semantics)
           NSRect r = NSMakeRect (0, y, FRAME_PIXEL_WIDTH (f), height);
           ns_focus (f, &r, 1);
 
-          [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+          [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
           NSRectFill (NSMakeRect (0, y, width, height));
           NSRectFill (NSMakeRect (FRAME_PIXEL_WIDTH (f) - width,
                                   y, width, height));
@@ -2966,8 +2967,7 @@ Hide the window (X11 semantics)
   if (! NSIsEmptyRect (clearRect))
     {
       NSTRACE_RECT ("clearRect", clearRect);
-
-      [[NSColor colorWithUnsignedLong:face->background] set];
+      [[[NSColor colorWithUnsignedLong:face->background] colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (clearRect);
     }
 
@@ -2994,7 +2994,7 @@ Hide the window (X11 semantics)
       if (!p->cursor_p)
         bm_color = [NSColor colorWithUnsignedLong:face->foreground];
       else if (p->overlay_p)
-        bm_color = [NSColor colorWithUnsignedLong:face->background];
+        bm_color = [[NSColor colorWithUnsignedLong:face->background] colorWithAlphaComponent: f->alpha_background];
       else
         bm_color = f->output_data.ns->cursor_color;
 
@@ -3491,7 +3491,7 @@ larger if there are taller display elements (e.g., characters
   if (s->face->use_box_color_for_shadows_p)
     color = [NSColor colorWithUnsignedLong: s->face->box_color];
   else
-    color = [NSColor colorWithUnsignedLong: s->face->background];
+    color = [[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background];
 
   if (s->hl == DRAW_CURSOR)
     color = FRAME_CURSOR_COLOR (s->f);
@@ -3719,7 +3719,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
     {
       ns_draw_box (r, abs (hthickness), abs (vthickness),
-                   [NSColor colorWithUnsignedLong:face->box_color],
+                   [[NSColor colorWithUnsignedLong:face->box_color] colorWithAlphaComponent: s->f->alpha_background],
                    left_p, right_p);
     }
   else
@@ -3757,8 +3757,10 @@ Function modeled after x_draw_glyph_string_box ().
             {
               if (s->hl != DRAW_CURSOR)
                 [(NS_FACE_BACKGROUND (face) != 0
-                  ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+		  ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+		      colorWithAlphaComponent: s->f->alpha_background]
                   : FRAME_BACKGROUND_COLOR (s->f)) set];
+
               else if (face && (NS_FACE_BACKGROUND (face)
                                 == [(NSColor *) FRAME_CURSOR_COLOR (s->f)
                                                 unsignedLong]))
@@ -3902,7 +3904,7 @@ Function modeled after x_draw_glyph_string_box ().
      otherwise, since we composite the image under NS (instead of mucking
      with its background color), we must clear just the image area.  */
 
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background] set];
 
   if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
       || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
@@ -3972,7 +3974,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->hl == DRAW_CURSOR)
     {
       [FRAME_CURSOR_COLOR (s->f) set];
-      tdCol = [NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)];
+      tdCol = [[NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background];
     }
   else
     tdCol = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (face)];
@@ -4066,10 +4068,10 @@ Function modeled after x_draw_glyph_string_box ().
 		face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
 	      prepare_face_for_display (s->f, face);
 
-	      [[NSColor colorWithUnsignedLong: face->background] set];
+	      [[[NSColor colorWithUnsignedLong: face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 	    }
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 	  NSRectFill (NSMakeRect (x, y, w, h));
 	}
     }
@@ -4095,7 +4097,7 @@ Function modeled after x_draw_glyph_string_box ().
 	  if (s->hl == DRAW_CURSOR)
 	    [FRAME_CURSOR_COLOR (s->f) set];
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 
 	  NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
 	}
@@ -8374,8 +8376,9 @@ - (void)toggleFullScreen: (id)sender
   w = (EmacsWindow *)[self window];
   onFirstScreen = [[w screen] isEqual:[[NSScreen screens] objectAtIndex:0]];
   f = emacsframe;
-  col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+  col = [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+	          colorWithAlphaComponent: f->alpha_background];
 
   if (fs_state != FULLSCREEN_BOTH)
     {
@@ -9171,8 +9174,9 @@ - (instancetype) initWithEmacsFrame: (struct frame *) f
 
       f->border_width = [self borderWidth];
 
-      col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-                                     (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+      col = [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+	          colorWithAlphaComponent: f->alpha_background];
       [self setBackgroundColor:col];
       if ([col alphaComponent] != (EmacsCGFloat) 1.0)
         [self setOpaque:NO];
-- 
2.39.3 (Apple Git-145)


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

* Re: macOS (Cocoa) alpha-background
  2024-01-23  4:17   ` Jon Rubens
@ 2024-01-24 23:25     ` Jon Rubens
  2024-01-25  1:46       ` Po Lu
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Rubens @ 2024-01-24 23:25 UTC (permalink / raw)
  To: Po Lu, Jon Rubens; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 512 bytes --]

I took a deep dive on this and have got it working. I don’t see any
obvious issues in this patched version but I’m certain there are edge
cases I haven’t tested.

I haven’t tried modifying cursor colors or fringes or even diverse
face backgrounds (I’ve only been working with default face), but this works for MacOS users.

Only open question I have to look into:
- The alpha on the ns transparent titlebar is off. I need to determine exactly where I set that.


Cheers,

-- 
Jon Rubens

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ns_alpha_background.patch --]
[-- Type: text/x-patch, Size: 10883 bytes --]

diff --git a/src/macfont.m b/src/macfont.m
index 8aba440d196..56c1eb57024 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -2953,9 +2953,14 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
             CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
           else
             CG_SET_FILL_COLOR_WITH_FRAME_CURSOR (context, f);
-        }
+	  CGContextSetAlpha(context, 1);
+	}
       else
-        CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+	{
+	  CGContextSetAlpha(context, f->alpha_background);
+	  CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+	}
+      CGContextClearRect(context, background_rect);
       CGContextFillRects (context, &background_rect, 1);
     }
 
@@ -2964,6 +2969,7 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
       CGAffineTransform atfm;
 
       CGContextScaleCTM (context, 1, -1);
+      CGContextSetAlpha(context, 1);
       if (s->hl == DRAW_CURSOR)
         {
           if (face && (NS_FACE_BACKGROUND (face)
diff --git a/src/nsfns.m b/src/nsfns.m
index b0281aac257..37b21e526e7 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -301,7 +301,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   struct face *face;
   NSColor *col;
   NSView *view = FRAME_NS_VIEW (f);
-  EmacsCGFloat alpha;
+  EmacsCGFloat alpha = f->alpha_background;
 
   block_input ();
   if (ns_lisp_to_color (arg, &col))
@@ -316,11 +316,10 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   f->output_data.ns->background_color = col;
 
   FRAME_BACKGROUND_PIXEL (f) = [col unsignedLong];
-  alpha = [col alphaComponent];
 
   if (view != nil)
     {
-      [[view window] setBackgroundColor: col];
+      [[view window] setBackgroundColor: [col colorWithAlphaComponent: alpha]];
 
       if (alpha != (EmacsCGFloat) 1.0)
           [[view window] setOpaque: NO];
@@ -330,10 +329,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
       face = FRAME_DEFAULT_FACE (f);
       if (face)
         {
-          col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)];
-          face->background = [[col colorWithAlphaComponent: alpha]
-                               unsignedLong];
-
+          face->background = [col unsignedLong];
           update_face_from_frame_parameter (f, Qbackground_color, arg);
         }
 
@@ -346,6 +342,36 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   unblock_input ();
 }
 
+static void
+ns_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  double alpha = 1.0;
+
+  if (NILP (arg))
+    alpha = 1.0;
+  else if (FLOATP (arg))
+    {
+      alpha = XFLOAT_DATA (arg);
+      if (! (0 <= alpha && alpha <= 1.0))
+	args_out_of_range (make_float (0.0), make_float (1.0));
+    }
+  else if (FIXNUMP (arg))
+    {
+      EMACS_INT ialpha = XFIXNUM (arg);
+      if (! (0 <= ialpha && ialpha <= 100))
+	args_out_of_range (make_fixnum (0), make_fixnum (100));
+      alpha = ialpha / 100.0;
+    }
+  else
+    wrong_type_argument (Qnumberp, arg);
+
+  f->alpha_background = alpha;
+  [[view window] setBackgroundColor: [f->output_data.ns->background_color colorWithAlphaComponent: alpha]];
+
+  recompute_basic_faces (f);
+  SET_FRAME_GARBAGED (f);
+}
 
 static void
 ns_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
@@ -1065,7 +1091,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   ns_set_z_group,
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
-  gui_set_alpha_background,
+  ns_set_alpha_background,
   NULL,
 #ifdef NS_IMPL_COCOA
   ns_set_appearance,
diff --git a/src/nsfont.m b/src/nsfont.m
index 1205fbe5263..9da964956e1 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -1185,7 +1185,7 @@ is false when (FROM > 0 || TO < S->nchars).  */
 	{
 	  if (s->hl != DRAW_CURSOR)
 	    [(NS_FACE_BACKGROUND (face) != 0
-	      ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+	      ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background]
 	      : FRAME_BACKGROUND_COLOR (s->f)) set];
 	  else
 	    [FRAME_CURSOR_COLOR (s->f) set];
diff --git a/src/nsterm.m b/src/nsterm.m
index 518b38658d1..bda3a12172f 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2618,8 +2618,9 @@ Hide the window (X11 semantics)
 
   block_input ();
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-			    (FACE_FROM_ID (f, DEFAULT_FACE_ID))] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+                                 colorWithAlphaComponent: f->alpha_background] set];
   NSRectFill (r);
   ns_unfocus (f);
 
@@ -2647,7 +2648,7 @@ Hide the window (X11 semantics)
 
   r = NSIntersectionRect (r, [view frame]);
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
 
   NSRectFill (r);
 
@@ -2751,7 +2752,7 @@ Hide the window (X11 semantics)
         return;
 
       ns_focus (f, NULL, 1);
-      [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+      [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (NSMakeRect (0, margin, width, border));
       NSRectFill (NSMakeRect (0, 0, border, height));
       NSRectFill (NSMakeRect (0, margin, width, border));
@@ -2802,7 +2803,7 @@ Hide the window (X11 semantics)
           NSRect r = NSMakeRect (0, y, FRAME_PIXEL_WIDTH (f), height);
           ns_focus (f, &r, 1);
 
-          [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+          [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: f->alpha_background] set];
           NSRectFill (NSMakeRect (0, y, width, height));
           NSRectFill (NSMakeRect (FRAME_PIXEL_WIDTH (f) - width,
                                   y, width, height));
@@ -2966,8 +2967,7 @@ Hide the window (X11 semantics)
   if (! NSIsEmptyRect (clearRect))
     {
       NSTRACE_RECT ("clearRect", clearRect);
-
-      [[NSColor colorWithUnsignedLong:face->background] set];
+      [[[NSColor colorWithUnsignedLong:face->background] colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (clearRect);
     }
 
@@ -2998,7 +2998,7 @@ Hide the window (X11 semantics)
       else
         bm_color = f->output_data.ns->cursor_color;
 
-      [bm_color set];
+      [[bm_color colorWithAlphaComponent:f->alpha_background] set];
       [bmp fill];
 
       [bmp release];
@@ -3719,7 +3719,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
     {
       ns_draw_box (r, abs (hthickness), abs (vthickness),
-                   [NSColor colorWithUnsignedLong:face->box_color],
+                   [[NSColor colorWithUnsignedLong:face->box_color] colorWithAlphaComponent: s->f->alpha_background],
                    left_p, right_p);
     }
   else
@@ -3757,8 +3757,10 @@ Function modeled after x_draw_glyph_string_box ().
             {
               if (s->hl != DRAW_CURSOR)
                 [(NS_FACE_BACKGROUND (face) != 0
-                  ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+		  ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+		      colorWithAlphaComponent: s->f->alpha_background]
                   : FRAME_BACKGROUND_COLOR (s->f)) set];
+
               else if (face && (NS_FACE_BACKGROUND (face)
                                 == [(NSColor *) FRAME_CURSOR_COLOR (s->f)
                                                 unsignedLong]))
@@ -3902,7 +3904,7 @@ Function modeled after x_draw_glyph_string_box ().
      otherwise, since we composite the image under NS (instead of mucking
      with its background color), we must clear just the image area.  */
 
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background] set];
 
   if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
       || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
@@ -3972,7 +3974,7 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->hl == DRAW_CURSOR)
     {
       [FRAME_CURSOR_COLOR (s->f) set];
-      tdCol = [NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)];
+      tdCol = [[NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)] colorWithAlphaComponent: s->f->alpha_background];
     }
   else
     tdCol = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (face)];
@@ -4066,10 +4068,10 @@ Function modeled after x_draw_glyph_string_box ().
 		face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
 	      prepare_face_for_display (s->f, face);
 
-	      [[NSColor colorWithUnsignedLong: face->background] set];
+	      [[[NSColor colorWithUnsignedLong: face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 	    }
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 	  NSRectFill (NSMakeRect (x, y, w, h));
 	}
     }
@@ -4095,7 +4097,7 @@ Function modeled after x_draw_glyph_string_box ().
 	  if (s->hl == DRAW_CURSOR)
 	    [FRAME_CURSOR_COLOR (s->f) set];
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background] colorWithAlphaComponent: s->f->alpha_background] set];
 
 	  NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
 	}
@@ -8436,8 +8438,8 @@ - (void)toggleFullScreen: (id)sender
         }
 
       [w setContentView:[fw contentView]];
-      [w setBackgroundColor: col];
-      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
+      [w setBackgroundColor: [col colorWithAlphaComponent: f->alpha_background]];
+      if (f->alpha_background != (EmacsCGFloat) 1.0)
         [w setOpaque: NO];
 
       f->border_width = [w borderWidth];
@@ -9172,9 +9174,9 @@ - (instancetype) initWithEmacsFrame: (struct frame *) f
       f->border_width = [self borderWidth];
 
       col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-                                     (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
-      [self setBackgroundColor:col];
-      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
+		      (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+      [self setBackgroundColor:[col colorWithAlphaComponent:f->alpha_background]];
+      if (f->alpha_background != (EmacsCGFloat) 1.0)
         [self setOpaque:NO];
 
       /* toolbar support */

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

* Re: macOS (Cocoa) alpha-background
  2024-01-24 23:25     ` Jon Rubens
@ 2024-01-25  1:46       ` Po Lu
  2024-04-14 19:35         ` Rudolf Adamkovič
  2024-05-19 10:18         ` Stefan Kangas
  0 siblings, 2 replies; 11+ messages in thread
From: Po Lu @ 2024-01-25  1:46 UTC (permalink / raw)
  To: Jon Rubens; +Cc: emacs-devel

Jon Rubens <jonathan.rubens@gmail.com> writes:

> I took a deep dive on this and have got it working. I don’t see any
> obvious issues in this patched version but I’m certain there are edge
> cases I haven’t tested.
>
> I haven’t tried modifying cursor colors or fringes or even diverse
> face backgrounds (I’ve only been working with default face), but this works for MacOS users.
>
> Only open question I have to look into:
> - The alpha on the ns transparent titlebar is off. I need to determine exactly where I set that.

Thanks.  Before we can accept this patch, you must sign copyright over
to the FSF; please start a separate thread, and someone will send you
the assignment form.

Meanwhile, please reformat the code into compliance with our preferred
style, which in your case is to place spaces between function
identifiers and their argument lists, and for no line to exceed 80
columns.



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

* Re: macOS (Cocoa) alpha-background
  2024-01-25  1:46       ` Po Lu
@ 2024-04-14 19:35         ` Rudolf Adamkovič
  2024-05-19 10:18         ` Stefan Kangas
  1 sibling, 0 replies; 11+ messages in thread
From: Rudolf Adamkovič @ 2024-04-14 19:35 UTC (permalink / raw)
  To: Jon Rubens; +Cc: emacs-devel

Po Lu <luangruo@yahoo.com> writes:

> Jon Rubens <jonathan.rubens@gmail.com> writes:
>
>> I took a deep dive on this and have got it working.
>
> Thanks.  Before we can accept this patch, [...]

Jon,

Thank you for working on this.  I hope your patch will be merged soon!

Rudy
-- 
"Great minds discuss ideas; average minds discuss events; small minds discuss
people."
--- Anna Eleanor Roosevelt (1884-1962)

Rudolf Adamkovič <rudolf@adamkovic.org> [he/him]
Studenohorská 25, 84103 Bratislava, Slovakia, European Union



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

* Re: macOS (Cocoa) alpha-background
  2024-01-25  1:46       ` Po Lu
  2024-04-14 19:35         ` Rudolf Adamkovič
@ 2024-05-19 10:18         ` Stefan Kangas
  2024-06-27 23:02           ` Jon Rubens
  1 sibling, 1 reply; 11+ messages in thread
From: Stefan Kangas @ 2024-05-19 10:18 UTC (permalink / raw)
  To: Po Lu, Jon Rubens; +Cc: emacs-devel

Po Lu <luangruo@yahoo.com> writes:

> Jon Rubens <jonathan.rubens@gmail.com> writes:
>
>> I took a deep dive on this and have got it working. I don’t see any
>> obvious issues in this patched version but I’m certain there are edge
>> cases I haven’t tested.
>>
>> I haven’t tried modifying cursor colors or fringes or even diverse
>> face backgrounds (I’ve only been working with default face), but this works for MacOS users.
>>
>> Only open question I have to look into:
>> - The alpha on the ns transparent titlebar is off. I need to determine exactly where I set that.
>
> Thanks.  Before we can accept this patch, you must sign copyright over
> to the FSF; please start a separate thread, and someone will send you
> the assignment form.

Having support for transparent background on macOS definitely seems like
something we would like to have.

Jonathan, did you have a chance to complete the copyright assignment to
the FSF?  If not, would you like me to send you the form to get started?



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

* Re: macOS (Cocoa) alpha-background
  2024-05-19 10:18         ` Stefan Kangas
@ 2024-06-27 23:02           ` Jon Rubens
  2024-06-27 23:19             ` Stefan Kangas
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Rubens @ 2024-06-27 23:02 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Po Lu, emacs-devel

> Jonathan, did you have a chance to complete the copyright assignment to
> the FSF?  If not, would you like me to send you the form to get started?

Please send me the form for copyright assignment to FSF. I might need
to update the code a bit because I noticed some changes in the Emacs
30 ref.

-- 
Jon



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

* Re: macOS (Cocoa) alpha-background
  2024-06-27 23:02           ` Jon Rubens
@ 2024-06-27 23:19             ` Stefan Kangas
  2024-06-28  0:38               ` Jon Rubens
  0 siblings, 1 reply; 11+ messages in thread
From: Stefan Kangas @ 2024-06-27 23:19 UTC (permalink / raw)
  To: jonathanrubens; +Cc: Po Lu, emacs-devel

Jon Rubens <jonathan.rubens@gmail.com> writes:

>> Jonathan, did you have a chance to complete the copyright assignment to
>> the FSF?  If not, would you like me to send you the form to get started?
>
> Please send me the form for copyright assignment to FSF. I might need
> to update the code a bit because I noticed some changes in the Emacs
> 30 ref.

Form sent off-list.



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

* Re: macOS (Cocoa) alpha-background
  2024-06-27 23:19             ` Stefan Kangas
@ 2024-06-28  0:38               ` Jon Rubens
  2024-06-30  5:29                 ` Stefan Kangas
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Rubens @ 2024-06-28  0:38 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Po Lu, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 148 bytes --]

> Copyright Form sent off-list.
Sent in the completed form.

Attached is an updated patch with the proper formatting updated for Emacs-30.

-- 
Jon

[-- Attachment #2: 0001-Add-alpha-background-feature-to-MacOS-Emacs.patch --]
[-- Type: application/octet-stream, Size: 10837 bytes --]

From 2695e80764bd254d12db3a627d2c020b102bf337 Mon Sep 17 00:00:00 2001
From: Jonathan Rubens <jonathanrubens@gmail.com>
Date: Thu, 27 Jun 2024 16:52:36 -0700
Subject: [PATCH] Add alpha-background feature to MacOS Emacs

---
 src/macfont.m | 10 ++++++++--
 src/nsfns.m   | 42 +++++++++++++++++++++++++++++++++--------
 src/nsterm.m  | 52 +++++++++++++++++++++++++++++++--------------------
 3 files changed, 74 insertions(+), 30 deletions(-)

diff --git a/src/macfont.m b/src/macfont.m
index e3b3d40df43..a2044f23b9d 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -2994,9 +2994,14 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
             CG_SET_FILL_COLOR_WITH_FACE_FOREGROUND (context, face);
           else
             CG_SET_FILL_COLOR_WITH_FRAME_CURSOR (context, f);
-        }
+	  CGContextSetAlpha (context, 1);
+	}
       else
-        CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+	{
+	  CGContextSetAlpha (context, f->alpha_background);
+	  CG_SET_FILL_COLOR_WITH_FACE_BACKGROUND (context, face);
+	}
+      CGContextClearRect (context, background_rect);
       CGContextFillRects (context, &background_rect, 1);
     }
 
@@ -3005,6 +3010,7 @@ So we use CTFontDescriptorCreateMatchingFontDescriptor (no
       CGAffineTransform atfm;
 
       CGContextScaleCTM (context, 1, -1);
+      CGContextSetAlpha (context, 1);
       if (s->hl == DRAW_CURSOR)
         {
           if (face && (NS_FACE_BACKGROUND (face)
diff --git a/src/nsfns.m b/src/nsfns.m
index add7a93dfba..6ee0f9cf707 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -299,7 +299,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   struct face *face;
   NSColor *col;
   NSView *view = FRAME_NS_VIEW (f);
-  EmacsCGFloat alpha;
+  EmacsCGFloat alpha = f->alpha_background;
 
   block_input ();
   if (ns_lisp_to_color (arg, &col))
@@ -314,11 +314,10 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   f->output_data.ns->background_color = col;
 
   FRAME_BACKGROUND_PIXEL (f) = [col unsignedLong];
-  alpha = [col alphaComponent];
 
   if (view != nil)
     {
-      [[view window] setBackgroundColor: col];
+      [[view window] setBackgroundColor: [col colorWithAlphaComponent: alpha]];
 
       if (alpha != (EmacsCGFloat) 1.0)
           [[view window] setOpaque: NO];
@@ -328,10 +327,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
       face = FRAME_DEFAULT_FACE (f);
       if (face)
         {
-          col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)];
-          face->background = [[col colorWithAlphaComponent: alpha]
-                               unsignedLong];
-
+          face->background = [col unsignedLong];
           update_face_from_frame_parameter (f, Qbackground_color, arg);
         }
 
@@ -344,6 +340,36 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   unblock_input ();
 }
 
+static void
+ns_set_alpha_background (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  NSView *view = FRAME_NS_VIEW (f);
+  double alpha = 1.0;
+
+  if (NILP (arg))
+    alpha = 1.0;
+  else if (FLOATP (arg))
+    {
+      alpha = XFLOAT_DATA (arg);
+      if (! (0 <= alpha && alpha <= 1.0))
+	args_out_of_range (make_float (0.0), make_float (1.0));
+    }
+  else if (FIXNUMP (arg))
+    {
+      EMACS_INT ialpha = XFIXNUM (arg);
+      if (! (0 <= ialpha && ialpha <= 100))
+	args_out_of_range (make_fixnum (0), make_fixnum (100));
+      alpha = ialpha / 100.0;
+    }
+  else
+    wrong_type_argument (Qnumberp, arg);
+
+  f->alpha_background = alpha;
+  [[view window] setBackgroundColor: [f->output_data.ns->background_color
+					 colorWithAlphaComponent: alpha]];
+  recompute_basic_faces (f);
+  SET_FRAME_GARBAGED (f);
+}
 
 static void
 ns_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
@@ -1109,7 +1135,7 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side.
   ns_set_z_group,
   0, /* x_set_override_redirect */
   gui_set_no_special_glyphs,
-  gui_set_alpha_background,
+  ns_set_alpha_background,
   NULL,
 #ifdef NS_IMPL_COCOA
   ns_set_appearance,
diff --git a/src/nsterm.m b/src/nsterm.m
index 794630de1c1..fe09de140dd 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2627,8 +2627,10 @@ Hide the window (X11 semantics)
 
   block_input ();
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-			    (FACE_FROM_ID (f, DEFAULT_FACE_ID))] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
+				 (FACE_FROM_ID (f, DEFAULT_FACE_ID))]
+                                 colorWithAlphaComponent: f->alpha
+     _background] set];
   NSRectFill (r);
   ns_unfocus (f);
 
@@ -2656,7 +2658,8 @@ Hide the window (X11 semantics)
 
   r = NSIntersectionRect (r, [view frame]);
   ns_focus (f, &r, 1);
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+     colorWithAlphaComponent: f->alpha_background] set];
 
   NSRectFill (r);
 
@@ -2760,7 +2763,8 @@ Hide the window (X11 semantics)
         return;
 
       ns_focus (f, NULL, 1);
-      [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+      [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+         colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (NSMakeRect (0, margin, width, border));
       NSRectFill (NSMakeRect (0, 0, border, height));
       NSRectFill (NSMakeRect (0, margin, width, border));
@@ -2812,7 +2816,8 @@ Hide the window (X11 semantics)
           NSRect r = NSMakeRect (0, y, FRAME_PIXEL_WIDTH (f), height);
           ns_focus (f, &r, 1);
 
-          [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+          [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+             colorWithAlphaComponent: f->alpha_background] set];
           NSRectFill (NSMakeRect (0, y, width, height));
           NSRectFill (NSMakeRect (FRAME_PIXEL_WIDTH (f) - width,
                                   y, width, height));
@@ -2976,8 +2981,8 @@ Hide the window (X11 semantics)
   if (! NSIsEmptyRect (clearRect))
     {
       NSTRACE_RECT ("clearRect", clearRect);
-
-      [[NSColor colorWithUnsignedLong:face->background] set];
+      [[[NSColor colorWithUnsignedLong:face->background]
+         colorWithAlphaComponent: f->alpha_background] set];
       NSRectFill (clearRect);
     }
 
@@ -3008,7 +3013,7 @@ Hide the window (X11 semantics)
       else
         bm_color = f->output_data.ns->cursor_color;
 
-      [bm_color set];
+      [[bm_color colorWithAlphaComponent:f->alpha_background] set];
       [bmp fill];
 
       [bmp release];
@@ -3797,7 +3802,8 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->face->box == FACE_SIMPLE_BOX && s->face->box_color)
     {
       ns_draw_box (r, abs (hthickness), abs (vthickness),
-                   [NSColor colorWithUnsignedLong:face->box_color],
+                   [[NSColor colorWithUnsignedLong:face->box_color]
+                     colorWithAlphaComponent: s->f->alpha_background],
                    left_p, right_p);
     }
   else
@@ -3842,7 +3848,8 @@ Function modeled after x_draw_glyph_string_box ().
 	{
 	  if (s->hl != DRAW_CURSOR)
 	    [(NS_FACE_BACKGROUND (face) != 0
-	      ? [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+	      ? [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+		      colorWithAlphaComponent: s->f->alpha_background]
 	      : FRAME_BACKGROUND_COLOR (s->f)) set];
 	  else if (face && (NS_FACE_BACKGROUND (face)
 			    == [(NSColor *) FRAME_CURSOR_COLOR (s->f)
@@ -3981,7 +3988,8 @@ Function modeled after x_draw_glyph_string_box ().
      otherwise, since we composite the image under NS (instead of mucking
      with its background color), we must clear just the image area.  */
 
-  [[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)] set];
+  [[[NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND (face)]
+     colorWithAlphaComponent: s->f->alpha_background] set];
 
   if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
       || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
@@ -4051,7 +4059,8 @@ Function modeled after x_draw_glyph_string_box ().
   if (s->hl == DRAW_CURSOR)
     {
       [FRAME_CURSOR_COLOR (s->f) set];
-      tdCol = [NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)];
+      tdCol = [[NSColor colorWithUnsignedLong: NS_FACE_BACKGROUND (face)]
+                colorWithAlphaComponent: s->f->alpha_background];
     }
   else
     tdCol = [NSColor colorWithUnsignedLong: NS_FACE_FOREGROUND (face)];
@@ -4144,10 +4153,12 @@ Function modeled after x_draw_glyph_string_box ().
 		face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
 	      prepare_face_for_display (s->f, face);
 
-	      [[NSColor colorWithUnsignedLong: face->background] set];
+	      [[[NSColor colorWithUnsignedLong: face->background]
+                 colorWithAlphaComponent: s->f->alpha_background] set];
 	    }
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background]
+               colorWithAlphaComponent: s->f->alpha_background] set];
 	  NSRectFill (NSMakeRect (x, y, w, h));
 	}
     }
@@ -4178,7 +4189,8 @@ Function modeled after x_draw_glyph_string_box ().
 	  else if (s->stippled_p)
 	    [[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set];
 	  else
-	    [[NSColor colorWithUnsignedLong: s->face->background] set];
+	    [[[NSColor colorWithUnsignedLong: s->face->background]
+               colorWithAlphaComponent: s->f->alpha_background] set];
 
 	  NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
 	}
@@ -8545,8 +8557,8 @@ - (void)toggleFullScreen: (id)sender
         }
 
       [w setContentView:[fw contentView]];
-      [w setBackgroundColor: col];
-      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
+      [w setBackgroundColor: [col colorWithAlphaComponent: f->alpha_background]];
+      if (f->alpha_background != (EmacsCGFloat) 1.0)
         [w setOpaque: NO];
 
       f->border_width = [w borderWidth];
@@ -9283,9 +9295,9 @@ - (instancetype) initWithEmacsFrame: (struct frame *) f
       f->border_width = [self borderWidth];
 
       col = [NSColor colorWithUnsignedLong:NS_FACE_BACKGROUND
-                                     (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
-      [self setBackgroundColor:col];
-      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
+		      (FACE_FROM_ID (f, DEFAULT_FACE_ID))];
+      [self setBackgroundColor:[col colorWithAlphaComponent:f->alpha_background]];
+      if (f->alpha_background != (EmacsCGFloat) 1.0)
         [self setOpaque:NO];
 
       /* toolbar support */
-- 
2.39.3 (Apple Git-146)


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

* Re: macOS (Cocoa) alpha-background
  2024-06-28  0:38               ` Jon Rubens
@ 2024-06-30  5:29                 ` Stefan Kangas
  0 siblings, 0 replies; 11+ messages in thread
From: Stefan Kangas @ 2024-06-30  5:29 UTC (permalink / raw)
  To: jonathanrubens; +Cc: Po Lu, emacs-devel

Jon Rubens <jonathan.rubens@gmail.com> writes:

>> Copyright Form sent off-list.
> Sent in the completed form.

Thank you.

> Attached is an updated patch with the proper formatting updated for
> Emacs-30.

I've forwarded it to the bug tracker so that we don't lose track of it.

See Bug#71850.



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

end of thread, other threads:[~2024-06-30  5:29 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-23  0:54 macOS (Cocoa) alpha-background Jon Rubens
2024-01-23  3:21 ` Po Lu
2024-01-23  4:17   ` Jon Rubens
2024-01-24 23:25     ` Jon Rubens
2024-01-25  1:46       ` Po Lu
2024-04-14 19:35         ` Rudolf Adamkovič
2024-05-19 10:18         ` Stefan Kangas
2024-06-27 23:02           ` Jon Rubens
2024-06-27 23:19             ` Stefan Kangas
2024-06-28  0:38               ` Jon Rubens
2024-06-30  5:29                 ` Stefan Kangas

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).