all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Seiji Zenitani <zenitani@mac.com>
To: emacs-devel@gnu.org
Subject: Re: new frame-parameter "alpha"
Date: Sat, 15 Mar 2008 15:54:43 -0400	[thread overview]
Message-ID: <D654D617-DFF5-4ABB-A209-A1B43D650AB6@mac.com> (raw)
In-Reply-To: <jwvk5k5kwc0.fsf-monnier+emacs@gnu.org>

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

Hi,

Thank you for your comments.
I have attached an revised code to this email.

On 2008/03/14, at 14:28, Stefan Monnier wrote:
>> The attached patch adds the window (frame) opacity feature to GNU  
>> Emacs.
>> The user can control the frame opacity via a frame parameter   
>> 'alpha'.
>> If you like the code, I'll start to contact major  contributors.
>
> I do not personally care for transparency, and I'm wondering if  
> it's not
> better handled by the (compositing) window-manager, but if some people
> like this feature, I'm not opposed to it.
>
I would like to mention that we can potentially use this frame  
parameter on various platforms.  I have another code for emacs 22,  
which works both on X11 and on Mac/Carbon.  As soon as the Mac/Carbon  
port or other mac port comes back in emacs 23, it will be easy to  
port the code to the mac port.  In addition, some people use the  
frame opacity code on the win32 platform.

> A few comments on the code:
>
>> +  (defun set-alpha (alpha &optional frame)
(snip)
>
> Is this necessary/important?

I have removed it.

>> +#ifdef HAVE_X_WINDOWS
>> +/* Lower limit value of frame transparency.  */
>> +
>> +Lisp_Object Vframe_alpha_lower_limit;
>> +#endif
>> +
>>  #endif
>
> Only use #ifdef conditional compilation if either it's necessary to  
> get
> the code to compile, or for code which is inherently only  
> meaningful for
> a particular configuration.  Since Vframe_alpha_lower_limit makes  
> sense
> with other GUIs than X11, it should not be protected with #ifdef
> HAVE_X_WINDOWS.
>
>> +#ifdef HAVE_X_WINDOWS
>> +Lisp_Object Qalpha;
>> +#endif
>
> Same here and various other places.
>
I have reduced #ifdef ... #endif.

>> +#ifdef HAVE_X_WINDOWS
>> +void
>> +x_set_alpha (f, arg, oldval)
>> +     struct frame *f;
>> +     Lisp_Object arg, oldval;
>> +{
(snip)
>> +}
>> +#endif
>
> Explain why you do things twice.

This is because two kinds of frame opacity are set: one for an active  
frame (the frontmost frame), the other for inactive frames  
(background frames).

> Also, note the coding conventions we use and try to reproduce them.
> E.g. we place a space before open parentheses but no space after (and
> no space before the close parenthesis either).
>
I have modified the coding style.

>> +#ifdef HAVE_X_WINDOWS
>> +  /* Opacity of the Frame  */
>> +  double alpha[2];
>> +#endif
>
> The comment should describe what the field holds, so in this case it
> should describe *both* entries of the table.
>
Done.

> Also in the docstring, don't just use "alpha" but "alpha transparency"
> or something like that, for people who don't know what you mean by  
> "alpha".
>
>         Stefan


At present I call the parameters/variables "alpha" ('alpha, frame- 
alpha-lower-limit, x_set_frame_alpha, etc.) similar to Meadow.  If  
"alpha" is ambiguous, we can rename them to "opacity" etc.


[-- Attachment #2: transparency4-x23.patch --]
[-- Type: application/octet-stream, Size: 7951 bytes --]

diff -Naur emacs.orig/src/frame.c emacs/src/frame.c
--- emacs.orig/src/frame.c	2008-02-11 23:03:16.000000000 -0500
+++ emacs/src/frame.c	2008-03-14 22:53:51.000000000 -0400
@@ -67,6 +67,10 @@
 
 Lisp_Object Vx_resource_class;
 
+/* Lower limit value of the frame opacity (alpha transparency).  */
+
+Lisp_Object Vframe_alpha_lower_limit;
+
 #endif
 
 Lisp_Object Qframep, Qframe_live_p;
@@ -117,6 +121,7 @@
 Lisp_Object Qtty, Qtty_type;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
+Lisp_Object Qalpha;
 #ifdef USE_FONT_BACKEND
 Lisp_Object Qfont_backend;
 #endif	/* USE_FONT_BACKEND */
@@ -2855,6 +2860,7 @@
   {"right-fringe",		&Qright_fringe},
   {"wait-for-wm",		&Qwait_for_wm},
   {"fullscreen",                &Qfullscreen},
+  {"alpha",			&Qalpha},
 #ifdef USE_FONT_BACKEND
   {"font-backend",		&Qfont_backend}
 #endif	/* USE_FONT_BACKEND */
@@ -3699,6 +3705,61 @@
     return Qnil;
 }
 
+void
+x_set_alpha (f, arg, oldval)
+     struct frame *f;
+     Lisp_Object arg, oldval;
+{
+  double alpha = 1.0;
+  double newval[2];
+  int i, ialpha;
+  Lisp_Object item;
+
+  for (i=0;i<2;i++)
+    {
+      newval[i] = 1.0;
+      if (CONSP (arg))
+        {
+          item = CAR (arg);
+          arg  = CDR (arg);
+        }
+      else
+        item=arg;
+
+      if (!NILP (item))
+        {
+          if (FLOATP (item))
+            {
+              alpha = XFLOAT_DATA (item);
+              if (alpha < 0.0 || 1.0 < alpha)
+                args_out_of_range (make_float (0.0), make_float (1.0));
+            }
+          else if (INTEGERP (item))
+            {
+              ialpha = XINT (item);
+              if (ialpha < 0 || 100 < ialpha)
+                args_out_of_range (make_number (0), make_number (100));
+              else
+                alpha = ialpha / 100.0;
+            }
+          else
+            wrong_type_argument (Qnumberp, item);
+        }
+      newval[i] = alpha;
+    }
+
+  for (i=0;i<2;i++)
+    f->alpha[i] = newval[i];
+
+#ifdef HAVE_X_WINDOWS
+  BLOCK_INPUT;
+  x_set_frame_alpha (f);
+  UNBLOCK_INPUT;
+#endif
+
+  return;
+}
+
 \f
 /* Subroutines of creating an X frame.  */
 
@@ -4468,6 +4527,13 @@
 but binding this variable locally around a call to `x-get-resource'
 is a reasonable practice.  See also the variable `x-resource-name'.  */);
   Vx_resource_class = build_string (EMACS_CLASS);
+
+  DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
+    doc: /* The lower limit of the frame opacity (alpha transparency).
+The value should range from 0 (invisible) to 100 (completely opaque).
+The user can also use a floating number between 0.0 and 1.0.
+The default is 20.  */);
+  Vframe_alpha_lower_limit = make_number (20);
 #endif
 
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
diff -Naur emacs.orig/src/frame.h emacs/src/frame.h
--- emacs.orig/src/frame.h	2008-02-22 12:42:08.000000000 -0500
+++ emacs/src/frame.h	2008-03-14 22:53:02.000000000 -0400
@@ -204,6 +204,11 @@
      be used for output.  */
   unsigned glyphs_initialized_p : 1;
 
+  /* frame opacity
+     alpha[0]: alpha transparency of the active frame
+     alpha[1]: alpha transparency of inactive frames   */
+  double alpha[2];
+
   /* Set to non-zero in change_frame_size when size of frame changed
      Clear the frame in clear_garbaged_frames if set.  */
   unsigned resized_p : 1;
@@ -1020,6 +1025,7 @@
 extern Lisp_Object Qline_spacing;
 extern Lisp_Object Qwait_for_wm;
 extern Lisp_Object Qfullscreen;
+extern Lisp_Object Qalpha;
 extern Lisp_Object Qfont_backend;
 
 extern Lisp_Object Qleft_fringe, Qright_fringe;
@@ -1100,6 +1106,8 @@
 
 extern int x_figure_window_size P_ ((struct frame *, Lisp_Object, int));
 
+extern Lisp_Object Vframe_alpha_lower_limit;
+extern void x_set_alpha P_ ((struct frame *, Lisp_Object, Lisp_Object));
 
 extern void validate_x_resource_name P_ ((void));
 
diff -Naur emacs.orig/src/macfns.c emacs/src/macfns.c
--- emacs.orig/src/macfns.c	2008-02-22 12:42:08.000000000 -0500
+++ emacs/src/macfns.c	2008-03-14 22:53:02.000000000 -0400
@@ -4680,6 +4680,7 @@
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
+  0, /* x_set_alpha, */
 };
 
 void
diff -Naur emacs.orig/src/w32fns.c emacs/src/w32fns.c
--- emacs.orig/src/w32fns.c	2008-03-01 05:02:23.000000000 -0500
+++ emacs/src/w32fns.c	2008-03-14 22:53:02.000000000 -0400
@@ -8854,6 +8854,7 @@
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
+  0, /* x_set_alpha, */
 #ifdef USE_FONT_BACKEND
   x_set_font_backend
 #endif
diff -Naur emacs.orig/src/xfns.c emacs/src/xfns.c
--- emacs.orig/src/xfns.c	2008-02-22 12:42:05.000000000 -0500
+++ emacs/src/xfns.c	2008-03-14 22:53:02.000000000 -0400
@@ -3578,6 +3578,8 @@
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
 		       "scrollBarWidth", "ScrollBarWidth",
 		       RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qalpha, Qnil,
+		       "alpha", "Alpha", RES_TYPE_NUMBER);
 
   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
      Change will not be effected unless different from the current
@@ -5991,6 +5993,7 @@
   x_set_fringe_width,
   x_set_wait_for_wm,
   x_set_fullscreen,
+  x_set_alpha,
 #ifdef USE_FONT_BACKEND
   x_set_font_backend
 #endif	/* USE_FONT_BACKEND */
