1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Windows: try to send only one term_size on request_resize.

Previously, the Windows implementation of win_request_resize would
call term_size() to tell the terminal about its new size, _before_
calling SetWindowPos to actually change the window size.

If SetWindowPos ends up not getting the exact window size it asks for,
Windows notifies the application by sending back a WM_SIZE message -
synchronously, by calling back to the window procedure from within
SetWindowPos. So after the first over-optimistic term_size(), the
WM_SIZE handler would trigger a second one, resetting the terminal
again to the _actual_ size.

This was more or less harmless, since current handling of terminal
resizes is such that no terminal data gets too confused: any lines
pushed into the scrollback by the first term_size will be pulled back
out by the second one if needed (or vice versa), and since commit
271de3e4ec, individual termlines are not eagerly truncated by
resizing them twice.

However, it's more work than we really wanted to be doing, and it
seems presumptuous to send term_size() before we know it's right! So
now we send term_size() after SetWindowPos returns, unless it already
got sent by a re-entrant call to the WM_SIZE handler _before_
SetWindowPos returned. That way, the terminal should get exactly one
term_size() call in response to win_request_resize(), whether it got
the size it was expecting or not.
This commit is contained in:
Simon Tatham 2021-12-13 06:54:49 +00:00
parent 420fe75552
commit cfc9023616

View File

@ -1590,6 +1590,8 @@ static void deinit_fonts(void)
trust_icon = INVALID_HANDLE_VALUE;
}
static bool sent_term_size; /* only live during wintw_request_resize() */
static void wintw_request_resize(TermWin *tw, int w, int h)
{
const struct BackendVtable *vt;
@ -1635,7 +1637,18 @@ static void wintw_request_resize(TermWin *tw, int w, int h)
}
}
term_size(term, h, w, conf_get_int(conf, CONF_savelines));
/*
* We want to send exactly one term_size() to the terminal,
* telling it what size it ended up after this operation.
*
* If we don't get the size we asked for in SetWindowPos, then
* we'll be sent a WM_SIZE message, whose handler will make that
* call, all before SetWindowPos even returns to here.
*
* But if that _didn't_ happen, we'll need to call term_size
* ourselves afterwards.
*/
sent_term_size = false;
if (conf_get_int(conf, CONF_resize_action) != RESIZE_FONT &&
!IsZoomed(wgs.term_hwnd)) {
@ -1648,6 +1661,9 @@ static void wintw_request_resize(TermWin *tw, int w, int h)
} else
reset_window(0);
if (!sent_term_size)
term_size(term, h, w, conf_get_int(conf, CONF_savelines));
InvalidateRect(wgs.term_hwnd, NULL, true);
}
@ -2088,6 +2104,11 @@ static void wm_size_resize_term(LPARAM lParam, bool border)
} else {
term_size(term, h, w,
conf_get_int(conf, CONF_savelines));
/* If this is happening re-entrantly during the call to
* SetWindowPos in wintw_request_resize, let it know that
* we've already done a term_size() so that it doesn't have
* to. */
sent_term_size = true;
}
}