Discussion:
bug#38013: [PATCH] Rectangular region selection with mouse
(too old to reply)
Mattias Engdegård
2019-10-31 21:55:26 UTC
Permalink
This is a proposal to add mouse-selection of rectangular regions. It turns out to be useful; Emacs should come with the facility built-in.

The main problem is what to bind it to. The common modifiers (shift, control, meta) are already taken. Platforms have different "standard" modifiers: Option on macOS, Alt on Windows, Control in Gnome (?).

Assuming that the secondary selection is somewhat of an anachronism which is likely to be less used today than the rectangular one would be, the patch uses Meta as default modifier. Both secondary and rectangular mouse selection have defcustoms permitting easy change.

The defaults could be different, for example if secondary mouse selection turns out to be very popular.
There is no documentation yet.
Drew Adams
2019-11-01 00:12:24 UTC
Permalink
Post by Mattias Engdegård
This is a proposal to add mouse-selection of rectangular regions. It
turns out to be useful; Emacs should come with the facility built-in.
The main problem is what to bind it to. The common modifiers (shift,
control, meta) are already taken. Platforms have different "standard"
modifiers: Option on macOS, Alt on Windows, Control in Gnome (?).
Assuming that the secondary selection is somewhat of an anachronism
which is likely to be less used today than the rectangular one would
be, the patch uses Meta as default modifier. Both secondary and
rectangular mouse selection have defcustoms permitting easy change.
The defaults could be different, for example if secondary mouse
selection turns out to be very popular.
There is no documentation yet.
FWIW -

1. I like the general idea of being able to use
the mouse to directly define a rectangular region.
_Good initiative_.

2. But I disagree completely that the secondary
selection is an anachronism.

IMO it is not used as much as it could (and should
and would) be used in Emacs only because it has no
_keyboard_ bindings, by default.

I use C-M-y to do all of this:

* yank the secondary (no pref arg)
* select the secondary as the region (pref arg = 0)
* move the secondary to the region (pref arg > 0)
* swap the secondary and the region (pref arg < 0)

The 3rd and 4th of those set the secondary with just
the keyboard - from the region. Another way to set
it using just the keyboard is to use C-x C-M-SPC to
start it and C-x C-M-<return> to end it.

(And I use C-M-y during Isearch to yank the secondary
to the end of the search string.)

The secondary selection is different from the region.
Its advantage, and its disadvantage, is that it is
liberated from point - it need not even be currently
visible in a window. It doesn't change just because
you move the cursor around.

