-
Notifications
You must be signed in to change notification settings - Fork 12
/
vte-osc52.diff
174 lines (165 loc) · 6.83 KB
/
vte-osc52.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
diff --git a/src/marshal.list b/src/marshal.list
index 241128c3..a40acc49 100644
--- a/src/marshal.list
+++ b/src/marshal.list
@@ -1,3 +1,4 @@
VOID:STRING,BOXED
VOID:STRING,UINT
+VOID:STRING,POINTER,UINT
VOID:UINT,UINT
diff --git a/src/vte.cc b/src/vte.cc
index 335a8a07..87b99e8b 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -961,6 +961,13 @@ Terminal::emit_paste_clipboard()
g_signal_emit(m_terminal, signals[SIGNAL_PASTE_CLIPBOARD], 0);
}
+void
+Terminal::emit_write_clipboard(const char *clipboards, const guchar *text, guint text_size)
+{
+ _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting 'write-clipboard'.\n");
+ g_signal_emit(m_terminal, signals[SIGNAL_WRITE_CLIPBOARD], 0, clipboards, text, text_size);
+}
+
/* Emit a "hyperlink_hover_uri_changed" signal. */
void
Terminal::emit_hyperlink_hover_uri_changed(const GdkRectangle *bbox)
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index a9e1e494..ad73ce2f 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -122,13 +122,18 @@ struct _VteTerminalClass {
void (*setup_context_menu)(VteTerminal* terminal,
VteEventContext const* context);
+ void (*write_clipboard)(VteTerminal* terminal,
+ const char *clipboards,
+ const char *text,
+ guint text_size);
+
/* Add new vfuncs just above, and subtract from the padding below. */
/* Padding for future expansion. */
#if _VTE_GTK == 3
- gpointer _padding[12];
+ gpointer _padding[11];
#elif _VTE_GTK == 4
- gpointer _padding[15];
+ gpointer _padding[14];
#endif /* _VTE_GTK */
// FIXMEgtk4 use class private data instead
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index 521f7450..bc7d5f3a 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -1383,6 +1383,8 @@ vte_terminal_class_init(VteTerminalClass *klass)
klass->bell = NULL;
+ klass->write_clipboard = NULL;
+
/* GtkScrollable interface properties */
g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
@@ -2053,6 +2055,45 @@ vte_terminal_class_init(VteTerminalClass *klass)
G_OBJECT_CLASS_TYPE(klass),
g_cclosure_marshal_VOID__POINTERv);
+ /**
+ * VteTerminal::write-clipboard:
+ * @vteterminal: the object which received the signal
+ * @clipboards: a string describing which clipboard(s) to set
+ * @text (nullable) (array length=text_size) (element-type guint8):
+ * a string that should be written to the clipboard
+ * @text_size: the length of that string
+ *
+ * Emitted when the terminal receives an OSC 52 (write clipboard) ESC
+ * sequence.
+ *
+ * The clipboards argument contains 0 or more characters from
+ * the set [cpqs0-7]. The letters represent clipboard, primary,
+ * secondary and select respectively; the numbers represent cut-buffers.
+ *
+ * The text argument is decoded from the base 64. It is unsanitized and
+ * may or may not include a 0 terminator, so always check text_size.
+ *
+ * If text is NULL or empty, the clipboard should be cleared. Attempts
+ * to query the clipboard (child sent "?" instead of base64) are ignored.
+ *
+ * Note: vte has a limit of 4096 characters in control sequences,
+ * including encoding overhead, so the amount of text you can copy at a
+ * time is somewhat limited.
+ */
+ signals[SIGNAL_WRITE_CLIPBOARD] =
+ g_signal_new(I_("write-clipboard"),
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(VteTerminalClass, write_clipboard),
+ NULL,
+ NULL,
+ _vte_marshal_VOID__STRING_POINTER_UINT,
+ G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
+ g_signal_set_va_marshaller(signals[SIGNAL_WRITE_CLIPBOARD],
+ G_OBJECT_CLASS_TYPE(klass),
+ _vte_marshal_VOID__STRING_POINTER_UINTv);
+
+
/**
* VteTerminal:allow-bold:
*
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index 1d1383af..1551d558 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -54,6 +54,7 @@ enum {
SIGNAL_SELECTION_CHANGED,
SIGNAL_SETUP_CONTEXT_MENU,
SIGNAL_WINDOW_TITLE_CHANGED,
+ SIGNAL_WRITE_CLIPBOARD,
LAST_SIGNAL
};
extern guint signals[LAST_SIGNAL];
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 90f45197..7d7caaa6 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1345,6 +1345,9 @@ public:
guint rows);
void emit_copy_clipboard();
void emit_paste_clipboard();
+
+ void emit_write_clipboard(const char *clipboards, const guchar *text, guint text_size);
+
void emit_hyperlink_hover_uri_changed(const GdkRectangle *bbox);
void hyperlink_invalidate_and_get_bbox(vte::base::Ring::hyperlink_idx_t idx, GdkRectangle *bbox);
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 3c552dc6..48f0607e 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -6678,6 +6678,24 @@ Terminal::OSC(vte::parser::Sequence const& seq)
reset_color(VTE_HIGHLIGHT_FG, VTE_COLOR_SOURCE_ESCAPE);
break;
+ case VTE_OSC_XTERM_SET_XSELECTION: {
+ auto clipboards = *it;
+ if (clipboards.find_first_not_of("cpqs01234567") != std::string::npos)
+ break;
+ auto payload = *++it;
+ guchar *decoded = NULL;
+ gsize decoded_len = 0;
+ if (payload.size())
+ {
+ if (payload[0] == '?')
+ break;
+ decoded = g_base64_decode(payload.c_str(), &decoded_len);
+ }
+ emit_write_clipboard(clipboards.c_str(), decoded, decoded_len);
+ g_free(decoded);
+ break;
+ }
+
case VTE_OSC_XTERM_SET_ICON_TITLE:
case VTE_OSC_XTERM_SET_XPROPERTY:
case VTE_OSC_XTERM_SET_COLOR_MOUSE_CURSOR_FG:
@@ -6688,7 +6706,6 @@ Terminal::OSC(vte::parser::Sequence const& seq)
case VTE_OSC_XTERM_SET_CURSOR_NAME:
case VTE_OSC_XTERM_LOGFILE:
case VTE_OSC_XTERM_SET_FONT:
- case VTE_OSC_XTERM_SET_XSELECTION:
case VTE_OSC_XTERM_SET_COLOR_MODE:
case VTE_OSC_XTERM_RESET_COLOR_MOUSE_CURSOR_FG:
case VTE_OSC_XTERM_RESET_COLOR_MOUSE_CURSOR_BG: