Releases: directvt/vtm
v2025.08.19
Changes
- Fix the issue with paths containing spaces (#789 (comment)).
- Set
Esc+I
to launchInfo-page
. - Set
Esc+F1
(Alt+Z
on non-Windows) to focus taskbar (but keyboard navigation on taskbar is not implemented yet, #86).
v2025.08.17
Changes
- Fix mouse pointer rendering (position offset), #789.
- Fix unintended selection on double click in Far Manager.
v2025.08.15
Known issues
Vtm sometimes crashes when multiple users connect to the desktop (fixed in v2025.08.17). May be related to #789.
Changes
- Make
vt-input-mode
mouse reporting better (could be enabled for test byprintf "\e_vtm.terminal.EventReporting('mouse')\a"
).
The mouse event message now has the following format (changes affected scrolling):
ESC _ event=mouse ; id=<ID> ; kbmods=<KeyMods> ; coor=<X>,<Y> ; buttons=<ButtonState> ; iscroll=<DeltaX>,<DeltaY> ; fscroll=<DeltaX>,<DeltaY> ST
where:
id=<ID>
Device group id (unsigned integer).kbmods=<KeyMods>
Keyboard modifiers bit field (unsigned integer).coor=<X>,<Y>
32-bit floating point coordinates of the mouse pointer relative to the console's text cell grid. The integer part corresponds to the cell coordinates, and the fractional part corresponds to the normalized position within the cell. The pointer's screen pixel coordinates can be calculated by multiplying these floating point values by the cell size. Receiving a NaN value is a signal that the mouse has left the window or disconnected.buttons=<ButtonState>
Mouse buttons bit field (unsigned integer).iscroll=<DeltaX>,<DeltaY>
Horizontal and vertical low-resolution scroll deltas in form of signed integers (one scroll line corresponds to a value of 1). Low-resolution scroll deltas increase as the values of high-resolution deltas accumulate, and are zeroed when the scroll direction changes.fscroll=<DeltaX>,<DeltaY>
Horizontal and vertical high-resolution scroll deltas in form of 32-bit floating-point values (one scroll line corresponds to a value of 1.0f).
We use HEX-form of the uint32 for the 32-bit floating point value representation (IEEE-754 32-bit binary float). For example, the floating point value 3.1415f
is represented as the unsigned integer in hex 40490E56
(decimal 1078529622).
v2025.08.14
Changes
- Implement mouse event reporting via
vt-input-mode
protocol. This protocol is capable of reporting pixel-wise mouse coordinates, as well as deltas for fine scrolling (when using touchpads).
v2025.08.13
Changes
- Allow to control terminal using Lua scripts via APC vt-sequences.
The built-in terminal is now capable of executing Lua scripts received via APC (Application Program Command) vt-sequences.
APC vt-sequence format:
ESC _ <script body> ESC \
or
ESC _ <script body> BEL
where:
ESC_
is the APC vt-sequence prefix.<script body>
- Lua script sent for execution.ESC\
orBEL
- APC vt-sequence terminator.
Usage examples:
bash
:# Print the current scrollback buffer limits printf "\e_local n,m,q=vtm.terminal.ScrollbackSize(); vtm.terminal.PrintLn('size=', n, ' growstep=', m, ' maxsize=', q)\e\\" # Set the scrollback buffer limit to 10K lines printf "\e_vtm.terminal.ScrollbackSize(10000)\e\a" # Maximize the terminal window printf "\e_vtm.applet.Maximize()\e\\"
A complete list of available script functions can be found in settings.md.
v2025.08.12
Changes
-
Enable pixel-wise mouse reporting over Win32 Console API.
Pixel-wise or fractional coordinates are 32-bit floating-point numbers that represent the position of the mouse cursor relative to the console's grid of text cells. Screen pixel coordinates can be calculated by multiplying the fractional coordinates by the cell size.
Fractional mouse coordinates are critical to UX. In particular, this directly relates to the sensitivity of scrollbars, where moving the mouse pointer even one pixel can cause content to scroll several lines.
On Windows, when using the Win32 Console API, vtm now reports mouse events with fractional mouse coordinates.For example, run the following snippet inside vtm and then in classic Windows Command Prompt outside vtm:
#include <iostream> #include <vector> #include <windows.h> static constexpr auto custom_type = 0b1000'0000'0000'0000; static constexpr auto fp2d_mouse = 3; struct fp2d_mouse_input : MENU_EVENT_RECORD // MENU_EVENT_RECORD structure extension. { //DWORD EventType = MENU_EVENT; //DWORD dwCommandId = custom_type | fp2d_mouse; float x; // Floating point mouse x coord. float y; // Floating point mouse y coord. }; int main() { auto inp = ::GetStdHandle(STD_INPUT_HANDLE); ::SetConsoleMode(inp, ENABLE_EXTENDED_FLAGS | ENABLE_MOUSE_INPUT); auto r = INPUT_RECORD{}; auto count = DWORD{}; auto x = std::numeric_limits<float>::quiet_NaN(); auto y = std::numeric_limits<float>::quiet_NaN(); auto mouse_out = false; std::cout << "Press any mouse button to exit\n"; while (true) { ::ReadConsoleInputW(inp, &r, 1, &count); if (r.EventType == MENU_EVENT) { if (r.Event.MenuEvent.dwCommandId == (custom_type | fp2d_mouse)) // The floating point coordinates message always precedes the classic mouse report. { x = reinterpret_cast<fp2d_mouse_input*>(&r.Event.MenuEvent)->x; y = reinterpret_cast<fp2d_mouse_input*>(&r.Event.MenuEvent)->y; mouse_out = std::isnan(x); // NaN is a sign that the mouse has gone away or is disconnected. if (mouse_out) std::cout << "The mouse has left the window\n"; } } else if (r.EventType == MOUSE_EVENT && !mouse_out) { if (r.Event.MouseEvent.dwButtonState) return 0; if (std::isnan(x)) // Classical behavior. { std::cout << "MOUSE_EVENT coord: " << r.Event.MouseEvent.dwMousePosition.X << "," << r.Event.MouseEvent.dwMousePosition.Y << "\n"; } else // Floating point mouse coordinates. { std::cout << "MOUSE_EVENT coord: " << x << "," << y << "\n"; } } } }