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 gdk_rgb_find_color (gtk_widget_get_colormap (darea), bg);
55 gdk_window_set_background (window, bg);
56 g_object_set_data_full (G_OBJECT (window), "color", bg, g_free);
58 gdk_window_show (window);
64 add_window_cb (GtkTreeModel *model,
69 GList **selected = data;
72 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
77 *selected = g_list_prepend (*selected, window);
81 get_selected_windows (void)
83 GtkTreeSelection *sel;
86 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
89 gtk_tree_selection_selected_foreach (sel, add_window_cb, &selected);
95 find_window_helper (GtkTreeModel *model,
98 GtkTreeIter *selected_iter)
100 GtkTreeIter child_iter;
105 gtk_tree_model_get (model, iter,
110 *selected_iter = *iter;
114 if (gtk_tree_model_iter_children (model,
118 if (find_window_helper (model, window, &child_iter, selected_iter))
121 } while (gtk_tree_model_iter_next (model, iter));
127 find_window (GdkWindow *window,
128 GtkTreeIter *window_iter)
132 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (window_store), &iter))
135 return find_window_helper (GTK_TREE_MODEL (window_store),
142 toggle_selection_window (GdkWindow *window)
144 GtkTreeSelection *selection;
147 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
149 if (window != NULL &&
150 find_window (window, &iter))
152 if (gtk_tree_selection_iter_is_selected (selection, &iter))
153 gtk_tree_selection_unselect_iter (selection, &iter);
155 gtk_tree_selection_select_iter (selection, &iter);
160 unselect_windows (void)
162 GtkTreeSelection *selection;
164 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
166 gtk_tree_selection_unselect_all (selection);
171 select_window (GdkWindow *window)
173 GtkTreeSelection *selection;
176 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
178 if (window != NULL &&
179 find_window (window, &iter))
180 gtk_tree_selection_select_iter (selection, &iter);
184 select_windows (GList *windows)
186 GtkTreeSelection *selection;
190 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
191 gtk_tree_selection_unselect_all (selection);
193 for (l = windows; l != NULL; l = l->next)
195 if (find_window (l->data, &iter))
196 gtk_tree_selection_select_iter (selection, &iter);
201 add_window_clicked (GtkWidget *button,
207 l = get_selected_windows ();
211 parent = darea->window;
215 create_window (parent, 10, 10, 100, 100, NULL);
220 draw_drawable_clicked (GtkWidget *button,
224 gc = gdk_gc_new (darea->window);
225 gdk_draw_drawable (darea->window,
236 remove_window_clicked (GtkWidget *button,
241 selected = get_selected_windows ();
243 for (l = selected; l != NULL; l = l->next)
244 gdk_window_destroy (l->data);
246 g_list_free (selected);
251 static void save_children (GString *s, GdkWindow *window);
254 save_window (GString *s,
260 gdk_window_get_position (window, &x, &y);
261 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
262 color = g_object_get_data (G_OBJECT (window), "color");
264 g_string_append_printf (s, "%d,%d %dx%d (%d,%d,%d) %d %d\n",
266 color->red, color->green, color->blue,
267 gdk_window_has_native (window),
268 g_list_length (gdk_window_peek_children (window)));
270 save_children (s, window);
275 save_children (GString *s,
281 for (l = g_list_reverse (gdk_window_peek_children (window));
287 save_window (s, child);
293 save_clicked (GtkWidget *button,
300 s = g_string_new ("");
302 save_children (s, darea->window);
304 dialog = gtk_file_chooser_dialog_new ("Filename for window data",
306 GTK_FILE_CHOOSER_ACTION_SAVE,
307 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
308 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
311 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
313 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
315 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
317 g_file_replace_contents (file,
320 0, NULL, NULL, NULL);
322 g_object_unref (file);
325 gtk_widget_destroy (dialog);
326 g_string_free (s, TRUE);
330 destroy_children (GdkWindow *window)
335 for (l = gdk_window_peek_children (window);
341 destroy_children (child);
342 gdk_window_destroy (child);
347 parse_window (GdkWindow *parent, char **lines)
349 int x, y, w, h, r, g, b, native, n_children;
357 if (sscanf(*lines, "%d,%d %dx%d (%d,%d,%d) %d %d",
358 &x, &y, &w, &h, &r, &g, &b, &native, &n_children) == 9)
364 window = create_window (parent, x, y, w, h, &color);
366 gdk_window_ensure_native (window);
368 for (i = 0; i < n_children; i++)
369 lines = parse_window (window, lines);
378 load_file (GFile *file)
383 if (g_file_load_contents (file, NULL, &data, NULL, NULL, NULL))
385 destroy_children (darea->window);
387 lines = g_strsplit (data, "\n", -1);
391 l = parse_window (darea->window, l);
398 move_window_clicked (GtkWidget *button,
402 GtkDirectionType direction;
406 direction = GPOINTER_TO_INT (data);
408 selected = get_selected_windows ();
410 for (l = selected; l != NULL; l = l->next)
414 gdk_window_get_position (window, &x, &y);
433 gdk_window_move (window, x, y);
436 g_list_free (selected);
440 manual_clicked (GtkWidget *button,
446 GtkWidget *dialog, *table, *label, *xspin, *yspin, *wspin, *hspin;
449 selected = get_selected_windows ();
451 if (selected == NULL)
454 gdk_window_get_position (selected->data, &x, &y);
455 gdk_drawable_get_size (selected->data, &w, &h);
457 dialog = gtk_dialog_new_with_buttons ("Select new position and size",
458 GTK_WINDOW (main_window),
460 GTK_STOCK_OK, GTK_RESPONSE_OK,
464 table = gtk_table_new (2, 4, TRUE);
465 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
471 label = gtk_label_new ("x:");
472 gtk_table_attach_defaults (GTK_TABLE (table),
476 label = gtk_label_new ("y:");
477 gtk_table_attach_defaults (GTK_TABLE (table),
481 label = gtk_label_new ("width:");
482 gtk_table_attach_defaults (GTK_TABLE (table),
486 label = gtk_label_new ("height:");
487 gtk_table_attach_defaults (GTK_TABLE (table),
492 xspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
493 gtk_spin_button_set_value (GTK_SPIN_BUTTON (xspin), x);
494 gtk_table_attach_defaults (GTK_TABLE (table),
498 yspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
499 gtk_spin_button_set_value (GTK_SPIN_BUTTON (yspin), y);
500 gtk_table_attach_defaults (GTK_TABLE (table),
504 wspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
505 gtk_spin_button_set_value (GTK_SPIN_BUTTON (wspin), w);
506 gtk_table_attach_defaults (GTK_TABLE (table),
510 hspin = gtk_spin_button_new_with_range (G_MININT, G_MAXINT, 1);
511 gtk_spin_button_set_value (GTK_SPIN_BUTTON (hspin), h);
512 gtk_table_attach_defaults (GTK_TABLE (table),
517 gtk_widget_show_all (dialog);
519 gtk_dialog_run (GTK_DIALOG (dialog));
521 x = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (xspin));
522 y = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (yspin));
523 w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (wspin));
524 h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (hspin));
526 gtk_widget_destroy (dialog);
528 for (l = selected; l != NULL; l = l->next)
532 gdk_window_move_resize (window, x, y, w, h);
535 g_list_free (selected);
539 restack_clicked (GtkWidget *button,
544 selected = get_selected_windows ();
546 if (g_list_length (selected) != 2)
548 g_warning ("select two windows");
551 gdk_window_restack (selected->data,
552 selected->next->data,
553 GPOINTER_TO_INT (data));
555 g_list_free (selected);
561 scroll_window_clicked (GtkWidget *button,
565 GtkDirectionType direction;
569 direction = GPOINTER_TO_INT (data);
571 selected = get_selected_windows ();
591 for (l = selected; l != NULL; l = l->next)
595 gdk_window_scroll (window, dx, dy);
598 g_list_free (selected);
603 raise_window_clicked (GtkWidget *button,
609 selected = get_selected_windows ();
611 for (l = selected; l != NULL; l = l->next)
615 gdk_window_raise (window);
618 g_list_free (selected);
624 lower_window_clicked (GtkWidget *button,
630 selected = get_selected_windows ();
632 for (l = selected; l != NULL; l = l->next)
636 gdk_window_lower (window);
639 g_list_free (selected);
646 smaller_window_clicked (GtkWidget *button,
653 selected = get_selected_windows ();
655 for (l = selected; l != NULL; l = l->next)
659 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
668 gdk_window_resize (window, w, h);
671 g_list_free (selected);
675 larger_window_clicked (GtkWidget *button,
682 selected = get_selected_windows ();
684 for (l = selected; l != NULL; l = l->next)
688 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
693 gdk_window_resize (window, w, h);
696 g_list_free (selected);
700 native_window_clicked (GtkWidget *button,
706 selected = get_selected_windows ();
708 for (l = selected; l != NULL; l = l->next)
712 gdk_window_ensure_native (window);
715 g_list_free (selected);
721 darea_button_release_event (GtkWidget *widget,
722 GdkEventButton *event)
724 if ((event->state & GDK_CONTROL_MASK) != 0)
726 toggle_selection_window (event->window);
731 select_window (event->window);
738 render_window_cell (GtkTreeViewColumn *tree_column,
739 GtkCellRenderer *cell,
740 GtkTreeModel *tree_model,
744 GdkColor *color = NULL;
748 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
753 if (gdk_window_has_native (window))
754 name = g_strdup_printf ("%p (native)", window);
756 name = g_strdup_printf ("%p", window);
758 gdk_window_get_background (window, color);
761 "background-gdk", color,
766 add_children (GtkTreeStore *store,
768 GtkTreeIter *window_iter)
771 GtkTreeIter child_iter;
773 for (l = gdk_window_peek_children (window);
777 gtk_tree_store_append (store, &child_iter, window_iter);
778 gtk_tree_store_set (store, &child_iter,
782 add_children (store, l->data, &child_iter);
791 selected = get_selected_windows ();
793 gtk_tree_store_clear (window_store);
795 add_children (window_store, darea->window, NULL);
796 gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
798 select_windows (selected);
799 g_list_free (selected);
804 main (int argc, char **argv)
806 GtkWidget *window, *vbox, *hbox, *frame;
807 GtkWidget *button, *scrolled, *table;
808 GtkTreeViewColumn *column;
809 GtkCellRenderer *renderer;
810 GdkColor black = {0};
813 gtk_init (&argc, &argv);
815 main_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
816 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
818 g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
820 hbox = gtk_hbox_new (FALSE, 5);
821 gtk_container_add (GTK_CONTAINER (window), hbox);
822 gtk_widget_show (hbox);
824 frame = gtk_frame_new ("GdkWindows");
825 gtk_box_pack_start (GTK_BOX (hbox),
829 gtk_widget_show (frame);
831 darea = gtk_drawing_area_new ();
832 /*gtk_widget_set_double_buffered (darea, FALSE);*/
833 gtk_widget_add_events (darea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
834 gtk_widget_set_size_request (darea, 500, 500);
835 g_signal_connect (darea, "button_release_event",
836 G_CALLBACK (darea_button_release_event),
840 gtk_container_add (GTK_CONTAINER (frame), darea);
841 gtk_widget_realize (darea);
842 gtk_widget_show (darea);
843 gtk_widget_modify_bg (darea, GTK_STATE_NORMAL,
847 vbox = gtk_vbox_new (FALSE, 5);
848 gtk_box_pack_start (GTK_BOX (hbox),
852 gtk_widget_show (vbox);
854 window_store = gtk_tree_store_new (1, GDK_TYPE_WINDOW);
856 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window_store));
857 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
858 GTK_SELECTION_MULTIPLE);
859 column = gtk_tree_view_column_new ();
860 gtk_tree_view_column_set_title (column, "Window");
861 renderer = gtk_cell_renderer_text_new ();
862 gtk_tree_view_column_pack_start (column, renderer, TRUE);
863 gtk_tree_view_column_set_cell_data_func (column,
868 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
871 scrolled = gtk_scrolled_window_new (NULL, NULL);
872 gtk_widget_set_size_request (scrolled, 200, 400);
873 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
874 gtk_box_pack_start (GTK_BOX (vbox),
878 gtk_widget_show (scrolled);
879 gtk_widget_show (treeview);
881 table = gtk_table_new (5, 4, TRUE);
882 gtk_box_pack_start (GTK_BOX (vbox),
886 gtk_widget_show (table);
888 button = gtk_button_new ();
889 gtk_button_set_image (GTK_BUTTON (button),
890 gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
891 GTK_ICON_SIZE_BUTTON));
892 g_signal_connect (button, "clicked",
893 G_CALLBACK (move_window_clicked),
894 GINT_TO_POINTER (GTK_DIR_LEFT));
895 gtk_table_attach_defaults (GTK_TABLE (table),
899 gtk_widget_show (button);
901 button = gtk_button_new ();
902 gtk_button_set_image (GTK_BUTTON (button),
903 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
904 GTK_ICON_SIZE_BUTTON));
905 g_signal_connect (button, "clicked",
906 G_CALLBACK (move_window_clicked),
907 GINT_TO_POINTER (GTK_DIR_UP));
908 gtk_table_attach_defaults (GTK_TABLE (table),
912 gtk_widget_show (button);
914 button = gtk_button_new ();
915 gtk_button_set_image (GTK_BUTTON (button),
916 gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
917 GTK_ICON_SIZE_BUTTON));
918 g_signal_connect (button, "clicked",
919 G_CALLBACK (move_window_clicked),
920 GINT_TO_POINTER (GTK_DIR_RIGHT));
921 gtk_table_attach_defaults (GTK_TABLE (table),
925 gtk_widget_show (button);
927 button = gtk_button_new ();
928 gtk_button_set_image (GTK_BUTTON (button),
929 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
930 GTK_ICON_SIZE_BUTTON));
931 g_signal_connect (button, "clicked",
932 G_CALLBACK (move_window_clicked),
933 GINT_TO_POINTER (GTK_DIR_DOWN));
934 gtk_table_attach_defaults (GTK_TABLE (table),
938 gtk_widget_show (button);
941 button = gtk_button_new_with_label ("Raise");
942 g_signal_connect (button, "clicked",
943 G_CALLBACK (raise_window_clicked),
945 gtk_table_attach_defaults (GTK_TABLE (table),
949 gtk_widget_show (button);
951 button = gtk_button_new_with_label ("Lower");
952 g_signal_connect (button, "clicked",
953 G_CALLBACK (lower_window_clicked),
955 gtk_table_attach_defaults (GTK_TABLE (table),
959 gtk_widget_show (button);
962 button = gtk_button_new_with_label ("Smaller");
963 g_signal_connect (button, "clicked",
964 G_CALLBACK (smaller_window_clicked),
966 gtk_table_attach_defaults (GTK_TABLE (table),
970 gtk_widget_show (button);
972 button = gtk_button_new_with_label ("Larger");
973 g_signal_connect (button, "clicked",
974 G_CALLBACK (larger_window_clicked),
976 gtk_table_attach_defaults (GTK_TABLE (table),
980 gtk_widget_show (button);
982 button = gtk_button_new_with_label ("Native");
983 g_signal_connect (button, "clicked",
984 G_CALLBACK (native_window_clicked),
986 gtk_table_attach_defaults (GTK_TABLE (table),
990 gtk_widget_show (button);
993 button = gtk_button_new_with_label ("scroll");
994 gtk_button_set_image (GTK_BUTTON (button),
995 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
996 GTK_ICON_SIZE_BUTTON));
997 g_signal_connect (button, "clicked",
998 G_CALLBACK (scroll_window_clicked),
999 GINT_TO_POINTER (GTK_DIR_UP));
1000 gtk_table_attach_defaults (GTK_TABLE (table),
1004 gtk_widget_show (button);
1006 button = gtk_button_new_with_label ("scroll");
1007 gtk_button_set_image (GTK_BUTTON (button),
1008 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
1009 GTK_ICON_SIZE_BUTTON));
1010 g_signal_connect (button, "clicked",
1011 G_CALLBACK (scroll_window_clicked),
1012 GINT_TO_POINTER (GTK_DIR_DOWN));
1013 gtk_table_attach_defaults (GTK_TABLE (table),
1017 gtk_widget_show (button);
1019 button = gtk_button_new_with_label ("Manual");
1020 g_signal_connect (button, "clicked",
1021 G_CALLBACK (manual_clicked),
1023 gtk_table_attach_defaults (GTK_TABLE (table),
1027 gtk_widget_show (button);
1029 button = gtk_button_new_with_label ("Restack above");
1030 g_signal_connect (button, "clicked",
1031 G_CALLBACK (restack_clicked),
1032 GINT_TO_POINTER (1));
1033 gtk_table_attach_defaults (GTK_TABLE (table),
1037 gtk_widget_show (button);
1039 button = gtk_button_new_with_label ("Restack below");
1040 g_signal_connect (button, "clicked",
1041 G_CALLBACK (restack_clicked),
1043 gtk_table_attach_defaults (GTK_TABLE (table),
1047 gtk_widget_show (button);
1049 button = gtk_button_new_with_label ("draw drawable");
1050 gtk_box_pack_start (GTK_BOX (vbox),
1054 gtk_widget_show (button);
1055 g_signal_connect (button, "clicked",
1056 G_CALLBACK (draw_drawable_clicked),
1059 button = gtk_button_new_with_label ("Add window");
1060 gtk_box_pack_start (GTK_BOX (vbox),
1064 gtk_widget_show (button);
1065 g_signal_connect (button, "clicked",
1066 G_CALLBACK (add_window_clicked),
1069 button = gtk_button_new_with_label ("Remove window");
1070 gtk_box_pack_start (GTK_BOX (vbox),
1074 gtk_widget_show (button);
1075 g_signal_connect (button, "clicked",
1076 G_CALLBACK (remove_window_clicked),
1079 button = gtk_button_new_with_label ("Save");
1080 gtk_box_pack_start (GTK_BOX (vbox),
1084 gtk_widget_show (button);
1085 g_signal_connect (button, "clicked",
1086 G_CALLBACK (save_clicked),
1089 gtk_widget_show (window);
1093 file = g_file_new_for_commandline_arg (argv[1]);
1095 g_object_unref (file);