emacs-diffs
[Top][All Lists]
Advanced

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

master e8d7139b4e: Fix minor bugs with XDND support


From: Po Lu
Subject: master e8d7139b4e: Fix minor bugs with XDND support
Date: Wed, 16 Mar 2022 05:03:39 -0400 (EDT)

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

    Fix minor bugs with XDND support
    
    * lisp/mouse.el (mouse-drag-and-drop-region): Report more
    selection targets for the benefit of Qt and Mozilla.
    * lisp/select.el (xselect--encode-string)
    (selection-converter-alist): Add new selection targets.
    
    * src/xterm.c (x_dnd_get_window_proxy): New function.
    (x_dnd_get_target_window): New argument proto_out, and return
    first window with XdndAware instead of bottommost window.
    (handle_one_xevent): Use new argument `proto_out'.
---
 lisp/mouse.el  |   4 +-
 lisp/select.el |  11 +++++-
 src/xterm.c    | 116 +++++++++++++++++++++++++++++++++++++--------------------
 3 files changed, 89 insertions(+), 42 deletions(-)

diff --git a/lisp/mouse.el b/lisp/mouse.el
index 4eead39925..3e7ae24697 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -3100,7 +3100,9 @@ is copied instead of being cut."
                 (x-hide-tip)
                 (gui-set-selection 'XdndSelection value-selection)
                 (let ((drag-action-or-frame
-                       (x-begin-drag '("UTF8_STRING" "STRING")
+                       (x-begin-drag '("UTF8_STRING" "text/plain"
+                                       "text/plain;charset=utf-8"
+                                       "STRING" "TEXT" "COMPOUND_TEXT")
                                      (if 
mouse-drag-and-drop-region-cut-when-buffers-differ
                                          'XdndActionMove
                                        'XdndActionCopy)
diff --git a/lisp/select.el b/lisp/select.el
index 42b50c44e6..e9bc545117 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -485,7 +485,8 @@ two markers or an overlay.  Otherwise, it is nil."
                               (if eight-bit 'C_STRING
                                 'STRING))))))))
          (cond
-          ((eq type 'UTF8_STRING)
+          ((or (eq type 'UTF8_STRING)
+                (eq type 'text/plain\;charset=utf-8))
            (if (or (not coding)
                    (not (eq (coding-system-type coding) 'utf-8)))
                (setq coding 'utf-8))
@@ -497,6 +498,12 @@ two markers or an overlay.  Otherwise, it is nil."
                (setq coding 'iso-8859-1))
            (setq str (encode-coding-string str coding)))
 
+           ((eq type 'text/plain)
+            (if (or (not coding)
+                   (not (eq (coding-system-type coding) 'charset)))
+               (setq coding 'ascii))
+           (setq str (encode-coding-string str coding)))
+
           ((eq type 'COMPOUND_TEXT)
            (if (or (not coding)
                    (not (eq (coding-system-type coding) 'iso-2022)))
@@ -630,6 +637,8 @@ This function returns the string \"emacs\"."
        (COMPOUND_TEXT . xselect-convert-to-string)
        (STRING . xselect-convert-to-string)
        (UTF8_STRING . xselect-convert-to-string)
+       (text/plain . xselect-convert-to-string)
+       (text/plain\;charset=utf-8 . xselect-convert-to-string)
        (TARGETS . xselect-convert-to-targets)
        (LENGTH . xselect-convert-to-length)
        (DELETE . xselect-convert-to-delete)
diff --git a/src/xterm.c b/src/xterm.c
index d01d3e7cce..83651376bf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -795,23 +795,21 @@ static struct frame *x_dnd_frame;
 
 #define X_DND_SUPPORTED_VERSION 5
 
+static int x_dnd_get_window_proto (struct x_display_info *, Window);
+static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
+
 static Window
 x_dnd_get_target_window (struct x_display_info *dpyinfo,
-                        int root_x, int root_y)
+                        int root_x, int root_y, int *proto_out)
 {
   Window child_return, child, dummy, proxy;
-  int dest_x_return, dest_y_return;
-  int rc;
-  int actual_format;
-  unsigned long actual_size, bytes_remaining;
-  unsigned char *tmp_data;
-  XWindowAttributes attrs;
-  Atom actual_type;
-
+  int dest_x_return, dest_y_return, rc, proto;
   child_return = dpyinfo->root_window;
   dest_x_return = root_x;
   dest_y_return = root_y;
 
+  proto = -1;
+
   /* Not strictly necessary, but satisfies GCC.  */
   child = dpyinfo->root_window;
 
@@ -832,8 +830,33 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo,
          break;
        }
 
+      proxy = x_dnd_get_window_proxy (dpyinfo, child_return);
+
+      if (proxy != None)
+       {
+         proto = x_dnd_get_window_proto (dpyinfo, proxy);
+
+         if (proto != -1)
+           {
+             *proto_out = proto;
+
+             x_uncatch_errors_after_check ();
+             return proxy;
+           }
+       }
+
       if (child_return)
        {
+         proto = x_dnd_get_window_proto (dpyinfo, child_return);
+
+         if (proto != -1)
+           {
+             *proto_out = proto;
+             x_uncatch_errors_after_check ();
+
+             return child_return;
+           }
+
          rc = XTranslateCoordinates (dpyinfo->display,
                                      child, child_return,
                                      dest_x_return, dest_y_return,
@@ -850,36 +873,47 @@ x_dnd_get_target_window (struct x_display_info *dpyinfo,
       x_uncatch_errors_after_check ();
     }
 
-  if (child != None)
-    {
-      x_catch_errors (dpyinfo->display);
-      rc = XGetWindowProperty (dpyinfo->display, child,
-                              dpyinfo->Xatom_XdndProxy,
-                              0, 1, False, XA_WINDOW,
-                              &actual_type, &actual_format,
-                              &actual_size, &bytes_remaining,
-                              &tmp_data);
-
-      if (!x_had_errors_p (dpyinfo->display)
-         && rc == Success
-         && actual_type == XA_WINDOW
-         && actual_format == 32
-         && actual_size == 1)
-       {
-         proxy = *(Window *) tmp_data;
-         XFree (tmp_data);
+  *proto_out = x_dnd_get_window_proto (dpyinfo, child);
+  return child;
+}
+
+static Window
+x_dnd_get_window_proxy (struct x_display_info *dpyinfo, Window wdesc)
+{
+  int rc, actual_format;
+  unsigned long actual_size, bytes_remaining;
+  unsigned char *tmp_data;
+  XWindowAttributes attrs;
+  Atom actual_type;
+  Window proxy;
 
-         /* Verify the proxy window exists.  */
-         XGetWindowAttributes (dpyinfo->display, proxy, &attrs);
+  proxy = None;
+  x_catch_errors (dpyinfo->display);
+  rc = XGetWindowProperty (dpyinfo->display, wdesc,
+                          dpyinfo->Xatom_XdndProxy,
+                          0, 1, False, XA_WINDOW,
+                          &actual_type, &actual_format,
+                          &actual_size, &bytes_remaining,
+                          &tmp_data);
 
-         if (!x_had_errors_p (dpyinfo->display))
-           child = proxy;
-       }
+  if (!x_had_errors_p (dpyinfo->display)
+      && rc == Success
+      && actual_type == XA_WINDOW
+      && actual_format == 32
+      && actual_size == 1)
+    {
+      proxy = *(Window *) tmp_data;
+      XFree (tmp_data);
 
-      x_uncatch_errors_after_check ();
+      /* Verify the proxy window exists.  */
+      XGetWindowAttributes (dpyinfo->display, proxy, &attrs);
+
+      if (x_had_errors_p (dpyinfo->display))
+       proxy = None;
     }
+  x_uncatch_errors_after_check ();
 
-  return child;
+  return proxy;
 }
 
 static int
@@ -11616,10 +11650,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
          {
            Window target;
+           int target_proto;
 
            target = x_dnd_get_target_window (dpyinfo,
                                              event->xmotion.x_root,
-                                             event->xmotion.y_root);
+                                             event->xmotion.y_root,
+                                             &target_proto);
 
            if (target != x_dnd_last_seen_window)
              {
@@ -11643,8 +11679,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
                x_dnd_wanted_action = None;
                x_dnd_last_seen_window = target;
-               x_dnd_last_protocol_version
-                 = x_dnd_get_window_proto (dpyinfo, target);
+               x_dnd_last_protocol_version = target_proto;
 
                if (target != None && x_dnd_last_protocol_version != -1)
                  x_dnd_send_enter (x_dnd_frame, target,
@@ -12849,10 +12884,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                  && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
                {
                  Window target;
+                 int target_proto;
 
                  target = x_dnd_get_target_window (dpyinfo,
                                                    xev->root_x,
-                                                   xev->root_y);
+                                                   xev->root_y,
+                                                   &target_proto);
 
                  if (target != x_dnd_last_seen_window)
                    {
@@ -12875,8 +12912,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                        }
 
                      x_dnd_last_seen_window = target;
-                     x_dnd_last_protocol_version
-                       = x_dnd_get_window_proto (dpyinfo, target);
+                     x_dnd_last_protocol_version = target_proto;
 
                      if (target != None && x_dnd_last_protocol_version != -1)
                        x_dnd_send_enter (x_dnd_frame, target,



reply via email to

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