diff -Naur emacs.orig/src/xterm.c emacs/src/xterm.c
--- emacs.orig/src/xterm.c	2008-03-11 11:54:05.000000000 -0400
+++ emacs/src/xterm.c	2008-03-14 22:53:02.000000000 -0400
@@ -1018,6 +1018,67 @@
   return FONT_TYPE_UNKNOWN;
 }
 
+#define OPAQUE  0xffffffff
+#define OPACITY "_NET_WM_WINDOW_OPACITY"
+
+void
+x_set_frame_alpha (f)
+     struct frame *f;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display *dpy = FRAME_X_DISPLAY (f);
+  Window win = FRAME_OUTER_WINDOW (f);
+  if (FRAME_X_DISPLAY_INFO (f)->root_window != FRAME_X_OUTPUT (f)->parent_desc)
+    /* Since the WM decoration lies under the FRAME_OUTER_WINDOW,
+       we must treat the former instead of the latter. */
+    win = FRAME_X_OUTPUT(f)->parent_desc;
+
+  double alpha = 1.0, alpha_min = 1.0;
+
+  if (dpyinfo->x_highlight_frame == f)
+    alpha = f->alpha[0];
+  else
+    alpha = f->alpha[1];
+
+  if (FLOATP (Vframe_alpha_lower_limit))
+    alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+  else if (INTEGERP (Vframe_alpha_lower_limit))
+    alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
+
+  if (alpha < 0.0 || 1.0 < alpha)
+    alpha = 1.0;
+  else if (0.0 <= alpha && alpha < alpha_min && alpha_min < 1.0)
+    alpha = alpha_min;
+
+  unsigned int opac = (unsigned int)(alpha * OPAQUE);
+
+  /* return unless necessary */
+  {
+    unsigned char *data;
+    Atom actual;
+    int format;
+    unsigned long n, left;
+
+    XGetWindowProperty(dpy, win, XInternAtom(dpy, OPACITY, False),
+		       0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left,
+		       (unsigned char **) &data);
+    if (data != None)
+      if (*(unsigned int *)data == opac)
+	{
+	  XFree ((void *) data);
+	  return;
+	}
+      else
+       {
+	  XFree ((void *) data);
+       }
+  }
+
+  XChangeProperty (dpy, win, XInternAtom (dpy, OPACITY, False),
+		   XA_CARDINAL, 32, PropModeReplace,
+		   (unsigned char *) &opac, 1L);
+  XSync (dpy, False);
+}
 
 \f
 /***********************************************************************
@@ -3468,6 +3529,7 @@
 		    f->output_data.x->border_pixel);
   UNBLOCK_INPUT;
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 static void
@@ -3483,6 +3545,7 @@
 			  f->output_data.x->border_tile);
   UNBLOCK_INPUT;
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 /* The focus has changed.  Update the frames as necessary to reflect

[-- Attachment #3: Type: text/plain, Size: 271 bytes --]



P.S.
Meadow has four settings for the frame opacity: (1) active frame, (2)  
inactive frames, (3) moving frame, and (4) resizing frame.
e.g. (set-frame-parameter (selected-frame) 'alpha '(<active>  
[<inactive> [<moving> [sizing]]]))


Seiji Zenitani
zenitani@mac.com


  parent reply	other threads:[~2008-03-15 19:54 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-14 11:02 new frame-parameter "alpha" Seiji Zenitani
2008-03-14 18:28 ` Stefan Monnier
2008-03-15  2:41   ` David De La Harpe Golden
2008-03-15 20:22     ` Seiji Zenitani
2008-03-15 20:53       ` David De La Harpe Golden
2008-03-15 19:54   ` Seiji Zenitani [this message]
2008-03-15 21:19     ` Stefan Monnier
2008-03-18 20:11       ` Brian Cully
2008-03-19  5:55         ` Seiji Zenitani
2008-03-19 20:23           ` David De La Harpe Golden
2008-03-26  0:46             ` Seiji Zenitani
2008-03-19  5:51       ` Seiji Zenitani
2008-03-19 16:16         ` Stefan Monnier
2008-03-20 22:47           ` Seiji Zenitani
2008-03-24 19:26             ` Stefan Monnier
2008-04-29  3:12             ` Seiji Zenitani
2008-04-29  7:13               ` Glenn Morris
2008-05-02 15:09               ` Stefan Monnier
2008-03-20 15:22 ` Ken Raeburn
2008-03-20 22:53   ` Seiji Zenitani
  -- strict thread matches above, loose matches on Subject: below --
2008-04-05 17:21 Seiji Zenitani
2008-05-02 20:37 Seiji Zenitani
2008-05-13 20:29 ` Stefan Monnier
2008-05-14 16:16   ` Seiji Zenitani
     [not found] <EEC622D2-0119-1000-F1CB-50016375E1D3-Webmail-10013@mac.com>
2008-05-15  3:56 ` Seiji Zenitani

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D654D617-DFF5-4ABB-A209-A1B43D650AB6@mac.com \
    --to=zenitani@mac.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.