emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master b299f17349: Update alpha frame parameter when the window manager


From: Po Lu
Subject: master b299f17349: Update alpha frame parameter when the window manager changes it
Date: Mon, 9 May 2022 21:33:16 -0400 (EDT)

branch: master
commit b299f173490f5c51476ad3c8436b19bb091c1b00
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Update alpha frame parameter when the window manager changes it
    
    * src/xfns.c (x_set_alpha): New function.  Set
    `alpha_identical_p' flag.
    (x_frame_parm_handlers): Use it to handle `alpha' instead.
    
    * src/xterm.c (x_set_frame_alpha): Make tests against current
    alpha safer.
    (handle_one_xevent): Set frame alpha when alpha property
    changes.
    * src/xterm.h (struct x_output): New flag `alpha_identical_p'.
---
 src/xfns.c  | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/xterm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
 src/xterm.h |  4 ++++
 3 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index dc8f02780c..7dbf1e16c3 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2372,6 +2372,63 @@ x_set_scroll_bar_default_height (struct frame *f)
 #endif
 }
 
+static void
+x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+  double alpha = 1.0;
+  double newval[2];
+  int i;
+  Lisp_Object item;
+  bool alpha_identical_p;
+
+  alpha_identical_p = true;
+
+  for (i = 0; i < 2; i++)
+    {
+      newval[i] = 1.0;
+      if (CONSP (arg))
+        {
+          item = CAR (arg);
+          arg  = CDR (arg);
+
+         alpha_identical_p = false;
+        }
+      else
+        item = arg;
+
+      if (NILP (item))
+       alpha = - 1.0;
+      else if (FLOATP (item))
+       {
+         alpha = XFLOAT_DATA (item);
+         if (! (0 <= alpha && alpha <= 1.0))
+           args_out_of_range (make_float (0.0), make_float (1.0));
+       }
+      else if (FIXNUMP (item))
+       {
+         EMACS_INT ialpha = XFIXNUM (item);
+         if (! (0 <= ialpha && ialpha <= 100))
+           args_out_of_range (make_fixnum (0), make_fixnum (100));
+         alpha = ialpha / 100.0;
+       }
+      else
+       wrong_type_argument (Qnumberp, item);
+      newval[i] = alpha;
+    }
+
+  for (i = 0; i < 2; i++)
+    f->alpha[i] = newval[i];
+
+  FRAME_X_OUTPUT (f)->alpha_identical_p = alpha_identical_p;
+
+  if (FRAME_TERMINAL (f)->set_frame_alpha_hook)
+    {
+      block_input ();
+      FRAME_TERMINAL (f)->set_frame_alpha_hook (f);
+      unblock_input ();
+    }
+}
+
 
 /* Record in frame F the specified or default value according to ALIST
    of the parameter named PROP (a Lisp symbol).  If no value is
@@ -9368,7 +9425,7 @@ frame_parm_handler x_frame_parm_handlers[] =
   x_set_wait_for_wm,
   gui_set_fullscreen,
   gui_set_font_backend,
-  gui_set_alpha,
+  x_set_alpha,
   x_set_sticky,
   x_set_tool_bar_position,
 #ifdef HAVE_XDBE
diff --git a/src/xterm.c b/src/xterm.c
index 10d268dc93..de3129fd87 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5358,9 +5358,16 @@ x_set_frame_alpha (struct frame *f)
                             &actual, &format, &n, &left,
                             &data);
 
-    if (rc == Success && actual != None && data)
+    if (rc == Success && actual != None
+       && n && format == XA_CARDINAL && data)
       {
         unsigned long value = *(unsigned long *) data;
+
+       /* Xlib sign-extends values greater than 0x7fffffff on 64-bit
+          machines.  Get the low bits by ourself.  */
+
+       value &= 0xffffffff;
+
        if (value == opac)
          {
            x_uncatch_errors ();
@@ -14746,7 +14753,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                  unsigned long nitems, bytesafter;
                  unsigned char *data = NULL;
 
-
                  if (event->xproperty.state == PropertyDelete)
                    {
                      if (!last)
@@ -14835,6 +14841,44 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            }
        }
 
+      if (f && FRAME_X_OUTPUT (f)->alpha_identical_p
+         && (event->xproperty.atom
+             == dpyinfo->Xatom_net_wm_window_opacity))
+       {
+         int rc, actual_format;
+         Atom actual;
+         unsigned char *tmp_data;
+         unsigned long n, left, opacity;
+
+         tmp_data = NULL;
+
+         if (event->xproperty.state == PropertyDelete)
+           {
+             f->alpha[0] = 1.0;
+             f->alpha[1] = 1.0;
+           }
+         else
+           {
+             rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f),
+                                      dpyinfo->Xatom_net_wm_window_opacity,
+                                      0, 1, False, XA_CARDINAL, &actual,
+                                      &actual_format, &n, &left, &tmp_data);
+
+             if (rc == Success && actual_format == 32
+                 && actual == XA_CARDINAL && n)
+               {
+                 opacity = *(unsigned long *) tmp_data & OPAQUE;
+                 f->alpha[0] = (double) opacity / (double) OPAQUE;
+                 f->alpha[1] = (double) opacity / (double) OPAQUE;
+
+                 store_frame_param (f, Qalpha, make_float (f->alpha[0]));
+               }
+           }
+
+         if (tmp_data)
+           XFree (tmp_data);
+       }
+
       if (event->xproperty.window == dpyinfo->root_window
          && (event->xproperty.atom == dpyinfo->Xatom_net_client_list_stacking
              || event->xproperty.atom == dpyinfo->Xatom_net_current_desktop)
diff --git a/src/xterm.h b/src/xterm.h
index 16635053be..98c4c5f01c 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -932,6 +932,10 @@ struct x_output
      false, tell Xt not to wait.  */
   bool_bf wait_for_wm : 1;
 
+  /* True if this frame's alpha value is the same for both the active
+     and inactive states.  */
+  bool_bf alpha_identical_p : 1;
+
 #ifdef HAVE_X_I18N
   /* Input context (currently, this means Compose key handler setup).  */
   XIC xic;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]