[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master b39f1f1 07/35: Implement function for sending events to widgets
From: |
Lars Ingebrigtsen |
Subject: |
master b39f1f1 07/35: Implement function for sending events to widgets |
Date: |
Sat, 6 Nov 2021 22:01:55 -0400 (EDT) |
branch: master
commit b39f1f158ba38d9db43fc714cf3041125ec0fa8a
Author: Po Lu <luangruo@yahoo.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Implement function for sending events to widgets
* doc/lispref/display.texi (Xwidgets): Document changes.
* src/keyboard.c (lispy_function_keys): Make non-static on X.
* src/keyboard.h (lispy_function_keys): Expose lispy_function_keys on
X.
* src/xterm.c (x_emacs_to_x_modifiers): Export function.
* src/xterm.h (x_emacs_to_x_modifiers): Likewise.
* src/xwidget.c (Fxwidget_perform_lispy_event)
(find_suitable_keyboard): New functions.
(syms_of_xwidget): Define new subr.
---
doc/lispref/display.texi | 15 ++++++++
src/keyboard.c | 2 +-
src/keyboard.h | 2 +-
src/xterm.c | 4 +-
src/xterm.h | 1 +
src/xwidget.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 117 insertions(+), 5 deletions(-)
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 22528a1..eab2c56 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -6878,6 +6878,21 @@ This function returns the current setting of
@var{xwidget}s
query-on-exit flag, either @code{t} or @code{nil}.
@end defun
+@defun xwidget-perform-lispy-event xwidget event frame
+Send an input event @var{event} to @var{xwidget}. The precise action
+performed is platform-specific. See @ref{Input Events}.
+
+You can optionally pass the frame the event was generated from via
+@var{frame}. On X11, modifier keys in key events will not be
+considered if @var{frame} is @code{nil}, and the selected frame is not
+an X-Windows frame.
+
+On GTK, only keyboard and function key events are implemented. Mouse,
+motion, and click events are dispatched to the xwidget without going
+through Lisp code, and as such shouldn't require this function to be
+sent.
+@end defun
+
@node Buttons
@section Buttons
@cindex buttons in buffers
diff --git a/src/keyboard.c b/src/keyboard.c
index aa6a4b9..46dce57 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4897,7 +4897,7 @@ static const char *const lispy_kana_keys[] =
/* You'll notice that this table is arranged to be conveniently
indexed by X Windows keysym values. */
-static const char *const lispy_function_keys[] =
+const char *const lispy_function_keys[] =
{
/* X Keysym value */
diff --git a/src/keyboard.h b/src/keyboard.h
index 8bdffaa..21c51ec 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -491,7 +491,7 @@ extern void process_pending_signals (void);
extern struct timespec timer_check (void);
extern void mark_kboards (void);
-#ifdef HAVE_NTGUI
+#if defined HAVE_NTGUI || defined HAVE_X_WINDOWS
extern const char *const lispy_function_keys[];
#endif
diff --git a/src/xterm.c b/src/xterm.c
index 12dad6a..fa7dd9b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5087,7 +5087,7 @@ x_x_to_emacs_modifiers (struct x_display_info *dpyinfo,
int state)
| ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
}
-static int
+int
x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
{
EMACS_INT mod_ctrl = ctrl_modifier;
@@ -9278,7 +9278,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.state,
event->xbutton.time);
-
+ goto OTHER;
}
#endif
/* If we decide we want to generate an event to be seen
diff --git a/src/xterm.h b/src/xterm.h
index de6ea50..9d9534d 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1108,6 +1108,7 @@ extern void x_mouse_leave (struct x_display_info *);
extern int x_dispatch_event (XEvent *, Display *);
#endif
extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
+extern int x_emacs_to_x_modifiers (struct x_display_info *, intmax_t);
#ifdef USE_CAIRO
extern void x_cr_destroy_frame_context (struct frame *);
extern void x_cr_update_surface_desired_size (struct frame *, int, int);
diff --git a/src/xwidget.c b/src/xwidget.c
index 5a4cb36..ff7d095 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -47,7 +47,8 @@ static uint32_t xwidget_counter = 0;
#ifdef USE_GTK
static Lisp_Object x_window_to_xwv_map;
static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer);
-static void synthesize_focus_in_event (GtkWidget *offscreen_window);
+static void synthesize_focus_in_event (GtkWidget *);
+static GdkDevice *find_suitable_keyboard (struct frame *);
#endif
static struct xwidget *
@@ -208,6 +209,88 @@ Returns the newly constructed xwidget, or nil if
construction fails. */)
return val;
}
+DEFUN ("xwidget-perform-lispy-event",
+ Fxwidget_perform_lispy_event, Sxwidget_perform_lispy_event,
+ 2, 3, 0, doc: /* Send a lispy event to XWIDGET.
+EVENT should be the event that will be sent. FRAME should be the
+frame which generated the event, or nil. On X11, modifier keys will
+not be processed if FRAME is nil and the selected frame is not an
+X-Windows frame. */)
+ (Lisp_Object xwidget, Lisp_Object event, Lisp_Object frame)
+{
+ struct xwidget *xw;
+ struct frame *f = NULL;
+ int character = -1, keycode = -1;
+ int modifiers = 0;
+ GdkEvent *xg_event;
+
+ CHECK_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+
+ if (!NILP (frame))
+ f = decode_window_system_frame (frame);
+ else if (FRAME_X_P (SELECTED_FRAME ()))
+ f = SELECTED_FRAME ();
+
+#ifdef USE_GTK
+ if (RANGED_FIXNUMP (0, event, INT_MAX))
+ {
+ character = XFIXNUM (event);
+ modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), character);
+ }
+ else if (SYMBOLP (event))
+ {
+ Lisp_Object decoded = parse_modifiers (event);
+ Lisp_Object decoded_name = SYMBOL_NAME (XCAR (decoded));
+ int off = 0;
+ bool found = false;
+
+ while (off < 256)
+ {
+ puts (SSDATA (decoded_name));
+ if (lispy_function_keys[off]
+ && !strcmp (lispy_function_keys[off],
+ SSDATA (decoded_name)))
+ {
+ found = true;
+ break;
+ }
+ ++off;
+ }
+
+ if (found)
+ keycode = off + 0xff00;
+ }
+
+ if (character == -1 && keycode == -1)
+ return Qnil;
+
+ block_input ();
+ xg_event = gdk_event_new (GDK_KEY_PRESS);
+ xg_event->any.window = gtk_widget_get_window (xw->widget_osr);
+ g_object_ref (xg_event->any.window);
+
+ if (character > -1)
+ xg_event->key.keyval = gdk_unicode_to_keyval (character & ~(1 << 21));
+ else if (keycode > -1)
+ xg_event->key.keyval = keycode;
+
+ xg_event->key.state = modifiers;
+
+ if (f)
+ gdk_event_set_device (xg_event,
+ find_suitable_keyboard (SELECTED_FRAME ()));
+
+ gtk_main_do_event (xg_event);
+ xg_event->type = GDK_KEY_RELEASE;
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
DEFUN ("get-buffer-xwidgets", Fget_buffer_xwidgets, Sget_buffer_xwidgets,
1, 1, 0,
doc: /* Return a list of xwidgets associated with BUFFER.
@@ -265,6 +348,18 @@ find_suitable_pointer (struct frame *f)
return gdk_seat_get_pointer (seat);
}
+static GdkDevice *
+find_suitable_keyboard (struct frame *f)
+{
+ GdkSeat *seat = gdk_display_get_default_seat
+ (gtk_widget_get_display (FRAME_GTK_WIDGET (f)));
+
+ if (!seat)
+ return NULL;
+
+ return gdk_seat_get_keyboard (seat);
+}
+
static void
xwidget_button_1 (struct xwidget_view *view,
bool down_p, int x, int y, int button,
@@ -1382,6 +1477,7 @@ syms_of_xwidget (void)
defsubr (&Sxwidget_plist);
defsubr (&Sxwidget_buffer);
defsubr (&Sset_xwidget_plist);
+ defsubr (&Sxwidget_perform_lispy_event);
DEFSYM (QCxwidget, ":xwidget");
DEFSYM (QCtitle, ":title");
- master updated (d69b5a9 -> 5b7ab89), Lars Ingebrigtsen, 2021/11/06
- master 61d049a 01/35: Use an X window to display xwidgets on X11, Lars Ingebrigtsen, 2021/11/06
- master 5c387ad 02/35: Enable scrolling optimization for xwidgets, Lars Ingebrigtsen, 2021/11/06
- master 9c9e15a 03/35: Destroy xwidgets when destroying frames, Lars Ingebrigtsen, 2021/11/06
- master 1e16fc2 05/35: Prefer XMoveResizeWindow to XMoveWindow for resizing xwidgets, Lars Ingebrigtsen, 2021/11/06
- master b39f1f1 07/35: Implement function for sending events to widgets,
Lars Ingebrigtsen <=
- master f52f772 04/35: Allow xwidgets to accept motion and button events, Lars Ingebrigtsen, 2021/11/06
- master c9c1b43 06/35: Use gtk_widget_queue_draw instead of xv_do_draw, Lars Ingebrigtsen, 2021/11/06
- master b48a89f 11/35: Fix special events in xwidgets, Lars Ingebrigtsen, 2021/11/06
- master 32b9df6 10/35: Fix drag on xwidget motion events, Lars Ingebrigtsen, 2021/11/06
- master 6ed7454 12/35: Add xwidget-webkit-edit-mode to make using the WebKit browser easier, Lars Ingebrigtsen, 2021/11/06
- master 8ddeebb 13/35: Allow enabling xwidget-webkit-edit-mode via a binding, Lars Ingebrigtsen, 2021/11/06
- master 74711c0 22/35: Display page titles in xwidget webkit header line, Lars Ingebrigtsen, 2021/11/06
- master eb5a079 24/35: Fix cursor for new widget views, Lars Ingebrigtsen, 2021/11/06
- master 1a84537 29/35: Add xwidget-webkit-isearch to the menu bar and tool bar, Lars Ingebrigtsen, 2021/11/06
- master e750329 28/35: Add xwidget-webkit-isearch-mode, Lars Ingebrigtsen, 2021/11/06