unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* new frame-parameter "alpha"
@ 2008-03-14 11:02 Seiji Zenitani
  2008-03-14 18:28 ` Stefan Monnier
  2008-03-20 15:22 ` Ken Raeburn
  0 siblings, 2 replies; 25+ messages in thread
From: Seiji Zenitani @ 2008-03-14 11:02 UTC (permalink / raw)
  To: emacs-devel

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

Hi,

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.


Tested on:

* Emacs 23.0.60 (CVS 2008-03-13; i686-pc-linux-gnu, GTK+ Version 2.12.0)
* Ubuntu Linux 7.10
* It may not work on older X11 systems (X11R6.x)

Elisp syntax:
We can use both a floating point number (0.0-1.0) as well as an  
integer number (0-100).

(set-frame-parameter nil 'alpha 80)
(set-frame-parameter nil 'alpha 0.8)
(set-frame-parameter nil 'alpha '(<active> [<inactive>]))
(set-frame-parameter nil 'alpha '(100 70))
(set-frame-parameter nil 'alpha '(nil 70))
(set-frame-parameter nil 'alpha '(0.8 nil))
(set-frame-parameter nil 'alpha nil) ;; nil = default = opaque
(set-alpha 80)
(set-alpha 0.8)
(set-alpha '(100 0.7))
(set-alpha nil)
(setq frame-alpha-lower-limit 20)
(setq frame-alpha-lower-limit 0.2)


Contributors:

* Ryo Yoshitake (frame parameter code, x_set_frame_alpha function)
* Seiji Zenitani (x_set_alpha function)
* Meadow devel team (the original version of x_set_alpha function)
* Takashi Hiromatsu (the author of the initial version)
* Yoichi Nakayama (minor improvement to x_set_frame_alpha function)


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

diff -Naur emacs.orig/lisp/frame.el emacs.new/lisp/frame.el
--- emacs.orig/lisp/frame.el	2008-02-14 16:16:36.000000000 -0500
+++ emacs.new/lisp/frame.el	2008-03-13 07:10:40.000000000 -0400
@@ -1079,6 +1079,17 @@
   (modify-frame-parameters (selected-frame)
 			   (list (cons 'border-color color-name))))
 
+  (defun set-alpha (alpha &optional frame)
+    "Set the opacity of FRAME to ALPHA.  First argument ALPHA 
+should range from 0 (invisible) to 100 (completely opaque).
+You can also use an floating point number 0.0 to 1.0.
+When called interactively, prompt for the value of the opacity to set.
+FRAME defaults to the selected frame.  To get the frame's current
+alpha value state, use `frame-parameters'."
+    (interactive "XWindow Opacity (0-100 or 0.0-1.0) : ")
+    (modify-frame-parameters frame
+                             (list (cons 'alpha alpha))))
+
 (defun auto-raise-mode (arg)
   "Toggle whether or not the selected frame should auto-raise.
 With arg, turn auto-raise mode on if and only if arg is positive.
diff -Naur emacs.orig/src/frame.c emacs.new/src/frame.c
--- emacs.orig/src/frame.c	2008-02-11 23:03:16.000000000 -0500
+++ emacs.new/src/frame.c	2008-03-13 07:10:40.000000000 -0400
@@ -67,6 +67,12 @@
 
 Lisp_Object Vx_resource_class;
 
+#ifdef HAVE_X_WINDOWS
+/* Lower limit value of frame transparency.  */
+
+Lisp_Object Vframe_alpha_lower_limit;
+#endif
+
 #endif
 
 Lisp_Object Qframep, Qframe_live_p;
@@ -120,6 +126,9 @@
 #ifdef USE_FONT_BACKEND
 Lisp_Object Qfont_backend;
 #endif	/* USE_FONT_BACKEND */
+#ifdef HAVE_X_WINDOWS
+Lisp_Object Qalpha;
+#endif
 
 Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
@@ -2855,6 +2864,9 @@
   {"right-fringe",		&Qright_fringe},
   {"wait-for-wm",		&Qwait_for_wm},
   {"fullscreen",                &Qfullscreen},
+#ifdef HAVE_X_WINDOWS
+  {"alpha",			 &Qalpha},
+#endif
 #ifdef USE_FONT_BACKEND
   {"font-backend",		&Qfont_backend}
 #endif	/* USE_FONT_BACKEND */
@@ -3699,6 +3711,63 @@
     return Qnil;
 }
 
+#ifdef HAVE_X_WINDOWS
+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;
+
+  for( i=0; i<2; i++ )
+    {
+      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];
+
+  BLOCK_INPUT;
+  x_set_frame_alpha (f);
+  UNBLOCK_INPUT;
+
+  return;
+}
+#endif
+
 \f
 /* Subroutines of creating an X frame.  */
 
@@ -4468,6 +4537,12 @@
 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);
+
+#ifdef HAVE_X_WINDOWS
+  DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
+    doc: /* Lower limit of alpha value of frame.  */);
+  Vframe_alpha_lower_limit = make_number (20);
+#endif
 #endif
 
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
diff -Naur emacs.orig/src/frame.h emacs.new/src/frame.h
--- emacs.orig/src/frame.h	2008-02-22 12:42:08.000000000 -0500
+++ emacs.new/src/frame.h	2008-03-13 07:10:40.000000000 -0400
@@ -204,6 +204,11 @@
      be used for output.  */
   unsigned glyphs_initialized_p : 1;
 
+#ifdef HAVE_X_WINDOWS
+  /* Opacity of the Frame  */
+  double alpha[2];
+#endif
+
   /* 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;
@@ -1021,6 +1026,9 @@
 extern Lisp_Object Qwait_for_wm;
 extern Lisp_Object Qfullscreen;
 extern Lisp_Object Qfont_backend;
+#ifdef HAVE_X_WINDOWS
+extern Lisp_Object Qalpha;
+#endif
 
 extern Lisp_Object Qleft_fringe, Qright_fringe;
 extern Lisp_Object Qheight, Qwidth;
@@ -1100,6 +1108,10 @@
 
 extern int x_figure_window_size P_ ((struct frame *, Lisp_Object, int));
 
+#if defined (HAVE_X_WINDOWS) || defined (HAVE_CARBON)
+extern Lisp_Object Vframe_alpha_lower_limit;
+extern void x_set_alpha P_ ((struct frame *, Lisp_Object, Lisp_Object));
+#endif
 
 extern void validate_x_resource_name P_ ((void));
 
diff -Naur emacs.orig/src/xfns.c emacs.new/src/xfns.c
--- emacs.orig/src/xfns.c	2008-02-22 12:42:05.000000000 -0500
+++ emacs.new/src/xfns.c	2008-03-13 07:10:40.000000000 -0400
@@ -585,6 +585,8 @@
 							     Lisp_Object,
 							     char *, char *,
 							     int));
+extern void x_set_frame_alpha P_ ((struct frame *));
+
 \f
 
 /* Store the screen positions of frame F into XPTR and YPTR.
@@ -3578,6 +3580,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 +5995,9 @@
   x_set_fringe_width,
   x_set_wait_for_wm,
   x_set_fullscreen,
+#ifdef HAVE_X_WINDOWS
+   x_set_alpha,
+#endif
 #ifdef USE_FONT_BACKEND
   x_set_font_backend
 #endif	/* USE_FONT_BACKEND */
diff -Naur emacs.orig/src/xterm.c emacs.new/src/xterm.c
--- emacs.orig/src/xterm.c	2008-03-11 11:54:05.000000000 -0400
+++ emacs.new/src/xterm.c	2008-03-13 07:10:40.000000000 -0400
@@ -1018,6 +1018,66 @@
   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_lower_limit = 1.0;
+
+  if (dpyinfo->x_highlight_frame == f)
+    alpha = f->alpha[0];
+  else
+    alpha = f->alpha[1];
+
+  if( FLOATP(Vframe_alpha_lower_limit) )
+    alpha_lower_limit = XFLOAT_DATA (Vframe_alpha_lower_limit);
+  else if( INTEGERP(Vframe_alpha_lower_limit) )
+    alpha_lower_limit = ( XINT (Vframe_alpha_lower_limit) ) / 100.0;
+
+  if( alpha < 0.0 || 1.0 < alpha ) alpha = 1.0;
+  if ( 0.0 <= alpha && alpha < alpha_lower_limit && alpha_lower_limit < 1.0)
+    alpha = alpha_lower_limit;
+
+  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 +3528,7 @@
 		    f->output_data.x->border_pixel);
   UNBLOCK_INPUT;
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 static void
@@ -3483,6 +3544,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: 38 bytes --]



==
Seiji Zenitani
zenitani@mac.com


^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: new frame-parameter "alpha"
@ 2008-04-05 17:21 Seiji Zenitani
  0 siblings, 0 replies; 25+ messages in thread
From: Seiji Zenitani @ 2008-04-05 17:21 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

On 2008/03/24, at 15:26, Stefan Monnier wrote:
>> In order to make sure, I extracted
>> the relevant lines which I ported from Meadow to GNU Emacs.
>> Let me know if there are any problems.
>
> This looks fine.  Just make sure the original author is happy to  
> see his
> code used in Emacs, and then we can include it as a (tiny change).
> Note that if we may later include more of his code, it may be worth it
> to ask him to sign the relevant paperwork (i.e. send him the same form
> as you sent to Ryo Yoshitake), but we don't have to wait for this
> paperwork before installing the change.

I wrote to the original author twice, but I've got no response.

Seiji





^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: new frame-parameter "alpha"
@ 2008-05-02 20:37 Seiji Zenitani
  2008-05-13 20:29 ` Stefan Monnier
  0 siblings, 1 reply; 25+ messages in thread
From: Seiji Zenitani @ 2008-05-02 20:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: YOSHITAKE Ryo, emacs-devel

Yoshitake-san sent the paper in early April.
Could you send another paper to him?

Seiji

On 2008/05/02, at 11:09, Stefan Monnier wrote:
> 
> > Did the FSF receive Ryo Yoshitake's paper?
> 
> It appears they haven't received them yet.
> 
> 
>        Stefan






^ permalink raw reply	[flat|nested] 25+ messages in thread
[parent not found: <EEC622D2-0119-1000-F1CB-50016375E1D3-Webmail-10013@mac.com>]

end of thread, other threads:[~2008-05-15  3:56 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).