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;
}
The solution is another EventController that only responds to the button.
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), tv, box);
GtkGesture *gesture_1 = gtk_gesture_click_new();
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture_1), 0);
gtk_widget_add_controller(button,(GTK_EVENT_CONTROLLER(gesture_1)));
g_signal_connect (gesture_1, "pressed", G_CALLBACK (close_page_cb), notebook);
// g_signal_connect (button, "clicked", G_CALLBACK (close_page_cb), notebook);
However, there is still a problem in the function:
close_page_cb
But the question should be answered.
Greetings
Supplement:
The request to move GtkWindow by holding mouse click on Notebook header,
does not fit the function gtk_notebook_set_tab_reorderable
.
How should the program distinguish whether you want to move the window or rearrange the tabs with a mouse click on the header.
#include<gtk/gtk.h>
#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 *)notebook);
int total_page = gtk_notebook_get_n_pages ((GtkNotebook *)notebook);
gtk_notebook_remove_page ((GtkNotebook *)notebook, page);
}
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);
/* Append page 1 to the notebook */
GtkWidget *tv1 = gtk_text_view_new ();
GtkWidget *label1 = gtk_label_new ("example1");
GtkWidget *button1 = gtk_button_new_with_label (" X ");
GtkWidget *box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous ( (GtkBox*) box1,TRUE);
gtk_box_prepend ((GtkBox *)box1, label1);
gtk_box_append ((GtkBox *)box1, button1);
/* Append page 2 to the notebook */
GtkWidget *tv2 = gtk_text_view_new ();
GtkWidget *label2 = gtk_label_new ("example2");
GtkWidget *button2 = gtk_button_new_with_label (" X ");
GtkWidget *box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous ( (GtkBox*) box2,TRUE);
gtk_box_prepend ((GtkBox *)box2, label2);
gtk_box_append ((GtkBox *)box2, button2);
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), tv1, box1);
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), tv2, box2);
gtk_notebook_set_tab_reorderable((GtkNotebook*)notebook,tv1,TRUE);
gtk_notebook_set_tab_reorderable((GtkNotebook*)notebook,tv2,TRUE);
g_signal_connect (button1, "clicked", G_CALLBACK (close_page_cb), NULL);
g_signal_connect (button2, "clicked", G_CALLBACK (close_page_cb), NULL);
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;
}
So I would do programming.
3