Try to save selections from being disowned during frame deletion
* lisp/cus-start.el (standard): Add `x-auto-preserve-selections'. * src/xselect.c (x_clear_frame_selections): Collect deleted selections into a variable and preserve them. * src/xterm.c (x_preserve_selections): New function. (syms_of_xterm): New variable `x-auto-preserve-selections'. * src/xterm.h: Update prototypes.
This commit is contained in:
parent
7ac313ea87
commit
86d128c6c3
5 changed files with 93 additions and 7 deletions
9
etc/NEWS
9
etc/NEWS
|
@ -2448,6 +2448,15 @@ be kept aligned with the buffer contents when the user switches
|
|||
This minor mode makes Emacs deactivate the mark in all buffers when
|
||||
the primary selection is obtained by another program.
|
||||
|
||||
---
|
||||
** On X, Emacs will try to preserve selection ownership when a frame is deleted.
|
||||
This means that if you make Emacs the owner of a selection, such as by
|
||||
selecting some text into the clipboard or primary selection, and then
|
||||
delete the current frame, you will still be able to insert the
|
||||
contents of that selection into other programs as long as another
|
||||
frame is open on the same display. This behavior can be disabled by
|
||||
setting the variable 'x-auto-preserve-selections' to nil.
|
||||
|
||||
+++
|
||||
** New predicate 'char-uppercase-p'.
|
||||
This returns non-nil if its argument its an uppercase character.
|
||||
|
|
|
@ -834,6 +834,7 @@ since it could result in memory overflow and make Emacs crash."
|
|||
(x-scroll-event-delta-factor mouse float "29.1")
|
||||
(x-gtk-use-native-input keyboard boolean "29.1")
|
||||
(x-dnd-disable-motif-drag dnd boolean "29.1")
|
||||
(x-auto-preserve-selections x boolean "29.1")
|
||||
;; xselect.c
|
||||
(x-select-enable-clipboard-manager killing boolean "24.1")
|
||||
;; xsettings.c
|
||||
|
@ -874,6 +875,8 @@ since it could result in memory overflow and make Emacs crash."
|
|||
(equal "x-scroll-event-delta-factor"
|
||||
(symbol-name symbol))
|
||||
(equal "x-dnd-disable-motif-drag"
|
||||
(symbol-name symbol))
|
||||
(equal "x-auto-preserve-selections"
|
||||
(symbol-name symbol)))
|
||||
(featurep 'x))
|
||||
((string-match "\\`x-" (symbol-name symbol))
|
||||
|
|
|
@ -1091,20 +1091,23 @@ x_handle_selection_event (struct selection_input_event *event)
|
|||
void
|
||||
x_clear_frame_selections (struct frame *f)
|
||||
{
|
||||
Lisp_Object frame;
|
||||
Lisp_Object rest;
|
||||
Lisp_Object frame, rest, lost;
|
||||
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
struct terminal *t = dpyinfo->terminal;
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
lost = Qnil;
|
||||
|
||||
/* Delete elements from the beginning of Vselection_alist. */
|
||||
while (CONSP (t->Vselection_alist)
|
||||
&& EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (t->Vselection_alist)))))))
|
||||
{
|
||||
/* Run the `x-lost-selection-functions' abnormal hook. */
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
Fcar (Fcar (t->Vselection_alist)));
|
||||
if (!x_auto_preserve_selections)
|
||||
/* Run the `x-lost-selection-functions' abnormal hook. */
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
Fcar (Fcar (t->Vselection_alist)));
|
||||
else
|
||||
lost = Fcons (Fcar (t->Vselection_alist), lost);
|
||||
|
||||
tset_selection_alist (t, XCDR (t->Vselection_alist));
|
||||
}
|
||||
|
@ -1114,11 +1117,18 @@ x_clear_frame_selections (struct frame *f)
|
|||
if (CONSP (XCDR (rest))
|
||||
&& EQ (frame, XCAR (XCDR (XCDR (XCDR (XCAR (XCDR (rest))))))))
|
||||
{
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
XCAR (XCAR (XCDR (rest))));
|
||||
if (!x_auto_preserve_selections)
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
XCAR (XCAR (XCDR (rest))));
|
||||
else
|
||||
lost = Fcons (XCAR (XCDR (rest)), lost);
|
||||
|
||||
XSETCDR (rest, XCDR (XCDR (rest)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (x_auto_preserve_selections)
|
||||
x_preserve_selections (dpyinfo, lost);
|
||||
}
|
||||
|
||||
/* True if any properties for DISPLAY and WINDOW
|
||||
|
|
63
src/xterm.c
63
src/xterm.c
|
@ -27951,6 +27951,62 @@ x_uncatch_errors_for_lisp (struct x_display_info *dpyinfo)
|
|||
x_stop_ignoring_errors (dpyinfo);
|
||||
}
|
||||
|
||||
/* Preserve the selections in LOST in another frame on DPYINFO. LOST
|
||||
is a list of local selections that were lost, due to their frame
|
||||
being deleted. */
|
||||
|
||||
void
|
||||
x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost)
|
||||
{
|
||||
Lisp_Object tail, frame, new_owner, tem;
|
||||
Time timestamp;
|
||||
Window owner;
|
||||
|
||||
new_owner = Qnil;
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
if (FRAME_X_P (XFRAME (frame))
|
||||
&& FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
|
||||
{
|
||||
new_owner = frame;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tail = lost;
|
||||
|
||||
FOR_EACH_TAIL_SAFE (tail)
|
||||
{
|
||||
tem = XCAR (tail);
|
||||
|
||||
/* The selection is really lost (since we cannot find a new
|
||||
owner), so run the appropriate hooks. */
|
||||
if (NILP (new_owner))
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
XCAR (tem));
|
||||
else
|
||||
{
|
||||
CONS_TO_INTEGER (XCAR (XCDR (XCDR (tem))), Time, timestamp);
|
||||
|
||||
/* This shouldn't be able to signal any errors, despite the
|
||||
call to `x_check_errors' inside. */
|
||||
x_own_selection (XCAR (tem), XCAR (XCDR (tem)),
|
||||
new_owner, XCAR (XCDR (XCDR (XCDR (XCDR (tem))))),
|
||||
timestamp);
|
||||
|
||||
/* Now check if we still don't own that selection, which can
|
||||
happen if another program set itself as the owner. */
|
||||
owner = XGetSelectionOwner (dpyinfo->display,
|
||||
symbol_to_x_atom (dpyinfo, XCAR (tem)));
|
||||
|
||||
if (owner != FRAME_X_WINDOW (XFRAME (new_owner)))
|
||||
CALLN (Frun_hook_with_args, Qx_lost_selection_functions,
|
||||
XCAR (tem));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_xterm (void)
|
||||
{
|
||||
|
@ -28265,4 +28321,11 @@ reply from the X server, and signal any errors that occurred while
|
|||
executing the protocol request. Otherwise, errors will be silently
|
||||
ignored without waiting, which is generally faster. */);
|
||||
x_fast_protocol_requests = false;
|
||||
|
||||
DEFVAR_BOOL ("x-auto-preserve-selections", x_auto_preserve_selections,
|
||||
doc: /* Whether or not to transfer selection ownership when deleting a frame.
|
||||
When non-nil, deleting a frame that is currently the owner of a
|
||||
selection will cause its ownership to be transferred to another frame
|
||||
on the same display. */);
|
||||
x_auto_preserve_selections = true;
|
||||
}
|
||||
|
|
|
@ -1643,6 +1643,7 @@ extern void xic_set_statusarea (struct frame *);
|
|||
extern void xic_set_xfontset (struct frame *, const char *);
|
||||
extern bool x_defined_color (struct frame *, const char *, Emacs_Color *,
|
||||
bool, bool);
|
||||
extern void x_preserve_selections (struct x_display_info *, Lisp_Object);
|
||||
#ifdef HAVE_X_I18N
|
||||
extern void free_frame_xic (struct frame *);
|
||||
# if defined HAVE_X_WINDOWS && defined USE_X_TOOLKIT
|
||||
|
|
Loading…
Add table
Reference in a new issue