4 static GtkWidget *darea;
5 static GtkTreeStore *window_store = NULL;
6 static GtkWidget *treeview;
8 static void update_store (void);
11 window_has_impl (GdkWindow *window)
14 w = (GdkWindowObject *)window;
15 return w->parent == NULL || w->parent->impl != w->impl;
19 create_window (GdkWindow *parent,
20 int x, int y, int w, int h,
23 GdkWindowAttr attributes;
31 attributes.height = h;
32 attributes.window_type = GDK_WINDOW_CHILD;
33 attributes.event_mask = GDK_STRUCTURE_MASK
34 | GDK_BUTTON_MOTION_MASK
35 | GDK_BUTTON_PRESS_MASK
36 | GDK_BUTTON_RELEASE_MASK
38 | GDK_ENTER_NOTIFY_MASK
39 | GDK_LEAVE_NOTIFY_MASK;
40 attributes.wclass = GDK_INPUT_OUTPUT;
42 attributes_mask = GDK_WA_X | GDK_WA_Y;
44 window = gdk_window_new (parent, &attributes, attributes_mask);
45 gdk_window_set_user_data (window, darea);
47 bg = g_new (GdkColor, 1);
52 bg->red = g_random_int_range (0, 0xffff);
53 bg->blue = g_random_int_range (0, 0xffff);
54 bg->green = g_random_int_range (0, 0xffff);;
57 gdk_rgb_find_color (gtk_widget_get_colormap (darea), bg);
58 gdk_window_set_background (window, bg);
59 g_object_set_data_full (G_OBJECT (window), "color", bg, g_free);
61 gdk_window_show (window);
67 add_window_cb (GtkTreeModel *model,
72 GList **selected = data;
75 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
80 *selected = g_list_prepend (*selected, window);
84 get_selected_windows (void)
86 GtkTreeSelection *sel;
89 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
92 gtk_tree_selection_selected_foreach (sel, add_window_cb, &selected);
98 find_window_helper (GtkTreeModel *model,
101 GtkTreeIter *selected_iter)
103 GtkTreeIter child_iter;
108 gtk_tree_model_get (model, iter,
113 *selected_iter = *iter;
117 if (gtk_tree_model_iter_children (model,
121 if (find_window_helper (model, window, &child_iter, selected_iter))
124 } while (gtk_tree_model_iter_next (model, iter));
130 find_window (GdkWindow *window,
131 GtkTreeIter *window_iter)
135 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (window_store), &iter))
138 return find_window_helper (GTK_TREE_MODEL (window_store),
145 toggle_selection_window (GdkWindow *window)
147 GtkTreeSelection *selection;
150 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
152 if (window != NULL &&
153 find_window (window, &iter))
155 if (gtk_tree_selection_iter_is_selected (selection, &iter))
156 gtk_tree_selection_unselect_iter (selection, &iter);
158 gtk_tree_selection_select_iter (selection, &iter);
163 unselect_windows (void)
165 GtkTreeSelection *selection;
167 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
169 gtk_tree_selection_unselect_all (selection);
174 select_window (GdkWindow *window)
176 GtkTreeSelection *selection;
179 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
181 if (window != NULL &&
182 find_window (window, &iter))
183 gtk_tree_selection_select_iter (selection, &iter);
187 select_windows (GList *windows)
189 GtkTreeSelection *selection;
193 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
194 gtk_tree_selection_unselect_all (selection);
196 for (l = windows; l != NULL; l = l->next)
198 if (find_window (l->data, &iter))
199 gtk_tree_selection_select_iter (selection, &iter);
204 add_window_clicked (GtkWidget *button,
210 l = get_selected_windows ();
214 parent = darea->window;
218 create_window (parent, 10, 10, 100, 100, NULL);
223 remove_window_clicked (GtkWidget *button,
228 selected = get_selected_windows ();
230 for (l = selected; l != NULL; l = l->next)
231 gdk_window_destroy (l->data);
233 g_list_free (selected);
238 static void save_children (GString *s, GdkWindow *window);
241 save_window (GString *s,
247 gdk_window_get_position (window, &x, &y);
248 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
249 color = g_object_get_data (G_OBJECT (window), "color");
251 g_string_append_printf (s, "%d,%d %dx%d (%d,%d,%d) %d %d\n",
253 color->red, color->green, color->blue,
254 window_has_impl (window),
255 g_list_length (gdk_window_peek_children (window)));
257 save_children (s, window);
262 save_children (GString *s,
268 for (l = g_list_reverse (gdk_window_peek_children (window));
274 save_window (s, child);
280 save_clicked (GtkWidget *button,
287 s = g_string_new ("");
289 save_children (s, darea->window);
291 dialog = gtk_file_chooser_dialog_new ("Filename for window data",
293 GTK_FILE_CHOOSER_ACTION_SAVE,
294 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
295 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
298 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
300 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
302 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
304 g_file_replace_contents (file,
307 0, NULL, NULL, NULL);
309 g_object_unref (file);
312 gtk_widget_destroy (dialog);
313 g_string_free (s, TRUE);
317 destroy_children (GdkWindow *window)
322 for (l = gdk_window_peek_children (window);
328 destroy_children (child);
329 gdk_window_destroy (child);
334 parse_window (GdkWindow *parent, char **lines)
336 int x, y, w, h, r, g, b, native, n_children;
344 if (sscanf(*lines, "%d,%d %dx%d (%d,%d,%d) %d %d",
345 &x, &y, &w, &h, &r, &g, &b, &native, &n_children) == 9)
351 window = create_window (parent, x, y, w, h, &color);
353 gdk_window_set_has_native (window, TRUE);
355 for (i = 0; i < n_children; i++)
356 lines = parse_window (window, lines);
365 load_file (GFile *file)
370 if (g_file_load_contents (file, NULL, &data, NULL, NULL, NULL))
372 destroy_children (darea->window);
374 lines = g_strsplit (data, "\n", -1);
378 l = parse_window (darea->window, l);
385 move_window_clicked (GtkWidget *button,
389 GtkDirectionType direction;
393 direction = GPOINTER_TO_INT (data);
395 selected = get_selected_windows ();
397 for (l = selected; l != NULL; l = l->next)
401 gdk_window_get_position (window, &x, &y);
420 gdk_window_move (window, x, y);
423 g_list_free (selected);
427 raise_window_clicked (GtkWidget *button,
433 selected = get_selected_windows ();
435 for (l = selected; l != NULL; l = l->next)
439 gdk_window_raise (window);
442 g_list_free (selected);
448 lower_window_clicked (GtkWidget *button,
454 selected = get_selected_windows ();
456 for (l = selected; l != NULL; l = l->next)
460 gdk_window_lower (window);
463 g_list_free (selected);
470 smaller_window_clicked (GtkWidget *button,
477 selected = get_selected_windows ();
479 for (l = selected; l != NULL; l = l->next)
483 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
492 gdk_window_resize (window, w, h);
495 g_list_free (selected);
499 larger_window_clicked (GtkWidget *button,
506 selected = get_selected_windows ();
508 for (l = selected; l != NULL; l = l->next)
512 gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h);
517 gdk_window_resize (window, w, h);
520 g_list_free (selected);
524 native_window_clicked (GtkWidget *button,
530 selected = get_selected_windows ();
532 for (l = selected; l != NULL; l = l->next)
536 gdk_window_set_has_native (window, TRUE);
539 g_list_free (selected);
545 darea_button_release_event (GtkWidget *widget,
546 GdkEventButton *event)
548 if ((event->state & GDK_CONTROL_MASK) != 0)
550 toggle_selection_window (event->window);
555 select_window (event->window);
562 render_window_cell (GtkTreeViewColumn *tree_column,
563 GtkCellRenderer *cell,
564 GtkTreeModel *tree_model,
571 gtk_tree_model_get (GTK_TREE_MODEL (window_store),
576 if (window_has_impl (window))
577 name = g_strdup_printf ("%p (native)", window);
579 name = g_strdup_printf ("%p", window);
582 "background-gdk", &((GdkWindowObject *)window)->bg_color,
587 add_children (GtkTreeStore *store,
589 GtkTreeIter *window_iter)
592 GtkTreeIter child_iter;
594 for (l = gdk_window_peek_children (window);
598 gtk_tree_store_append (store, &child_iter, window_iter);
599 gtk_tree_store_set (store, &child_iter,
603 add_children (store, l->data, &child_iter);
612 selected = get_selected_windows ();
614 gtk_tree_store_clear (window_store);
616 add_children (window_store, darea->window, NULL);
617 gtk_tree_view_expand_all (GTK_TREE_VIEW (treeview));
619 select_windows (selected);
620 g_list_free (selected);
625 main (int argc, char **argv)
627 GtkWidget *window, *vbox, *hbox, *frame;
628 GtkWidget *button, *scrolled, *table;
629 GtkTreeViewColumn *column;
630 GtkCellRenderer *renderer;
631 GdkColor black = {0};
634 gtk_init (&argc, &argv);
636 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
637 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
639 g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit, NULL);
641 hbox = gtk_hbox_new (FALSE, 5);
642 gtk_container_add (GTK_CONTAINER (window), hbox);
643 gtk_widget_show (hbox);
645 frame = gtk_frame_new ("GdkWindows");
646 gtk_box_pack_start (GTK_BOX (hbox),
650 gtk_widget_show (frame);
652 darea = gtk_drawing_area_new ();
653 /*gtk_widget_set_double_buffered (darea, FALSE);*/
654 gtk_widget_add_events (darea, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
655 gtk_widget_set_size_request (darea, 500, 500);
656 g_signal_connect (darea, "button_release_event",
657 G_CALLBACK (darea_button_release_event),
661 gtk_container_add (GTK_CONTAINER (frame), darea);
662 gtk_widget_realize (darea);
663 gtk_widget_show (darea);
664 gtk_widget_modify_bg (darea, GTK_STATE_NORMAL,
668 vbox = gtk_vbox_new (FALSE, 5);
669 gtk_box_pack_start (GTK_BOX (hbox),
673 gtk_widget_show (vbox);
675 window_store = gtk_tree_store_new (1, GDK_TYPE_WINDOW);
677 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window_store));
678 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
679 GTK_SELECTION_MULTIPLE);
680 column = gtk_tree_view_column_new ();
681 gtk_tree_view_column_set_title (column, "Window");
682 renderer = gtk_cell_renderer_text_new ();
683 gtk_tree_view_column_pack_start (column, renderer, TRUE);
684 gtk_tree_view_column_set_cell_data_func (column,
689 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
692 scrolled = gtk_scrolled_window_new (NULL, NULL);
693 gtk_widget_set_size_request (scrolled, 200, 400);
694 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
695 gtk_box_pack_start (GTK_BOX (vbox),
699 gtk_widget_show (scrolled);
700 gtk_widget_show (treeview);
702 table = gtk_table_new (3, 3, TRUE);
703 gtk_box_pack_start (GTK_BOX (vbox),
707 gtk_widget_show (table);
709 button = gtk_button_new ();
710 gtk_button_set_image (GTK_BUTTON (button),
711 gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
712 GTK_ICON_SIZE_BUTTON));
713 g_signal_connect (button, "clicked",
714 G_CALLBACK (move_window_clicked),
715 GINT_TO_POINTER (GTK_DIR_LEFT));
716 gtk_table_attach_defaults (GTK_TABLE (table),
720 gtk_widget_show (button);
722 button = gtk_button_new ();
723 gtk_button_set_image (GTK_BUTTON (button),
724 gtk_image_new_from_stock (GTK_STOCK_GO_UP,
725 GTK_ICON_SIZE_BUTTON));
726 g_signal_connect (button, "clicked",
727 G_CALLBACK (move_window_clicked),
728 GINT_TO_POINTER (GTK_DIR_UP));
729 gtk_table_attach_defaults (GTK_TABLE (table),
733 gtk_widget_show (button);
735 button = gtk_button_new ();
736 gtk_button_set_image (GTK_BUTTON (button),
737 gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
738 GTK_ICON_SIZE_BUTTON));
739 g_signal_connect (button, "clicked",
740 G_CALLBACK (move_window_clicked),
741 GINT_TO_POINTER (GTK_DIR_RIGHT));
742 gtk_table_attach_defaults (GTK_TABLE (table),
746 gtk_widget_show (button);
748 button = gtk_button_new ();
749 gtk_button_set_image (GTK_BUTTON (button),
750 gtk_image_new_from_stock (GTK_STOCK_GO_DOWN,
751 GTK_ICON_SIZE_BUTTON));
752 g_signal_connect (button, "clicked",
753 G_CALLBACK (move_window_clicked),
754 GINT_TO_POINTER (GTK_DIR_DOWN));
755 gtk_table_attach_defaults (GTK_TABLE (table),
759 gtk_widget_show (button);
762 button = gtk_button_new_with_label ("Raise");
763 g_signal_connect (button, "clicked",
764 G_CALLBACK (raise_window_clicked),
766 gtk_table_attach_defaults (GTK_TABLE (table),
770 gtk_widget_show (button);
772 button = gtk_button_new_with_label ("Lower");
773 g_signal_connect (button, "clicked",
774 G_CALLBACK (lower_window_clicked),
776 gtk_table_attach_defaults (GTK_TABLE (table),
780 gtk_widget_show (button);
783 button = gtk_button_new_with_label ("Smaller");
784 g_signal_connect (button, "clicked",
785 G_CALLBACK (smaller_window_clicked),
787 gtk_table_attach_defaults (GTK_TABLE (table),
791 gtk_widget_show (button);
793 button = gtk_button_new_with_label ("Larger");
794 g_signal_connect (button, "clicked",
795 G_CALLBACK (larger_window_clicked),
797 gtk_table_attach_defaults (GTK_TABLE (table),
801 gtk_widget_show (button);
803 button = gtk_button_new_with_label ("Native");
804 g_signal_connect (button, "clicked",
805 G_CALLBACK (native_window_clicked),
807 gtk_table_attach_defaults (GTK_TABLE (table),
811 gtk_widget_show (button);
814 button = gtk_button_new_with_label ("Add window");
815 gtk_box_pack_start (GTK_BOX (vbox),
819 gtk_widget_show (button);
820 g_signal_connect (button, "clicked",
821 G_CALLBACK (add_window_clicked),
824 button = gtk_button_new_with_label ("Remove window");
825 gtk_box_pack_start (GTK_BOX (vbox),
829 gtk_widget_show (button);
830 g_signal_connect (button, "clicked",
831 G_CALLBACK (remove_window_clicked),
834 button = gtk_button_new_with_label ("Save");
835 gtk_box_pack_start (GTK_BOX (vbox),
839 gtk_widget_show (button);
840 g_signal_connect (button, "clicked",
841 G_CALLBACK (save_clicked),
844 gtk_widget_show (window);
848 file = g_file_new_for_commandline_arg (argv[1]);
850 g_object_unref (file);