summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Persch <chpe@src.gnome.org>2022-07-24 14:45:57 +0200
committerChristian Persch <chpe@src.gnome.org>2022-07-24 14:45:57 +0200
commit0effa40fd9520e7e9af83d5a26d0d7be58b4094e (patch)
tree795598af2d77eccdaf820c706242fcf5f320c189
parent011b7acc60b71ea4762544ee72d106c3bccfa131 (diff)
downloadvte-0effa40fd9520e7e9af83d5a26d0d7be58b4094e.tar.gz
widget: gtk4: Add API to check event context
https://gitlab.gnome.org/GNOME/vte/-/issues/2530
-rw-r--r--src/vte.cc33
-rw-r--r--src/vte/vteterminal.h33
-rw-r--r--src/vtegtk.cc183
-rw-r--r--src/vteinternal.hh20
-rw-r--r--src/widget.hh27
5 files changed, 288 insertions, 8 deletions
diff --git a/src/vte.cc b/src/vte.cc
index 00cd243b..ed99daf6 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -1866,6 +1866,39 @@ Terminal::regex_match_check(vte::platform::MouseEvent const& event,
return regex_match_check(col, row - (long)m_screen->scroll_delta, tag);
}
+#if VTE_GTK == 4
+
+char*
+Terminal::regex_match_check_at(double x,
+ double y,
+ int *tag)
+{
+ long col, row;
+ if (!rowcol_at(x, y, &col, &row))
+ return nullptr;
+
+ /* FIXME Shouldn't rely on a deprecated, not sub-row aware method. */
+ // FIXMEchpe fix this scroll_delta substraction!
+ return regex_match_check(col, row - (long)m_screen->scroll_delta, tag);
+}
+
+bool
+Terminal::regex_match_check_extra_at(double x,
+ double y,
+ vte::base::Regex const** regexes,
+ size_t n_regexes,
+ uint32_t match_flags,
+ char** matches)
+{
+ long col, row;
+ if (!rowcol_at(x, y, &col, &row))
+ return false;
+
+ return regex_match_check_extra(col, row, regexes, n_regexes, match_flags, matches);
+}
+
+#endif /* VTE_GTK == 4 */
+
bool
Terminal::regex_match_check_extra(vte::platform::MouseEvent const& event,
vte::base::Regex const** regexes,
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index c71658d2..d2d9a736 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -425,6 +425,13 @@ _VTE_PUBLIC
char *vte_terminal_hyperlink_check_event(VteTerminal *terminal,
GdkEvent *event) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1, 2) G_GNUC_MALLOC;
+#elif _VTE_GTK == 4
+
+_VTE_PUBLIC
+char* vte_terminal_hyperlink_check_at(VteTerminal* terminal,
+ double x,
+ double y) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+
#endif /* _VTE_GTK */
/* Add a matching expression, returning the tag the widget assigns to that
@@ -469,6 +476,32 @@ gboolean vte_terminal_event_check_regex_simple(VteTerminal *terminal,
guint32 match_flags,
char **matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1, 2);
+#elif _VTE_GTK == 4
+
+_VTE_PUBLIC
+char* vte_terminal_match_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ int* tag) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+
+_VTE_PUBLIC
+char** vte_terminal_regex_array_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ VteRegex** regexes,
+ gsize n_regexes,
+ guint32 match_flags,
+ gsize* n_matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1) G_GNUC_MALLOC;
+
+_VTE_PUBLIC
+gboolean vte_terminal_regex_simple_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ VteRegex** regexes,
+ gsize n_regexes,
+ guint32 match_flags,
+ char** matches) _VTE_CXX_NOEXCEPT _VTE_GNUC_NONNULL(1);
+
#endif /* _VTE_GTK */
_VTE_PUBLIC
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index f12ee256..8a50360e 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -3137,6 +3137,189 @@ catch (...)
return false;
}
+#elif VTE_GTK == 4
+
+/**
+ * vte_terminal_match_check_at:
+ * @terminal: a #VteTerminal
+ * @x:
+ * @y:
+ * @tag: (out) (allow-none): a location to store the tag, or %NULL
+ *
+ * Checks if the text in and around the position (x, y) matches any of the
+ * regular expressions previously set using vte_terminal_match_add(). If a
+ * match exists, the text string is returned and if @tag is not %NULL, the number
+ * associated with the matched regular expression will be stored in @tag.
+ *
+ * If more than one regular expression has been set with
+ * vte_terminal_match_add(), then expressions are checked in the order in
+ * which they were added.
+ *
+ * Returns: (transfer full) (nullable): a newly allocated string which matches one of the previously
+ * set regular expressions, or %NULL if there is no match
+ *
+ * Since: 0.70
+ */
+char*
+vte_terminal_match_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ int* tag) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+ return WIDGET(terminal)->regex_match_check_at(x, y, tag);
+}
+catch (...)
+{
+ vte::log_exception();
+ return nullptr;
+}
+
+/**
+ * vte_terminal_hyperlink_check_at:
+ * @terminal: a #VteTerminal
+ * @x:
+ * @y:
+ *
+ * Returns a nonempty string: the target of the explicit hyperlink (printed using the OSC 8
+ * escape sequence) at the position (x, y), or %NULL.
+ *
+ * Proper use of the escape sequence should result in URI-encoded URIs with a proper scheme
+ * like "http://", "https://", "file://", "mailto:" etc. This is, however, not enforced by VTE.
+ * The caller must tolerate the returned string potentially not being a valid URI.
+ *
+ * Returns: (transfer full) (nullable): a newly allocated string containing the target of the hyperlink,
+ * or %NULL
+ *
+ * Since: 0.70
+ */
+char*
+vte_terminal_hyperlink_check_at(VteTerminal* terminal,
+ double x,
+ double y) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), nullptr);
+ return WIDGET(terminal)->hyperlink_check_at(x, y);
+}
+catch (...)
+{
+ vte::log_exception();
+ return nullptr;
+}
+
+/**
+ * vte_terminal_regex_array_check_at: (rename-to vte_terminal_check_regex_simple_at)
+ * @terminal: a #VteTerminal
+ * @x:
+ * @y:
+ * @regexes: (array length=n_regexes): an array of #VteRegex
+ * @n_regexes: number of items in @regexes
+ * @match_flags: PCRE2 match flags, or 0
+ * @n_matches: (out) (optional): number of items in @matches, which is always equal to @n_regexes
+ *
+ * Like vte_terminal_check_regex_simple_at(), but returns an array of strings,
+ * containing the matching text (or %NULL if no match) corresponding to each of the
+ * regexes in @regexes.
+ *
+ * You must free each string and the array; but note that this is *not* a %NULL-terminated
+ * string array, and so you must *not* use g_strfreev() on it.
+ *
+ * Returns: (nullable) (transfer full) (array length=n_matches): a newly allocated array of strings,
+ * or %NULL if none of the regexes matched
+ *
+ * Since: 0.70
+ */
+char**
+vte_terminal_regex_array_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ VteRegex** regexes,
+ gsize n_regexes,
+ guint32 match_flags,
+ gsize* n_matches) noexcept
+try
+{
+ if (n_matches)
+ *n_matches = n_regexes;
+
+ if (n_regexes == 0)
+ return nullptr;
+
+ auto matches = vte::glib::take_free_ptr(g_new0(char*, n_regexes));
+ if (!vte_terminal_regex_simple_check_at(terminal,
+ x, y,
+ regexes,
+ n_regexes,
+ match_flags,
+ matches.get()))
+ return nullptr;
+
+ return matches.release();
+}
+catch (...)
+{
+ vte::log_exception();
+ return nullptr;
+}
+
+/**
+ * vte_terminal_regex_simple_check_at: (skip)
+ * @terminal: a #VteTerminal
+ * @x:
+ * @y:
+ * @regexes: (array length=n_regexes): an array of #VteRegex
+ * @n_regexes: number of items in @regexes
+ * @match_flags: PCRE2 match flags, or 0
+ * @matches: (out caller-allocates) (array length=n_regexes) (transfer full): a location to store the matches
+ *
+ * Checks each regex in @regexes if the text in and around the position (x, y)
+ * matches the regular expressions. If a match exists, the matched
+ * text is stored in @matches at the position of the regex in @regexes; otherwise
+ * %NULL is stored there. Each non-%NULL element of @matches should be freed with
+ * g_free().
+ *
+ * Note that the regexes in @regexes should have been created using the %PCRE2_MULTILINE flag.
+ *
+ * Returns: %TRUE iff any of the regexes produced a match
+ *
+ * Since: 0.70
+ */
+gboolean
+vte_terminal_regex_simple_check_at(VteTerminal* terminal,
+ double x,
+ double y,
+ VteRegex** regexes,
+ gsize n_regexes,
+ guint32 match_flags,
+ char** matches) noexcept
+try
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
+ g_return_val_if_fail(regexes != NULL || n_regexes == 0, FALSE);
+ for (gsize i = 0; i < n_regexes; i++) {
+ g_return_val_if_fail(_vte_regex_has_purpose(regexes[i], vte::base::Regex::Purpose::eMatch), -1);
+ g_warn_if_fail(_vte_regex_has_multiline_compile_flag(regexes[i]));
+ }
+ g_return_val_if_fail(matches != NULL, FALSE);
+
+ return WIDGET(terminal)->regex_match_check_extra_at(x, y,
+ regex_array_from_wrappers(regexes),
+ n_regexes,
+ match_flags,
+ matches);
+}
+catch (...)
+{
+ vte::log_exception();
+ return false;
+}
+
+#endif /* VTE_GTK */
+
+#if VTE_GTK == 3
+
/**
* vte_terminal_event_check_gregex_simple:
* @terminal: a #VteTerminal
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 5037096d..fbe696b1 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1244,8 +1244,6 @@ public:
#endif
char *hyperlink_check(vte::platform::MouseEvent const& event);
- char *hyperlink_check_at(double x,
- double y);
char *hyperlink_check(vte::grid::column_t column,
vte::grid::row_t row);
@@ -1254,12 +1252,6 @@ public:
size_t n_regexes,
uint32_t match_flags,
char** matches);
- bool regex_match_check_extra_at(double x,
- double y,
- vte::base::Regex const** regexes,
- size_t n_regexes,
- uint32_t match_flags,
- char** matches);
bool regex_match_check_extra(vte::grid::column_t column,
vte::grid::row_t row,
vte::base::Regex const** regexes,
@@ -1272,9 +1264,21 @@ public:
int *tag);
char *regex_match_check(vte::platform::MouseEvent const& event,
int *tag);
+
+#if VTE_GTK == 4
+ char *hyperlink_check_at(double x,
+ double y);
+ bool regex_match_check_extra_at(double x,
+ double y,
+ vte::base::Regex const** regexes,
+ size_t n_regexes,
+ uint32_t match_flags,
+ char** matches);
char *regex_match_check_at(double x,
double y,
int *tag);
+#endif /* VTE_GTK == 4 */
+
void regex_match_remove(int tag) noexcept;
void regex_match_remove_all() noexcept;
void regex_match_set_cursor(int tag,
diff --git a/src/widget.hh b/src/widget.hh
index 5e6b1bdc..308edb57 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -469,6 +469,33 @@ public:
return terminal()->hyperlink_check(mouse_event_from_gdk(event));
}
+#elif VTE_GTK == 4
+
+ char* regex_match_check_at(double x,
+ double y,
+ int* tag)
+ {
+ return terminal()->regex_match_check(x, y, tag);
+ }
+
+ bool regex_match_check_extra_at(double x,
+ double y,
+ vte::base::Regex const** regexes,
+ size_t n_regexes,
+ uint32_t match_flags,
+ char** matches)
+ {
+ return terminal()->regex_match_check_extra_at(x, y,
+ regexes, n_regexes,
+ match_flags, matches);
+ }
+
+ char* hyperlink_check_at(double x,
+ double y)
+ {
+ return terminal()->hyperlink_check_at(x, y);
+ }
+
#endif /* VTE_GTK */
bool should_emit_signal(int id) noexcept;