forked from aniani/vim
patch 9.0.0775: MS-Windows: mouse scrolling not supported in the console
Problem: MS-Windows: mouse scrolling not supported in the console. Solution: Add event handling for mouse scroll events. (Christopher Plewright, closes #11374)
This commit is contained in:
committed by
Bram Moolenaar
parent
6a12d26f34
commit
2a46f81ec7
137
src/os_win32.c
137
src/os_win32.c
@@ -1231,6 +1231,100 @@ mch_bevalterm_changed(void)
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* Win32 console mouse scroll event handler.
|
||||
* Loosely based on the _OnMouseWheel() function in gui_w32.c
|
||||
*
|
||||
* This encodes the mouse scroll direction and keyboard modifiers into
|
||||
* g_nMouseClick, and the mouse position into g_xMouse and g_yMouse
|
||||
*
|
||||
* The direction of the scroll is decoded from two fields of the win32 console
|
||||
* mouse event record;
|
||||
* 1. The axis - vertical or horizontal flag - from dwEventFlags, and
|
||||
* 2. The sign - positive or negative (aka delta flag) - from dwButtonState
|
||||
*
|
||||
* When scroll axis is HORIZONTAL
|
||||
* - If the high word of the dwButtonState member contains a positive
|
||||
* value, the wheel was rotated to the right.
|
||||
* - Otherwise, the wheel was rotated to the left.
|
||||
* When scroll axis is VERTICAL
|
||||
* - If the high word of the dwButtonState member contains a positive value,
|
||||
* the wheel was rotated forward, away from the user.
|
||||
* - Otherwise, the wheel was rotated backward, toward the user.
|
||||
*/
|
||||
static void
|
||||
decode_mouse_wheel(MOUSE_EVENT_RECORD *pmer)
|
||||
{
|
||||
win_T *wp;
|
||||
int horizontal = (pmer->dwEventFlags == MOUSE_HWHEELED);
|
||||
int zDelta = pmer->dwButtonState;
|
||||
|
||||
g_xMouse = pmer->dwMousePosition.X;
|
||||
g_yMouse = pmer->dwMousePosition.Y;
|
||||
|
||||
#ifdef FEAT_PROP_POPUP
|
||||
int lcol;
|
||||
int lrow;
|
||||
lcol = g_xMouse;
|
||||
lrow = g_yMouse;
|
||||
wp = mouse_find_win(&lrow, &lcol, FAIL_POPUP);
|
||||
if (wp != NULL && popup_is_popup(wp))
|
||||
{
|
||||
g_nMouseClick = -1;
|
||||
cmdarg_T cap;
|
||||
oparg_T oa;
|
||||
CLEAR_FIELD(cap);
|
||||
clear_oparg(&oa);
|
||||
cap.oap = &oa;
|
||||
if (horizontal)
|
||||
{
|
||||
cap.arg = zDelta < 0 ? MSCR_LEFT : MSCR_RIGHT;
|
||||
cap.cmdchar = zDelta < 0 ? K_MOUSELEFT : K_MOUSERIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
cap.cmdchar = zDelta < 0 ? K_MOUSEUP : K_MOUSEDOWN;
|
||||
cap.arg = zDelta < 0 ? MSCR_UP : MSCR_DOWN;
|
||||
}
|
||||
|
||||
// Mouse hovers over popup window, scroll it if possible.
|
||||
mouse_row = wp->w_winrow;
|
||||
mouse_col = wp->w_wincol;
|
||||
nv_mousescroll(&cap);
|
||||
update_screen(0);
|
||||
setcursor();
|
||||
out_flush();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
mouse_col = g_xMouse;
|
||||
mouse_row = g_yMouse;
|
||||
|
||||
char_u modifiers = 0;
|
||||
char_u direction = 0;
|
||||
|
||||
// Decode the direction into an event that Vim can process
|
||||
if (horizontal)
|
||||
direction = zDelta >= 0 ? KE_MOUSELEFT : KE_MOUSERIGHT;
|
||||
else
|
||||
direction = zDelta >= 0 ? KE_MOUSEDOWN : KE_MOUSEUP;
|
||||
|
||||
// Decode the win32 console key modifers into Vim mouse modifers.
|
||||
if (pmer->dwControlKeyState & SHIFT_PRESSED)
|
||||
modifiers |= MOD_MASK_SHIFT; //MOUSE_SHIFT;
|
||||
if (pmer->dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
|
||||
modifiers |= MOD_MASK_CTRL; //MOUSE_CTRL;
|
||||
if (pmer->dwControlKeyState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
|
||||
modifiers |= MOD_MASK_ALT; // MOUSE_ALT;
|
||||
|
||||
// add (bitwise or) the scroll direction and the key modifier chars
|
||||
// together.
|
||||
g_nMouseClick = ((direction << 8) | modifiers);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a MOUSE_EVENT. If it's a valid event, return MOUSE_LEFT,
|
||||
* MOUSE_MIDDLE, or MOUSE_RIGHT for a click; MOUSE_DRAG for a mouse
|
||||
@@ -1304,6 +1398,13 @@ decode_mouse_event(
|
||||
if (g_nMouseClick != -1)
|
||||
return TRUE;
|
||||
|
||||
if (pmer->dwEventFlags == MOUSE_WHEELED
|
||||
|| pmer->dwEventFlags == MOUSE_HWHEELED)
|
||||
{
|
||||
decode_mouse_wheel(pmer);
|
||||
return TRUE; // we now should have a mouse scroll in g_nMouseClick
|
||||
}
|
||||
|
||||
nButton = -1;
|
||||
g_xMouse = pmer->dwMousePosition.X;
|
||||
g_yMouse = pmer->dwMousePosition.Y;
|
||||
@@ -1939,12 +2040,34 @@ mch_inchar(
|
||||
fprintf(fdDump, "{%02x @ %d, %d}",
|
||||
g_nMouseClick, g_xMouse, g_yMouse);
|
||||
# endif
|
||||
typeahead[typeaheadlen++] = ESC + 128;
|
||||
typeahead[typeaheadlen++] = 'M';
|
||||
typeahead[typeaheadlen++] = g_nMouseClick;
|
||||
typeahead[typeaheadlen++] = g_xMouse + '!';
|
||||
typeahead[typeaheadlen++] = g_yMouse + '!';
|
||||
g_nMouseClick = -1;
|
||||
char_u modifiers = ((char_u *)(&g_nMouseClick))[0];
|
||||
char_u scroll_dir = ((char_u *)(&g_nMouseClick))[1];
|
||||
|
||||
if (scroll_dir == KE_MOUSEDOWN
|
||||
|| scroll_dir == KE_MOUSEUP
|
||||
|| scroll_dir == KE_MOUSELEFT
|
||||
|| scroll_dir == KE_MOUSERIGHT)
|
||||
{
|
||||
if (modifiers > 0)
|
||||
{
|
||||
typeahead[typeaheadlen++] = CSI;
|
||||
typeahead[typeaheadlen++] = KS_MODIFIER;
|
||||
typeahead[typeaheadlen++] = modifiers;
|
||||
}
|
||||
typeahead[typeaheadlen++] = CSI;
|
||||
typeahead[typeaheadlen++] = KS_EXTRA;
|
||||
typeahead[typeaheadlen++] = scroll_dir;
|
||||
g_nMouseClick = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeahead[typeaheadlen++] = ESC + 128;
|
||||
typeahead[typeaheadlen++] = 'M';
|
||||
typeahead[typeaheadlen++] = g_nMouseClick;
|
||||
typeahead[typeaheadlen++] = g_xMouse + '!';
|
||||
typeahead[typeaheadlen++] = g_yMouse + '!';
|
||||
g_nMouseClick = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8361,7 +8484,7 @@ stop_timeout(void)
|
||||
{
|
||||
if (timer_active)
|
||||
{
|
||||
BOOL ret = DeleteTimerQueueTimer(NULL, timer_handle, NULL);
|
||||
BOOL ret = DeleteTimerQueueTimer(NULL, timer_handle, NULL);
|
||||
timer_active = FALSE;
|
||||
if (!ret && GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
|
Reference in New Issue
Block a user