]> git.eshelyaron.com Git - emacs.git/commitdiff
Update alpha frame parameter when the window manager changes it
authorPo Lu <luangruo@yahoo.com>
Tue, 10 May 2022 01:32:59 +0000 (09:32 +0800)
committerPo Lu <luangruo@yahoo.com>
Tue, 10 May 2022 01:32:59 +0000 (09:32 +0800)
* 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
src/xterm.c
src/xterm.h

index dc8f02780ce5755c0de062ffbb0538b946e69ed9..7dbf1e16c3a93978d63da665dd52cbbd7835f8e2 100644 (file)
@@ -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 ();
+    }
+}
+
 \f
 /* 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
index 10d268dc93f0d47fc1da05c119d8f0ce0c8e0280..de3129fd87c961eb47e353691abfea69b88b6e79 100644 (file)
@@ -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)
index 16635053be490ce4adc23865ee425038c6aee32c..98c4c5f01c6f16054e4d9b02554ca66a7d87aeb8 100644 (file)
@@ -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;