[vte/wip/egmont/bidi: 70/87] block selection copy
- From: Egmont Koblinger <egmontkob src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/egmont/bidi: 70/87] block selection copy
- Date: Tue, 9 Apr 2019 09:14:26 +0000 (UTC)
commit a157c99a19d47b43f0d7009f5bc15e8ac58a99a3
Author: Egmont Koblinger <egmont gmail com>
Date: Fri Sep 28 16:57:19 2018 +0200
block selection copy
BIDI-STATUS | 5 ++---
src/vte.cc | 44 +++++++++++++++++++++++++++++++++++---------
src/vte/vteterminal.h | 2 +-
3 files changed, 38 insertions(+), 13 deletions(-)
---
diff --git a/BIDI-STATUS b/BIDI-STATUS
index c6c9c387..ff78efb6 100644
--- a/BIDI-STATUS
+++ b/BIDI-STATUS
@@ -5,8 +5,8 @@ Done:
- Possibility to make box drawing characters mirrorable (DECSET / DECRST 2500).
- I-Beam cursor shows the character's resolved directionality when the
paragraph has a foreign directionality character.
-- Mouse highlighting (logical in normal modes, visual in rectangle mode).
-- Copying text in logical modes.
+- Mouse highlighting, text copying (logical in normal modes, visual in
+ rectangle mode).
- Mouse reporting.
- Regex match and explicit hyperlink underlining on hover.
- VTE_DEBUG=bidi highlights characters with resolved RTL directionality.
@@ -18,7 +18,6 @@ Bugs:
- The way the modes apply to paragraphs, and what happens when a paragraph
is split or two paragraphs are joined is just a first hack, needs to be
reviewed, adjusted, fixed properly.
-- Copying text in rectangle mode.
Missing from first release:
- The entire screen is always invalidated. Have some more fine grained
diff --git a/src/vte.cc b/src/vte.cc
index 947b0248..41a48eb1 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -6202,9 +6202,6 @@ Terminal::rgb_from_index(guint index,
}
}
-// FIXMEegmont block mode doesn't work with BiDi, it won't be that easy.
-// We'll need to get the bidirow for areas not necessarily inside the current view.
-// Needs a bit of refactoring in bidi.cc.
GString*
Terminal::get_text(vte::grid::row_t start_row,
vte::grid::column_t start_col,
@@ -6218,6 +6215,9 @@ Terminal::get_text(vte::grid::row_t start_row,
GString *string;
struct _VteCharAttributes attr;
vte::color::rgb fore, back;
+ vte::base::RingView *ringview = nullptr;
+ vte::base::BidiRow const *bidirow = nullptr;
+ vte::grid::column_t col_vis;
if (attributes)
g_array_set_size (attributes, 0);
@@ -6228,26 +6228,50 @@ Terminal::get_text(vte::grid::row_t start_row,
if (start_col < 0)
start_col = 0;
- vte::grid::column_t next_first_column = block ? start_col : 0;
- vte::grid::column_t col = start_col;
+ if (block) {
+ /* Rectangular selection operates on the visual contents, not the logical.
+ * m_ringview corresponds to the currently onscreen bits, therefore does not
+ * necessarily include the entire selection.
+ * Modifying m_ringview and then reverting would be a bit cumbersome,
+ * creating a new one for the selection is cleaner. */
+ ringview = new vte::base::RingView();
+ ringview->set_ring(m_screen->row_data);
+ ringview->set_rows(start_row, end_row - start_row + 1);
+ ringview->set_width(m_column_count);
+ ringview->update();
+ }
+
+ vte::grid::column_t col = block ? 0 : start_col;
vte::grid::row_t row;
- for (row = start_row; row < end_row + 1; row++, col = next_first_column) {
+ for (row = start_row; row < end_row + 1; row++, col = 0) {
VteRowData const* row_data = find_row_data(row);
gsize last_empty, last_nonempty;
vte::grid::column_t last_emptycol, last_nonemptycol;
- vte::grid::column_t line_last_column = (block || row == end_row) ? end_col : G_MAXLONG;
+ vte::grid::column_t line_last_column = (!block && row == end_row) ? end_col : m_column_count;
last_empty = last_nonempty = string->len;
last_emptycol = last_nonemptycol = -1;
attr.row = row;
- attr.column = col;
+ attr.column = col; // FIXME is attr.column supposed to contain logical or visual? What is it
used for?
pcell = NULL;
if (row_data != NULL) {
+ bidirow = ringview ? ringview->get_row_map(row) : nullptr;
while (col < line_last_column &&
(pcell = _vte_row_data_get (row_data, col))) {
- attr.column = col;
+ /* In block mode, we scan each row from its very beginning to its very end
in logical order,
+ * and here filter out the characters that are visually outside of the
block. */
+ if (bidirow) {
+ col_vis = bidirow->log2vis(col);
+ // FIXME handle CJK and friends consistently with cell_is_selected().
+ if (col_vis < start_col || col_vis >= end_col) {
+ col++;
+ continue;
+ }
+ }
+
+ attr.column = col; // FIXME ditto
/* If it's not part of a multi-column character,
* and passes the selection criterion, add it to
@@ -6346,6 +6370,8 @@ Terminal::get_text(vte::grid::row_t start_row,
}
}
+ delete ringview;
+
/* Sanity check. */
if (attributes != nullptr)
g_assert_cmpuint(string->len, ==, attributes->len);
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index 26ac236e..4ca6efb4 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -113,7 +113,7 @@ struct _VteTerminalClass {
/* The structure we return as the supplemental attributes for strings. */
struct _VteCharAttributes {
/*< private >*/
- long row, column;
+ long row, column; // FIXME clarify if column is logical or visual
PangoColor fore, back;
guint underline:1, strikethrough:1, columns:4;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]