October 23, 2024
Chicago 12, Melborne City, USA
C#

How to drag and drop GtkWindow by holding on GtkNotebook header?


I am trying to move(drag & drop) GtkWindow by holding mouse click on Notebook header. But my problem is, due to the Drag & Drop EventController signal, other child widgets (button on tab) not working properly.
Can someone tell me how to properly implement the drag and drop window signal in the GtkNotebook header, without interrupting the child widgets.

#include <gtk/gtk.h>
GtkWidget *window;
GtkWidget *notebook;

static gboolean close_page_cb( GtkWidget *widget, gpointer   user_data )
{
  int page = gtk_notebook_get_current_page ((GtkNotebook *)user_data);
  int total_page = gtk_notebook_get_n_pages ((GtkNotebook *)user_data);
      gtk_notebook_remove_page ((GtkNotebook *)user_data, page);
}


static void
start_move (GtkGestureClick *gesture,
            int n_press,
            double x,
            double y,
            gpointer   data)
{
  GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
  GdkSurface *surface;
  GdkEvent *event;
  guint button;
  guint32 timestamp;

  gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
  surface = gtk_native_get_surface (gtk_widget_get_native (widget));
  event = gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER (gesture));
  if (gdk_event_get_event_type (event) == GDK_BUTTON_PRESS)
    button = gdk_button_event_get_button (event);
  else
    button = 0;
  timestamp = gdk_event_get_time (event);
  gtk_widget_translate_coordinates (widget, GTK_WIDGET (gtk_widget_get_root (widget)),
                                x, y, &x, &y);
  gdk_toplevel_begin_move (GDK_TOPLEVEL (surface), gdk_event_get_device (event), button, x, y, timestamp);
  gtk_event_controller_reset (GTK_EVENT_CONTROLLER (gesture));
}



static void
activate (GtkApplication *app,
      gpointer        user_data)
{
  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "example");
  gtk_window_set_default_size (GTK_WINDOW (window), 400, 200);

  GtkWidget *grid = gtk_grid_new ();
  gtk_window_set_child ((GtkWindow    *)window, grid);
  gtk_widget_set_vexpand(grid, TRUE);
  gtk_widget_set_hexpand(grid, TRUE);

    /* Create notebook, place position of tabs */
    notebook = gtk_notebook_new ();
    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
    gtk_grid_attach (GTK_GRID (grid), notebook, 0, 6, 3, 3);
    gtk_notebook_set_scrollable((GtkNotebook     *)notebook, TRUE);
    gtk_widget_set_vexpand(notebook, TRUE);
    gtk_widget_set_hexpand(notebook, TRUE);


    GtkGesture *gesture;
    gesture = gtk_gesture_click_new ();
    g_signal_connect (gesture, "pressed", G_CALLBACK (start_move), NULL);
    gtk_widget_add_controller (notebook, GTK_EVENT_CONTROLLER (gesture));

   /* Append page to the notebook */
    GtkWidget *tv = gtk_text_view_new ();
    GtkWidget *label = gtk_label_new ("example");
    GtkWidget *button = gtk_button_new_with_label ("  X  ");

    GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_box_prepend ((GtkBox  *)box, label);
    gtk_box_append ((GtkBox  *)box, button);

    gtk_notebook_append_page (GTK_NOTEBOOK(notebook), tv, box); 
    g_signal_connect (button, "clicked", G_CALLBACK (close_page_cb), notebook);

  
  gtk_window_present ((GtkWindow*)window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video