summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-03-16 17:03:19 +0800
committerPo Lu <luangruo@yahoo.com>2022-03-16 17:03:19 +0800
commite8d7139b4e069f4641a7e11261541acb4c5fff7b (patch)
treed70f006c6e91a65071079f374e9634b43a08bd5a
parent1babe5fb2d7575fb15e515fffd3387d60a975553 (diff)
downloademacs-e8d7139b4e069f4641a7e11261541acb4c5fff7b.tar.gz
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'.
-rw-r--r--lisp/mouse.el4
-rw-r--r--lisp/select.el11
-rw-r--r--src/xterm.c116
3 files changed, 89 insertions, 42 deletions
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 4eead399252..3e7ae246975 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 42b50c44e6c..e9bc5451171 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 d01d3e7cce3..83651376bfd 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,