From: Po Lu Date: Sat, 19 Mar 2022 01:11:09 +0000 (+0800) Subject: Handle composite overlay window during drag and drop sessions X-Git-Tag: emacs-29.0.90~1931^2~1046 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1467b04f5cf586c0f44b7df00591986fa8d40c66;p=emacs.git Handle composite overlay window during drag and drop sessions * configure.ac: Test for the composite extension and use it if available. * msdos/sed1v2.inp: Update. * src/Makefile.in (XCOMPOSITE_LIBS, XCOMPOSITE_CFLAGS): New variables. (EMACS_CFLAGS, LIBES): Add new libs and cflags. * src/xterm.c (x_dnd_get_target_window): Look for proxy on composite overlay window if mapped. (x_term_init): Test if the composite extension is available. * src/xterm.h (struct x_display_info): New fields for composite extension presence. --- diff --git a/configure.ac b/configure.ac index bc17935eb13..6e637477334 100644 --- a/configure.ac +++ b/configure.ac @@ -4538,6 +4538,24 @@ fi AC_SUBST(XDBE_CFLAGS) AC_SUBST(XDBE_LIBS) +### Use Xcomposite (-lXcomposite) if available +HAVE_XCOMPOSITE=no +if test "${HAVE_X11}" = "yes"; then + AC_CHECK_HEADER(X11/extensions/Xcomposite.h, + [AC_CHECK_LIB(Xcomposite, XCompositeRedirectWindow, HAVE_XCOMPOSITE=yes)], + [], + [#include + ]) + if test $HAVE_XCOMPOSITE = yes; then + XCOMPOSITE_LIBS=-lXcomposite + fi + if test $HAVE_XCOMPOSITE = yes; then + AC_DEFINE(HAVE_XCOMPOSITE, 1, [Define to 1 if you have the XCOMPOSITE extension.]) + fi +fi +AC_SUBST(XCOMPOSITE_CFLAGS) +AC_SUBST(XCOMPOSITE_LIBS) + ### Use libxml (-lxml2) if available ### mingw32 doesn't use -lxml2, since it loads the library dynamically. HAVE_LIBXML2=no diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp index cc29ad02819..24ae079db1b 100644 --- a/msdos/sed1v2.inp +++ b/msdos/sed1v2.inp @@ -117,6 +117,8 @@ s/ *@WEBP_LIBS@// /^XFIXES_CFLAGS *=/s/@XFIXES_CFLAGS@// /^XDBE_LIBS *=/s/@XDBE_LIBS@// /^XDBE_CFLAGS *=/s/@XDBE_CFLAGS@// +/^XCOMPOSITE_LIBS *=/s/@XCOMPOSITE_LIBS@// +/^XCOMPOSITE_CFLAGS *=/s/@XCOMPOSITE_CFLAGS@// /^XINPUT_LIBS *=/s/@XINPUT_LIBS@// /^XINPUT_CFLAGS *=/s/@XINPUT_CFLAGS@// /^XSYNC_LIBS *=/s/@XSYNC_LIBS@// diff --git a/src/Makefile.in b/src/Makefile.in index 2b7c4bb316c..0ec2d342646 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -271,6 +271,9 @@ XSYNC_CFLAGS = @XSYNC_CFLAGS@ XDBE_LIBS = @XDBE_LIBS@ XDBE_CFLAGS = @XDBE_CFLAGS@ +XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@ +XCOMPOSITE_CFLAGS = @XCOMPOSITE_CFLAGS@ + ## widget.o if USE_X_TOOLKIT, otherwise empty. WIDGET_OBJ=@WIDGET_OBJ@ @@ -402,7 +405,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \ $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) \ $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \ - $(WERROR_CFLAGS) $(HAIKU_CFLAGS) + $(WERROR_CFLAGS) $(HAIKU_CFLAGS) $(XCOMPOSITE_CFLAGS) ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS) ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \ $(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \ @@ -559,7 +562,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(PGTK_LIBS) $(LIBX_BASE) $(LIBIMAGE $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS) \ - $(SQLITE3_LIBS) + $(SQLITE3_LIBS) $(XCOMPOSITE_LIBS) ## FORCE it so that admin/unidata can decide whether this file is ## up-to-date. Although since charprop depends on bootstrap-emacs, diff --git a/src/xterm.c b/src/xterm.c index f7047ff0e88..5c5f24e297d 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -542,6 +542,10 @@ along with GNU Emacs. If not, see . */ #include #endif +#ifdef HAVE_XCOMPOSITE +#include +#endif + /* Load sys/types.h if not already loaded. In some systems loading it twice is suicidal. */ #ifndef makedev @@ -817,6 +821,10 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, { Window child_return, child, dummy, proxy; int dest_x_return, dest_y_return, rc, proto; +#if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2) + Window overlay_window; + XWindowAttributes attrs; +#endif child_return = dpyinfo->root_window; dest_x_return = root_x; dest_y_return = root_y; @@ -853,7 +861,7 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, { *proto_out = proto; - x_uncatch_errors_after_check (); + x_uncatch_errors (); return proxy; } } @@ -865,7 +873,7 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, if (proto != -1) { *proto_out = proto; - x_uncatch_errors_after_check (); + x_uncatch_errors (); return child_return; } @@ -887,8 +895,49 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo, x_uncatch_errors_after_check (); } +#if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2) + if (child != dpyinfo->root_window) + { +#endif + *proto_out = x_dnd_get_window_proto (dpyinfo, child); + return child; +#if defined HAVE_XCOMPOSITE && (XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR > 2) + } + else if (dpyinfo->composite_supported_p + && (dpyinfo->composite_major > 0 + || dpyinfo->composite_minor > 2)) + { + /* Only do this if a compositing manager is present. */ + if (XGetSelectionOwner (dpyinfo->display, + dpyinfo->Xatom_NET_WM_CM_Sn) != None) + { + overlay_window = XCompositeGetOverlayWindow (dpyinfo->display, + dpyinfo->root_window); + XCompositeReleaseOverlayWindow (dpyinfo->display, + dpyinfo->root_window); + XGetWindowAttributes (dpyinfo->display, overlay_window, &attrs); + + if (attrs.map_state == IsViewable) + { + proxy = x_dnd_get_window_proxy (dpyinfo, overlay_window); + + if (proxy != None) + { + proto = x_dnd_get_window_proto (dpyinfo, proxy); + + if (proto != -1) + { + *proto_out = proto; + return proxy; + } + } + } + } + } + *proto_out = x_dnd_get_window_proto (dpyinfo, child); return child; +#endif } static Window @@ -17936,6 +17985,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) #ifdef USE_XCB xcb_connection_t *xcb_conn; #endif + char *cm_atom_sprintf; block_input (); @@ -18217,6 +18267,20 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) &dpyinfo->xrender_minor); #endif + /* This must come after XRenderQueryVersion! */ +#ifdef HAVE_XCOMPOSITE + int composite_event_base, composite_error_base; + dpyinfo->composite_supported_p = XCompositeQueryExtension (dpyinfo->display, + &composite_event_base, + &composite_error_base); + + if (dpyinfo->composite_supported_p) + dpyinfo->composite_supported_p + = XCompositeQueryVersion (dpyinfo->display, + &dpyinfo->composite_major, + &dpyinfo->composite_minor); +#endif + /* Put the rdb where we can find it in a way that works on all versions. */ dpyinfo->rdb = xrdb; @@ -18575,6 +18639,15 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) dpyinfo->resx = (mm < 1) ? 100 : pixels * 25.4 / mm; } + { + int n = snprintf (NULL, 0, "_NET_WM_CM_S%d", + XScreenNumberOfScreen (dpyinfo->screen)); + cm_atom_sprintf = alloca (n + 1); + + snprintf (cm_atom_sprintf, n + 1, "_NET_WM_CM_S%d", + XScreenNumberOfScreen (dpyinfo->screen)); + } + { static const struct { @@ -18688,7 +18761,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) int i; enum { atom_count = ARRAYELTS (atom_refs) }; /* 1 for _XSETTINGS_SN. */ - enum { total_atom_count = 1 + atom_count }; + enum { total_atom_count = 2 + atom_count }; Atom atoms_return[total_atom_count]; char *atom_names[total_atom_count]; static char const xsettings_fmt[] = "_XSETTINGS_S%d"; @@ -18702,6 +18775,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) sprintf (xsettings_atom_name, xsettings_fmt, XScreenNumberOfScreen (dpyinfo->screen)); atom_names[i] = xsettings_atom_name; + atom_names[i + 1] = cm_atom_sprintf; XInternAtoms (dpyinfo->display, atom_names, total_atom_count, False, atoms_return); @@ -18709,8 +18783,9 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) for (i = 0; i < atom_count; i++) *(Atom *) ((char *) dpyinfo + atom_refs[i].offset) = atoms_return[i]; - /* Manually copy last atom. */ + /* Manually copy last two atoms. */ dpyinfo->Xatom_xsettings_sel = atoms_return[i]; + dpyinfo->Xatom_NET_WM_CM_Sn = atoms_return[i + 1]; } #ifdef HAVE_XKB diff --git a/src/xterm.h b/src/xterm.h index 9665e92a9fb..05d5e08dc01 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -429,6 +429,9 @@ struct x_display_info /* Atom used in XEmbed client messages. */ Atom Xatom_XEMBED, Xatom_XEMBED_INFO; + /* Atom used to determine whether or not the screen is composited. */ + Atom Xatom_NET_WM_CM_Sn; + /* The frame (if any) which has the X window that has keyboard focus. Zero if none. This is examined by Ffocus_frame in xfns.c. Note that a mere EnterNotify event can set this; if you need to know the @@ -635,6 +638,12 @@ struct x_display_info #ifdef HAVE_XINERAMA bool xinerama_supported_p; #endif + +#ifdef HAVE_XCOMPOSITE + bool composite_supported_p; + int composite_major; + int composite_minor; +#endif }; #ifdef HAVE_X_I18N