diff options
author | Christian Persch <chpe@gnome.org> | 2015-08-30 22:21:10 +0200 |
---|---|---|
committer | Christian Persch <chpe@gnome.org> | 2015-08-30 22:21:10 +0200 |
commit | 89541b675021b74a8668462fd930ebce2cda3afc (patch) | |
tree | ad070e042fd33bea63b0408fd86f4cd112510e84 | |
parent | f1b199b66e9eedef163bcbd68bc28613408a2e54 (diff) | |
download | vte-89541b675021b74a8668462fd930ebce2cda3afc.tar.gz |
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.
-rw-r--r-- | src/vte-private.h | 2 | ||||
-rw-r--r-- | src/vte.cc | 24 | ||||
-rw-r--r-- | src/vteinternal.hh | 2 | ||||
-rw-r--r-- | src/vteseq.cc | 16 |
4 files changed, 44 insertions, 0 deletions
diff --git a/src/vte-private.h b/src/vte-private.h index 736520aa..d8fb11a8 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); @@ -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 4eeeddbc..04d8104b 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 ffb00f68..af27ff5e 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, |