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;
16 create_window (GdkWindow *parent,
17 int x, int y, int w, int h,
20 GdkWindowAttr attributes;
28 attributes.height = h;
29 attributes.window_type = GDK_WINDOW_CHILD;
30 attributes.event_mask = GDK_STRUCTURE_MASK
31 | GDK_BUTTON_MOTION_MASK
32 | GDK_BUTTON_PRESS_MASK
33 | GDK_BUTTON_RELEASE_MASK
35 | GDK_ENTER_NOTIFY_MASK
36 | GDK_LEAVE_NOTIFY_MASK;
37 attributes.wclass = GDK_INPUT_OUTPUT;
39 attributes_mask = GDK_WA_X | GDK_WA_Y;
41 window = gdk_window_new (parent, &attributes, attributes_mask);
42 gdk_window_set_user_data (window, darea);
44 bg = g_new (GdkColor, 1);
49 bg->red = g_random_int_range (0, 0xffff);
50 bg->blue = g_random_int_range (0, 0xffff);
51 bg->green = g_random_int_range (0, 0xffff);;
54 if (!gdk_colormap_alloc_color (gtk_widget_get_colormap (darea), bg, FALSE, TRUE))
55 g_assert_not_reached ();
56 gdk_window_set_background (window, bg);
57 g_object_set_data_full (G_OBJECT (window), "color", bg, g_free);
59 gdk_window_show (window);
65 add_window_cb (GtkTreeModel *model,
70 GList **selected = data;
73 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
78 *selected = g_list_prepend (*selected, window);
82 get_selected_windows (void)
84 GtkTreeSelection *sel;
87 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
90 gtk_tree_selection_selected_foreach (sel, add_window_cb, &selected);
96 find_window_helper (GtkTreeModel *model,
99 GtkTreeIter *selected_iter)
101 GtkTreeIter child_iter;
106 gtk_tree_model_get (model, iter,
111 *selected_iter = *iter;
115 if (gtk_tree_model_iter_children (model,
119 if (find_window_helper (model, window, &child_iter, selected_iter))
122 } while (gtk_tree_model_iter_next (model, iter));
128 find_window (GdkWindow *window,
129 GtkTreeIter *window_iter)
133 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (window_store), &iter))
136 return find_window_helper (GTK_TREE_MODEL (window_store),
143 toggle_selection_window (GdkWindow *window)
145 GtkTreeSelection *selection;
148 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
150 if (window != NULL &&
151 find_window (window, &iter))
153 if (gtk_tree_selection_iter_is_selected (selection, &iter))
154 gtk_tree_selection_unselect_iter (selection, &iter);
156 gtk_tree_selection_select_iter (selection, &iter);
161 unselect_windows (void)
163 GtkTreeSelection *selection;
165 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
167 gtk_tree_selection_unselect_all (selection);
172 select_window (GdkWindow *window)
174 GtkTreeSelection *selection;
177 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
179 if (window != NULL &&
180 find_window (window, &iter))
181 gtk_tree_selection_select_iter (selection, &iter);
185 select_windows (GList *windows)
187 GtkTreeSelection *selection;
191 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
192 gtk_tree_selection_unselect_all (selection);
194 for (l = windows; l != NULL; l = l->next)
196 if (find_window (l->data, &iter))
197 gtk_tree_selection_select_iter (selection, &iter);
202 add_window_clicked (GtkWidget *button,
208 l = get_selected_windows ();
212 parent = gtk_widget_get_window (darea);
216 create_window (parent, 10, 10, 100, 100, NULL);
221 remove_window_clicked (GtkWidget *button,
226 selected = get_selected_windows ();
228 for (l = selected; l != NULL; l = l->next)
229 gdk_window_destroy (l->data);
231 g_list_free (selected);
236 static void save_children (GString *s, GdkWindow *window);
239 save_window (GString *s,
245 gdk_window_get_position (window, &x, &y);
246 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
247 color = g_object_get_data (G_OBJECT (window), "color");
249 g_string_append_printf (s, "%d,%d %dx%d (%d,%d,%d) %d %d\n",
251 color->red, color->green, color->blue,
252 gdk_window_has_native (window),
253 g_list_length (gdk_window_peek_children (window)));
255 save_children (s, window);
260 save_children (GString *s,
266 for (l = g_list_reverse (gdk_window_peek_children (window));
272 save_window (s, child);
278 save_clicked (GtkWidget *button,
285 s = g_string_new ("");
287 save_children (s, gtk_widget_get_window (darea));
289 dialog = gtk_file_chooser_dialog_new ("Filename for window data",
291 GTK_FILE_CHOOSER_ACTION_SAVE,
292 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
293 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
296 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
298 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
300 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
302 g_file_replace_contents (file,
305 0, NULL, NULL, NULL);
307 g_object_unref (file);
310 gtk_widget_destroy (dialog);
311 g_string_free (s, TRUE);
315 destroy_children (GdkWindow *window)
320 for (l = gdk_window_peek_children (window);
326 destroy_children (child);
327 gdk_window_destroy (child);
332 parse_window (GdkWindow *parent, char **lines)
334 int x, y, w, h, r, g, b, native, n_children;
342 if (sscanf(*lines, "%d,%d %dx%d (%d,%d,%d) %d %d",
343 &x, &y, &w, &h, &r, &g, &b, &native, &n_children) == 9)
349 window = create_window (parent, x, y, w, h, &color);
351 gdk_window_ensure_native (window);
353 for (i = 0; i < n_children; i++)
354 lines = parse_window (window, lines);
363 load_file (GFile *file)
369 if (g_file_load_contents (file, NULL, &data, NULL, NULL, NULL))
371 window = gtk_widget_get_window (darea);
373 destroy_children (window);
375 lines = g_strsplit (data, "\n", -1);
379 l = parse_window (window, l);
386 move_window_clicked (GtkWidget *button,
390 GtkDirectionType direction;
394 direction = GPOINTER_TO_INT (data);
396 selected = get_selected_windows ();
398 for (l = selected; l != NULL; l = l->next)
402 gdk_window_get_position (window, &x, &y);
421 gdk_window_move (window, x, y);
424 g_list_free (selected);
428 manual_clicked (GtkWidget *button,
434 GtkWidget *dialog, *table, *label, *xspin, *yspin, *wspin, *hspin;
437 selected = get_selected_windows ();
439 if (selected == NULL)
442 gdk_window_get_position (selected->data, &x, &y);
443 gdk_drawable_get_size (selected->data, &w, &h);
445 dialog = gtk_dialog_new_with_buttons ("Select new position and size",
446 GTK_WINDOW (main_window),
448 GTK_STOCK_OK, GTK_RESPONSE_OK,
452 table = gtk_table_new (2, 4, TRUE);
453 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
459 label = gtk_label_new ("x:");
460 gtk_table_attach_defaults (GTK_TABLE (table),
464 label = gtk_label_new ("y:");
465 gtk_table_attach_defaults (GTK_TABLE (table),
469 label = gtk_label_new ("width:");
470 gtk_table_attach_defaults (GTK_TABLE (table),
474 label = gtk_label_new ("height:");
475 gtk_table_attach_defaults (GTK_TABLE (table),
480 xspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
481 gtk_spin_button_set_value (GTK_SPIN_BUTTON (xspin), x);
482 gtk_table_attach_defaults (GTK_TABLE (table),
486 yspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
487 gtk_spin_button_set_value (GTK_SPIN_BUTTON (yspin), y);
488 gtk_table_attach_defaults (GTK_TABLE (table),
492 wspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
493 gtk_spin_button_set_value (GTK_SPIN_BUTTON (wspin), w);
494 gtk_table_attach_defaults (GTK_TABLE (table),
498 hspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
499 gtk_spin_button_set_value (GTK_SPIN_BUTTON (hspin), h);
500 gtk_table_attach_defaults (GTK_TABLE (table),
505 gtk_widget_show_all (dialog);
507 gtk_dialog_run (GTK_DIALOG (dialog));
509 x = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (xspin));
510 y = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (yspin));
511 w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (wspin));
512 h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (hspin));
514 gtk_widget_destroy (dialog);
516 for (l = selected; l != NULL; l = l->next)
520 gdk_window_move_resize (window, x, y, w, h);
523 g_list_free (selected);
527 restack_clicked (GtkWidget *button,
532 selected = get_selected_windows ();
534 if (g_list_length (selected) != 2)
536 g_warning ("select two windows");
539 gdk_window_restack (selected->data,
540 selected->next->data,
541 GPOINTER_TO_INT (data));
543 g_list_free (selected);
549 scroll_window_clicked (GtkWidget *button,
553 GtkDirectionType direction;
557 direction = GPOINTER_TO_INT (data);
559 selected = get_selected_windows ();
579 for (l = selected; l != NULL; l = l->next)
583 gdk_window_scroll (window, dx, dy);
586 g_list_free (selected);
591 raise_window_clicked (GtkWidget *button,
597 selected = get_selected_windows ();
599 for (l = selected; l != NULL; l = l->next)
603 gdk_window_raise (window);
606 g_list_free (selected);
612 lower_window_clicked (GtkWidget *button,
618 selected = get_selected_windows ();
620 for (l = selected; l != NULL; l = l->next)
624 gdk_window_lower (window);
627 g_list_free (selected);
634 smaller_window_clicked (GtkWidget *button,
641 selected = get_selected_windows ();
643 for (l = selected; l != NULL; l = l->next)
647 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
656 gdk_window_resize (window, w, h);
659 g_list_free (selected);
663 larger_window_clicked (GtkWidget *button,
670 selected = get_selected_windows ();
672 for (l = selected; l != NULL; l = l->next)
676 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
681 gdk_window_resize (window, w, h);
684 g_list_free (selected);
688 native_window_clicked (GtkWidget *button,
694 selected = get_selected_windows ();
696 for (l = selected; l != NULL; l = l->next)
700 gdk_window_ensure_native (window);
703 g_list_free (selected);
709 darea_button_release_event (GtkWidget *widget,
710 GdkEventButton *event)
712 if ((event->state & GDK_CONTROL_MASK) != 0)
714 toggle_selection_window (event->window);
719 select_window (event->window);
726 render_window_cell (GtkTreeViewColumn *tree_column,
727 GtkCellRenderer *cell,
728 GtkTreeModel *tree_model,
735 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
740 if (gdk_window_has_native (window))
741 name = g_strdup_printf ("%p (native)", window);
743 name = g_strdup_printf ("%p", window);
751 add_children (GtkTreeStore *store,
753 GtkTreeIter *window_iter)
756 GtkTreeIter child_iter;
758 for (l = gdk_window_peek_children (window);
762 gtk_tree_store_append (store, &child_iter, window_iter);
763 gtk_tree_store_set (store, &child_iter,
767 add_children (store, l->data, &child_iter);
776 selected = get_selected_windows ();
778 gtk_tree_store_clear (window_store);
780 add_children (window_store, gtk_widget_get_window (darea), NULL);
781 gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
783 select_windows (selected);
784 g_list_free (selected);
789 main (int argc, char **argv)
791 GtkWidget *window, *vbox, *hbox, *frame;
792 GtkWidget *button, *scrolled, *table;
793 GtkTreeViewColumn *column;
794 GtkCellRenderer *renderer;
795 GdkColor black = {0};
798 gtk_init (&argc, &argv);
800 main_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
801 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
803 g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
805 hbox = gtk_hbox_new (FALSE, 5);
806 gtk_container_add (GTK_CONTAINER (window), hbox);
807 gtk_widget_show (hbox);
809 frame = gtk_frame_new ("GdkWindows");
810 gtk_box_pack_start (GTK_BOX (hbox),
814 gtk_widget_show (frame);
816 darea = gtk_drawing_area_new ();
817 /*gtk_widget_set_double_buffered (darea, FALSE);*/
818 gtk_widget_add_events (darea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
819 gtk_widget_set_size_request (darea, 500, 500);
820 g_signal_connect (darea, "button_release_event",
821 G_CALLBACK (darea_button_release_event),
825 gtk_container_add (GTK_CONTAINER (frame), darea);
826 gtk_widget_realize (darea);
827 gtk_widget_show (darea);
828 gtk_widget_modify_bg (darea, GTK_STATE_NORMAL,
832 vbox = gtk_vbox_new (FALSE, 5);
833 gtk_box_pack_start (GTK_BOX (hbox),
837 gtk_widget_show (vbox);
839 window_store = gtk_tree_store_new (1, GDK_TYPE_WINDOW);
841 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window_store));
842 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
843 GTK_SELECTION_MULTIPLE);
844 column = gtk_tree_view_column_new ();
845 gtk_tree_view_column_set_title (column, "Window");
846 renderer = gtk_cell_renderer_text_new ();
847 gtk_tree_view_column_pack_start (column, renderer, TRUE);
848 gtk_tree_view_column_set_cell_data_func (column,
853 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
856 scrolled = gtk_scrolled_window_new (NULL, NULL);
857 gtk_widget_set_size_request (scrolled, 200, 400);
858 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
859 gtk_box_pack_start (GTK_BOX (vbox),
863 gtk_widget_show (scrolled);
864 gtk_widget_show (treeview);
866 table = gtk_table_new (5, 4, TRUE);
867 gtk_box_pack_start (GTK_BOX (vbox),
871 gtk_widget_show (table);
873 button = gtk_button_new ();
874 gtk_button_set_image (GTK_BUTTON (button),
875 gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
876 GTK_ICON_SIZE_BUTTON));
877 g_signal_connect (button, "clicked",
878 G_CALLBACK (move_window_clicked),
879 GINT_TO_POINTER (GTK_DIR_LEFT));
880 gtk_table_attach_defaults (GTK_TABLE (table),
884 gtk_widget_show (button);
886 button = gtk_button_new ();
887 gtk_button_set_image (GTK_BUTTON (button),
888 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
889 GTK_ICON_SIZE_BUTTON));
890 g_signal_connect (button, "clicked",
891 G_CALLBACK (move_window_clicked),
892 GINT_TO_POINTER (GTK_DIR_UP));
893 gtk_table_attach_defaults (GTK_TABLE (table),
897 gtk_widget_show (button);
899 button = gtk_button_new ();
900 gtk_button_set_image (GTK_BUTTON (button),
901 gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
902 GTK_ICON_SIZE_BUTTON));
903 g_signal_connect (button, "clicked",
904 G_CALLBACK (move_window_clicked),
905 GINT_TO_POINTER (GTK_DIR_RIGHT));
906 gtk_table_attach_defaults (GTK_TABLE (table),
910 gtk_widget_show (button);
912 button = gtk_button_new ();
913 gtk_button_set_image (GTK_BUTTON (button),
914 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
915 GTK_ICON_SIZE_BUTTON));
916 g_signal_connect (button, "clicked",
917 G_CALLBACK (move_window_clicked),
918 GINT_TO_POINTER (GTK_DIR_DOWN));
919 gtk_table_attach_defaults (GTK_TABLE (table),
923 gtk_widget_show (button);
926 button = gtk_button_new_with_label ("Raise");
927 g_signal_connect (button, "clicked",
928 G_CALLBACK (raise_window_clicked),
930 gtk_table_attach_defaults (GTK_TABLE (table),
934 gtk_widget_show (button);
936 button = gtk_button_new_with_label ("Lower");
937 g_signal_connect (button, "clicked",
938 G_CALLBACK (lower_window_clicked),
940 gtk_table_attach_defaults (GTK_TABLE (table),
944 gtk_widget_show (button);
947 button = gtk_button_new_with_label ("Smaller");
948 g_signal_connect (button, "clicked",
949 G_CALLBACK (smaller_window_clicked),
951 gtk_table_attach_defaults (GTK_TABLE (table),
955 gtk_widget_show (button);
957 button = gtk_button_new_with_label ("Larger");
958 g_signal_connect (button, "clicked",
959 G_CALLBACK (larger_window_clicked),
961 gtk_table_attach_defaults (GTK_TABLE (table),
965 gtk_widget_show (button);
967 button = gtk_button_new_with_label ("Native");
968 g_signal_connect (button, "clicked",
969 G_CALLBACK (native_window_clicked),
971 gtk_table_attach_defaults (GTK_TABLE (table),
975 gtk_widget_show (button);
978 button = gtk_button_new_with_label ("scroll");
979 gtk_button_set_image (GTK_BUTTON (button),
980 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
981 GTK_ICON_SIZE_BUTTON));
982 g_signal_connect (button, "clicked",
983 G_CALLBACK (scroll_window_clicked),
984 GINT_TO_POINTER (GTK_DIR_UP));
985 gtk_table_attach_defaults (GTK_TABLE (table),
989 gtk_widget_show (button);
991 button = gtk_button_new_with_label ("scroll");
992 gtk_button_set_image (GTK_BUTTON (button),
993 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
994 GTK_ICON_SIZE_BUTTON));
995 g_signal_connect (button, "clicked",
996 G_CALLBACK (scroll_window_clicked),
997 GINT_TO_POINTER (GTK_DIR_DOWN));
998 gtk_table_attach_defaults (GTK_TABLE (table),
1002 gtk_widget_show (button);
1004 button = gtk_button_new_with_label ("Manual");
1005 g_signal_connect (button, "clicked",
1006 G_CALLBACK (manual_clicked),
1008 gtk_table_attach_defaults (GTK_TABLE (table),
1012 gtk_widget_show (button);
1014 button = gtk_button_new_with_label ("Restack above");
1015 g_signal_connect (button, "clicked",
1016 G_CALLBACK (restack_clicked),
1017 GINT_TO_POINTER (1));
1018 gtk_table_attach_defaults (GTK_TABLE (table),
1022 gtk_widget_show (button);
1024 button = gtk_button_new_with_label ("Restack below");
1025 g_signal_connect (button, "clicked",
1026 G_CALLBACK (restack_clicked),
1028 gtk_table_attach_defaults (GTK_TABLE (table),
1032 gtk_widget_show (button);
1034 button = gtk_button_new_with_label ("Add window");
1035 gtk_box_pack_start (GTK_BOX (vbox),
1039 gtk_widget_show (button);
1040 g_signal_connect (button, "clicked",
1041 G_CALLBACK (add_window_clicked),
1044 button = gtk_button_new_with_label ("Remove window");
1045 gtk_box_pack_start (GTK_BOX (vbox),
1049 gtk_widget_show (button);
1050 g_signal_connect (button, "clicked",
1051 G_CALLBACK (remove_window_clicked),
1054 button = gtk_button_new_with_label ("Save");
1055 gtk_box_pack_start (GTK_BOX (vbox),
1059 gtk_widget_show (button);
1060 g_signal_connect (button, "clicked",
1061 G_CALLBACK (save_clicked),
1064 gtk_widget_show (window);
1068 file = g_file_new_for_commandline_arg (argv[1]);
1070 g_object_unref (file);