2 #ifdef GDK_WINDOWING_X11
6 static GtkWidget *darea;
7 static GtkTreeStore *window_store = NULL;
8 static GtkWidget *treeview;
10 static void update_store (void);
12 static GtkWidget *main_window;
15 window_has_impl (GdkWindow *window)
18 w = (GdkWindowObject *)window;
19 return w->parent == NULL || w->parent->impl != w->impl;
23 create_window (GdkWindow *parent,
24 int x, int y, int w, int h,
27 GdkWindowAttr attributes;
35 attributes.height = h;
36 attributes.window_type = GDK_WINDOW_CHILD;
37 attributes.event_mask = GDK_STRUCTURE_MASK
38 | GDK_BUTTON_MOTION_MASK
39 | GDK_BUTTON_PRESS_MASK
40 | GDK_BUTTON_RELEASE_MASK
42 | GDK_ENTER_NOTIFY_MASK
43 | GDK_LEAVE_NOTIFY_MASK;
44 attributes.wclass = GDK_INPUT_OUTPUT;
46 attributes_mask = GDK_WA_X | GDK_WA_Y;
48 window = gdk_window_new (parent, &attributes, attributes_mask);
49 gdk_window_set_user_data (window, darea);
51 bg = g_new (GdkColor, 1);
56 bg->red = g_random_int_range (0, 0xffff);
57 bg->blue = g_random_int_range (0, 0xffff);
58 bg->green = g_random_int_range (0, 0xffff);;
61 gdk_rgb_find_color (gtk_widget_get_colormap (darea), bg);
62 gdk_window_set_background (window, bg);
63 g_object_set_data_full (G_OBJECT (window), "color", bg, g_free);
65 gdk_window_show (window);
71 add_window_cb (GtkTreeModel *model,
76 GList **selected = data;
79 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
84 *selected = g_list_prepend (*selected, window);
88 get_selected_windows (void)
90 GtkTreeSelection *sel;
93 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
96 gtk_tree_selection_selected_foreach (sel, add_window_cb, &selected);
102 find_window_helper (GtkTreeModel *model,
105 GtkTreeIter *selected_iter)
107 GtkTreeIter child_iter;
112 gtk_tree_model_get (model, iter,
117 *selected_iter = *iter;
121 if (gtk_tree_model_iter_children (model,
125 if (find_window_helper (model, window, &child_iter, selected_iter))
128 } while (gtk_tree_model_iter_next (model, iter));
134 find_window (GdkWindow *window,
135 GtkTreeIter *window_iter)
139 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (window_store), &iter))
142 return find_window_helper (GTK_TREE_MODEL (window_store),
149 toggle_selection_window (GdkWindow *window)
151 GtkTreeSelection *selection;
154 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
156 if (window != NULL &&
157 find_window (window, &iter))
159 if (gtk_tree_selection_iter_is_selected (selection, &iter))
160 gtk_tree_selection_unselect_iter (selection, &iter);
162 gtk_tree_selection_select_iter (selection, &iter);
167 unselect_windows (void)
169 GtkTreeSelection *selection;
171 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
173 gtk_tree_selection_unselect_all (selection);
178 select_window (GdkWindow *window)
180 GtkTreeSelection *selection;
183 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
185 if (window != NULL &&
186 find_window (window, &iter))
187 gtk_tree_selection_select_iter (selection, &iter);
191 select_windows (GList *windows)
193 GtkTreeSelection *selection;
197 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
198 gtk_tree_selection_unselect_all (selection);
200 for (l = windows; l != NULL; l = l->next)
202 if (find_window (l->data, &iter))
203 gtk_tree_selection_select_iter (selection, &iter);
208 add_window_clicked (GtkWidget *button,
214 l = get_selected_windows ();
218 parent = darea->window;
222 create_window (parent, 10, 10, 100, 100, NULL);
227 draw_drawable_clicked (GtkWidget *button,
231 gc = gdk_gc_new (darea->window);
232 gdk_draw_drawable (darea->window,
243 remove_window_clicked (GtkWidget *button,
248 selected = get_selected_windows ();
250 for (l = selected; l != NULL; l = l->next)
251 gdk_window_destroy (l->data);
253 g_list_free (selected);
258 static void save_children (GString *s, GdkWindow *window);
261 save_window (GString *s,
267 gdk_window_get_position (window, &x, &y);
268 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
269 color = g_object_get_data (G_OBJECT (window), "color");
271 g_string_append_printf (s, "%d,%d %dx%d (%d,%d,%d) %d %d\n",
273 color->red, color->green, color->blue,
274 window_has_impl (window),
275 g_list_length (gdk_window_peek_children (window)));
277 save_children (s, window);
282 save_children (GString *s,
288 for (l = g_list_reverse (gdk_window_peek_children (window));
294 save_window (s, child);
300 save_clicked (GtkWidget *button,
307 s = g_string_new ("");
309 save_children (s, darea->window);
311 dialog = gtk_file_chooser_dialog_new ("Filename for window data",
313 GTK_FILE_CHOOSER_ACTION_SAVE,
314 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
315 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
318 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
320 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
322 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
324 g_file_replace_contents (file,
327 0, NULL, NULL, NULL);
329 g_object_unref (file);
332 gtk_widget_destroy (dialog);
333 g_string_free (s, TRUE);
337 destroy_children (GdkWindow *window)
342 for (l = gdk_window_peek_children (window);
348 destroy_children (child);
349 gdk_window_destroy (child);
354 parse_window (GdkWindow *parent, char **lines)
356 int x, y, w, h, r, g, b, native, n_children;
364 if (sscanf(*lines, "%d,%d %dx%d (%d,%d,%d) %d %d",
365 &x, &y, &w, &h, &r, &g, &b, &native, &n_children) == 9)
371 window = create_window (parent, x, y, w, h, &color);
373 gdk_window_ensure_native (window);
375 for (i = 0; i < n_children; i++)
376 lines = parse_window (window, lines);
385 load_file (GFile *file)
390 if (g_file_load_contents (file, NULL, &data, NULL, NULL, NULL))
392 destroy_children (darea->window);
394 lines = g_strsplit (data, "\n", -1);
398 l = parse_window (darea->window, l);
405 move_window_clicked (GtkWidget *button,
409 GtkDirectionType direction;
413 direction = GPOINTER_TO_INT (data);
415 selected = get_selected_windows ();
417 for (l = selected; l != NULL; l = l->next)
421 gdk_window_get_position (window, &x, &y);
440 gdk_window_move (window, x, y);
443 g_list_free (selected);
447 manual_clicked (GtkWidget *button,
453 GtkWidget *dialog, *table, *label, *xspin, *yspin, *wspin, *hspin;
456 selected = get_selected_windows ();
458 if (selected == NULL)
461 gdk_window_get_position (selected->data, &x, &y);
462 gdk_drawable_get_size (selected->data, &w, &h);
464 dialog = gtk_dialog_new_with_buttons ("Select new position and size",
465 GTK_WINDOW (main_window),
467 GTK_STOCK_OK, GTK_RESPONSE_OK,
471 table = gtk_table_new (2, 4, TRUE);
472 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
478 label = gtk_label_new ("x:");
479 gtk_table_attach_defaults (GTK_TABLE (table),
483 label = gtk_label_new ("y:");
484 gtk_table_attach_defaults (GTK_TABLE (table),
488 label = gtk_label_new ("width:");
489 gtk_table_attach_defaults (GTK_TABLE (table),
493 label = gtk_label_new ("height:");
494 gtk_table_attach_defaults (GTK_TABLE (table),
499 xspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
500 gtk_spin_button_set_value (GTK_SPIN_BUTTON (xspin), x);
501 gtk_table_attach_defaults (GTK_TABLE (table),
505 yspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
506 gtk_spin_button_set_value (GTK_SPIN_BUTTON (yspin), y);
507 gtk_table_attach_defaults (GTK_TABLE (table),
511 wspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
512 gtk_spin_button_set_value (GTK_SPIN_BUTTON (wspin), w);
513 gtk_table_attach_defaults (GTK_TABLE (table),
517 hspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
518 gtk_spin_button_set_value (GTK_SPIN_BUTTON (hspin), h);
519 gtk_table_attach_defaults (GTK_TABLE (table),
524 gtk_widget_show_all (dialog);
526 gtk_dialog_run (GTK_DIALOG (dialog));
528 x = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (xspin));
529 y = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (yspin));
530 w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (wspin));
531 h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (hspin));
533 gtk_widget_destroy (dialog);
535 for (l = selected; l != NULL; l = l->next)
539 gdk_window_move_resize (window, x, y, w, h);
542 g_list_free (selected);
546 scroll_window_clicked (GtkWidget *button,
550 GtkDirectionType direction;
554 direction = GPOINTER_TO_INT (data);
556 selected = get_selected_windows ();
576 for (l = selected; l != NULL; l = l->next)
580 gdk_window_scroll (window, dx, dy);
583 g_list_free (selected);
588 raise_window_clicked (GtkWidget *button,
594 selected = get_selected_windows ();
596 for (l = selected; l != NULL; l = l->next)
600 gdk_window_raise (window);
603 g_list_free (selected);
609 lower_window_clicked (GtkWidget *button,
615 selected = get_selected_windows ();
617 for (l = selected; l != NULL; l = l->next)
621 gdk_window_lower (window);
624 g_list_free (selected);
631 smaller_window_clicked (GtkWidget *button,
638 selected = get_selected_windows ();
640 for (l = selected; l != NULL; l = l->next)
644 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
653 gdk_window_resize (window, w, h);
656 g_list_free (selected);
660 larger_window_clicked (GtkWidget *button,
667 selected = get_selected_windows ();
669 for (l = selected; l != NULL; l = l->next)
673 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
678 gdk_window_resize (window, w, h);
681 g_list_free (selected);
685 native_window_clicked (GtkWidget *button,
691 selected = get_selected_windows ();
693 for (l = selected; l != NULL; l = l->next)
697 gdk_window_ensure_native (window);
700 g_list_free (selected);
706 darea_button_release_event (GtkWidget *widget,
707 GdkEventButton *event)
709 if ((event->state & GDK_CONTROL_MASK) != 0)
711 toggle_selection_window (event->window);
716 select_window (event->window);
723 render_window_cell (GtkTreeViewColumn *tree_column,
724 GtkCellRenderer *cell,
725 GtkTreeModel *tree_model,
732 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
737 if (window_has_impl (window))
738 name = g_strdup_printf ("%p (native)", window);
740 name = g_strdup_printf ("%p", window);
743 "background-gdk", &((GdkWindowObject *)window)->bg_color,
748 add_children (GtkTreeStore *store,
750 GtkTreeIter *window_iter)
753 GtkTreeIter child_iter;
755 for (l = gdk_window_peek_children (window);
759 gtk_tree_store_append (store, &child_iter, window_iter);
760 gtk_tree_store_set (store, &child_iter,
764 add_children (store, l->data, &child_iter);
773 selected = get_selected_windows ();
775 gtk_tree_store_clear (window_store);
777 add_children (window_store, darea->window, NULL);
778 gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
780 select_windows (selected);
781 g_list_free (selected);
786 main (int argc, char **argv)
788 GtkWidget *window, *vbox, *hbox, *frame;
789 GtkWidget *button, *scrolled, *table;
790 GtkTreeViewColumn *column;
791 GtkCellRenderer *renderer;
792 GdkColor black = {0};
795 gtk_init (&argc, &argv);
797 main_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
798 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
800 g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
802 hbox = gtk_hbox_new (FALSE, 5);
803 gtk_container_add (GTK_CONTAINER (window), hbox);
804 gtk_widget_show (hbox);
806 frame = gtk_frame_new ("GdkWindows");
807 gtk_box_pack_start (GTK_BOX (hbox),
811 gtk_widget_show (frame);
813 darea = gtk_drawing_area_new ();
814 /*gtk_widget_set_double_buffered (darea, FALSE);*/
815 gtk_widget_add_events (darea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
816 gtk_widget_set_size_request (darea, 500, 500);
817 g_signal_connect (darea, "button_release_event",
818 G_CALLBACK (darea_button_release_event),
822 gtk_container_add (GTK_CONTAINER (frame), darea);
823 gtk_widget_realize (darea);
824 gtk_widget_show (darea);
825 gtk_widget_modify_bg (darea, GTK_STATE_NORMAL,
829 vbox = gtk_vbox_new (FALSE, 5);
830 gtk_box_pack_start (GTK_BOX (hbox),
834 gtk_widget_show (vbox);
836 window_store = gtk_tree_store_new (1, GDK_TYPE_WINDOW);
838 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window_store));
839 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
840 GTK_SELECTION_MULTIPLE);
841 column = gtk_tree_view_column_new ();
842 gtk_tree_view_column_set_title (column, "Window");
843 renderer = gtk_cell_renderer_text_new ();
844 gtk_tree_view_column_pack_start (column, renderer, TRUE);
845 gtk_tree_view_column_set_cell_data_func (column,
850 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
853 scrolled = gtk_scrolled_window_new (NULL, NULL);
854 gtk_widget_set_size_request (scrolled, 200, 400);
855 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
856 gtk_box_pack_start (GTK_BOX (vbox),
860 gtk_widget_show (scrolled);
861 gtk_widget_show (treeview);
863 table = gtk_table_new (4, 4, TRUE);
864 gtk_box_pack_start (GTK_BOX (vbox),
868 gtk_widget_show (table);
870 button = gtk_button_new ();
871 gtk_button_set_image (GTK_BUTTON (button),
872 gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
873 GTK_ICON_SIZE_BUTTON));
874 g_signal_connect (button, "clicked",
875 G_CALLBACK (move_window_clicked),
876 GINT_TO_POINTER (GTK_DIR_LEFT));
877 gtk_table_attach_defaults (GTK_TABLE (table),
881 gtk_widget_show (button);
883 button = gtk_button_new ();
884 gtk_button_set_image (GTK_BUTTON (button),
885 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
886 GTK_ICON_SIZE_BUTTON));
887 g_signal_connect (button, "clicked",
888 G_CALLBACK (move_window_clicked),
889 GINT_TO_POINTER (GTK_DIR_UP));
890 gtk_table_attach_defaults (GTK_TABLE (table),
894 gtk_widget_show (button);
896 button = gtk_button_new ();
897 gtk_button_set_image (GTK_BUTTON (button),
898 gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
899 GTK_ICON_SIZE_BUTTON));
900 g_signal_connect (button, "clicked",
901 G_CALLBACK (move_window_clicked),
902 GINT_TO_POINTER (GTK_DIR_RIGHT));
903 gtk_table_attach_defaults (GTK_TABLE (table),
907 gtk_widget_show (button);
909 button = gtk_button_new ();
910 gtk_button_set_image (GTK_BUTTON (button),
911 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
912 GTK_ICON_SIZE_BUTTON));
913 g_signal_connect (button, "clicked",
914 G_CALLBACK (move_window_clicked),
915 GINT_TO_POINTER (GTK_DIR_DOWN));
916 gtk_table_attach_defaults (GTK_TABLE (table),
920 gtk_widget_show (button);
923 button = gtk_button_new_with_label ("Raise");
924 g_signal_connect (button, "clicked",
925 G_CALLBACK (raise_window_clicked),
927 gtk_table_attach_defaults (GTK_TABLE (table),
931 gtk_widget_show (button);
933 button = gtk_button_new_with_label ("Lower");
934 g_signal_connect (button, "clicked",
935 G_CALLBACK (lower_window_clicked),
937 gtk_table_attach_defaults (GTK_TABLE (table),
941 gtk_widget_show (button);
944 button = gtk_button_new_with_label ("Smaller");
945 g_signal_connect (button, "clicked",
946 G_CALLBACK (smaller_window_clicked),
948 gtk_table_attach_defaults (GTK_TABLE (table),
952 gtk_widget_show (button);
954 button = gtk_button_new_with_label ("Larger");
955 g_signal_connect (button, "clicked",
956 G_CALLBACK (larger_window_clicked),
958 gtk_table_attach_defaults (GTK_TABLE (table),
962 gtk_widget_show (button);
964 button = gtk_button_new_with_label ("Native");
965 g_signal_connect (button, "clicked",
966 G_CALLBACK (native_window_clicked),
968 gtk_table_attach_defaults (GTK_TABLE (table),
972 gtk_widget_show (button);
975 button = gtk_button_new_with_label ("scroll");
976 gtk_button_set_image (GTK_BUTTON (button),
977 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
978 GTK_ICON_SIZE_BUTTON));
979 g_signal_connect (button, "clicked",
980 G_CALLBACK (scroll_window_clicked),
981 GINT_TO_POINTER (GTK_DIR_UP));
982 gtk_table_attach_defaults (GTK_TABLE (table),
986 gtk_widget_show (button);
988 button = gtk_button_new_with_label ("scroll");
989 gtk_button_set_image (GTK_BUTTON (button),
990 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
991 GTK_ICON_SIZE_BUTTON));
992 g_signal_connect (button, "clicked",
993 G_CALLBACK (scroll_window_clicked),
994 GINT_TO_POINTER (GTK_DIR_DOWN));
995 gtk_table_attach_defaults (GTK_TABLE (table),
999 gtk_widget_show (button);
1001 button = gtk_button_new_with_label ("Manual");
1002 g_signal_connect (button, "clicked",
1003 G_CALLBACK (manual_clicked),
1005 gtk_table_attach_defaults (GTK_TABLE (table),
1009 gtk_widget_show (button);
1011 button = gtk_button_new_with_label ("draw drawable");
1012 gtk_box_pack_start (GTK_BOX (vbox),
1016 gtk_widget_show (button);
1017 g_signal_connect (button, "clicked",
1018 G_CALLBACK (draw_drawable_clicked),
1021 button = gtk_button_new_with_label ("Add window");
1022 gtk_box_pack_start (GTK_BOX (vbox),
1026 gtk_widget_show (button);
1027 g_signal_connect (button, "clicked",
1028 G_CALLBACK (add_window_clicked),
1031 button = gtk_button_new_with_label ("Remove window");
1032 gtk_box_pack_start (GTK_BOX (vbox),
1036 gtk_widget_show (button);
1037 g_signal_connect (button, "clicked",
1038 G_CALLBACK (remove_window_clicked),
1041 button = gtk_button_new_with_label ("Save");
1042 gtk_box_pack_start (GTK_BOX (vbox),
1046 gtk_widget_show (button);
1047 g_signal_connect (button, "clicked",
1048 G_CALLBACK (save_clicked),
1051 gtk_widget_show (window);
1055 file = g_file_new_for_commandline_arg (argv[1]);
1057 g_object_unref (file);