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.
(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
(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))
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));
}
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);
}
\f
/* True if any properties for DISPLAY and WINDOW
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)
{
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;
}
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