[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Texmacs-dev] Patches: copy/paste and selection handling.
From: |
Joris van der Hoeven |
Subject: |
Re: [Texmacs-dev] Patches: copy/paste and selection handling. |
Date: |
Sat, 7 Feb 2009 00:48:48 +0100 |
User-agent: |
Mutt/1.5.9i |
Hi Norbert,
I will examine your patches as soon as possible;
I am currently abroad for a few weeks and
deal with all TeXmacs-related stuff when back (march).
Best wishes, Joris
On Fri, Jan 23, 2009 at 11:07:00PM +0000, Norbert Nemec wrote:
> Hi there,
>
> following the bugfix two days ago, I have now finally sat down and tried
> to clean out the annoyingly non-standard behavior of TeXmacs in terms of
> selection handling and cut-and-paste. Resulting are the three attached
> patches that handle mostly independent issues. Each patch has an
> explanation included in the header.
>
> To begin with: I am used to the Windows/KDE/Gnome standard behavior
> which is very different from that of Emacs. I believe the patches in
> their current form will work in Emacs mode as well, but I would ask some
> of the true Emacs users to try these patches.
>
> The first patch should be pretty much invisible if you don't use
> X11-style mouse-select-and-middle-button-paste. If you do use this, you
> should find the new behavior identical to that in other common editors.
> If you have xclipboard, klipper or any similar clipboard manager
> running, please check how it might interfere with the inter-program
> cut-and-paste.
>
> The second patch makes selections generally non-persistent (i.e. text is
> unselected as soon as cursor is moved). This is the standard set by
> Windows and adopted by freedesktop.org (i.e. KDE, Gnome, etc.). If
> anybody has a good reason for supporting persistent selections, please
> bring it forward.
>
> The third patch does away with the annoying habit of TeXmacs overwriting
> the clipboard when you press <delete> on a selection. I know that some
> Emacs users prefer to have their <delete> key bound to perform a <cut>
> operation. If anybody out there thinks this kind of behavior should be
> configurable (or even default in Emacs mode), could you please contact
> me, so we could try to figure out at which place I should put a switch.
>
> Please, test these patches thoroughly and give your feedback. This is
> something that will affect every user every day, so it should be polished.
>
> Greeting,
> Norbert
> Make copy-and-paste compliant with freedesktop standards
>
> From: <>
>
> According to the freedesktop standard, there are two separate buffers to do
> cut-and-paste:
> XA_CLIPBOARD: Windows like via Ctrl-C and Ctrl-V (XA_CLIPBOARD)
> XA_PRIMARY: mouse-shortcut by marking with mouse and pressing middle button
> in some other place
>
> Formerly, both methods were mapped to TeXmacs "primary" buffer, causing some
> strange behavior.
>
> Now, the mouse selection is copied to a new "mouse" buffer and middle-click
> pastes from
> this special buffer. The regular "primary" buffer is unaffected by mouse
> selection. Of
> course the mouse-selection can also be copied to the "primary" buffer as well.
>
> The interaction with the world outside depends on the GUI:
>
> X11:
> The naming is a bit confusing to avoid changing too much code
> * The "primary" buffer is mapped to XA_CLIPBOARD
> * The "mouse" buffer is mapped to XA_PRIMARY
>
> Qt:
> The handling of the "primary" is encapsulated by QClipboard. The "mouse"
> cut-and-paste should work TeXmacs internally. No idea how to get it to
> work
> properly with other applications.
>
> All other GUIs should work as before with the "primary" selection and should
> work
> following the freedesktop standard within TeXmacs. Whether a inter-application
> mechanism exists and can be used for mouse copy-paste depends on the system.
>
> ============
>
> The changes in detail:
>
> * added function 'bool contains(list<T>,T)' to list.hpp
>
> * created symbols XA_CLIPBOARD and XA_TARGETS in x_gui initialized at startup
> to standard XAtom values.
>
> * changed edit_interface_rep::mouse_select to select into "mouse" instead of
> "primary" buffer
>
> * changed edit_interface_rep::mouse_paste to
> a) go_to position of mouse click
> b) paste from "mouse" instead of "primary" buffer
>
> * removed x_gui_rep::selection variable - do conversion from selection_s on
> the fly in
> x_loop instead
>
> * changed x_gui_rep::set_selection to handle "mouse" (pointing to XA_PRIMARY)
> and "primary" (pointing to XA_CLIPBOARD)
>
> * completely restructured x_gui_rep::get_selection to achieve the same here
>
> * handle SelectionRequestEvent and SelectionClearEvent for either XA_PRIMARY
> or XA_CLIPBOARD
> ---
>
> src/src/Edit/Interface/edit_mouse.cpp | 10 +++--
> src/src/Edit/Replace/edit_select.cpp | 2 +
> src/src/Kernel/Containers/list.cpp | 5 +++
> src/src/Kernel/Containers/list.hpp | 1 +
> src/src/Plugins/X11/x_drawable.hpp | 2 +
> src/src/Plugins/X11/x_gui.cpp | 62
> ++++++++++++++++++++-------------
> src/src/Plugins/X11/x_gui.hpp | 4 ++
> src/src/Plugins/X11/x_init.cpp | 9 +++--
> src/src/Plugins/X11/x_loop.cpp | 32 +++++++++++------
> src/src/Plugins/X11/x_window.hpp | 2 +
> 10 files changed, 80 insertions(+), 49 deletions(-)
>
>
> diff --git a/src/src/Edit/Interface/edit_mouse.cpp
> b/src/src/Edit/Interface/edit_mouse.cpp
> index bf6eebc..3af1018 100644
> --- a/src/src/Edit/Interface/edit_mouse.cpp
> +++ b/src/src/Edit/Interface/edit_mouse.cpp
> @@ -56,7 +56,7 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int
> mods, time_t t) {
> dragging= true;
> }
> else if (dragging && (type == "move"))
> - type2= "dragging";
> + type2= "dragging";
> if (dragging && (type == "release-left"))
> type2= "end-drag";
>
> @@ -66,7 +66,7 @@ edit_interface_rep::mouse_any (string type, SI x, SI y, int
> mods, time_t t) {
> right_dragging= true;
> }
> else if (right_dragging && (type == "move"))
> - type2= "right-dragging";
> + type2= "right-dragging";
> if (right_dragging && (type == "release-right"))
> type2= "end-right-drag";
>
> @@ -180,14 +180,14 @@ edit_interface_rep::mouse_select (SI x, SI y, int mods)
> {
> eval ("(graphics-reset-context 'exit)");
> }
> if (selection_active_any ())
> - selection_set ("primary", selection_get (), true);
> + selection_set ("mouse", selection_get (), true);
> }
>
> void
> edit_interface_rep::mouse_paste (SI x, SI y) { (void) x; (void) y;
> if (eb->action ("paste", x, y, 0) != "") return;
> - selection_copy ();
> - selection_paste ();
> + go_to (x, y);
> + selection_paste ("mouse");
> }
>
> void
> diff --git a/src/src/Edit/Replace/edit_select.cpp
> b/src/src/Edit/Replace/edit_select.cpp
> index 7eb32ee..9b0fd6f 100644
> --- a/src/src/Edit/Replace/edit_select.cpp
> +++ b/src/src/Edit/Replace/edit_select.cpp
> @@ -557,7 +557,7 @@ edit_select_rep::selection_set (string key, tree t, bool
> persistant) {
> nicely copying graphics into text, text into graphics, etc.
> */
> string s;
> - if (key == "primary") {
> + if (key == "primary" || key == "mouse") {
> if (selection_export == "verbatim") t= exec_texmacs (t, tp);
> if (selection_export == "html") t= exec_html (t, tp);
> if (selection_export == "latex") t= exec_latex (t, tp);
> diff --git a/src/src/Kernel/Containers/list.cpp
> b/src/src/Kernel/Containers/list.cpp
> index 4efd8c4..faa1bcf 100644
> --- a/src/src/Kernel/Containers/list.cpp
> +++ b/src/src/Kernel/Containers/list.cpp
> @@ -194,4 +194,9 @@ remove (list<T> l, T what) {
> else return list<T> (l->item, remove (l->next, what));
> }
>
> +template<class T> bool
> +contains (list<T> l, T what) {
> + return (!is_nil(l) && (l->item == what || contains(l->next, what)));
> +}
> +
> #endif // defined LIST_CC
> diff --git a/src/src/Kernel/Containers/list.hpp
> b/src/src/Kernel/Containers/list.hpp
> index 2a82d01..1df1dff 100644
> --- a/src/src/Kernel/Containers/list.hpp
> +++ b/src/src/Kernel/Containers/list.hpp
> @@ -70,6 +70,7 @@ TMPL T& access_last (list<T>& l);
> TMPL list<T>& suppress_last (list<T>& l);
> TMPL list<T> reverse (list<T> l);
> TMPL list<T> remove (list<T> l, T what);
> +TMPL bool contains (list<T> l, T what);
>
> TMPL ostream& operator << (ostream& out, list<T> l);
> TMPL list<T>& operator << (list<T>& l, T item);
> diff --git a/src/src/Plugins/X11/x_drawable.hpp
> b/src/src/Plugins/X11/x_drawable.hpp
> index a877a6f..088a3b5 100644
> --- a/src/src/Plugins/X11/x_drawable.hpp
> +++ b/src/src/Plugins/X11/x_drawable.hpp
> @@ -81,7 +81,7 @@ public:
>
> friend class x_gui_rep;
> friend class x_window_rep;
> - friend Bool my_predicate (Display* dpy, XEvent* ev, XPointer arg);
> + friend Bool my_selnotify_predicate (Display* dpy, XEvent* ev, XPointer
> arg);
> };
>
> #endif // defined X_DRAWABLE_H
> diff --git a/src/src/Plugins/X11/x_gui.cpp b/src/src/Plugins/X11/x_gui.cpp
> index e99254f..13ceb7a 100644
> --- a/src/src/Plugins/X11/x_gui.cpp
> +++ b/src/src/Plugins/X11/x_gui.cpp
> @@ -188,7 +188,7 @@ x_gui_rep::has_mouse_grab (widget w) {
>
> ******************************************************************************/
>
> Bool
> -my_predicate (Display* dpy, XEvent* ev, XPointer arg) { (void) dpy;
> +my_selnotify_predicate (Display* dpy, XEvent* ev, XPointer arg) { (void) dpy;
> x_window win= (x_window) arg;
> return (win->win==ev->xany.window) && (ev->type==SelectionNotify);
> }
> @@ -212,29 +212,41 @@ bool
> x_gui_rep::get_selection (string key, tree& t, string& s) {
> t= "none";
> s= "";
> + bool res=false;
> +
> if (selection_t->contains (key)) {
> t= copy (selection_t [key]);
> s= copy (selection_s [key]);
> - return true;
> + res=true;
> }
> - if (key != "primary") return false;
> - if (XGetSelectionOwner (dpy, XA_PRIMARY) == None) return false;
>
> - if (is_nil (windows_l)) return false;
> + Atom xsel;
> + if(key == "primary")
> + xsel = XA_CLIPBOARD;
> + else if (key == "mouse")
> + xsel = XA_PRIMARY;
> + else
> + return res;
> +
> + Window selown = XGetSelectionOwner(dpy, xsel);
> + if (selown == None
> + || is_nil (windows_l)
> + || contains(windows_l,selown)) return res;
> +
> Window win= windows_l->item;
> x_window x_win= (x_window) Window_to_window[win];
> - Atom data= XInternAtom (dpy, "MY_STRING_SELECTION", false);
> - XConvertSelection (dpy, XA_PRIMARY, XA_STRING, data, win, CurrentTime);
> + Atom prop= XInternAtom (dpy, "MY_STRING_SELECTION", false);
> + XConvertSelection (dpy, xsel, XA_STRING, prop, win, CurrentTime);
>
> int i;
> XEvent ev;
> for (i=0; i<1000000; i++)
> - if (XCheckIfEvent (dpy, &ev, my_predicate, (XPointer) x_win))
> + if (XCheckIfEvent (dpy, &ev, my_selnotify_predicate, (XPointer) x_win))
> break;
> - if (i==1000000) return false;
> + if (i==1000000) return res;
> XSelectionEvent& sel= ev.xselection;
>
> - if (sel.property!=None) {
> + if (sel.property==prop) {
> long offset=0;
> Atom type;
> int fm;
> @@ -249,23 +261,27 @@ x_gui_rep::get_selection (string key, tree& t, string&
> s) {
> offset += (n >> 2);
> XFree (ret);
> } while (remains>0);
> - }
> - t= tuple ("extern", s);
> - return true;
> + t= tuple ("extern", s);
> + return true;
> + } else
> + return res;
> }
>
> bool
> x_gui_rep::set_selection (string key, tree t, string s) {
> selection_t (key)= copy (t);
> selection_s (key)= copy (s);
> - if (key == "primary") {
> - if (is_nil (windows_l)) return false;
> - Window win= windows_l->item;
> - if (selection!=NULL) tm_delete_array (selection);
> - XSetSelectionOwner (dpy, XA_PRIMARY, win, CurrentTime);
> - if (XGetSelectionOwner(dpy, XA_PRIMARY)==None) return false;
> - selection= as_charp (s);
> - }
> + Atom xsel;
> + if(key == "primary") {
> + xsel = XA_CLIPBOARD;
> + } else if (key == "mouse") {
> + xsel = XA_PRIMARY;
> + } else
> + return true;
> + if (is_nil (windows_l)) return false;
> + Window win= windows_l->item;
> + XSetSelectionOwner (dpy, xsel, win, CurrentTime);
> + if (XGetSelectionOwner(dpy, xsel)==None) return false;
> return true;
> }
>
> @@ -273,10 +289,6 @@ void
> x_gui_rep::clear_selection (string key) {
> selection_t->reset (key);
> selection_s->reset (key);
> - if ((key == "primary") && (selection != NULL)) {
> - tm_delete_array (selection);
> - selection= NULL;
> - }
> }
>
> bool
> diff --git a/src/src/Plugins/X11/x_gui.hpp b/src/src/Plugins/X11/x_gui.hpp
> index c1abfd6..24840fa 100644
> --- a/src/src/Plugins/X11/x_gui.hpp
> +++ b/src/src/Plugins/X11/x_gui.hpp
> @@ -125,10 +125,12 @@ public:
> hashmap<int,string> upper_key;
>
> list<Window> windows_l;
> - char* selection;
> hashmap<string,tree> selection_t;
> hashmap<string,string> selection_s;
>
> + Atom XA_CLIPBOARD;
> + Atom XA_TARGETS;
> +
> public:
> x_gui_rep (int argc, char** argv);
> ~x_gui_rep ();
> diff --git a/src/src/Plugins/X11/x_init.cpp b/src/src/Plugins/X11/x_init.cpp
> index adae260..0294337 100644
> --- a/src/src/Plugins/X11/x_init.cpp
> +++ b/src/src/Plugins/X11/x_init.cpp
> @@ -443,9 +443,9 @@ x_gui_rep::initialize_keyboard_pointer () {
> Map (XK_Cyrillic_E, "\xdd");
> Map (XK_Cyrillic_YU, "\xde");
> Map (XK_Cyrillic_YA, "\xdf");
> -
> +
> //Ukrainian letters in T2A encoding
> - Map (XK_Ukrainian_i, "i"); // Fall back!
> + Map (XK_Ukrainian_i, "i"); // Fall back!
> Map (XK_Ukrainian_I, "I"); // Fall back!
> Map (XK_Ukrainian_yi, "\xa8");
> Map (XK_Ukrainian_YI, "\x88");
> @@ -808,7 +808,7 @@ x_gui_rep::x_gui_rep (int argc2, char** argv2):
> character_bitmap (NULL), character_pixmap ((pointer) 0),
> xpm_bitmap (0), xpm_pixmap (0),
> lower_key (""), upper_key (""),
> - selection (NULL), selection_t ("none"), selection_s ("")
> + selection_t ("none"), selection_s ("")
> {
> the_gui= this;
> if ((dpy= XOpenDisplay (NULL)) == NULL)
> @@ -834,6 +834,9 @@ x_gui_rep::x_gui_rep (int argc2, char** argv2):
> interrupted = false;
> interrupt_time = texmacs_time ();
>
> + XA_CLIPBOARD = XInternAtom (dpy, "CLIPBOARD", false);
> + XA_TARGETS = XInternAtom (dpy, "TARGETS", false);
> +
> if (XMatchVisualInfo (dpy, scr, depth, TrueColor, &visual) != 0) {
> if (visual.red_mask == (255 << 16) &&
> visual.green_mask == (255 << 8) &&
> diff --git a/src/src/Plugins/X11/x_loop.cpp b/src/src/Plugins/X11/x_loop.cpp
> index 17919e3..def6a40 100644
> --- a/src/src/Plugins/X11/x_loop.cpp
> +++ b/src/src/Plugins/X11/x_loop.cpp
> @@ -273,8 +273,7 @@ x_gui_rep::process_event (x_window win, XEvent* ev) {
> if (N(key)>0) win->key_event (key);
> break;
> }
> - case SelectionRequest:
> - {
> + case SelectionRequest: {
> XSelectionRequestEvent& req= ev->xselectionrequest;
> XSelectionEvent sel;
> sel.type = SelectionNotify;
> @@ -282,10 +281,14 @@ x_gui_rep::process_event (x_window win, XEvent* ev) {
> sel.selection = req.selection;
> sel.target = req.target;
> sel.time = req.time;
> - Atom XA_TARGETS = XInternAtom(dpy, "TARGETS", False);
> - if (selection==NULL)
> + string key = "none";
> + if(req.selection == XA_PRIMARY) {
> + key = "mouse";
> + } else if(req.selection == XA_CLIPBOARD)
> + key = "primary";
> + if (!selection_s->contains(key)) {
> sel.property = None;
> - else if (req.target==XA_TARGETS) {
> + } else if (req.target==XA_TARGETS) {
> Atom targets[2];
> targets[0] = XA_TARGETS;
> targets[1] = XA_STRING;
> @@ -294,19 +297,24 @@ x_gui_rep::process_event (x_window win, XEvent* ev) {
> (unsigned char*)&targets[0],2);
> sel.property = req.property;
> } else if ((req.target==AnyPropertyType) || (req.target==XA_STRING)) {
> + char *txt = as_charp (selection_s(key));
> XChangeProperty (dpy, req.requestor, req.property, XA_STRING,
> 8, PropModeReplace,
> - (unsigned char*) selection,
> - strlen (selection));
> + (unsigned char*) txt,
> + strlen (txt));
> + tm_delete_array (txt);
> sel.property = req.property;
> } else
> sel.property = None;
> XSendEvent (dpy, sel.requestor, false, 0, (XEvent*) &sel);
> - break;
> - }
> - case SelectionClear:
> - clear_selection ("primary");
> - break;
> + } break;
> + case SelectionClear: {
> + XSelectionClearEvent& req= ev->xselectionclear;
> + if(req.selection == XA_PRIMARY) {
> + clear_selection("mouse");
> + } else if(req.selection == XA_CLIPBOARD)
> + clear_selection ("primary");
> + } break;
> case ClientMessage:
> {
> Atom wm_protocols = XInternAtom(win->dpy, "WM_PROTOCOLS", 1);
> diff --git a/src/src/Plugins/X11/x_window.hpp
> b/src/src/Plugins/X11/x_window.hpp
> index a4631e9..56ad01b 100644
> --- a/src/src/Plugins/X11/x_window.hpp
> +++ b/src/src/Plugins/X11/x_window.hpp
> @@ -97,7 +97,7 @@ public:
>
> friend class x_gui_rep;
> friend class x_drawable_rep;
> - friend Bool my_predicate (Display* dpy, XEvent* ev, XPointer arg);
> + friend Bool my_selnotify_predicate (Display* dpy, XEvent* ev, XPointer
> arg);
> friend int get_identifier (window w);
> };
>
> Makes selections non-persistent following Windows (KDE etc.) standard.
>
> From: <>
>
> The selection is deactivated as soon as the cursor is moved by keys or mouse
> click.
> This solves the annoying problem that a selection might still exist somewhere
> off-screen, being replaced unnoticed when new text is entered. Now a
> selection may only
> exist at the position of the cursor. (Clipboard and mouse-copy-paste buffer
> are
> preserved beyond the life of the selection itself.)
> ---
>
> src/src/Edit/Interface/edit_mouse.cpp | 11 ++++++++++-
> src/src/Edit/Replace/edit_select.cpp | 34
> +++++++++++++++++++++------------
> 2 files changed, 32 insertions(+), 13 deletions(-)
>
>
> diff --git a/src/src/Edit/Interface/edit_mouse.cpp
> b/src/src/Edit/Interface/edit_mouse.cpp
> index 3af1018..5639f19 100644
> --- a/src/src/Edit/Interface/edit_mouse.cpp
> +++ b/src/src/Edit/Interface/edit_mouse.cpp
> @@ -132,6 +132,8 @@ edit_interface_rep::mouse_extra_click (SI x, SI y) {
> get_selection (p1, p2);
> if ((p1==p2) || path_less (tp, p1) || path_less (p2, tp)) select (tp, tp);
> select_enlarge ();
> + if (selection_active_any ())
> + selection_set ("mouse", selection_get (), true);
> return false;
> }
>
> @@ -139,6 +141,7 @@ void
> edit_interface_rep::mouse_drag (SI x, SI y) {
> if (inside_graphics ()) return;
> if (eb->action ("drag", x, y, 0) != "") return;
> + go_to (x, y);
> end_x = x;
> end_y = y;
> selection_visible ();
> @@ -150,8 +153,8 @@ edit_interface_rep::mouse_drag (SI x, SI y) {
> p1= p2;
> p2= temp;
> }
> - set_selection (p1, p2);
> if ((p1 == p2) && start_drag) return;
> + set_selection (p1, p2);
> start_drag= start_right_drag= false;
> notify_change (THE_SELECTION);
> }
> @@ -179,6 +182,12 @@ edit_interface_rep::mouse_select (SI x, SI y, int mods) {
> invalidate_graphical_object ();
> eval ("(graphics-reset-context 'exit)");
> }
> + if(start_drag) {
> + path sp= find_innermost_scroll (eb, tp);
> + path p0= tree_path (sp, x, y, 0);
> + set_selection (p0, p0);
> + notify_change (THE_SELECTION);
> + }
> if (selection_active_any ())
> selection_set ("mouse", selection_get (), true);
> }
> diff --git a/src/src/Edit/Replace/edit_select.cpp
> b/src/src/Edit/Replace/edit_select.cpp
> index 9b0fd6f..c99a2fb 100644
> --- a/src/src/Edit/Replace/edit_select.cpp
> +++ b/src/src/Edit/Replace/edit_select.cpp
> @@ -98,21 +98,31 @@ edit_select_rep::select_line () {
>
> void
> edit_select_rep::select_from_cursor () {
> - if (!(selecting || shift_selecting)) return;
> - if (path_less (mid_p, tp)) {
> - start_p= copy (mid_p);
> - end_p = copy (tp);
> - }
> - else {
> - start_p= copy (tp);
> - end_p = copy (mid_p);
> + if (selecting) {
> + if (path_less (mid_p, tp)) {
> + start_p= copy (mid_p);
> + end_p = copy (tp);
> + } else {
> + start_p= copy (tp);
> + end_p = copy (mid_p);
> + }
> + notify_change (THE_SELECTION);
> + if (shift_selecting) selecting = false;
> }
> - notify_change (THE_SELECTION);
> }
>
> void
> edit_select_rep::select_from_cursor_if_active () {
> - if (selecting) select_from_cursor ();
> + if (selecting) {
> + if (path_less (mid_p, tp)) {
> + start_p= copy (mid_p);
> + end_p = copy (tp);
> + } else {
> + start_p= copy (tp);
> + end_p = copy (mid_p);
> + }
> + notify_change (THE_SELECTION);
> + } else selection_cancel ();
> }
>
> void
> @@ -128,10 +138,10 @@ edit_select_rep::select_from_shift_keyboard () {
> if ((!shift_selecting) || (end_p == start_p) ||
> ((tp != start_p) && (tp != end_p)))
> {
> - selecting= false;
> - shift_selecting= true;
> mid_p= copy (tp);
> }
> + selecting= true;
> + shift_selecting= true;
> }
>
>
> /******************************************************************************
> Make delete act without touching the clipboard.
>
> From: <>
>
> Formerly, pressing the <delete> key with an active selection would perform a
> "cut" operation,
> placing the deleted text in the clipboard.
>
> Now, <delete> does actually only delete the selected text following Windows
> (KDE etc.) standards.
> ---
>
> src/TeXmacs/progs/generic/generic-edit.scm | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
>
> diff --git a/src/TeXmacs/progs/generic/generic-edit.scm
> b/src/TeXmacs/progs/generic/generic-edit.scm
> index 8dc9d92..c5d5d70 100644
> --- a/src/TeXmacs/progs/generic/generic-edit.scm
> +++ b/src/TeXmacs/progs/generic/generic-edit.scm
> @@ -41,7 +41,8 @@
> (tm-define (kbd-remove forward?) (remove-text forward?))
> (tm-define (kbd-remove forward?)
> (:mode with-active-selection?)
> - (clipboard-cut "primary"))
> + (clipboard-cut "nowhere")
> + (clipboard-clear "nowhere"))
>
> (tm-define (kbd-tab)
> (if (not (complete-try?))
> _______________________________________________
> Texmacs-dev mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/texmacs-dev
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., (continued)
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Norbert Nemec, 2009/02/06
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Todd Wilson, 2009/02/06
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Norbert Nemec, 2009/02/07
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Daniel Bump, 2009/02/07
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Norbert Nemec, 2009/02/07
- Re: [Texmacs-dev] Patches: copy/paste and selection handling., Lukasz Stafiniak, 2009/02/06
Re: [Texmacs-dev] Patches: copy/paste and selection handling.,
Joris van der Hoeven <=