I'm trying to show my custom menu on textview

Hi guys
I’m trying to show my custom menu on textview

        gesture = Gtk.GestureClick.new()
        gesture.set_button(0)
        gesture.connect("pressed", self.pressed_cb)
        self.textview.add_controller(gesture);
    
    def pressed_cb(self, gesture, n, x, y):
        if gesture.get_current_button() == Gdk.BUTTON_SECONDARY:
            menu = Gtk.Popover.new()
            menu.set_has_arrow(False)
            menu.set_pointing_to(Gdk.Rectangle(x, y, 1, 1))
            menu.set_parent(self.textview)
            box = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
            menu.set_child(box)
            #-------------------------------------
            item = Gtk.Button.new_with_label ("New1")
            item.set_has_frame(False)
            item.connect ("clicked", self.released_cb)
            box.append (item)
            #-------------------------------------
            menu.popup ()

This code gives me the following error: “tried to map a grabbing popup with a non-top most parent”

        gesture = Gtk.GestureClick.new()
        gesture.set_button(0)
        gesture.connect("pressed", self.pressed_cb)
        self.add_controller(gesture)
    
    def pressed_cb(self, gesture, n, x, y):
        if gesture.get_current_button() == Gdk.BUTTON_SECONDARY:
            rect = Gdk.Rectangle()
            rect.x = x
            rect.y = y
            rect.width = rect.height = 1
            popover = Gtk.Popover()
            popover.set_has_arrow(False)
            popover.set_pointing_to(rect)
            popover.set_parent(self)
            box = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
            popover.set_child(box)
            #-------------------------------------
            item = Gtk.Button.new_with_label ("New1")
            item.set_has_frame(False)
            box.append (item)
            #-------------------------------------
            item = Gtk.Separator.new(Gtk.Orientation.HORIZONTAL)
            box.append (item)
            #-------------------------------------
            item = Gtk.Button.new_with_label ("New2")
            item.set_has_frame(False)
            box.append (item)
            #-------------------------------------
            item = Gtk.Separator.new(Gtk.Orientation.HORIZONTAL)
            box.append (item)
            #-------------------------------------
            item = Gtk.Button.new_with_label ("New3")
            item.set_has_frame(False)
            box.append (item)
            #-------------------------------------
            popover.popup ()

My custom menu appeared
But the default textview menu did not appear
I think that is the reason for the error
I didn’t know how to stop the original right click event

Is the problem with Wayland? Because when I tried with xorg no problem occurred

But my custom menu appeared with the default popup menu
How can I hide the default menu or disable the event signal responsible for it?

You cannot open a popover at random: it needs to be parented to a widget.

It also means you cannot add a popover to any random widget: you need to have your own custom GtkWidget that adds a popover as one of its children.

See:

1 Like

I have no knowledge of C language
But I tried to translate the code into Python

static void
pressed_cb (GtkGesture *gesture,
            int         n_press,
            double      x,
            double      y,
            gpointer    data)
{
  GtkWidget *widget;
  GtkWidget *child;

  widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
  child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
  child = gtk_widget_get_ancestor (child, canvas_item_get_type ());

  if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
    {
      GtkWidget *menu;
      GtkWidget *box;
      GtkWidget *item;

      menu = gtk_popover_new ();
      gtk_widget_set_parent (menu, widget);
      gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
      gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
      gtk_popover_set_child (GTK_POPOVER (menu), box);

      item = gtk_button_new_with_label ("New");
      gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
      g_signal_connect (item, "clicked", G_CALLBACK (new_item_cb), widget);
      gtk_box_append (GTK_BOX (box), item);

      item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
      gtk_box_append (GTK_BOX (box), item);

      item = gtk_button_new_with_label ("Edit");
      gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
      gtk_widget_set_sensitive (item, child != NULL && child != widget);
      g_signal_connect (item, "clicked", G_CALLBACK (edit_cb), child);
      gtk_box_append (GTK_BOX (box), item);

      item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
      gtk_box_append (GTK_BOX (box), item);

      item = gtk_button_new_with_label ("Delete");
      gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
      gtk_widget_set_sensitive (item, child != NULL && child != widget);
      g_signal_connect (item, "clicked", G_CALLBACK (delete_cb), child);
      gtk_box_append (GTK_BOX (box), item);

      gtk_popover_popup (GTK_POPOVER (menu));
    }
}

from GTK demo,
to

def pressed_cb(self, gesture, n, x, y):
        widget = gesture.get_widget()
        if gesture.get_current_button() == Gdk.BUTTON_SECONDARY:
            print(n, x, y)
            rect = Gdk.Rectangle()
            rect.x = x
            rect.y = y
            rect.width = rect.height = 1
            popover = Gtk.Popover()
            popover.set_autohide(True)
            popover.set_has_arrow(False)
            popover.set_pointing_to(rect)
            popover.set_parent(widget)
            box = Gtk.Box(spacing=0, orientation=Gtk.Orientation.VERTICAL)
            popover.set_child(box)
            #-------------------------------------
            item = Gtk.Button.new_with_label ("New")
            item.set_has_frame(False)
            box.append (item)
            #-------------------------------------
            popover.popup ()

I don’t know where I went wrong