diff options
| author | Po Lu | 2021-11-05 14:34:45 +0800 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-11-07 02:59:40 +0100 |
| commit | b48a89fd2ec9a2f4ecf77d6f82ebeac23a7d9a88 (patch) | |
| tree | b1633e613e3ca1f151c2cb8f8ed68efeb1973d17 /src | |
| parent | 32b9df6d215bd1fc4cb14163761cd4543262aa48 (diff) | |
| download | emacs-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.c | 77 |
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 | ||
| 213 | static void | ||
| 214 | set_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 | |||
| 212 | DEFUN ("xwidget-perform-lispy-event", | 225 | DEFUN ("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 ())); |