aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2021-11-05 14:34:45 +0800
committerLars Ingebrigtsen2021-11-07 02:59:40 +0100
commitb48a89fd2ec9a2f4ecf77d6f82ebeac23a7d9a88 (patch)
treeb1633e613e3ca1f151c2cb8f8ed68efeb1973d17 /src
parent32b9df6d215bd1fc4cb14163761cd4543262aa48 (diff)
downloademacs-b48a89fd2ec9a2f4ecf77d6f82ebeac23a7d9a88.tar.gz
emacs-b48a89fd2ec9a2f4ecf77d6f82ebeac23a7d9a88.zip
Fix special events in xwidgets
* src/xwidget.c (set_widget_if_text_view): New function. (Fxwidget_perform_lispy_event): Fix for webkit widgets.
Diffstat (limited to 'src')
-rw-r--r--src/xwidget.c77
1 files changed, 72 insertions, 5 deletions
diff --git a/src/xwidget.c b/src/xwidget.c
index 42b1b85cb8b..64bff281634 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -209,6 +209,19 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
209 return val; 209 return val;
210} 210}
211 211
212#ifdef USE_GTK
213static void
214set_widget_if_text_view (GtkWidget *widget, void *data)
215{
216 GtkWidget **pointer = data;
217
218 if (GTK_IS_TEXT_VIEW (widget))
219 {
220 *pointer = widget;
221 }
222}
223#endif
224
212DEFUN ("xwidget-perform-lispy-event", 225DEFUN ("xwidget-perform-lispy-event",
213 Fxwidget_perform_lispy_event, Sxwidget_perform_lispy_event, 226 Fxwidget_perform_lispy_event, Sxwidget_perform_lispy_event,
214 2, 3, 0, doc: /* Send a lispy event to XWIDGET. 227 2, 3, 0, doc: /* Send a lispy event to XWIDGET.
@@ -222,7 +235,13 @@ X-Windows frame. */)
222 struct frame *f = NULL; 235 struct frame *f = NULL;
223 int character = -1, keycode = -1; 236 int character = -1, keycode = -1;
224 int modifiers = 0; 237 int modifiers = 0;
238
239#ifdef USE_GTK
225 GdkEvent *xg_event; 240 GdkEvent *xg_event;
241 GtkContainerClass *klass;
242 GtkWidget *widget;
243 GtkWidget *temp = NULL;
244#endif
226 245
227 CHECK_XWIDGET (xwidget); 246 CHECK_XWIDGET (xwidget);
228 xw = XXWIDGET (xwidget); 247 xw = XXWIDGET (xwidget);
@@ -232,22 +251,42 @@ X-Windows frame. */)
232 else if (FRAME_X_P (SELECTED_FRAME ())) 251 else if (FRAME_X_P (SELECTED_FRAME ()))
233 f = SELECTED_FRAME (); 252 f = SELECTED_FRAME ();
234 253
254 widget = xw->widget_osr;
255
235#ifdef USE_GTK 256#ifdef USE_GTK
236 if (RANGED_FIXNUMP (0, event, INT_MAX)) 257 if (RANGED_FIXNUMP (0, event, INT_MAX))
237 { 258 {
238 character = XFIXNUM (event); 259 character = XFIXNUM (event);
239 modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), character); 260
261 if (character < 32)
262 modifiers |= ctrl_modifier;
263
264 modifiers |= character & meta_modifier;
265 modifiers |= character & hyper_modifier;
266 modifiers |= character & super_modifier;
267 modifiers |= character & shift_modifier;
268 modifiers |= character & ctrl_modifier;
269
270 character = character & ~(1 << 21);
271
272 if (character < 32)
273 character += '_';
274
275 if (f)
276 modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), modifiers);
277 else
278 modifiers = 0;
240 } 279 }
241 else if (SYMBOLP (event)) 280 else if (SYMBOLP (event))
242 { 281 {
243 Lisp_Object decoded = parse_modifiers (event); 282 Lisp_Object decoded = parse_modifiers (event);
244 Lisp_Object decoded_name = SYMBOL_NAME (XCAR (decoded)); 283 Lisp_Object decoded_name = SYMBOL_NAME (XCAR (decoded));
284
245 int off = 0; 285 int off = 0;
246 bool found = false; 286 bool found = false;
247 287
248 while (off < 256) 288 while (off < 256)
249 { 289 {
250 puts (SSDATA (decoded_name));
251 if (lispy_function_keys[off] 290 if (lispy_function_keys[off]
252 && !strcmp (lispy_function_keys[off], 291 && !strcmp (lispy_function_keys[off],
253 SSDATA (decoded_name))) 292 SSDATA (decoded_name)))
@@ -258,6 +297,12 @@ X-Windows frame. */)
258 ++off; 297 ++off;
259 } 298 }
260 299
300 if (f)
301 modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f),
302 XFIXNUM (XCAR (XCDR (decoded))));
303 else
304 modifiers = 0;
305
261 if (found) 306 if (found)
262 keycode = off + 0xff00; 307 keycode = off + 0xff00;
263 } 308 }
@@ -271,12 +316,34 @@ X-Windows frame. */)
271 g_object_ref (xg_event->any.window); 316 g_object_ref (xg_event->any.window);
272 317
273 if (character > -1) 318 if (character > -1)
274 xg_event->key.keyval = gdk_unicode_to_keyval (character & ~(1 << 21)); 319 keycode = gdk_unicode_to_keyval (character);
275 else if (keycode > -1)
276 xg_event->key.keyval = keycode;
277 320
321 xg_event->key.keyval = keycode;
278 xg_event->key.state = modifiers; 322 xg_event->key.state = modifiers;
279 323
324 if (keycode > -1)
325 {
326 /* WebKitGTK internals abuse follows. */
327 if (EQ (xw->type, Qwebkit))
328 {
329 /* WebKitGTK relies on an internal GtkTextView object to
330 "translate" keys such as backspace. We must find that
331 widget and activate its binding to this key if any. */
332 klass = GTK_CONTAINER_CLASS (G_OBJECT_GET_CLASS (widget));
333
334 klass->forall (GTK_CONTAINER (xw->widget_osr), TRUE,
335 set_widget_if_text_view, &temp);
336
337 if (GTK_IS_WIDGET (temp))
338 {
339 if (!gtk_widget_get_realized (temp))
340 gtk_widget_realize (temp);
341
342 gtk_bindings_activate (G_OBJECT (temp), keycode, modifiers);
343 }
344 }
345 }
346
280 if (f) 347 if (f)
281 gdk_event_set_device (xg_event, 348 gdk_event_set_device (xg_event,
282 find_suitable_keyboard (SELECTED_FRAME ())); 349 find_suitable_keyboard (SELECTED_FRAME ()));