diff options
| author | Po Lu | 2022-05-12 09:36:43 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-12 09:37:33 +0800 |
| commit | 2dc996a95dce3435ff50017bfc4e3a7609e594df (patch) | |
| tree | e3036fde54c7910e6cceb274372a295d3afe62e1 /src | |
| parent | 0d0dc1af591c2cb687462e88631561fbf2690ba4 (diff) | |
| download | emacs-2dc996a95dce3435ff50017bfc4e3a7609e594df.tar.gz emacs-2dc996a95dce3435ff50017bfc4e3a7609e594df.zip | |
Port some stuff to XCB to avoid confusing Xlib behavior
* src/xterm.c (x_set_frame_alpha, handle_one_xevent): Port
retrieving the opacity property to XCB.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 102 |
1 files changed, 96 insertions, 6 deletions
diff --git a/src/xterm.c b/src/xterm.c index 1c2b727c0f8..5c5de191dcc 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -5310,6 +5310,20 @@ x_set_frame_alpha (struct frame *f) | |||
| 5310 | unsigned long opac; | 5310 | unsigned long opac; |
| 5311 | Window parent; | 5311 | Window parent; |
| 5312 | 5312 | ||
| 5313 | #ifndef USE_XCB | ||
| 5314 | unsigned char *data = NULL; | ||
| 5315 | Atom actual; | ||
| 5316 | int rc, format; | ||
| 5317 | unsigned long n, left; | ||
| 5318 | unsigned long value; | ||
| 5319 | #else | ||
| 5320 | xcb_get_property_cookie_t opacity_cookie; | ||
| 5321 | xcb_get_property_reply_t *opacity_reply; | ||
| 5322 | xcb_generic_error_t *error; | ||
| 5323 | bool rc; | ||
| 5324 | uint32_t value; | ||
| 5325 | #endif | ||
| 5326 | |||
| 5313 | if (dpyinfo->highlight_frame == f) | 5327 | if (dpyinfo->highlight_frame == f) |
| 5314 | alpha = f->alpha[0]; | 5328 | alpha = f->alpha[0]; |
| 5315 | else | 5329 | else |
| @@ -5348,11 +5362,7 @@ x_set_frame_alpha (struct frame *f) | |||
| 5348 | 5362 | ||
| 5349 | /* return unless necessary */ | 5363 | /* return unless necessary */ |
| 5350 | { | 5364 | { |
| 5351 | unsigned char *data = NULL; | 5365 | #ifndef USE_XCB |
| 5352 | Atom actual; | ||
| 5353 | int rc, format; | ||
| 5354 | unsigned long n, left; | ||
| 5355 | |||
| 5356 | rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, | 5366 | rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, |
| 5357 | 0, 1, False, XA_CARDINAL, | 5367 | 0, 1, False, XA_CARDINAL, |
| 5358 | &actual, &format, &n, &left, | 5368 | &actual, &format, &n, &left, |
| @@ -5361,7 +5371,7 @@ x_set_frame_alpha (struct frame *f) | |||
| 5361 | if (rc == Success && actual != None | 5371 | if (rc == Success && actual != None |
| 5362 | && n && format == XA_CARDINAL && data) | 5372 | && n && format == XA_CARDINAL && data) |
| 5363 | { | 5373 | { |
| 5364 | unsigned long value = *(unsigned long *) data; | 5374 | value = *(unsigned long *) data; |
| 5365 | 5375 | ||
| 5366 | /* Xlib sign-extends values greater than 0x7fffffff on 64-bit | 5376 | /* Xlib sign-extends values greater than 0x7fffffff on 64-bit |
| 5367 | machines. Get the low bits by ourself. */ | 5377 | machines. Get the low bits by ourself. */ |
| @@ -5378,6 +5388,37 @@ x_set_frame_alpha (struct frame *f) | |||
| 5378 | 5388 | ||
| 5379 | if (data) | 5389 | if (data) |
| 5380 | XFree (data); | 5390 | XFree (data); |
| 5391 | #else | ||
| 5392 | /* Avoid the confusing Xlib sign-extension mess by using XCB | ||
| 5393 | instead. */ | ||
| 5394 | opacity_cookie | ||
| 5395 | = xcb_get_property (dpyinfo->xcb_connection, 0, (xcb_window_t) win, | ||
| 5396 | (xcb_atom_t) dpyinfo->Xatom_net_wm_window_opacity, | ||
| 5397 | XCB_ATOM_CARDINAL, 0, 1); | ||
| 5398 | opacity_reply | ||
| 5399 | = xcb_get_property_reply (dpyinfo->xcb_connection, | ||
| 5400 | opacity_cookie, &error); | ||
| 5401 | |||
| 5402 | rc = opacity_reply; | ||
| 5403 | |||
| 5404 | if (!opacity_reply) | ||
| 5405 | free (error); | ||
| 5406 | else | ||
| 5407 | { | ||
| 5408 | rc = (opacity_reply->format == 32 | ||
| 5409 | && opacity_reply->type == XCB_ATOM_CARDINAL | ||
| 5410 | && (xcb_get_property_value_length (opacity_reply) >= 4)); | ||
| 5411 | |||
| 5412 | if (rc) | ||
| 5413 | value = *(uint32_t *) xcb_get_property_value (opacity_reply); | ||
| 5414 | } | ||
| 5415 | |||
| 5416 | if (opacity_reply) | ||
| 5417 | free (opacity_reply); | ||
| 5418 | |||
| 5419 | if (rc && value == opac) | ||
| 5420 | return; | ||
| 5421 | #endif | ||
| 5381 | } | 5422 | } |
| 5382 | 5423 | ||
| 5383 | XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, | 5424 | XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, |
| @@ -14924,12 +14965,20 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14924 | && (event->xproperty.atom | 14965 | && (event->xproperty.atom |
| 14925 | == dpyinfo->Xatom_net_wm_window_opacity)) | 14966 | == dpyinfo->Xatom_net_wm_window_opacity)) |
| 14926 | { | 14967 | { |
| 14968 | #ifndef USE_XCB | ||
| 14927 | int rc, actual_format; | 14969 | int rc, actual_format; |
| 14928 | Atom actual; | 14970 | Atom actual; |
| 14929 | unsigned char *tmp_data; | 14971 | unsigned char *tmp_data; |
| 14930 | unsigned long n, left, opacity; | 14972 | unsigned long n, left, opacity; |
| 14931 | 14973 | ||
| 14932 | tmp_data = NULL; | 14974 | tmp_data = NULL; |
| 14975 | #else | ||
| 14976 | xcb_get_property_cookie_t opacity_cookie; | ||
| 14977 | xcb_get_property_reply_t *opacity_reply; | ||
| 14978 | xcb_generic_error_t *error; | ||
| 14979 | bool rc; | ||
| 14980 | uint32_t value; | ||
| 14981 | #endif | ||
| 14933 | 14982 | ||
| 14934 | if (event->xproperty.state == PropertyDelete) | 14983 | if (event->xproperty.state == PropertyDelete) |
| 14935 | { | 14984 | { |
| @@ -14940,6 +14989,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14940 | } | 14989 | } |
| 14941 | else | 14990 | else |
| 14942 | { | 14991 | { |
| 14992 | #ifndef USE_XCB | ||
| 14943 | rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f), | 14993 | rc = XGetWindowProperty (dpyinfo->display, FRAME_OUTER_WINDOW (f), |
| 14944 | dpyinfo->Xatom_net_wm_window_opacity, | 14994 | dpyinfo->Xatom_net_wm_window_opacity, |
| 14945 | 0, 1, False, AnyPropertyType, &actual, | 14995 | 0, 1, False, AnyPropertyType, &actual, |
| @@ -14966,10 +15016,50 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 14966 | 15016 | ||
| 14967 | store_frame_param (f, Qalpha, Qnil); | 15017 | store_frame_param (f, Qalpha, Qnil); |
| 14968 | } | 15018 | } |
| 15019 | #else | ||
| 15020 | opacity_cookie | ||
| 15021 | = xcb_get_property (dpyinfo->xcb_connection, 0, | ||
| 15022 | (xcb_window_t) FRAME_OUTER_WINDOW (f), | ||
| 15023 | (xcb_atom_t) dpyinfo->Xatom_net_wm_window_opacity, | ||
| 15024 | XCB_ATOM_CARDINAL, 0, 1); | ||
| 15025 | opacity_reply | ||
| 15026 | = xcb_get_property_reply (dpyinfo->xcb_connection, | ||
| 15027 | opacity_cookie, &error); | ||
| 15028 | |||
| 15029 | if (!opacity_reply) | ||
| 15030 | free (error), rc = false; | ||
| 15031 | else | ||
| 15032 | rc = (opacity_reply->format == 32 | ||
| 15033 | && (opacity_reply->type == XCB_ATOM_CARDINAL | ||
| 15034 | || opacity_reply->type == XCB_ATOM_ATOM | ||
| 15035 | || opacity_reply->type == XCB_ATOM_WINDOW) | ||
| 15036 | && (xcb_get_property_value_length (opacity_reply) >= 4)); | ||
| 15037 | |||
| 15038 | if (rc) | ||
| 15039 | { | ||
| 15040 | value = *(uint32_t *) xcb_get_property_value (opacity_reply); | ||
| 15041 | |||
| 15042 | f->alpha[0] = (double) value / (double) OPAQUE; | ||
| 15043 | f->alpha[1] = (double) value / (double) OPAQUE; | ||
| 15044 | store_frame_param (f, Qalpha, make_float (f->alpha[0])); | ||
| 15045 | } | ||
| 15046 | else | ||
| 15047 | { | ||
| 15048 | f->alpha[0] = 1.0; | ||
| 15049 | f->alpha[1] = 1.0; | ||
| 15050 | |||
| 15051 | store_frame_param (f, Qalpha, Qnil); | ||
| 15052 | } | ||
| 15053 | |||
| 15054 | if (opacity_reply) | ||
| 15055 | free (opacity_reply); | ||
| 15056 | #endif | ||
| 14969 | } | 15057 | } |
| 14970 | 15058 | ||
| 15059 | #ifndef USE_XCB | ||
| 14971 | if (tmp_data) | 15060 | if (tmp_data) |
| 14972 | XFree (tmp_data); | 15061 | XFree (tmp_data); |
| 15062 | #endif | ||
| 14973 | } | 15063 | } |
| 14974 | 15064 | ||
| 14975 | if (event->xproperty.window == dpyinfo->root_window | 15065 | if (event->xproperty.window == dpyinfo->root_window |