The region has a ring, `kill-ring', to let you get
previous selections. I do the same thing for the
secondary selection, as well - give it a ring. And
if the previous command yanked the secondary then
M-y yank-pops the secondary ring (not the kill-ring),
to replace that yank with the previous secondary on
the ring.

https://www.emacswiki.org/emacs/SecondarySelection#second-sel.el
Eli Zaretskii
2019-11-01 07:51:35 UTC
Permalink
Date: Thu, 31 Oct 2019 22:55:26 +0100
This is a proposal to add mouse-selection of rectangular regions. It turns out to be useful; Emacs should come with the facility built-in.
Could you please tell how to try and test this feature? The patch
comes without any documentation, so it's hard to understand quickly
what to do to see this in action.
The main problem is what to bind it to. The common modifiers (shift, control, meta) are already taken. Platforms have different "standard" modifiers: Option on macOS, Alt on Windows, Control in Gnome (?).
Assuming that the secondary selection is somewhat of an anachronism which is likely to be less used today than the rectangular one would be, the patch uses Meta as default modifier. Both secondary and rectangular mouse selection have defcustoms permitting easy change.
I'd prefer not to step on another feature, if possible. How about
defining a minor mode, and then using the usual mouse selection
gestures instead? That would be more natural, IMO, and will not
require users to give up another feature.

Thanks.
Mattias Engdegård
2019-11-01 11:53:44 UTC
Permalink
Post by Eli Zaretskii
Could you please tell how to try and test this feature? The patch
comes without any documentation, so it's hard to understand quickly
what to do to see this in action.
With the default settings, click and drag (mouse button 1) with meta held to mark a rectangular region.
Sorry about the lack of documentation; it will be written once we agree on the design.
Post by Eli Zaretskii
I'd prefer not to step on another feature, if possible. How about
defining a minor mode, and then using the usual mouse selection
gestures instead? That would be more natural, IMO, and will not
require users to give up another feature.
Very much agree that other features should be left alone, but in this case there seemed to be no really good unused binding.
A minor mode is less ideal: rectangular selection is something the user wants to be able to do on a whim, without having to plan ahead by activating a minor mode. It is also good to follow standard practice in other editors and terminal emulators

Competing mouse bindings are:

Meta: secondary selection
Shift: mouse-appearance-menu (mouse-save-then-kill for NS)
Control: mouse-buffer-menu

The secondary selection appeared weaker than the rest, in the sense that repurposing its binding would annoy fewer users than the alternatives. (Annoyed users can still regain the old behaviour by customisation.)

Other possibilities:

A. Unbind mouse-appearance-menu, mouse-save-then-kill or mouse-buffer-menu instead. The trade-offs are similar.
B. Combined modifiers (Shift-Meta etc). Less ergonomic; there may be platform restrictions.
C. Use a different mouse button. Diverges from other platforms; messy on Macs.
D. Less common modifiers (Super, Hyper). Many don't have them.
E. Follow the platform conventions. Not the Emacs tradition, and makes for more binding clashes.
F. Leaving rectangular selection unbound by default. This is tantamount to stating that it is less useful. Is it?
Eli Zaretskii
2019-11-01 13:17:07 UTC
Permalink
Date: Fri, 1 Nov 2019 12:53:44 +0100
With the default settings, click and drag (mouse button 1) with meta held to mark a rectangular region.
Thanks, I will try.
A minor mode is less ideal: rectangular selection is something the user wants to be able to do on a whim, without having to plan ahead by activating a minor mode. It is also good to follow standard practice in other editors and terminal emulators
And yet cua-rect.el defined a command to enter this mode.

I don't really buy the "on a whim" argument; I think the user always
knows in advance whether the next selection will or won't be
rectangular. So I still think a minor mode is the best solution, if
something like C-M-mouse-1 is not portable enough.
martin rudalics
2019-11-01 13:23:03 UTC
Permalink
Post by Mattias Engdegård
Meta: secondary selection
The meta combinations are bound to the secondary selection in a very
elaborate fashion and should be left alone.
Post by Mattias Engdegård
Shift: mouse-appearance-menu (mouse-save-then-kill for NS)
Control: mouse-buffer-menu
I have no idea why these are bound to down events in the first place.
I would reserve S-down-mouse-1 for extending an existing selection and
provide C-down-mouse-1 for rectangular selection. Some programs allow
C-down-mouse-1 to provide non-contiguous selections which we then
could accommodate easily by checking initially whether a selection is
already active.
Post by Mattias Engdegård
B. Combined modifiers (Shift-Meta etc). Less ergonomic; there may be platform restrictions.
I'd consider these as viable alternatives.

martin
Eli Zaretskii
2019-11-01 13:30:36 UTC
Permalink
Date: Fri, 01 Nov 2019 15:17:07 +0200
Date: Fri, 1 Nov 2019 12:53:44 +0100
With the default settings, click and drag (mouse button 1) with meta held to mark a rectangular region.
Thanks, I will try.
Tried it. I see 2 problems:

. an annoying 1-pixel horizontal movement when I just press
M-mouse-1, but don't move it; this doesn't happen in a "normal"
selection by dragging mouse-1
. problems when dragging the mouse across a TAB -- you cannot select
just a "part" of the TAB's 8-column white space (see cua-rect.el
for how this can be done better)

In addition, it looks like making the rectangular selection is very
error-prone: about 40% of the attempts I get a non-rectangular
selection instead, and sometimes the selection "jumps" to the other
side, i.e. I drag the mouse to the right, but get the text from the
mouse to the _left_ selected, and the selection extends to the BOB.

Thanks.
Drew Adams
2019-11-03 21:51:31 UTC
Permalink
Sorry, but I don't see why you did any of what you
did that affects the secondary selection. Why all
of that? Why not just continue to provide the same
default mouse key bindings for it?

It's always been easy for a user to change those
default mouse key bindings. How are things easier
for users after the proposed changes?

Searching your patch for "second", it seems that the
only changes affecting the secondary affect just the
(mouse) key bindings for it. How is any of that
related to rectangular region selection?

I really don't see what has been gained by the
changes that affect the secondary selection. Can
you please explain? What's the aim - what's the
problem that this is trying to solve?

How about just removing all of the code in the
patch that deals with the secondary selection?
Is any of that needed, to provide mouse selection
of a rectangular region?

And I disagree with removing the longstanding
default mouse key bindings for the secondary.
You've done that in a roundabout way (defaulting
a new user option to nil), but you've done it,
AFAICT.

[BTW, there's no need to use '(); just () suffices.]
martin rudalics
2019-11-04 09:07:17 UTC
Permalink
Post by martin rudalics
The meta combinations are bound to the secondary selection in a very
elaborate fashion and should be left alone.
Abstracting the modifiers for the secondary selection seemed
straightforward to me. Did I miss anything?
I meant that the code for working with the secondary selection has
been set up in a quite meticulous way so I would never mess with it
(including the modifiers it uses).
Picking some free multi-key modifier like shift-control would
have nobody complain, but isn't necessarily optimal.
I usually shift-control with my pinkie alone so I would consider it
optimal and use it for many key combinations all the time.
You seem to believe that mouse-buffer-menu and mouse-appearance-menu
don't deserve their bindings. I'm neutral, but would be interested
in what other people have to say about it.
These deserve their bindings though I would not pop up a menu from a
mouse-down event alone. What I am obviously assuming is that the
rectangular region selection code is based on mouse-dragging from one
corner of the rectangle to the opposite one, so a mouse-drag is easily
distinguishable from a click for a pop-up-menu. If this assumption is
wrong, my rebinding proposal is clearly void.

martin
Mattias Engdegård
2019-11-04 11:33:36 UTC
Permalink
Post by martin rudalics
I meant that the code for working with the secondary selection has
been set up in a quite meticulous way so I would never mess with it
(including the modifiers it uses).
Not here to mess with it, but if the user prefers to free up the Meta modifier for something else but still have access to the secondary selection, it seems to be perfectly possible. The current patch applies the modifier in a consistent way on all related bindings.

Even better would be a unified binding interface that also takes care of clashes in an automated way.

(Drew, don't worry --- the bindings are placeholders so that people can try out the selection mechanism. The default bindings are yet to be determined.)
Post by martin rudalics
I usually shift-control with my pinkie alone so I would consider it
optimal and use it for many key combinations all the time.
Geometry of hands and keyboards varies; I find single-key modifiers easier (but not necessarily difficult) to use.

However, shift-control could be a reasonable default value, if we dare not alter anything else. Is there any reason to prefer one of {shift-control, shift-meta, control-meta} to the rest?
Post by martin rudalics
These deserve their bindings though I would not pop up a menu from a
mouse-down event alone. What I am obviously assuming is that the
rectangular region selection code is based on mouse-dragging from one
corner of the rectangle to the opposite one, so a mouse-drag is easily
distinguishable from a click for a pop-up-menu. If this assumption is
wrong, my rebinding proposal is clearly void.
Thanks for explaining. Unfortunately, region selection and menu pop-up do not seem to be compatible in that way --- at least I didn't manage to use the same modifier for both. Perhaps the events could be multiplexed somehow, but it seems to be on the hacky side.
Drew Adams
2019-11-04 15:25:51 UTC
Permalink
Post by Mattias Engdegård
(Drew, don't worry --- the bindings are placeholders so that people can
try out the selection mechanism. The default bindings are yet to be
determined.)
My latest question was why we would add all of that
stuff - options for choosing modifiers etc. _Users
have control_ over key bindings now. Just what's
the point of adding this other stuff?

And what exactly does that have to do with selecting
a rectangular region with the mouse? Why should that
be mixed in with providing the possibility of using
a mouse to select a rectangular region?

And why provide any binding, by default, for doing
that? The feature hasn't even been introduced to
users yet. Why would we sacrifice a default binding
for it at this time?
martin rudalics
2019-11-04 18:27:44 UTC
Permalink
Post by Mattias Engdegård
Thanks for explaining. Unfortunately, region selection and menu
pop-up do not seem to be compatible in that way --- at least I
didn't manage to use the same modifier for both. Perhaps the events
could be multiplexed somehow, but it seems to be on the hacky side.
If you bind it to the control key you should at least be able to pop
up the buffer menu yourself if the up event occurs at the same
position as the down event.

But here I can simply do

(global-set-key [C-down-mouse-1] 'mouse-drag-region)
(global-set-key [C-drag-mouse-1] 'mouse-set-region)
(global-set-key [C-mouse-1] 'mouse-buffer-menu)

and get both, normal mouse dragging and the buffer menu. What more
would you need?

martin
Mattias Engdegård
2019-11-04 20:18:20 UTC
Permalink
Post by martin rudalics
If you bind it to the control key you should at least be able to pop
up the buffer menu yourself if the up event occurs at the same
position as the down event.
But here I can simply do
(global-set-key [C-down-mouse-1] 'mouse-drag-region)
(global-set-key [C-drag-mouse-1] 'mouse-set-region)
(global-set-key [C-mouse-1] 'mouse-buffer-menu)
and get both, normal mouse dragging and the buffer menu. What more
would you need?
The rectangle-mark code can perhaps be rewritten to work that way, but doesn't it force the pop-up menu to be used with click-release-select-click-release instead of the quicker click-select-release?
martin rudalics
2019-11-05 09:35:30 UTC
Permalink
Post by Mattias Engdegård
The rectangle-mark code can perhaps be rewritten to work that way,
Any code based on mouse dragging should be written in such way that
the corresponding click event can be easily handed over to a separate
command. That's what the drag- prefix is for.
Post by Mattias Engdegård
but doesn't it force the pop-up menu to be used with
click-release-select-click-release instead of the quicker
click-select-release?
Yes and I think that the former is the correct and expected behavior.
I don't use the buffer menu but if I did I were much more annoyed by
the fact that when I abandon the selection by clicking somewhere else
I get an active region which I then have to click away in a further
step.

Note that even the Emacs manual itself confuses down-mouse events and
clicks as

‘C-mouse-1’
This menu is for selecting a buffer.

The MSB (“mouse select buffer”) global minor mode makes this menu
smarter and more customizable. *Note Buffer Menus::.

and

It replaces the ‘mouse-buffer-menu’ commands, normally bound to
‘C-Down-mouse-1’

IMHO the rule should be that non-dragging commands are always bound to
clicks (including double and triple ones) and never to a down- event.
The menu bar might be an exception (Firefox even pops up an entry when
the mouse just hovers over it) but the various (non-)toolkits Emacs
uses for it apparently defeat a common unified behavior anway.

And personally, I'd reserve C-drag-mouse for marking arbitrary
non-contiguous text (like, for example, Firefox does) and use
C-S-drag-mouse for marking rectangular regions.

martin
Mattias Engdegård
2019-11-07 17:48:21 UTC
Permalink
Post by martin rudalics
Any code based on mouse dragging should be written in such way that
the corresponding click event can be easily handed over to a separate
command. That's what the drag- prefix is for.
All right, I re-wrote the patch to allow for independent use for X-mouse-N, but...
Post by martin rudalics
Post by Mattias Engdegård
but doesn't it force the pop-up menu to be used with
click-release-select-click-release instead of the quicker
click-select-release?
Yes and I think that the former is the correct and expected behavior.
I don't use the buffer menu but if I did I were much more annoyed by
the fact that when I abandon the selection by clicking somewhere else
I get an active region which I then have to click away in a further
step.
I don't think so; being able to select from a menu with a single dragging movement is not only more ergonomic, it's the expected behaviour of pop-up menus. mouse.el even contains a comment to that effect:

;; By binding these to down-going events, we let the user use the up-going
;; event to make the selection, saving a click.

You can try for yourself: with the patch applied, bind M-mouse-1 to a menu:

(global-set-key [M-mouse-1] 'mouse-buffer-menu)

Now a single meta-click will open the menu, and meta-drag will mark a rectangle. This sort of multiplexing doesn't feel right, and affects both uses negatively.

For example, suppose you have marked a rectangle and change your mind. Intuitively, you will click somewhere to make the mark go away, using the same modifiers. But that doesn't work, because now you get a pop-up menu.
Post by martin rudalics
IMHO the rule should be that non-dragging commands are always bound to
clicks (including double and triple ones) and never to a down- event.
My patch now follows that rule, but it doesn't seem to solve any problem.
Post by martin rudalics
And personally, I'd reserve C-drag-mouse for marking arbitrary
non-contiguous text (like, for example, Firefox does) and use
C-S-drag-mouse for marking rectangular regions.
Emacs's mouse bindings seem rather haphazard and organised mainly on the principle of first-come, enshrining a fair bit of historical baggage. For example, there are two different buffer menus (one for font and one for everything else). There is also the secondary selection, of which there seems to be much fewer actual users than people who just want to know how to disable it.

We could do worse than following some conventions that have become more or less universal, such as right-clicking (control-click on macOS) for a context menu.

That said, do you have any particular reason (precedence, ergonomics) for suggesting control-shift? I'd rather use meta and move secondary selection to shift-meta (say).

(As before, the attached patch uses meta but that is just a placeholder and should not be interpreted as the final word.)
Drew Adams
2019-11-07 17:53:05 UTC
Permalink
Post by Mattias Engdegård
All right, I re-wrote the patch to allow for
independent use for X-mouse-N, but...
I have the same comments as before, FWIW.

My latest question was why we would add all of that
stuff - options for choosing modifiers etc. _Users
have control_ over key bindings now. Just what's
the point of adding this other stuff?

And what exactly does that have to do with selecting
a rectangular region with the mouse? Why should that
be mixed in with providing the possibility of using
a mouse to select a rectangular region?

And why provide any binding, by default, for doing
that? The feature hasn't even been introduced to
users yet. Why would we sacrifice a default binding
for it at this time?
martin rudalics
2019-11-07 19:08:55 UTC
Permalink
Post by Mattias Engdegård
I don't think so; being able to select from a menu with a single
dragging movement is not only more ergonomic, it's the expected
behaviour of pop-up menus.
But by doing so it usurps all combinations of the control key and
mouse-1. So we pay a high price for such a small convenience. And
since I have never anywhere else seen a "context" menu pop up right
after a mouse press I would not consider it the expected behavior.
Post by Mattias Engdegård
mouse.el even contains a comment to that
;; By binding these to down-going events, we let the user use the up-going
;; event to make the selection, saving a click.
In all those 25 or more years it hasn't found its way into the Emacs
manual though.
Post by Mattias Engdegård
(global-set-key [M-mouse-1] 'mouse-buffer-menu)
Now a single meta-click will open the menu, and meta-drag will mark
a rectangle. This sort of multiplexing doesn't feel right, and
affects both uses negatively.
But the same "multiplexing" already applies for operating the mouse
without any modifiers. And I sometimes use it in a different context:
When I prematurely press the mouse button on a browser link, I can
always bow out by slightly moving the mouse, thus avoiding the
semantics of a click.
Post by Mattias Engdegård
For example, suppose you have marked a rectangle and change your
mind. Intuitively, you will click somewhere to make the mark go
away, using the same modifiers. But that doesn't work, because now
you get a pop-up menu.
The menu should pop up iff the down and up events happen at the same
location. Can we agree that this is hard to achieve after having
marked a rectangle?
Post by Mattias Engdegård
Emacs's mouse bindings seem rather haphazard and organised mainly on
the principle of first-come, enshrining a fair bit of historical
baggage. For example, there are two different buffer menus (one for
font and one for everything else). There is also the secondary
selection, of which there seems to be much fewer actual users than
people who just want to know how to disable it.
Most applications I know do not even distinguish mouse and meta mouse
clicks so I doubt that many users will see this as a problem.
Post by Mattias Engdegård
We could do worse than following some conventions that have become
more or less universal, such as right-clicking (control-click on
macOS) for a context menu.
For me mouse-3 is the preferred button to pop up a menu. I never use
mouse-3 to extend the selection because I'm not used to switch mouse
buttons during one and the same action.
Post by Mattias Engdegård
That said, do you have any particular reason (precedence,
ergonomics) for suggesting control-shift? I'd rather use meta and
move secondary selection to shift-meta (say).
I suggested control-shift because it's IMHO the most convenient
combination with two modifiers (at least on my past and present
keyboards). And I wouldn't change default key bindings that have
existed for decades. But since I never use the secondary selection I
cannot really defend it either.

martin
Drew Adams
2019-11-07 20:46:22 UTC
Permalink
Post by martin rudalics
For me mouse-3 is the preferred button to pop up a menu. I never use
mouse-3 to extend the selection because I'm not used to switch mouse
buttons during one and the same action.
(Replying just about this: mouse-3.)

Vanilla Emacs hard-wires the behavior to kill or
delete the region (depending on the value of
`mouse-drag-copy-region'). That action can be
handy, but it's sometimes inappropriate (e.g., in
a read-only buffer). In any case, it is only one
possible action; there are often other actions on
the selected text that you might want to take.

