Re: Key press synthesis (for WebKitGTK)

2018-11-24 Thread Gergely Polonkai
On Sat, Nov 24, 2018 at 09:59:00AM +0100, Pierre Neidhardt wrote:
> Hi Gergely,
> 
> > So if you change your handler’s return type from `void` to `gboolean`
> > and return `FALSE` if the lisp thingy doesn’t understand your key, it
> > will be automatically propagated to the next handler (which, hopefully,
> > will insert your "a" key.
> 
> Thanks for the tip.  Indeed, I had missed that.
> 
> That said, the current situation is a little more complex because the call to
> Lisp is _asynchronous_.  Which means that I can only know the answer from the
> callback of the Soup request, not within the key-press handler.  In the Soup
> callback, the key press event is gone, hence my need to synthesize a new one.
> 
> I have successfully managed to synthesize a key-press event in a dummy 
> program.
> In the above scenario, it fails seemingly because it happens from within a 
> Soup
> callback.  Maybe Libsoup uses different threads, which causes threading issue
> when manipulating GTK widgets?

No, it shouldn’t, at least not by default.

How about you send the event as `user_data` to `soup_request_send()` (or 
whatever method you use) and send that to the webkit widget?

> 
> I also tried to synthesize the key event from another callback started in a
> g_idle_add() in the Soup callback, to no avail.
> g_main_context_invoke() seems to make no difference.
> 
> Thoughts?
> 
> -- 
> Pierre Neidhardt
> https://ambrevar.xyz/



-- 
You must believe in things that are not true.
Otherwise, how will they become?
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Key press synthesis (for WebKitGTK)

2018-11-24 Thread Pierre Neidhardt
Hi Gergely,

> So if you change your handler’s return type from `void` to `gboolean`
> and return `FALSE` if the lisp thingy doesn’t understand your key, it
> will be automatically propagated to the next handler (which, hopefully,
> will insert your "a" key.

Thanks for the tip.  Indeed, I had missed that.

That said, the current situation is a little more complex because the call to
Lisp is _asynchronous_.  Which means that I can only know the answer from the
callback of the Soup request, not within the key-press handler.  In the Soup
callback, the key press event is gone, hence my need to synthesize a new one.

I have successfully managed to synthesize a key-press event in a dummy program.
In the above scenario, it fails seemingly because it happens from within a Soup
callback.  Maybe Libsoup uses different threads, which causes threading issue
when manipulating GTK widgets?

I also tried to synthesize the key event from another callback started in a
g_idle_add() in the Soup callback, to no avail.
g_main_context_invoke() seems to make no difference.

Thoughts?

-- 
Pierre Neidhardt
https://ambrevar.xyz/
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Re: Key press synthesis (for WebKitGTK)

2018-11-23 Thread Gergely Polonkai
Hello,

from the manual
(https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-key-press-event),
the signature of key-press-event handlers is:

```
gboolean
user_function (GtkWidget *widget,
   GdkEvent  *event,
   gpointer   user_data)
```

From the same manual:

> Returns
>
> TRUE to stop other handlers from being invoked for the event. FALSE to
> propagate the event further.

So if you change your handler’s return type from `void` to `gboolean`
and return `FALSE` if the lisp thingy doesn’t understand your key, it
will be automatically propagated to the next handler (which, hopefully,
will insert your "a" key.

Best,
Gergely

Pierre Neidhardt writes:

> Hi all!
>
> I'm working on the GTK port of Next browser (http://next.atlas.engineer/,
> source: https://source.atlas.engineer/public/next).
>
> I have a window with a WebKitGTK view in it.
>
> I intercept all key-press-events and send them to a third-party Lisp program 
> via
> XML-RPC.
>
> Whenever the Lisp program does not recognize the key bindings, it notifies the
> GTK program.  From there, GTK must forward the key press to the WebKit view.
>
> Example:
>
> - The focus is on a text field on a web page.
> - I press "a".
> - "a" is sent to the Lisp third party program.
> - Lisp does not know what to do with "a", and sends a message back to the GTK 
> program.
> - The GTK program must insert "a" in the text field in the WebKit view.
>
>
> To achieve that, I think I need to synthesize a key press event during the 
> last
> step.
> (Unless someone can think of a direct way to forward a key press to the WebKit
> view.)
>
> Here is what I've got:
>
> - In the widget creation function:
>
> --8<---cut here---start->8---
>   g_signal_connect(buffer->web_view, "key-press-event", 
> G_CALLBACK(window_send_event), window);
> --8<---cut here---end--->8---
>
> A 'window_send_event' callback for all key-presses.  I use Libsoup to send an
> XML-RPC message containing the keypress to the Lisp program:
>
> --8<---cut here---start->8---
> void window_send_event(GtkWidget *widget, GdkEventKey *event, gpointer data) {
>   // ...  Some provision to avoid infinite loops...
>
>   WindowEvent *window_event = g_new(WindowEvent, 1);
>   Window *window = (Window *)data;
>   window_event->window = window;
>   window_event->event = event;
>
>   g_debug("Sending keypress XML-RPC message for window %p", 
> window_event->window);
>   soup_session_queue_message(xmlrpc_env, msg, _event_callback, 
> window_event);
> }
> --8<---cut here---end--->8---
>
> And finally, the callback when the response arrives from the Lisp program:
>
> --8<---cut here---start->8---
> void window_event_callback(SoupSession *_session, SoupMessage *msg, gpointer 
> data) {
>   // ...
>   if (!g_variant_get_boolean(consumed)) {
>   g_debug("Event not consumed, forwarding to GTK");
>
>   WindowEvent *window_event = (WindowEvent *)data;
>
>   GdkDevice *device = NULL;
>   GdkDisplay *display = gdk_display_get_default();
>   GdkSeat *seat = gdk_display_get_default_seat(display);
>   device = gdk_seat_get_keyboard(seat);
>
>   GdkEvent *event = gdk_event_new(GDK_KEY_PRESS);
>   event->key = *(window_event->event);
>   event->key.string = g_strdup(window_event->event->string);
>   event->key.time = gtk_get_current_event_time();
>   event->key.window = 
> g_object_ref(gtk_widget_get_window(GTK_WIDGET(window_event->window->base)));
>   gdk_event_set_device(event, device);
>
>   gtk_main_do_event(event);
>   gdk_event_free(event);
>
>   g_debug("Event emitted");
>   }
> }
> --8<---cut here---end--->8---
>
> The
>
> --8<---cut here---start->8---
>   gtk_main_do_event(event);
> --8<---cut here---end--->8---
>
> call is not caught anywhere though.  Any idea why?
>
> I've tried with different event settings and sometimes I get
>
> --8<---cut here---start->8---
> (next-gtk-webkit:10768): GLib-GObject-WARNING **: 15:31:27.027: 
> gsignal.c:2172: signal id '68' cannot be chained from current emission stage 
> for instance '0x1c3a2a0'
> --8<---cut here---end--->8---
>
> I don't understand the above error message.  Any idea what could issue it?
>
> Any clue, anyone?
>
> Cheers!
___
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list