[vte] emulation: Implement DECSET 1004



commit 89541b675021b74a8668462fd930ebce2cda3afc
Author: Christian Persch <chpe gnome org>
Date:   Sun Aug 30 22:21:10 2015 +0200

    emulation: Implement DECSET 1004
    
    Add support for xterm's DECSET 1004 to enable focus tracking.
    This sends CSI I on focus in, and CSI O on focus out.
    
    Contrary to xterm, vte disables the focus tracking on reset, and when
    focus tracking is enabled, immediately sends a focus in or focus out, so
    that clients always have an accurate value.

 src/vte-private.h  |    2 ++
 src/vte.cc         |   24 ++++++++++++++++++++++++
 src/vteinternal.hh |    2 ++
 src/vteseq.cc      |   16 ++++++++++++++++
 4 files changed, 44 insertions(+), 0 deletions(-)
---
diff --git a/src/vte-private.h b/src/vte-private.h
index 736520a..d8fb11a 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -93,6 +93,8 @@ void _vte_terminal_set_color_internal(VteTerminal *terminal,
                                       int source,
                                       const PangoColor *color);
 
+void _vte_terminal_feed_focus_event(VteTerminal *terminal, gboolean in);
+
 void _vte_terminal_inline_error_message(VteTerminal *terminal, const char *format, ...) G_GNUC_PRINTF(2,3);
 
 VteRowData *_vte_terminal_ring_insert (VteTerminal *terminal, glong position, gboolean fill);
diff --git a/src/vte.cc b/src/vte.cc
index 5b70bd1..3ddcee5 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -5656,6 +5656,25 @@ vte_terminal_send_mouse_button_internal(VteTerminal *terminal,
        vte_terminal_feed_mouse_event(terminal, button, FALSE /* not drag */, is_release, col, row);
 }
 
+void
+_vte_terminal_feed_focus_event(VteTerminal *terminal,
+                               gboolean in)
+{
+        char buf[8];
+        gsize len;
+
+        len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "%c", in ? 'I' : 'O');
+        vte_terminal_feed_child_binary(terminal, (guint8 *)buf, len);
+}
+
+static void
+vte_terminal_feed_focus_event_internal(VteTerminal *terminal,
+                                       gboolean in)
+{
+        if (terminal->pvt->focus_tracking_mode)
+                _vte_terminal_feed_focus_event(terminal, in);
+}
+
 /*
  * vte_terminal_maybe_send_mouse_button:
  * @terminal:
@@ -7630,6 +7649,7 @@ vte_terminal_focus_in(GtkWidget *widget, GdkEventFocus *event)
                gtk_im_context_focus_in(terminal->pvt->im_context);
                _vte_invalidate_cursor_once(terminal, FALSE);
                _vte_terminal_set_pointer_visible(terminal, TRUE);
+                vte_terminal_feed_focus_event_internal(terminal, TRUE);
        }
 
        return FALSE;
@@ -7646,6 +7666,8 @@ vte_terminal_focus_out(GtkWidget *widget, GdkEventFocus *event)
        /* We only have an IM context when we're realized, and there's not much
         * point to painting ourselves if we don't have a window. */
        if (gtk_widget_get_realized (widget)) {
+                vte_terminal_feed_focus_event_internal(terminal, FALSE);
+
                _vte_terminal_maybe_end_selection (terminal);
 
                gtk_im_context_focus_out(terminal->pvt->im_context);
@@ -12279,6 +12301,8 @@ vte_terminal_reset(VteTerminal *terminal,
        pvt->mouse_xterm_extension = FALSE;
        pvt->mouse_urxvt_extension = FALSE;
        pvt->mouse_smooth_scroll_delta = 0.;
+        /* Reset focus tracking. xterm doesn't, but that makes no sense */
+        pvt->focus_tracking_mode = FALSE;
        /* Clear modifiers. */
        pvt->modifiers = 0;
        /* Reset miscellaneous stuff. */
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 4eeeddb..04d8104 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -311,6 +311,8 @@ public:
        gboolean mouse_urxvt_extension;
        double mouse_smooth_scroll_delta;
 
+        gboolean focus_tracking_mode;
+
        /* State variables for handling match checks. */
        char *match_contents;
        GArray *match_attributes;
diff --git a/src/vteseq.cc b/src/vteseq.cc
index ffb00f6..af27ff5 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -601,6 +601,16 @@ vte_reset_mouse_smooth_scroll_delta(VteTerminal *terminal,
        terminal->pvt->mouse_smooth_scroll_delta = 0.;
 }
 
+static void
+vte_set_focus_tracking_mode(VteTerminal *terminal,
+                            GValueArray *params)
+{
+        /* We immediately send the terminal a focus event, since otherwise
+         * it has no way to know the current status.
+         */
+        _vte_terminal_feed_focus_event(terminal, gtk_widget_has_focus(&terminal->widget));
+}
+
 struct decset_t {
         gint16 setting;
         /* offset in VteTerminalPrivate (> 0) or VteScreen (< 0) */
@@ -732,6 +742,12 @@ vte_sequence_handler_decset_internal(VteTerminal *terminal,
                 (MOUSE_TRACKING_ALL_MOTION_TRACKING),
                 vte_reset_mouse_smooth_scroll_delta,
                 vte_reset_mouse_smooth_scroll_delta,},
+               /* 1004: Focus tracking. */
+               {1004, PRIV_OFFSET(focus_tracking_mode), 0, 0,
+                FALSE,
+                TRUE,
+                 NULL,
+                 vte_set_focus_tracking_mode,},
                /* 1006: Extended mouse coordinates. */
                {1006, PRIV_OFFSET(mouse_xterm_extension), 0, 0,
                 FALSE,


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