See `mouse3.el'. You can use mouse-3 for both
a contextual pop-up menu and for extending the
selection.

https://www.emacswiki.org/emacs/Mouse3
Mattias Engdegård
2019-11-08 17:33:24 UTC
Permalink
Post by martin rudalics
But by doing so it usurps all combinations of the control key and
mouse-1. So we pay a high price for such a small convenience. And
since I have never anywhere else seen a "context" menu pop up right
after a mouse press I would not consider it the expected behavior.
I can assure you that press-select-release semantics for popup menus is very common, and has been for several decades. Most applications also support the click-select-click model.

However, I think we largely agree that the current buffer and face menus are of limited utility and that their bindings should not be considered sacred territory.
Post by martin rudalics
For me mouse-3 is the preferred button to pop up a menu. I never use
mouse-3 to extend the selection because I'm not used to switch mouse
buttons during one and the same action.
Finally something we seem to agree on.
Post by martin rudalics
I suggested control-shift because it's IMHO the most convenient
combination with two modifiers (at least on my past and present
keyboards).
Thank you; it's not very convenient on my keyboards, so I'd rather use control-meta, but plain meta is of course better still.
In decreasing order of preference: meta, control, shift, control-meta, shift-meta, shift-control.
martin rudalics
2019-11-08 18:28:48 UTC
Permalink
Post by Mattias Engdegård
I can assure you that press-select-release semantics for popup menus
is very common,
At least here on Windows pressing the right mouse button does nothing
with Firefox, Thunderbird or the desktop.
Post by Mattias Engdegård
and has been for several decades. Most applications also support the
click-select-click model.
However, I think we largely agree that the current buffer and face
menus are of limited utility and that their bindings should not be
considered sacred territory.
I fully agree but obviously cannot speak for the others. It would be
nice though to settle this very issue in order to free the down
bindings for good.
Post by Mattias Engdegård
Thank you; it's not very convenient on my keyboards, so I'd rather
use control-meta, but plain meta is of course better still. In
decreasing order of preference: meta, control, shift, control-meta,
shift-meta, shift-control.
It's clearly up to you to propose any of them.

martin
Mattias Engdegård
2019-11-09 15:35:56 UTC
Permalink
Post by martin rudalics
At least here on Windows pressing the right mouse button does nothing
with Firefox, Thunderbird or the desktop.
Not much of a Windows user myself. Firefox on Linux allows press-drag-release.
Post by martin rudalics
Post by Mattias Engdegård
However, I think we largely agree that the current buffer and face
menus are of limited utility and that their bindings should not be
considered sacred territory.
I fully agree but obviously cannot speak for the others. It would be
nice though to settle this very issue in order to free the down
bindings for good.
Right. To avoid conflating issues, I propose using control-meta for rectangular selection at least as the initial binding. The attached patch also contains documentation updates.

Not sure what to do about the menus. Combining the buffer and appearance menus would free up a binding.

Eli had some concerns regarding the behaviour of an early patch, so I'll wait for him to take another look whenever he can spare a moment. (No hurry.)
Eli Zaretskii
2019-11-09 17:54:56 UTC
Permalink
Date: Sat, 9 Nov 2019 16:35:56 +0100
Eli had some concerns regarding the behaviour of an early patch, so I'll wait for him to take another look whenever he can spare a moment. (No hurry.)
Not sure what I'm missing, but those issues I described before are
still there. Can you tell what you changed and how?
Mattias Engdegård
2019-11-09 19:32:46 UTC
Permalink
Post by Eli Zaretskii
Not sure what I'm missing, but those issues I described before are
still there. Can you tell what you changed and how?
In the first patch, the start and end corners of the rectangle had to be a point in the buffer; ie, not a position beyond the end of a line or in the middle of a tab character. That was not only unnecessarily restrictive but also made the rectangle flutter back and forth as the dragged corner passed through lines of different length. Now the rectangle corners can be any character cell.

If that was not the reason for your concern, would you mind describing the problem more in detail and how to reproduce it?
Eli Zaretskii
2019-11-09 20:04:52 UTC
Permalink
Date: Sat, 9 Nov 2019 20:32:46 +0100
In the first patch, the start and end corners of the rectangle had to be a point in the buffer; ie, not a position beyond the end of a line or in the middle of a tab character. That was not only unnecessarily restrictive but also made the rectangle flutter back and forth as the dragged corner passed through lines of different length. Now the rectangle corners can be any character cell.
OK, that's good.
If that was not the reason for your concern, would you mind describing the problem more in detail and how to reproduce it?
I still see a 1-pixel thin "region" sometimes, which causes the text
to move horizontally. More importantly, if I drag the mouse through a
TAB, it moves in jumps of several columns, not one column at a time.
Richard Stallman
2019-11-10 03:48:10 UTC
Permalink
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
Post by Mattias Engdegård
Not much of a Windows user myself.
Good for you! When someone uses Windows (or MacOS, or Android, or iOS),
that is an instance of the unjust power that free software aims to
free people from.

Firefox on GNU/Linux allows press-drag-release.
--
Dr Richard Stallman
Founder, Free Software Foundation (https://gnu.org, https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)
Mattias Engdegård
2019-11-10 13:49:11 UTC
Permalink
Post by Eli Zaretskii
I still see a 1-pixel thin "region" sometimes, which causes the text
to move horizontally.
Such 'thin' regions (0 cells wide) are legitimate and useful for marking a vertical span of insertion points. For example, they can be used with 'C-x r t' or 'C-x r N'. They are produced in keyboard-based rectangle selection (C-x SPC C-n C-n C-n) as well.
Post by Eli Zaretskii
More importantly, if I drag the mouse through a
TAB, it moves in jumps of several columns, not one column at a time.
The reason is that 'mouse-movement' events are not generated as long as the mouse stays within the same glyph, and a tab counts as a (suitably wide) single glyph. It can be worked around by zig-zagging the mouse a bit, but I agree it's untidy.

Fixing this requires some work on the lower-level plumbing which I'd hoped to avoid. One possibility is to add a global flag that forces 'remember_mouse_glyph' to consider all text glyphs to have nominal char width, or just zero width.

Or even simpler: assuming that STRETCH_GLYPHS are mostly tabs, we can treat them as image glyphs for 'remember_mouse_glyph' purposes. What about:

--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2572,7 +2572,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)

if (g < end)
{
- if (g->type == IMAGE_GLYPH)
+ if (g->type == IMAGE_GLYPH || g->type == STRETCH_GLYPH)
Mattias Engdegård
2019-11-12 14:26:02 UTC
Permalink
This revised patch includes fine-grained mouse-movement events inside stretch glyphs, controlled by 'mouse-movement-in-tab'. Eli, does this fix the problems you observed?

If desired, the variable could be generalised to 'fine-grained-mouse-movement' and affect all movement (not just over stretch glyphs).
Drew Adams
2019-11-12 15:39:27 UTC
Permalink
Again, this is wrong:

"Dragging 'C-M-mouse-1' now marks rectangular regions."

This shouldn't be done, IMO. No default
binding should be made for this.

After years of user experience, we can, if
appropriate, provide a default binding based
on what users actually use. There's no good
excuse for doing that now, IMHO.
Mattias Engdegård
2019-11-14 13:56:34 UTC
Permalink
Slightly polished patch, where the variable is now 'fine-grained-mouse-movement' which seems more generally useful. Please review.
Eli Zaretskii
2019-11-16 12:35:41 UTC
Permalink
Date: Sun, 10 Nov 2019 14:49:11 +0100
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2572,7 +2572,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
if (g < end)
{
- if (g->type == IMAGE_GLYPH)
+ if (g->type == IMAGE_GLYPH || g->type == STRETCH_GLYPH)
Sorry for a late response.

Did you try this with stretch glyphs generated by the likes of
:align-to display 'space' properties? Also, what about stretch glyphs
generated by the display engine in R2L screen lines (you can get those
easily by visiting TUTORIAL.he: each line that has white space at its
left end has a stretch glyph there)?

IOW, it might be necessary to add more conditions here, and just the
mouse_movement_in_tab thingy you added in a later version might not be
enough. E.g., we may need a condition that verifies that this is a
TAB (should be easy by looking at glyph->object, I think).
Mattias Engdegård
2019-11-17 12:11:26 UTC
Permalink
Post by Eli Zaretskii
Did you try this with stretch glyphs generated by the likes of
:align-to display 'space' properties? Also, what about stretch glyphs
generated by the display engine in R2L screen lines (you can get those
easily by visiting TUTORIAL.he: each line that has white space at its
left end has a stretch glyph there)?
I didn't try right-to-left text until now --- thanks for prodding --- and the behaviour was predictably awful. An updated patch (attached) tries to do better (up to what is possible with the underlying rect.el machinery).
Post by Eli Zaretskii
IOW, it might be necessary to add more conditions here, and just the
mouse_movement_in_tab thingy you added in a later version might not be
enough. E.g., we may need a condition that verifies that this is a
TAB (should be easy by looking at glyph->object, I think).
After some false starts, I settled on the simpler 'fine-grained-mouse-movement' solution, giving pixel-wise events no matter what the mouse is pointing at. The extra cost for this is imperceptibly slight, and it feels more generally useful than the 'mouse-movement-in-tab' thingy.
Mattias Engdegård
2019-11-18 18:08:24 UTC
Permalink
Here is an updated patch that makes the selection work better with characters that aren't a multiple of the standard font width.

The underlying rect.el isn't really geared for this sort of thing, leading to ragged rectangle edges and other effects, but at least it is not a new problem; this is not the time to fix it.
Drew Adams
2019-11-18 19:22:36 UTC
Permalink
Please don't bind any mouse buttons for
this, by default.

E.g., please don't bind `C-M-(down-)mouse-1'.

