2019-07-09 16:26:36 +02:00
|
|
|
#include "commands.h"
|
|
|
|
|
|
|
|
|
|
#define LOG_MODULE "commands"
|
2019-07-10 14:45:00 +02:00
|
|
|
#define LOG_ENABLE_DBG 0
|
2019-07-09 16:26:36 +02:00
|
|
|
#include "log.h"
|
|
|
|
|
#include "grid.h"
|
2020-05-19 18:49:42 +02:00
|
|
|
#include "render.h"
|
|
|
|
|
#include "selection.h"
|
|
|
|
|
#include "terminal.h"
|
2021-02-23 09:28:43 +01:00
|
|
|
#include "url-mode.h"
|
2020-05-01 11:46:24 +02:00
|
|
|
#include "util.h"
|
2019-07-09 16:26:36 +02:00
|
|
|
|
|
|
|
|
void
|
2019-07-10 09:15:37 +02:00
|
|
|
cmd_scrollback_up(struct terminal *term, int rows)
|
2019-07-09 16:26:36 +02:00
|
|
|
{
|
2019-07-10 09:15:37 +02:00
|
|
|
if (term->grid == &term->alt)
|
|
|
|
|
return;
|
2021-02-23 09:28:43 +01:00
|
|
|
if (urls_mode_is_active(term))
|
|
|
|
|
return;
|
2019-07-10 09:15:37 +02:00
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
const struct grid *grid = term->grid;
|
|
|
|
|
const int offset = grid->offset;
|
|
|
|
|
const int view = grid->view;
|
|
|
|
|
const int grid_rows = grid->num_rows;
|
|
|
|
|
const int screen_rows = term->rows;
|
|
|
|
|
|
|
|
|
|
int scrollback_start = (offset + screen_rows) & (grid_rows - 1);
|
|
|
|
|
|
|
|
|
|
/* Part of the scrollback may be uninitialized */
|
|
|
|
|
while (grid->rows[scrollback_start] == NULL) {
|
|
|
|
|
scrollback_start++;
|
|
|
|
|
scrollback_start &= grid_rows - 1;
|
2019-07-10 14:28:20 +02:00
|
|
|
}
|
|
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
/* Number of rows to scroll, without going past the scrollback start */
|
|
|
|
|
int max_rows = 0;
|
|
|
|
|
if (view + screen_rows >= grid_rows) {
|
|
|
|
|
/* View crosses scrollback wrap-around */
|
|
|
|
|
xassert(scrollback_start <= view);
|
|
|
|
|
max_rows = view - scrollback_start;
|
2019-07-10 09:29:36 +02:00
|
|
|
} else {
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
if (scrollback_start <= view)
|
|
|
|
|
max_rows = view - scrollback_start;
|
|
|
|
|
else
|
|
|
|
|
max_rows = view + (grid_rows - scrollback_start);
|
2019-07-10 09:29:36 +02:00
|
|
|
}
|
|
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
rows = min(rows, max_rows);
|
|
|
|
|
if (rows == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int new_view = (view + grid_rows) - rows;
|
|
|
|
|
new_view &= grid_rows - 1;
|
2020-02-21 23:35:43 +01:00
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
xassert(new_view != view);
|
|
|
|
|
xassert(grid->rows[new_view] != NULL);
|
2019-07-10 16:36:10 +02:00
|
|
|
#if defined(_DEBUG)
|
|
|
|
|
for (int r = 0; r < term->rows; r++)
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
xassert(grid->rows[(new_view + r) & (grid->num_rows - 1)] != NULL);
|
2019-07-10 16:36:10 +02:00
|
|
|
#endif
|
|
|
|
|
|
2019-07-10 14:42:48 +02:00
|
|
|
LOG_DBG("scrollback UP: %d -> %d (offset = %d, end = %d, rows = %d)",
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
view, new_view, offset, end, grid_rows);
|
2019-08-04 19:06:49 +02:00
|
|
|
|
2020-05-19 18:49:42 +02:00
|
|
|
selection_view_up(term, new_view);
|
2019-07-09 16:26:36 +02:00
|
|
|
term->grid->view = new_view;
|
|
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
if (rows < term->rows) {
|
|
|
|
|
term_damage_scroll(
|
|
|
|
|
term, DAMAGE_SCROLL_REVERSE_IN_VIEW,
|
|
|
|
|
(struct scroll_region){0, term->rows}, rows);
|
|
|
|
|
term_damage_rows_in_view(term, 0, rows - 1);
|
2019-08-04 19:06:49 +02:00
|
|
|
} else
|
|
|
|
|
term_damage_view(term);
|
|
|
|
|
|
2021-02-06 11:47:59 +01:00
|
|
|
render_refresh_urls(term);
|
2019-07-24 20:09:49 +02:00
|
|
|
render_refresh(term);
|
2019-07-09 16:26:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2019-07-10 09:15:37 +02:00
|
|
|
cmd_scrollback_down(struct terminal *term, int rows)
|
2019-07-09 16:26:36 +02:00
|
|
|
{
|
2019-07-10 09:15:37 +02:00
|
|
|
if (term->grid == &term->alt)
|
|
|
|
|
return;
|
2021-02-23 09:28:43 +01:00
|
|
|
if (urls_mode_is_active(term))
|
|
|
|
|
return;
|
2019-07-10 09:15:37 +02:00
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
const struct grid *grid = term->grid;
|
|
|
|
|
const int offset = grid->offset;
|
|
|
|
|
const int view = grid->view;
|
|
|
|
|
const int grid_rows = grid->num_rows;
|
|
|
|
|
const int screen_rows = term->rows;
|
|
|
|
|
|
|
|
|
|
const int scrollback_end = offset;
|
|
|
|
|
|
|
|
|
|
/* Number of rows to scroll, without going past the scrollback end */
|
|
|
|
|
int max_rows = 0;
|
|
|
|
|
if (view <= scrollback_end)
|
|
|
|
|
max_rows = scrollback_end - view;
|
|
|
|
|
else
|
|
|
|
|
max_rows = offset + (grid_rows - view);
|
|
|
|
|
|
|
|
|
|
rows = min(rows, max_rows);
|
|
|
|
|
if (rows == 0)
|
2019-07-10 14:42:48 +02:00
|
|
|
return;
|
|
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
int new_view = (view + rows) & (grid_rows - 1);
|
2019-07-10 09:29:36 +02:00
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
xassert(new_view != view);
|
|
|
|
|
xassert(grid->rows[new_view] != NULL);
|
2019-07-10 16:36:10 +02:00
|
|
|
#if defined(_DEBUG)
|
|
|
|
|
for (int r = 0; r < term->rows; r++)
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
xassert(grid->rows[(new_view + r) & (grid_rows - 1)] != NULL);
|
2019-07-10 16:36:10 +02:00
|
|
|
#endif
|
2019-07-10 09:29:36 +02:00
|
|
|
|
2019-07-10 14:42:48 +02:00
|
|
|
LOG_DBG("scrollback DOWN: %d -> %d (offset = %d, end = %d, rows = %d)",
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
view, new_view, offset, end, grid_rows);
|
2019-08-04 19:06:49 +02:00
|
|
|
|
2020-05-19 18:49:42 +02:00
|
|
|
selection_view_down(term, new_view);
|
2019-07-09 16:26:36 +02:00
|
|
|
term->grid->view = new_view;
|
|
|
|
|
|
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.
This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.
I.e. the implementation was _reactive_.
This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.
When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.
As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 18:59:06 +01:00
|
|
|
if (rows < term->rows) {
|
|
|
|
|
term_damage_scroll(
|
|
|
|
|
term, DAMAGE_SCROLL_IN_VIEW,
|
|
|
|
|
(struct scroll_region){0, term->rows}, rows);
|
|
|
|
|
term_damage_rows_in_view(term, term->rows - rows, screen_rows - 1);
|
2019-08-04 19:06:49 +02:00
|
|
|
} else
|
|
|
|
|
term_damage_view(term);
|
|
|
|
|
|
2021-02-06 11:47:59 +01:00
|
|
|
render_refresh_urls(term);
|
2019-07-24 20:09:49 +02:00
|
|
|
render_refresh(term);
|
2019-07-09 16:26:36 +02:00
|
|
|
}
|