emacs-diffs
[Top][All Lists]
Advanced

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

master 1467b04f5c: Handle composite overlay window during drag and drop


From: Po Lu
Subject: master 1467b04f5c: Handle composite overlay window during drag and drop sessions
Date: Fri, 18 Mar 2022 21:29:21 -0400 (EDT)

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

    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.
---
 configure.ac     | 18 ++++++++++++
 msdos/sed1v2.inp |  2 ++
 src/Makefile.in  |  7 +++--
 src/xterm.c      | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/xterm.h      |  9 ++++++
 5 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/configure.ac b/configure.ac
index bc17935eb1..6e63747733 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 <X11/extensions/Xcomposite.h>
+    ])
+  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 cc29ad0281..24ae079db1 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 2b7c4bb316..0ec2d34264 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 f7047ff0e8..5c5f24e297 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -542,6 +542,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <X11/extensions/Xinerama.h>
 #endif
 
+#ifdef HAVE_XCOMPOSITE
+#include <X11/extensions/Xcomposite.h>
+#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 9665e92a9f..05d5e08dc0 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



reply via email to

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