In the doc, just refer to the command, not
a pre-imposed binding for it.
Juri Linkov
2019-11-18 21:29:35 UTC
Permalink
Post by Drew Adams
please don't bind `C-M-(down-)mouse-1'.
I agree. We need to use the same keys as in other applications:
`C-down-mouse-1' to select the rectangular region, then move
its current binding of `mouse-buffer-menu' to the context popup menu
bound to `<mouse-3>' like on all other applications.
martin rudalics
2019-11-19 07:57:15 UTC
Permalink
Post by Juri Linkov
`C-down-mouse-1' to select the rectangular region, then move
its current binding of `mouse-buffer-menu' to the context popup menu
bound to `<mouse-3>' like on all other applications.
As I tried to explain before: Other applications use 'C-down-mouse-1'
for building non-contiguous regions that do _not_ necessarily form a
rectangle.

martin
Mattias Engdegård
2019-11-19 13:57:59 UTC
Permalink
Post by martin rudalics
Post by Juri Linkov
`C-down-mouse-1' to select the rectangular region, then move
its current binding of `mouse-buffer-menu' to the context popup menu
bound to `<mouse-3>' like on all other applications.
As I tried to explain before: Other applications use 'C-down-mouse-1'
for building non-contiguous regions that do _not_ necessarily form a
rectangle.
You are both right, and I, too, would prefer a better modifier than control-meta.
Platform conventions vary, although right-button is clearly dominant for context menus today. There is no similarly agreed way to select rectangles of text.

Nevertheless, I would like this patch to be pushed as long as there is no objection to the design and implementation of the feature itself. It uses nobody's favourite binding, but at least the feature is accessible in a useful way. With it in place, we can argue about shuffling bindings around.
Drew Adams
2019-11-19 15:09:32 UTC
Permalink
Post by Mattias Engdegård
You are both right, and I, too, would prefer a better modifier than
control-meta.
Platform conventions vary, although right-button is clearly dominant
for context menus today. There is no similarly agreed way to select
rectangles of text.
Nevertheless, I would like this patch to be pushed as long as there is
no objection to the design and implementation of the feature itself.
The feature itself does not include imposing a
binding by default. The feature is not the problem.
Post by Mattias Engdegård
It uses nobody's favourite binding, but at least
the feature is accessible in a useful way.
The feature is accessible without a default binding.
Post by Mattias Engdegård
With it in place, we can argue about shuffling
bindings around.
No. We should argue, if that's needed, only after
the feature has been used by users for quite a while
and users have called for a default binding.

Please do not bind this feature by default at all.
Users can bind it as they see fit.

This is a new feature. Binding can be considered
after a (hopefully long) period of use and experimentation.
Mattias Engdegård
2019-11-19 15:37:50 UTC
Permalink
Post by Drew Adams
No. We should argue, if that's needed, only after
the feature has been used by users for quite a while
and users have called for a default binding.
Of course rectangular selection should have a binding by default. This is not controversial in the slightest.
Drew Adams
2019-11-19 16:08:32 UTC
Permalink
Post by Mattias Engdegård
Post by Drew Adams
No. We should argue, if that's needed, only after
the feature has been used by users for quite a while
and users have called for a default binding.
Of course rectangular selection should have a binding by default. This
is not controversial in the slightest.
Count me as one user who disagrees that this deserves
a default binding.

Eli suggested defining a minor mode, as does CUA.

That mode could be global, and it could have a default
binding for this, like CUA. That's the right approach,
IMHO.

When CUA (including CUA rectangle) was introduced, it
wasn't foisted on all Emacs users by imposing its
bindings. It's coexisted politely in a minor mode.

Lots of users liked CUA and used it. And eventually
its rectangle selection was introduced outside CUA.

I see no reason why Emacs should precipitously bind
mouse actions to this new feature by default. Anyone
who wants to use it could just turn on the minor mode
once, and leave it on, getting whatever default
bindings you want for that.

That shouldn't be "controversial in the slightest".
Mattias Engdegård
2019-11-19 16:26:22 UTC
Permalink
Post by Drew Adams
Count me as one user who disagrees that this deserves
a default binding.
We'll have to disagree then. A mode is useful when a different set of behaviour is desired, but it's not the case here.
Eli Zaretskii
2019-11-19 17:30:56 UTC
Permalink
Date: Tue, 19 Nov 2019 08:08:32 -0800 (PST)
Post by Mattias Engdegård
Of course rectangular selection should have a binding by default. This
is not controversial in the slightest.
Count me as one user who disagrees that this deserves
a default binding.
A command that needs to drag the mouse makes no sense without a
binding to some mouse gesture.
Eli suggested defining a minor mode, as does CUA.
I suggested a minor mode as a way to allow us using the same binding
as used for another command by default. I did NOT suggest to have a
minor mode _instead_ of a binding.
Juri Linkov
2019-11-19 23:07:43 UTC
Permalink
Post by martin rudalics
Post by Juri Linkov
`C-down-mouse-1' to select the rectangular region, then move
its current binding of `mouse-buffer-menu' to the context popup menu
bound to `<mouse-3>' like on all other applications.
As I tried to explain before: Other applications use 'C-down-mouse-1'
for building non-contiguous regions that do _not_ necessarily form a
rectangle.
Indeed Emacs could use the same 'C-down-mouse-1' to select non-contiguous
regions. In fact the Emacs rectangular region is a special case of the
non-contiguous region. So implementing the non-contiguous region selection
would require just writing a pair of short functions.

