]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix minor bugs with XDND support
authorPo Lu <luangruo@yahoo.com>
Wed, 16 Mar 2022 09:03:19 +0000 (17:03 +0800)
committerPo Lu <luangruo@yahoo.com>
Wed, 16 Mar 2022 09:03:19 +0000 (17:03 +0800)
* 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
lisp/select.el
src/xterm.c

index 4eead39925293fc046857eabbb0598984df46636..3e7ae24697504f3b20b8640e527b30f1bb3e63a5 100644 (file)
@@ -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)
index 42b50c44e6c32142b31c3af9354ac602655b28ff..e9bc545117137874e7356aa2415f5169e7ab3f38 100644 (file)
@@ -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)
index d01d3e7cce3bac2effd36888e671da96f3b69ba9..83651376bfd46f86428dece01623fc5a7c805ef2 100644 (file)
@@ -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,