mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Cancel drag-select when the context menu pops up.
I got a pterm into a stuck state this morning by an accidental mouse action. I'd intended to press Ctrl + right-click to pop up the context menu, but I accidentally pressed down the left button first, starting a selection drag, and then while the left button was still held down, pressed down the right button as well, triggering the menu. The effect was that the context menu appeared while term->selstate was set to DRAGGING, in which state terminal output is suppressed, and which is only unset by a mouse-button release event. But then that release event went to the popup menu, and the terminal window never got it. So the terminal stayed stuck forever - or rather, until I guessed the cause and did another selection drag to reset it. This happened to me on GTK, but once I knew how I'd done it, I found I could reproduce the same misbehaviour on Windows by the same method. Added a simplistic fix, on both platforms, that cancels a selection drag if the popup menu is summoned part way through it.
This commit is contained in:
parent
5d58931b51
commit
bdab00341b
1
putty.h
1
putty.h
@ -2137,6 +2137,7 @@ void term_pwron(Terminal *, bool);
|
||||
void term_clrsb(Terminal *);
|
||||
void term_mouse(Terminal *, Mouse_Button, Mouse_Button, Mouse_Action,
|
||||
int, int, bool, bool, bool);
|
||||
void term_cancel_selection_drag(Terminal *);
|
||||
void term_key(Terminal *, Key_Sym, wchar_t *, size_t, unsigned int,
|
||||
unsigned int);
|
||||
void term_lost_clipboard_ownership(Terminal *, int clipboard);
|
||||
|
@ -7299,6 +7299,23 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
void term_cancel_selection_drag(Terminal *term)
|
||||
{
|
||||
/*
|
||||
* In unusual circumstances, a mouse drag might be interrupted by
|
||||
* something that steals the rest of the mouse gesture. An example
|
||||
* is the GTK popup menu appearing. In that situation, we'll never
|
||||
* receive the MA_RELEASE that finishes the DRAGGING state, which
|
||||
* means terminal output could be suppressed indefinitely. Call
|
||||
* this function from the front end in such situations to restore
|
||||
* sensibleness.
|
||||
*/
|
||||
if (term->selstate == DRAGGING)
|
||||
term->selstate = NO_SELECTION;
|
||||
term_out(term, false);
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
static int shift_bitmap(bool shift, bool ctrl, bool alt, bool *consumed_alt)
|
||||
{
|
||||
int bitmap = (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0);
|
||||
|
@ -2162,6 +2162,8 @@ static gboolean button_internal(GtkFrontend *inst, GdkEventButton *event)
|
||||
}
|
||||
|
||||
if (event->button == 3 && ctrl) {
|
||||
/* Just in case this happened in mid-select */
|
||||
term_cancel_selection_drag(inst->term);
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
gtk_menu_popup_at_pointer(GTK_MENU(inst->menu), (GdkEvent *)event);
|
||||
#else
|
||||
|
@ -2641,6 +2641,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
(conf_get_int(conf, CONF_mouse_is_xterm) == 2))) {
|
||||
POINT cursorpos;
|
||||
|
||||
/* Just in case this happened in mid-select */
|
||||
term_cancel_selection_drag(term);
|
||||
|
||||
show_mouseptr(true); /* make sure pointer is visible */
|
||||
GetCursorPos(&cursorpos);
|
||||
TrackPopupMenu(popup_menus[CTXMENU].menu,
|
||||
|
Loading…
Reference in New Issue
Block a user