Regarding a mouse binding for the rectangular region selection,
maybe 'C-M-down-mouse-1' still would be a good choice after all,
while 'C-down-mouse-1' should be reserved for the more general
non-contiguous region selection.

Another variant is not to bind 'C-M-down-mouse-1', but use just
'mouse-1' after the rectangle selection mode is activated by its
current key sequence 'C-x RET'.
martin rudalics
2019-11-20 07:57:51 UTC
Permalink
Post by Juri Linkov
Regarding a mouse binding for the rectangular region selection,
maybe 'C-M-down-mouse-1' still would be a good choice after all,
while 'C-down-mouse-1' should be reserved for the more general
non-contiguous region selection.
Another variant is not to bind 'C-M-down-mouse-1', but use just
'mouse-1' after the rectangle selection mode is activated by its
current key sequence 'C-x RET'.
We probably should provide both in a customizable way. I already lack
the ability to reliably move the mouse cursor between characters, so I
have no preference.

martin
Eli Zaretskii
2019-11-23 11:57:24 UTC
Permalink
Date: Mon, 18 Nov 2019 19:08:24 +0100
Here is an updated patch that makes the selection work better with characters that aren't a multiple of the standard font width.
I think this variable's name should start with "mouse-". Like
mouse-fine-grained-movement or something.
+ (setq fine-grained-mouse-movement t)
What happens if this function signals an error? won't
fine-grained-mouse-movement be left at its non-nil value?
Mattias Engdegård
2019-11-23 12:46:08 UTC
Permalink
Post by Eli Zaretskii
I think this variable's name should start with "mouse-". Like
mouse-fine-grained-movement or something.
True, but since the variable pertains to the 'mouse-movement' event in particular and not to moving the mouse about in general, it is also useful to have the name reflect that relation.
'mouse-movement-fine-grained' is possible but a bit awkward. What about 'mouse-fine-grained-tracking'?
Post by Eli Zaretskii
+ (setq fine-grained-mouse-movement t)
What happens if this function signals an error? won't
fine-grained-mouse-movement be left at its non-nil value?
Good question. Ideally, the variable (and 'track-mouse') would be dynamically bound during the drag. However, since the function, mouse-drag-region-rectangle, returns as the drag commences, this is not possible.

