1 #undef GDK_DISABLE_DEPRECATED
3 #ifdef GDK_WINDOWING_X11
7 static GtkWidget *darea;
8 static GtkTreeStore *window_store = NULL;
9 static GtkWidget *treeview;
11 static void update_store (void);
13 static GtkWidget *main_window;
16 window_has_impl (GdkWindow *window)
19 w = (GdkWindowObject *)window;
20 return w->parent == NULL || w->parent->impl != w->impl;
24 create_window (GdkWindow *parent,
25 int x, int y, int w, int h,
28 GdkWindowAttr attributes;
36 attributes.height = h;
37 attributes.window_type = GDK_WINDOW_CHILD;
38 attributes.event_mask = GDK_STRUCTURE_MASK
39 | GDK_BUTTON_MOTION_MASK
40 | GDK_BUTTON_PRESS_MASK
41 | GDK_BUTTON_RELEASE_MASK
43 | GDK_ENTER_NOTIFY_MASK
44 | GDK_LEAVE_NOTIFY_MASK;
45 attributes.wclass = GDK_INPUT_OUTPUT;
47 attributes_mask = GDK_WA_X | GDK_WA_Y;
49 window = gdk_window_new (parent, &attributes, attributes_mask);
50 gdk_window_set_user_data (window, darea);
52 bg = g_new (GdkColor, 1);
57 bg->red = g_random_int_range (0, 0xffff);
58 bg->blue = g_random_int_range (0, 0xffff);
59 bg->green = g_random_int_range (0, 0xffff);;
62 gdk_rgb_find_color (gtk_widget_get_colormap (darea), bg);
63 gdk_window_set_background (window, bg);
64 g_object_set_data_full (G_OBJECT (window), "color", bg, g_free);
66 gdk_window_show (window);
72 add_window_cb (GtkTreeModel *model,
77 GList **selected = data;
80 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
85 *selected = g_list_prepend (*selected, window);
89 get_selected_windows (void)
91 GtkTreeSelection *sel;
94 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
97 gtk_tree_selection_selected_foreach (sel, add_window_cb, &selected);
103 find_window_helper (GtkTreeModel *model,
106 GtkTreeIter *selected_iter)
108 GtkTreeIter child_iter;
113 gtk_tree_model_get (model, iter,
118 *selected_iter = *iter;
122 if (gtk_tree_model_iter_children (model,
126 if (find_window_helper (model, window, &child_iter, selected_iter))
129 } while (gtk_tree_model_iter_next (model, iter));
135 find_window (GdkWindow *window,
136 GtkTreeIter *window_iter)
140 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (window_store), &iter))
143 return find_window_helper (GTK_TREE_MODEL (window_store),
150 toggle_selection_window (GdkWindow *window)
152 GtkTreeSelection *selection;
155 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
157 if (window != NULL &&
158 find_window (window, &iter))
160 if (gtk_tree_selection_iter_is_selected (selection, &iter))
161 gtk_tree_selection_unselect_iter (selection, &iter);
163 gtk_tree_selection_select_iter (selection, &iter);
168 unselect_windows (void)
170 GtkTreeSelection *selection;
172 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
174 gtk_tree_selection_unselect_all (selection);
179 select_window (GdkWindow *window)
181 GtkTreeSelection *selection;
184 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
186 if (window != NULL &&
187 find_window (window, &iter))
188 gtk_tree_selection_select_iter (selection, &iter);
192 select_windows (GList *windows)
194 GtkTreeSelection *selection;
198 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
199 gtk_tree_selection_unselect_all (selection);
201 for (l = windows; l != NULL; l = l->next)
203 if (find_window (l->data, &iter))
204 gtk_tree_selection_select_iter (selection, &iter);
209 add_window_clicked (GtkWidget *button,
215 l = get_selected_windows ();
219 parent = darea->window;
223 create_window (parent, 10, 10, 100, 100, NULL);
228 draw_drawable_clicked (GtkWidget *button,
232 gc = gdk_gc_new (darea->window);
233 gdk_draw_drawable (darea->window,
244 remove_window_clicked (GtkWidget *button,
249 selected = get_selected_windows ();
251 for (l = selected; l != NULL; l = l->next)
252 gdk_window_destroy (l->data);
254 g_list_free (selected);
259 static void save_children (GString *s, GdkWindow *window);
262 save_window (GString *s,
268 gdk_window_get_position (window, &x, &y);
269 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
270 color = g_object_get_data (G_OBJECT (window), "color");
272 g_string_append_printf (s, "%d,%d %dx%d (%d,%d,%d) %d %d\n",
274 color->red, color->green, color->blue,
275 window_has_impl (window),
276 g_list_length (gdk_window_peek_children (window)));
278 save_children (s, window);
283 save_children (GString *s,
289 for (l = g_list_reverse (gdk_window_peek_children (window));
295 save_window (s, child);
301 save_clicked (GtkWidget *button,
308 s = g_string_new ("");
310 save_children (s, darea->window);
312 dialog = gtk_file_chooser_dialog_new ("Filename for window data",
314 GTK_FILE_CHOOSER_ACTION_SAVE,
315 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
316 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
319 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
321 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
323 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
325 g_file_replace_contents (file,
328 0, NULL, NULL, NULL);
330 g_object_unref (file);
333 gtk_widget_destroy (dialog);
334 g_string_free (s, TRUE);
338 destroy_children (GdkWindow *window)
343 for (l = gdk_window_peek_children (window);
349 destroy_children (child);
350 gdk_window_destroy (child);
355 parse_window (GdkWindow *parent, char **lines)
357 int x, y, w, h, r, g, b, native, n_children;
365 if (sscanf(*lines, "%d,%d %dx%d (%d,%d,%d) %d %d",
366 &x, &y, &w, &h, &r, &g, &b, &native, &n_children) == 9)
372 window = create_window (parent, x, y, w, h, &color);
374 gdk_window_ensure_native (window);
376 for (i = 0; i < n_children; i++)
377 lines = parse_window (window, lines);
386 load_file (GFile *file)
391 if (g_file_load_contents (file, NULL, &data, NULL, NULL, NULL))
393 destroy_children (darea->window);
395 lines = g_strsplit (data, "\n", -1);
399 l = parse_window (darea->window, l);
406 move_window_clicked (GtkWidget *button,
410 GtkDirectionType direction;
414 direction = GPOINTER_TO_INT (data);
416 selected = get_selected_windows ();
418 for (l = selected; l != NULL; l = l->next)
422 gdk_window_get_position (window, &x, &y);
441 gdk_window_move (window, x, y);
444 g_list_free (selected);
448 manual_clicked (GtkWidget *button,
454 GtkWidget *dialog, *table, *label, *xspin, *yspin, *wspin, *hspin;
457 selected = get_selected_windows ();
459 if (selected == NULL)
462 gdk_window_get_position (selected->data, &x, &y);
463 gdk_drawable_get_size (selected->data, &w, &h);
465 dialog = gtk_dialog_new_with_buttons ("Select new position and size",
466 GTK_WINDOW (main_window),
468 GTK_STOCK_OK, GTK_RESPONSE_OK,
472 table = gtk_table_new (2, 4, TRUE);
473 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
479 label = gtk_label_new ("x:");
480 gtk_table_attach_defaults (GTK_TABLE (table),
484 label = gtk_label_new ("y:");
485 gtk_table_attach_defaults (GTK_TABLE (table),
489 label = gtk_label_new ("width:");
490 gtk_table_attach_defaults (GTK_TABLE (table),
494 label = gtk_label_new ("height:");
495 gtk_table_attach_defaults (GTK_TABLE (table),
500 xspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
501 gtk_spin_button_set_value (GTK_SPIN_BUTTON (xspin), x);
502 gtk_table_attach_defaults (GTK_TABLE (table),
506 yspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
507 gtk_spin_button_set_value (GTK_SPIN_BUTTON (yspin), y);
508 gtk_table_attach_defaults (GTK_TABLE (table),
512 wspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
513 gtk_spin_button_set_value (GTK_SPIN_BUTTON (wspin), w);
514 gtk_table_attach_defaults (GTK_TABLE (table),
518 hspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
519 gtk_spin_button_set_value (GTK_SPIN_BUTTON (hspin), h);
520 gtk_table_attach_defaults (GTK_TABLE (table),
525 gtk_widget_show_all (dialog);
527 gtk_dialog_run (GTK_DIALOG (dialog));
529 x = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (xspin));
530 y = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (yspin));
531 w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (wspin));
532 h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (hspin));
534 gtk_widget_destroy (dialog);
536 for (l = selected; l != NULL; l = l->next)
540 gdk_window_move_resize (window, x, y, w, h);
543 g_list_free (selected);
547 restack_clicked (GtkWidget *button,
552 selected = get_selected_windows ();
554 if (g_list_length (selected) != 2)
556 g_warning ("select two windows");
559 gdk_window_restack (selected->data,
560 selected->next->data,
561 GPOINTER_TO_INT (data));
563 g_list_free (selected);
569 scroll_window_clicked (GtkWidget *button,
573 GtkDirectionType direction;
577 direction = GPOINTER_TO_INT (data);
579 selected = get_selected_windows ();
599 for (l = selected; l != NULL; l = l->next)
603 gdk_window_scroll (window, dx, dy);
606 g_list_free (selected);
611 raise_window_clicked (GtkWidget *button,
617 selected = get_selected_windows ();
619 for (l = selected; l != NULL; l = l->next)
623 gdk_window_raise (window);
626 g_list_free (selected);
632 lower_window_clicked (GtkWidget *button,
638 selected = get_selected_windows ();
640 for (l = selected; l != NULL; l = l->next)
644 gdk_window_lower (window);
647 g_list_free (selected);
654 smaller_window_clicked (GtkWidget *button,
661 selected = get_selected_windows ();
663 for (l = selected; l != NULL; l = l->next)
667 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
676 gdk_window_resize (window, w, h);
679 g_list_free (selected);
683 larger_window_clicked (GtkWidget *button,
690 selected = get_selected_windows ();
692 for (l = selected; l != NULL; l = l->next)
696 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
701 gdk_window_resize (window, w, h);
704 g_list_free (selected);
708 native_window_clicked (GtkWidget *button,
714 selected = get_selected_windows ();
716 for (l = selected; l != NULL; l = l->next)
720 gdk_window_ensure_native (window);
723 g_list_free (selected);
729 darea_button_release_event (GtkWidget *widget,
730 GdkEventButton *event)
732 if ((event->state & GDK_CONTROL_MASK) != 0)
734 toggle_selection_window (event->window);
739 select_window (event->window);
746 render_window_cell (GtkTreeViewColumn *tree_column,
747 GtkCellRenderer *cell,
748 GtkTreeModel *tree_model,
755 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
760 if (window_has_impl (window))
761 name = g_strdup_printf ("%p (native)", window);
763 name = g_strdup_printf ("%p", window);
766 "background-gdk", &((GdkWindowObject *)window)->bg_color,
771 add_children (GtkTreeStore *store,
773 GtkTreeIter *window_iter)
776 GtkTreeIter child_iter;
778 for (l = gdk_window_peek_children (window);
782 gtk_tree_store_append (store, &child_iter, window_iter);
783 gtk_tree_store_set (store, &child_iter,
787 add_children (store, l->data, &child_iter);
796 selected = get_selected_windows ();
798 gtk_tree_store_clear (window_store);
800 add_children (window_store, darea->window, NULL);
801 gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
803 select_windows (selected);
804 g_list_free (selected);
809 main (int argc, char **argv)
811 GtkWidget *window, *vbox, *hbox, *frame;
812 GtkWidget *button, *scrolled, *table;
813 GtkTreeViewColumn *column;
814 GtkCellRenderer *renderer;
815 GdkColor black = {0};
818 gtk_init (&argc, &argv);
820 main_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
821 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
823 g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
825 hbox = gtk_hbox_new (FALSE, 5);
826 gtk_container_add (GTK_CONTAINER (window), hbox);
827 gtk_widget_show (hbox);
829 frame = gtk_frame_new ("GdkWindows");
830 gtk_box_pack_start (GTK_BOX (hbox),
834 gtk_widget_show (frame);
836 darea = gtk_drawing_area_new ();
837 /*gtk_widget_set_double_buffered (darea, FALSE);*/
838 gtk_widget_add_events (darea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
839 gtk_widget_set_size_request (darea, 500, 500);
840 g_signal_connect (darea, "button_release_event",
841 G_CALLBACK (darea_button_release_event),
845 gtk_container_add (GTK_CONTAINER (frame), darea);
846 gtk_widget_realize (darea);
847 gtk_widget_show (darea);
848 gtk_widget_modify_bg (darea, GTK_STATE_NORMAL,
852 vbox = gtk_vbox_new (FALSE, 5);
853 gtk_box_pack_start (GTK_BOX (hbox),
857 gtk_widget_show (vbox);
859 window_store = gtk_tree_store_new (1, GDK_TYPE_WINDOW);
861 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window_store));
862 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
863 GTK_SELECTION_MULTIPLE);
864 column = gtk_tree_view_column_new ();
865 gtk_tree_view_column_set_title (column, "Window");
866 renderer = gtk_cell_renderer_text_new ();
867 gtk_tree_view_column_pack_start (column, renderer, TRUE);
868 gtk_tree_view_column_set_cell_data_func (column,
873 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
876 scrolled = gtk_scrolled_window_new (NULL, NULL);
877 gtk_widget_set_size_request (scrolled, 200, 400);
878 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
879 gtk_box_pack_start (GTK_BOX (vbox),
883 gtk_widget_show (scrolled);
884 gtk_widget_show (treeview);
886 table = gtk_table_new (5, 4, TRUE);
887 gtk_box_pack_start (GTK_BOX (vbox),
891 gtk_widget_show (table);
893 button = gtk_button_new ();
894 gtk_button_set_image (GTK_BUTTON (button),
895 gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
896 GTK_ICON_SIZE_BUTTON));
897 g_signal_connect (button, "clicked",
898 G_CALLBACK (move_window_clicked),
899 GINT_TO_POINTER (GTK_DIR_LEFT));
900 gtk_table_attach_defaults (GTK_TABLE (table),
904 gtk_widget_show (button);
906 button = gtk_button_new ();
907 gtk_button_set_image (GTK_BUTTON (button),
908 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
909 GTK_ICON_SIZE_BUTTON));
910 g_signal_connect (button, "clicked",
911 G_CALLBACK (move_window_clicked),
912 GINT_TO_POINTER (GTK_DIR_UP));
913 gtk_table_attach_defaults (GTK_TABLE (table),
917 gtk_widget_show (button);
919 button = gtk_button_new ();
920 gtk_button_set_image (GTK_BUTTON (button),
921 gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
922 GTK_ICON_SIZE_BUTTON));
923 g_signal_connect (button, "clicked",
924 G_CALLBACK (move_window_clicked),
925 GINT_TO_POINTER (GTK_DIR_RIGHT));
926 gtk_table_attach_defaults (GTK_TABLE (table),
930 gtk_widget_show (button);
932 button = gtk_button_new ();
933 gtk_button_set_image (GTK_BUTTON (button),
934 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
935 GTK_ICON_SIZE_BUTTON));
936 g_signal_connect (button, "clicked",
937 G_CALLBACK (move_window_clicked),
938 GINT_TO_POINTER (GTK_DIR_DOWN));
939 gtk_table_attach_defaults (GTK_TABLE (table),
943 gtk_widget_show (button);
946 button = gtk_button_new_with_label ("Raise");
947 g_signal_connect (button, "clicked",
948 G_CALLBACK (raise_window_clicked),
950 gtk_table_attach_defaults (GTK_TABLE (table),
954 gtk_widget_show (button);
956 button = gtk_button_new_with_label ("Lower");
957 g_signal_connect (button, "clicked",
958 G_CALLBACK (lower_window_clicked),
960 gtk_table_attach_defaults (GTK_TABLE (table),
964 gtk_widget_show (button);
967 button = gtk_button_new_with_label ("Smaller");
968 g_signal_connect (button, "clicked",
969 G_CALLBACK (smaller_window_clicked),
971 gtk_table_attach_defaults (GTK_TABLE (table),
975 gtk_widget_show (button);
977 button = gtk_button_new_with_label ("Larger");
978 g_signal_connect (button, "clicked",
979 G_CALLBACK (larger_window_clicked),
981 gtk_table_attach_defaults (GTK_TABLE (table),
985 gtk_widget_show (button);
987 button = gtk_button_new_with_label ("Native");
988 g_signal_connect (button, "clicked",
989 G_CALLBACK (native_window_clicked),
991 gtk_table_attach_defaults (GTK_TABLE (table),
995 gtk_widget_show (button);
998 button = gtk_button_new_with_label ("scroll");
999 gtk_button_set_image (GTK_BUTTON (button),
1000 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
1001 GTK_ICON_SIZE_BUTTON));
1002 g_signal_connect (button, "clicked",
1003 G_CALLBACK (scroll_window_clicked),
1004 GINT_TO_POINTER (GTK_DIR_UP));
1005 gtk_table_attach_defaults (GTK_TABLE (table),
1009 gtk_widget_show (button);
1011 button = gtk_button_new_with_label ("scroll");
1012 gtk_button_set_image (GTK_BUTTON (button),
1013 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
1014 GTK_ICON_SIZE_BUTTON));
1015 g_signal_connect (button, "clicked",
1016 G_CALLBACK (scroll_window_clicked),
1017 GINT_TO_POINTER (GTK_DIR_DOWN));
1018 gtk_table_attach_defaults (GTK_TABLE (table),
1022 gtk_widget_show (button);
1024 button = gtk_button_new_with_label ("Manual");
1025 g_signal_connect (button, "clicked",
1026 G_CALLBACK (manual_clicked),
1028 gtk_table_attach_defaults (GTK_TABLE (table),
1032 gtk_widget_show (button);
1034 button = gtk_button_new_with_label ("Restack above");
1035 g_signal_connect (button, "clicked",
1036 G_CALLBACK (restack_clicked),
1038 gtk_table_attach_defaults (GTK_TABLE (table),
1042 gtk_widget_show (button);
1044 button = gtk_button_new_with_label ("Restack below");
1045 g_signal_connect (button, "clicked",
1046 G_CALLBACK (restack_clicked),
1048 gtk_table_attach_defaults (GTK_TABLE (table),
1052 gtk_widget_show (button);
1054 button = gtk_button_new_with_label ("draw drawable");
1055 gtk_box_pack_start (GTK_BOX (vbox),
1059 gtk_widget_show (button);
1060 g_signal_connect (button, "clicked",
1061 G_CALLBACK (draw_drawable_clicked),
1064 button = gtk_button_new_with_label ("Add window");
1065 gtk_box_pack_start (GTK_BOX (vbox),
1069 gtk_widget_show (button);
1070 g_signal_connect (button, "clicked",
1071 G_CALLBACK (add_window_clicked),
1074 button = gtk_button_new_with_label ("Remove window");
1075 gtk_box_pack_start (GTK_BOX (vbox),
1079 gtk_widget_show (button);
1080 g_signal_connect (button, "clicked",
1081 G_CALLBACK (remove_window_clicked),
1084 button = gtk_button_new_with_label ("Save");
1085 gtk_box_pack_start (GTK_BOX (vbox),
1089 gtk_widget_show (button);
1090 g_signal_connect (button, "clicked",
1091 G_CALLBACK (save_clicked),
1094 gtk_widget_show (window);
1098 file = g_file_new_for_commandline_arg (argv[1]);
1100 g_object_unref (file);