[vte] widget: gtk4: Add API to check event context



commit 0effa40fd9520e7e9af83d5a26d0d7be58b4094e
Author: Christian Persch <chpe src gnome org>
Date:   Sun Jul 24 14:45:57 2022 +0200

    widget: gtk4: Add API to check event context
    
    https://gitlab.gnome.org/GNOME/vte/-/issues/2530

 src/vte.cc            |  33 +++++++++
 src/vte/vteterminal.h |  33 +++++++++
 src/vtegtk.cc         | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/vteinternal.hh    |  20 +++---
 src/widget.hh         |  27 ++++++++
 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;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]