The code follows the pattern of other functions in the same file in that it trusts the exit function of the transient map to be executed eventually, and the first thing done in that exit function is to reset the variables.

All these functions have a small hole between setting the variables and the successful return of set-transient-map, during which an error will not result in the variables being reset. We could wrap the set-transient-map calls in condition-case everywhere, if we think that this would increase robustness. Basically,

(condition-case err
(set-transient-map ...)
(error (setq fine-grained-mouse-movement nil)
(setq track-mouse nil)
(signal (car err) (cdr err))))

An earlier version of the patch used the 'track-mouse' macro instead, which does not have this problem, but I changed after complaints that it does not permit independent use of the mouse click event. (For instance, if the selection uses M-down-mouse-1 and M-drag-mouse-1, M-mouse-1 could not be used for anything else.) However, I'm not convinced that this would be much of a limitation.

(Some code in mouse.el uses the track-mouse macro: mouse-drag-and-drop-region and mouse-drag-secondary.)
Eli Zaretskii
2019-11-23 14:53:13 UTC
Permalink
Date: Sat, 23 Nov 2019 13:46:08 +0100
Post by Eli Zaretskii
I think this variable's name should start with "mouse-". Like
mouse-fine-grained-movement or something.
True, but since the variable pertains to the 'mouse-movement' event in particular and not to moving the mouse about in general, it is also useful to have the name reflect that relation.
'mouse-movement-fine-grained' is possible but a bit awkward. What about 'mouse-fine-grained-tracking'?
Fine with me.
The code follows the pattern of other functions in the same file in that it trusts the exit function of the transient map to be executed eventually, and the first thing done in that exit function is to reset the variables.
All these functions have a small hole between setting the variables and the successful return of set-transient-map, during which an error will not result in the variables being reset. We could wrap the set-transient-map calls in condition-case everywhere, if we think that this would increase robustness. Basically,
(condition-case err
(set-transient-map ...)
(error (setq fine-grained-mouse-movement nil)
(setq track-mouse nil)
(signal (car err) (cdr err))))
I think this would be better. IME, such small windows eventually
cause strange and hard to debug bugs, so any measures to make the
window smaller or eliminate it are welcome.

Thanks.
Mattias Engdegård
2019-11-23 15:17:12 UTC
Permalink
Post by Eli Zaretskii
Fine with me.
Good, mouse-fine-grained-tracking it is then.
Post by Eli Zaretskii
I think this would be better. IME, such small windows eventually
cause strange and hard to debug bugs, so any measures to make the
window smaller or eliminate it are welcome.
The window has now been shrunk to almost nothing, and condition-case added for good measure. (Old code in mouse.el left untouched.)
Mattias Engdegård
2019-11-27 14:04:00 UTC
Permalink
It seems that we are done; pushed.
It would still be nice to have a simpler binding.

Loading...