summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Persch <chpe@gnome.org>2015-08-30 22:21:10 +0200
committerChristian Persch <chpe@gnome.org>2015-08-30 22:21:10 +0200
commit89541b675021b74a8668462fd930ebce2cda3afc (patch)
treead070e042fd33bea63b0408fd86f4cd112510e84
parentf1b199b66e9eedef163bcbd68bc28613408a2e54 (diff)
downloadvte-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.h2
-rw-r--r--src/vte.cc24
-rw-r--r--src/vteinternal.hh2
-rw-r--r--src/vteseq.cc16
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);
diff --git a/src/vte.cc b/src/vte.cc
index 5b70bd1b..3ddcee55 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 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,