summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-05-10 09:32:59 +0800
committerPo Lu <luangruo@yahoo.com>2022-05-10 09:32:59 +0800
commitb299f173490f5c51476ad3c8436b19bb091c1b00 (patch)
tree44b63675a726a6cb13854b4c20222e84b6062b11
parentb7167ba8d14ad722452c297e33ae5e496f17f72c (diff)
downloademacs-b299f173490f5c51476ad3c8436b19bb091c1b00.tar.gz
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'.
-rw-r--r--src/xfns.c59
-rw-r--r--src/xterm.c48
-rw-r--r--src/xterm.h4
3 files changed, 108 insertions, 3 deletions
diff --git a/src/xfns.c b/src/xfns.c
index dc8f02780ce..7dbf1e16c3a 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 10d268dc93f..de3129fd87c 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 16635053be4..98c4c5f01c6 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;