'Generate BackSpace event gtk/C
In GTK/C, I want to propagate the backspace
keypress to a button
clicked. Following the suggestion in this previous post, I tried with a small program: create an GdkEventKey then use gtk_propagate_event
to set the keypress to button. The program compiles normally but it did not function as I expected. I have found this, this and this but I couldn't get my code to work (when I click the btn_bspace
, I want it to generate a backspace event in the text_entry
). Could you look at my code and tell me what is wrong? Thank you very much!
//compile with gcc -o main main.c `pkg-config --cflags --libs gtk+-3.0`
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
GtkWidget *btn_bspace;
GtkWidget *entry;
GtkWidget *window;
GtkWidget *box;
gboolean on_btn_bspace_clicked(GtkButton *button, gpointer data)
{
guint keyval = GDK_KEY_BackSpace;
GdkEvent* event = gdk_event_new(GDK_KEY_PRESS);
((GdkEventKey*)event)->window = gtk_widget_get_window(GTK_WIDGET(window));
((GdkEventKey*)event)->send_event = TRUE;
((GdkEventKey*)event)->time = GDK_CURRENT_TIME;
((GdkEventKey*)event)->state = GDK_KEY_PRESS_MASK;
((GdkEventKey*)event)->keyval = keyval;
((GdkEventKey*)event)->state = 0;
((GdkEventKey*)event)->length = 0;
((GdkEventKey*)event)->string = 0;
((GdkEventKey*)event)->hardware_keycode = 0xff08;
((GdkEventKey*)event)->group = 0;
gtk_propagate_event(entry, event);
return FALSE;
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
box = gtk_box_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), box);
gtk_widget_show(box);
entry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(entry), "testing");
gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
gtk_widget_show(entry);
btn_bspace = gtk_button_new_with_label("Backspace");
g_signal_connect(btn_bspace, "clicked", G_CALLBACK(on_btn_bspace_clicked), NULL);
gtk_box_pack_start(GTK_BOX(box), btn_bspace, TRUE, TRUE, 0);
gtk_widget_show(btn_bspace);
gtk_widget_show(window);
gtk_main();
return 0;
}
// called when window is closed
void on_window_main_destroy()
{
gtk_main_quit();
}
Update: assign ((GdkEventKey)event)->window
to a GdkWindow
Solution 1:[1]
I am not sure if this is still a relevant issue for you, but I did some investigation into this issue to come up with a solution. Perhaps you or others can benefit from the information.
I tested out your code and was also getting no response to the button click event. In researching this, what seems to be the issue is that trying to match up a GtkWindow to a GdkWindow seems to falter. I am not proficient in how to get GTK objects to communicate with GDK objects. So, I looked at a different approach that just relied on GTK objects and events.
I took a look at the source code for the GtkEntry widget to see what type of signals it accepts and went at this with a different approach. Instead of utilizing a GDK event, I emitted a signal to the entry widget for a backspace. Backspace is one of the signals associated with a GtkEntry widget.
The "on_btn_bspace_clicked" function was revised as follows:
void on_btn_bspace_clicked(GtkEntry *ent, gpointer data)
{
g_signal_emit (ent, g_signal_lookup ("backspace", G_OBJECT_CLASS_TYPE (GTK_WIDGET_GET_CLASS(GTK_ENTRY(ent)))), 0);
}
This actually simplified the code a bit.
Then within your mainline block, I revised the signal connection to utilize the "g_signal_connect_swapped" function which lets one reference the widget to be affected.
g_signal_connect_swapped(btn_bspace, "clicked", G_CALLBACK(on_btn_bspace_clicked), entry);
I tested this revision out and got the result that you were after.
I hope this helps you out.
Regards.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | NoDakker |