I am trying to create a context menu, which will show in the Gtk4 window on mouse right click. In case of Gtk3 i used gtk_menu_popup_at_pointer(GTK_MENU(popup), event)
function to show context menu, but this function is removed from gtk4. In Gtk4 How can this be done?
I tried it this way, but it is showing —
Gtk-WARNING **: 08:37:09.566: Finalizing GtkApplicationWindow 0x563d9f0da290, but it still has children left:
massage! check this script —
#include <gtk/gtk.h>
void create_window ( GtkApplication *application );
static void quit ( GSimpleAction *action, GVariant *parameter, gpointer data );
static void msg ( GSimpleAction *action, GVariant *parameter, gpointer data );
static void
click_pos_on_button_release (GtkGesture *click,
int n_press,
gdouble x,
gdouble y,
gpointer user_data)
{
GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence (
GTK_GESTURE_SINGLE (click));
GdkEvent *event = gtk_gesture_get_last_event (click, sequence);
g_print ("%f %fn", x, y);
GdkRectangle rectangle;
rectangle.x = x;
rectangle.y = y;
rectangle.width = 1;
rectangle.height = 1;
gtk_popover_set_pointing_to (GTK_POPOVER (user_data), &rectangle);
gtk_popover_popup (GTK_POPOVER (user_data));
gtk_gesture_set_sequence_state (GTK_GESTURE (click), sequence,
GTK_EVENT_SEQUENCE_CLAIMED);
}
int main ( int argc, char **argv )
{
GtkApplication *application;
int status;
/// ***
application = gtk_application_new ( "gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect_swapped ( application, "activate", G_CALLBACK ( create_window ), application );
/// ***
status = g_application_run ( G_APPLICATION ( application ), argc, argv );
g_object_unref ( application );
return status;
}
void create_window ( GtkApplication *application )
{
GtkWidget *window;
GMenu *menubar;
GMenu *menu;
GMenuItem *close_item, *pref_menu_item;
/// ***
window = gtk_application_window_new ( application );
gtk_window_set_application ( GTK_WINDOW ( window ), application );
/// ***
const GActionEntry entries[] =
{
{"close", quit, NULL, NULL, NULL, { 0, 0, 0 } },
{"Preferences", msg, NULL, NULL, NULL, { 0, 0, 0 } }
};
/// **
g_action_map_add_action_entries ( G_ACTION_MAP ( application ), entries, G_N_ELEMENTS ( entries ), NULL );
/// ***
menubar = g_menu_new();
menu = g_menu_new();
close_item = g_menu_item_new ( "Close", "app.close" );
pref_menu_item = g_menu_item_new("Preferences", "app.Preferences");
/// *** add item on menu
g_menu_append_item ( menu, close_item );
g_menu_append_item ( menu, pref_menu_item );
g_object_unref ( close_item );
g_object_unref ( pref_menu_item );
/// ***
g_menu_append_submenu ( menubar, "File", G_MENU_MODEL ( menu ) );
g_object_unref ( menu );
/// ***
gtk_application_set_menubar ( application, G_MENU_MODEL ( menubar ) );
gtk_application_window_set_show_menubar ( GTK_APPLICATION_WINDOW ( window ), FALSE );
GMenuModel *model;
model = G_MENU_MODEL(menu);
GtkWidget *popover = gtk_popover_menu_new_from_model_full (G_MENU_MODEL (model), GTK_POPOVER_MENU_NESTED);
gtk_popover_set_autohide (GTK_POPOVER (popover), TRUE);
gtk_popover_set_has_arrow (GTK_POPOVER (popover), FALSE);
gtk_widget_set_parent (popover, window);
GtkGesture *gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
GtkEventController *controller = GTK_EVENT_CONTROLLER (gesture);
g_signal_connect (controller, "pressed", G_CALLBACK (click_pos_on_button_release), popover);
gtk_widget_add_controller (window, controller);
/// ***
gtk_window_present ( GTK_WINDOW ( window ) );
}
static void quit ( GSimpleAction *action, G_GNUC_UNUSED GVariant *parameter, G_GNUC_UNUSED gpointer data )
{
g_print ( "You choose `%s` actionn", g_action_get_name ( G_ACTION( action ) ) );
}
static void msg ( GSimpleAction *action, G_GNUC_UNUSED GVariant *parameter, G_GNUC_UNUSED gpointer data )
{
g_print ( "You choose `%s` actionn", g_action_get_name ( G_ACTION( action ) ) );
}
*Thanks in advance to the answerers.