Hi Nicola,
It seems that Onboard is already available on Ubuntu18.04. If you use GIO you can get your window id and not need to start Onboard before your app. Looked interesting so I gave it a try. A lot that can be improved here also.
Eric
/*
Test getting an onboard keyboard as a plug in a socket.
gcc -Wall onboard_socket1.c -o onboard_socket1 `pkg-config --cflags --libs gtk+-3.0`
Tested on Ubuntu18.04 and GTK3.22
*/
#include<gtk/gtk.h>
#include<gtk/gtkx.h>
#include<stdlib.h>
static GPid child_pid=0;
static void plug_added(GtkSocket *socket, gpointer data);
static void add_plug(GtkWidget *widget, gpointer *data);
static gboolean watch_out_channel(GIOChannel *channel, GIOCondition cond, gpointer *data);
static void quit_program(GtkWidget *widget, gpointer data);
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Socket");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 300);
g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);
GtkWidget *entry=gtk_entry_new();
gtk_widget_set_hexpand(entry, TRUE);
GtkWidget *socket=gtk_socket_new();
gtk_widget_set_size_request(socket, 500, 200);
gtk_widget_set_hexpand(socket, TRUE);
gtk_widget_set_vexpand(socket, TRUE);
g_signal_connect(socket, "plug-added", G_CALLBACK(plug_added), NULL);
GtkWidget *expander=gtk_expander_new("Keyboard");
gtk_container_add(GTK_CONTAINER(expander), socket);
GtkWidget *button=gtk_button_new_with_label("Get Keyboard");
gtk_widget_set_hexpand(button, TRUE);
gpointer data[]={button, socket, entry, expander};
g_signal_connect(button, "clicked", G_CALLBACK(add_plug), data);
GtkWidget *grid=gtk_grid_new();
gtk_container_add(GTK_CONTAINER(window), grid);
gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(grid), entry, 0, 1, 1, 1);
gtk_grid_attach(GTK_GRID(grid), expander, 0, 2, 1, 1);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
static void plug_added(GtkSocket *socket, gpointer data)
{
g_print("Keyboard Added\n");
}
static void add_plug(GtkWidget *widget, gpointer *data)
{
g_print("Add Plug\n");
gboolean retval;
gchar *cmd=g_strdup("onboard -e -l Phone -t ModelM -s 400x300");
gchar **arg_v = NULL;
gint std_out=0;
GError *error=NULL;
GIOChannel *std_out_ch;
g_shell_parse_argv(cmd, NULL, &arg_v, NULL);
retval=g_spawn_async_with_pipes(NULL, arg_v, NULL, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, NULL, &std_out, NULL, &error);
g_strfreev(arg_v);
if(retval)
{
gtk_widget_set_sensitive(widget, FALSE);
std_out_ch=g_io_channel_unix_new(std_out);
g_io_add_watch(std_out_ch, G_IO_IN | G_IO_HUP, (GIOFunc)watch_out_channel, data);
g_print("Channel Added\n");
}
else
{
g_print("Couldn't start plug. %s\n", error->message);
g_error_free(error);
}
}
static gboolean watch_out_channel(GIOChannel *channel, GIOCondition cond, gpointer *data)
{
g_print("Watch Out\n");
if(cond==G_IO_HUP)
{
g_print("Unreference Channel\n");
g_io_channel_unref(channel);
return FALSE;
}
else
{
gsize size;
gchar *string1=NULL;
g_io_channel_read_line(channel, &string1, &size, NULL, NULL);
g_print("Window ID %s", string1);
if(atoi(string1)>0)
{
gtk_socket_add_id(GTK_SOCKET(data[1]), (Window)atoi(string1));
gtk_expander_set_expanded(GTK_EXPANDER(data[3]), TRUE);
gtk_widget_grab_focus(GTK_WIDGET(data[2]));
}
if(g_strcmp0("dis\n", string1)==0)
{
gchar *string2=g_strdup_printf("kill %i", (gint)child_pid);
g_print("%s\n", string2);
g_spawn_command_line_async(string2, NULL);
g_spawn_close_pid(child_pid);
g_free(string2);
gtk_widget_set_sensitive(GTK_WIDGET(data[0]), TRUE);
}
g_free(string1);
return TRUE;
}
}
static void quit_program(GtkWidget *widget, gpointer data)
{
g_print("Pid %i\n", child_pid);
if(child_pid!=0)
{
gchar *string=g_strdup_printf("kill %i", (gint)child_pid);
g_print("%s\n", string);
g_spawn_command_line_async(string, NULL);
g_spawn_close_pid(child_pid);
g_free(string);
}
gtk_main_quit();
}