1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gdk/gdkkeysyms.h"
23 #include "gtksignal.h"
24 #include "gtkwindow.h"
33 typedef gint (*GtkWindowSignal1) (GtkObject *object,
39 typedef void (*GtkWindowSignal2) (GtkObject *object,
43 static void gtk_window_marshal_signal_1 (GtkObject *object,
47 static void gtk_window_marshal_signal_2 (GtkObject *object,
51 static void gtk_window_class_init (GtkWindowClass *klass);
52 static void gtk_window_init (GtkWindow *window);
53 static void gtk_window_arg (GtkWindow *window,
55 static void gtk_window_destroy (GtkObject *object);
56 static void gtk_window_show (GtkWidget *widget);
57 static void gtk_window_hide (GtkWidget *widget);
58 static void gtk_window_map (GtkWidget *widget);
59 static void gtk_window_unmap (GtkWidget *widget);
60 static void gtk_window_realize (GtkWidget *widget);
61 static void gtk_window_size_request (GtkWidget *widget,
62 GtkRequisition *requisition);
63 static void gtk_window_size_allocate (GtkWidget *widget,
64 GtkAllocation *allocation);
65 static gint gtk_window_expose_event (GtkWidget *widget,
66 GdkEventExpose *event);
67 static gint gtk_window_configure_event (GtkWidget *widget,
68 GdkEventConfigure *event);
69 static gint gtk_window_key_press_event (GtkWidget *widget,
71 static gint gtk_window_key_release_event (GtkWidget *widget,
73 static gint gtk_window_enter_notify_event (GtkWidget *widget,
74 GdkEventCrossing *event);
75 static gint gtk_window_leave_notify_event (GtkWidget *widget,
76 GdkEventCrossing *event);
77 static gint gtk_window_focus_in_event (GtkWidget *widget,
78 GdkEventFocus *event);
79 static gint gtk_window_focus_out_event (GtkWidget *widget,
80 GdkEventFocus *event);
81 static gint gtk_window_client_event (GtkWidget *widget,
82 GdkEventClient *event);
83 static gint gtk_window_need_resize (GtkContainer *container);
84 static gint gtk_real_window_move_resize (GtkWindow *window,
89 static void gtk_real_window_set_focus (GtkWindow *window,
91 static gint gtk_window_move_resize (GtkWidget *widget);
92 static void gtk_window_set_hints (GtkWidget *widget,
93 GtkRequisition *requisition);
94 static gint gtk_window_check_accelerator (GtkWindow *window,
99 static GtkBinClass *parent_class = NULL;
100 static gint window_signals[LAST_SIGNAL] = { 0 };
104 gtk_window_get_type ()
106 static guint window_type = 0;
110 GtkTypeInfo window_info =
114 sizeof (GtkWindowClass),
115 (GtkClassInitFunc) gtk_window_class_init,
116 (GtkObjectInitFunc) gtk_window_init,
117 (GtkArgFunc) gtk_window_arg,
120 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
127 gtk_window_class_init (GtkWindowClass *klass)
129 GtkObjectClass *object_class;
130 GtkWidgetClass *widget_class;
131 GtkContainerClass *container_class;
133 object_class = (GtkObjectClass*) klass;
134 widget_class = (GtkWidgetClass*) klass;
135 container_class = (GtkContainerClass*) klass;
137 parent_class = gtk_type_class (gtk_bin_get_type ());
139 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE);
140 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING);
141 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL);
142 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL);
143 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL);
145 window_signals[MOVE_RESIZE] =
146 gtk_signal_new ("move_resize",
149 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
150 gtk_window_marshal_signal_1,
152 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
153 GTK_TYPE_INT, GTK_TYPE_INT);
155 window_signals[SET_FOCUS] =
156 gtk_signal_new ("set_focus",
159 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
160 gtk_window_marshal_signal_2,
164 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
166 object_class->destroy = gtk_window_destroy;
168 widget_class->show = gtk_window_show;
169 widget_class->hide = gtk_window_hide;
170 widget_class->map = gtk_window_map;
171 widget_class->unmap = gtk_window_unmap;
172 widget_class->realize = gtk_window_realize;
173 widget_class->size_request = gtk_window_size_request;
174 widget_class->size_allocate = gtk_window_size_allocate;
175 widget_class->expose_event = gtk_window_expose_event;
176 widget_class->configure_event = gtk_window_configure_event;
177 widget_class->key_press_event = gtk_window_key_press_event;
178 widget_class->key_release_event = gtk_window_key_release_event;
179 widget_class->enter_notify_event = gtk_window_enter_notify_event;
180 widget_class->leave_notify_event = gtk_window_leave_notify_event;
181 widget_class->focus_in_event = gtk_window_focus_in_event;
182 widget_class->focus_out_event = gtk_window_focus_out_event;
183 widget_class->client_event = gtk_window_client_event;
185 container_class->need_resize = gtk_window_need_resize;
187 klass->move_resize = gtk_real_window_move_resize;
188 klass->set_focus = gtk_real_window_set_focus;
192 gtk_window_init (GtkWindow *window)
194 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
195 GTK_WIDGET_SET_FLAGS (window, GTK_ANCHORED);
197 window->title = NULL;
198 window->wmclass_name = NULL;
199 window->wmclass_class = NULL;
200 window->type = GTK_WINDOW_TOPLEVEL;
201 window->accelerator_tables = NULL;
202 window->focus_widget = NULL;
203 window->default_widget = NULL;
204 window->resize_count = 0;
205 window->need_resize = FALSE;
206 window->allow_shrink = FALSE;
207 window->allow_grow = TRUE;
208 window->auto_shrink = FALSE;
209 window->handling_resize = FALSE;
210 window->position = GTK_WIN_POS_NONE;
211 window->use_uposition = TRUE;
215 gtk_window_arg (GtkWindow *window,
218 if (strcmp (arg->name, "type") == 0)
220 window->type = GTK_VALUE_ENUM(*arg);
222 else if (strcmp (arg->name, "title") == 0)
224 gtk_window_set_title (window, GTK_VALUE_STRING(*arg));
226 else if (strcmp (arg->name, "auto_shrink") == 0)
228 window->auto_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
230 else if (strcmp (arg->name, "allow_shrink") == 0)
232 window->allow_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
234 else if (strcmp (arg->name, "allow_grow") == 0)
236 window->allow_grow = (GTK_VALUE_BOOL(*arg) != FALSE);
241 gtk_window_new (GtkWindowType type)
245 window = gtk_type_new (gtk_window_get_type ());
249 return GTK_WIDGET (window);
253 gtk_window_set_title (GtkWindow *window,
256 g_return_if_fail (window != NULL);
257 g_return_if_fail (GTK_IS_WINDOW (window));
260 g_free (window->title);
261 window->title = g_strdup (title);
263 if (GTK_WIDGET_REALIZED (window))
264 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
268 gtk_window_set_wmclass (GtkWindow *window,
270 gchar *wmclass_class)
272 g_return_if_fail (window != NULL);
273 g_return_if_fail (GTK_IS_WINDOW (window));
275 if (window->wmclass_name)
276 g_free (window->wmclass_name);
277 window->wmclass_name = g_strdup (wmclass_name);
279 if (window->wmclass_class)
280 g_free (window->wmclass_class);
281 window->wmclass_class = g_strdup (wmclass_class);
283 if (GTK_WIDGET_REALIZED (window))
284 g_warning ("shouldn't set wmclass after window is realized!\n");
288 gtk_window_set_focus (GtkWindow *window,
291 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
295 gtk_window_set_default (GtkWindow *window,
298 g_return_if_fail (window != NULL);
299 g_return_if_fail (GTK_IS_WINDOW (window));
300 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (defaultw));
302 if (window->default_widget != defaultw)
304 if (window->default_widget)
306 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
307 gtk_widget_draw_default (window->default_widget);
310 window->default_widget = defaultw;
312 if (window->default_widget)
314 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
315 gtk_widget_draw_default (window->default_widget);
321 gtk_window_set_policy (GtkWindow *window,
326 g_return_if_fail (window != NULL);
327 g_return_if_fail (GTK_IS_WINDOW (window));
329 window->allow_shrink = (allow_shrink != FALSE);
330 window->allow_grow = (allow_grow != FALSE);
331 window->auto_shrink = (auto_shrink != FALSE);
335 gtk_window_add_accelerator_table (GtkWindow *window,
336 GtkAcceleratorTable *table)
338 g_return_if_fail (window != NULL);
339 g_return_if_fail (GTK_IS_WINDOW (window));
341 gtk_accelerator_table_ref (table);
342 window->accelerator_tables = g_list_prepend (window->accelerator_tables,
347 gtk_window_remove_accelerator_table (GtkWindow *window,
348 GtkAcceleratorTable *table)
350 g_return_if_fail (window != NULL);
351 g_return_if_fail (GTK_IS_WINDOW (window));
353 window->accelerator_tables = g_list_remove (window->accelerator_tables,
355 gtk_accelerator_table_unref (table);
359 gtk_window_position (GtkWindow *window,
360 GtkWindowPosition position)
362 g_return_if_fail (window != NULL);
363 g_return_if_fail (GTK_IS_WINDOW (window));
365 window->position = position;
369 gtk_window_marshal_signal_1 (GtkObject *object,
374 GtkWindowSignal1 rfunc;
377 rfunc = (GtkWindowSignal1) func;
378 return_val = GTK_RETLOC_BOOL (args[4]);
380 *return_val = (* rfunc) (object,
381 GTK_VALUE_POINTER (args[0]),
382 GTK_VALUE_POINTER (args[1]),
383 GTK_VALUE_INT (args[2]),
384 GTK_VALUE_INT (args[3]),
389 gtk_window_marshal_signal_2 (GtkObject *object,
394 GtkWindowSignal2 rfunc;
396 rfunc = (GtkWindowSignal2) func;
398 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
402 gtk_window_destroy (GtkObject *object)
406 g_return_if_fail (object != NULL);
407 g_return_if_fail (GTK_IS_WINDOW (object));
409 window = GTK_WINDOW (object);
410 g_free (window->title);
412 if (GTK_OBJECT_CLASS (parent_class)->destroy)
413 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
417 gtk_window_show (GtkWidget *widget)
419 g_return_if_fail (widget != NULL);
420 g_return_if_fail (GTK_IS_WINDOW (widget));
422 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
423 gtk_container_need_resize (GTK_CONTAINER (widget));
424 gtk_widget_map (widget);
428 gtk_window_hide (GtkWidget *widget)
430 g_return_if_fail (widget != NULL);
431 g_return_if_fail (GTK_IS_WINDOW (widget));
433 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
434 gtk_widget_unmap (widget);
438 gtk_window_map (GtkWidget *widget)
442 g_return_if_fail (widget != NULL);
443 g_return_if_fail (GTK_IS_WINDOW (widget));
445 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
446 GTK_WIDGET_UNSET_FLAGS (widget, GTK_UNMAPPED);
448 gtk_window_move_resize (widget);
449 window = GTK_WINDOW (widget);
451 if (window->bin.child &&
452 GTK_WIDGET_VISIBLE (window->bin.child) &&
453 !GTK_WIDGET_MAPPED (window->bin.child))
454 gtk_widget_map (window->bin.child);
456 gtk_window_set_hints (widget, &widget->requisition);
457 gdk_window_show (widget->window);
461 gtk_window_unmap (GtkWidget *widget)
465 g_return_if_fail (widget != NULL);
466 g_return_if_fail (GTK_IS_WINDOW (widget));
468 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
469 GTK_WIDGET_SET_FLAGS (widget, GTK_UNMAPPED);
470 gdk_window_hide (widget->window);
472 window = GTK_WINDOW (widget);
473 window->use_uposition = TRUE;
477 gtk_window_realize (GtkWidget *widget)
480 GdkWindowAttr attributes;
481 gint attributes_mask;
483 g_return_if_fail (widget != NULL);
484 g_return_if_fail (GTK_IS_WINDOW (widget));
486 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
487 window = GTK_WINDOW (widget);
489 switch (window->type)
491 case GTK_WINDOW_TOPLEVEL:
492 attributes.window_type = GDK_WINDOW_TOPLEVEL;
494 case GTK_WINDOW_DIALOG:
495 attributes.window_type = GDK_WINDOW_DIALOG;
497 case GTK_WINDOW_POPUP:
498 attributes.window_type = GDK_WINDOW_TEMP;
502 attributes.title = window->title;
503 attributes.wmclass_name = window->wmclass_name;
504 attributes.wmclass_class = window->wmclass_class;
505 attributes.width = widget->allocation.width;
506 attributes.height = widget->allocation.height;
507 attributes.wclass = GDK_INPUT_OUTPUT;
508 attributes.visual = gtk_widget_get_visual (widget);
509 attributes.colormap = gtk_widget_get_colormap (widget);
510 attributes.event_mask = gtk_widget_get_events (widget);
511 attributes.event_mask |= (GDK_EXPOSURE_MASK |
513 GDK_ENTER_NOTIFY_MASK |
514 GDK_LEAVE_NOTIFY_MASK |
515 GDK_FOCUS_CHANGE_MASK |
518 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
519 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
520 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
522 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
523 gdk_window_set_user_data (widget->window, window);
525 widget->style = gtk_style_attach (widget->style, widget->window);
526 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
530 gtk_window_size_request (GtkWidget *widget,
531 GtkRequisition *requisition)
535 g_return_if_fail (widget != NULL);
536 g_return_if_fail (GTK_IS_WINDOW (widget));
537 g_return_if_fail (requisition != NULL);
539 window = GTK_WINDOW (widget);
541 if (window->bin.child)
543 requisition->width = GTK_CONTAINER (window)->border_width * 2;
544 requisition->height = GTK_CONTAINER (window)->border_width * 2;
546 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
548 requisition->width += window->bin.child->requisition.width;
549 requisition->height += window->bin.child->requisition.height;
553 if (!GTK_WIDGET_VISIBLE (window))
554 window->need_resize = TRUE;
559 gtk_window_size_allocate (GtkWidget *widget,
560 GtkAllocation *allocation)
563 GtkAllocation child_allocation;
565 g_return_if_fail (widget != NULL);
566 g_return_if_fail (GTK_IS_WINDOW (widget));
567 g_return_if_fail (allocation != NULL);
569 window = GTK_WINDOW (widget);
570 widget->allocation = *allocation;
572 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
574 child_allocation.x = GTK_CONTAINER (window)->border_width;
575 child_allocation.y = GTK_CONTAINER (window)->border_width;
576 child_allocation.width = allocation->width - child_allocation.x * 2;
577 child_allocation.height = allocation->height - child_allocation.y * 2;
579 gtk_widget_size_allocate (window->bin.child, &child_allocation);
584 gtk_window_expose_event (GtkWidget *widget,
585 GdkEventExpose *event)
587 g_return_val_if_fail (widget != NULL, FALSE);
588 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
589 g_return_val_if_fail (event != NULL, FALSE);
591 if (!GTK_WIDGET_UNMAPPED (widget))
592 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
594 if (GTK_WIDGET_DRAWABLE (widget))
595 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
596 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
602 gtk_window_configure_event (GtkWidget *widget,
603 GdkEventConfigure *event)
606 GtkAllocation allocation;
608 g_return_val_if_fail (widget != NULL, FALSE);
609 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
610 g_return_val_if_fail (event != NULL, FALSE);
612 window = GTK_WINDOW (widget);
613 window->handling_resize = TRUE;
617 allocation.width = event->width;
618 allocation.height = event->height;
620 gtk_widget_size_allocate (widget, &allocation);
622 if (window->bin.child &&
623 GTK_WIDGET_VISIBLE (window->bin.child) &&
624 !GTK_WIDGET_MAPPED (window->bin.child))
625 gtk_widget_map (window->bin.child);
627 window->resize_count -= 1;
628 if (window->resize_count == 0)
630 if ((event->width != widget->requisition.width) ||
631 (event->height != widget->requisition.height))
633 window->resize_count += 1;
634 gdk_window_resize (widget->window,
635 widget->requisition.width,
636 widget->requisition.height);
639 else if (window->resize_count < 0)
641 window->resize_count = 0;
644 window->handling_resize = FALSE;
650 gtk_window_key_press_event (GtkWidget *widget,
654 GtkDirectionType direction = 0;
657 g_return_val_if_fail (widget != NULL, FALSE);
658 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
659 g_return_val_if_fail (event != NULL, FALSE);
661 window = GTK_WINDOW (widget);
664 if (window->focus_widget)
665 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
667 if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
672 switch (event->keyval)
675 if (window->focus_widget)
677 gtk_widget_activate (window->focus_widget);
683 if (window->default_widget)
685 gtk_widget_activate (window->default_widget);
688 else if (window->focus_widget)
690 gtk_widget_activate (window->focus_widget);
699 switch (event->keyval)
702 direction = GTK_DIR_UP;
705 direction = GTK_DIR_DOWN;
708 direction = GTK_DIR_LEFT;
711 direction = GTK_DIR_RIGHT;
714 if (event->state & GDK_SHIFT_MASK)
715 direction = GTK_DIR_TAB_BACKWARD;
717 direction = GTK_DIR_TAB_FORWARD;
720 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
723 gtk_container_focus (GTK_CONTAINER (widget), direction);
725 if (!GTK_CONTAINER (window)->focus_child)
726 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
737 gtk_window_key_release_event (GtkWidget *widget,
743 g_return_val_if_fail (widget != NULL, FALSE);
744 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
745 g_return_val_if_fail (event != NULL, FALSE);
747 window = GTK_WINDOW (widget);
749 if (window->focus_widget)
750 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
756 gtk_window_enter_notify_event (GtkWidget *widget,
757 GdkEventCrossing *event)
759 g_return_val_if_fail (widget != NULL, FALSE);
760 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
761 g_return_val_if_fail (event != NULL, FALSE);
767 gtk_window_leave_notify_event (GtkWidget *widget,
768 GdkEventCrossing *event)
770 g_return_val_if_fail (widget != NULL, FALSE);
771 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
772 g_return_val_if_fail (event != NULL, FALSE);
778 gtk_window_focus_in_event (GtkWidget *widget,
779 GdkEventFocus *event)
782 GdkEventFocus fevent;
784 g_return_val_if_fail (widget != NULL, FALSE);
785 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
786 g_return_val_if_fail (event != NULL, FALSE);
788 /* It appears spurious focus in events can occur when
789 * the window is hidden. So we'll just check to see if
790 * the window is visible before actually handling the
793 if (GTK_WIDGET_VISIBLE (widget))
795 window = GTK_WINDOW (widget);
796 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
798 fevent.type = GDK_FOCUS_CHANGE;
799 fevent.window = window->focus_widget->window;
802 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
810 gtk_window_focus_out_event (GtkWidget *widget,
811 GdkEventFocus *event)
814 GdkEventFocus fevent;
816 g_return_val_if_fail (widget != NULL, FALSE);
817 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
818 g_return_val_if_fail (event != NULL, FALSE);
820 window = GTK_WINDOW (widget);
821 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
823 fevent.type = GDK_FOCUS_CHANGE;
824 fevent.window = window->focus_widget->window;
827 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
834 gtk_window_style_set_event (GtkWidget *widget,
835 GdkEventClient *event)
837 GdkAtom atom_default_colors;
838 GtkStyle *style_newdefault;
841 GdkColor *data, *stylecolors;
843 GdkColormap *widget_cmap;
845 atom_default_colors = gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE);
847 if(gdk_property_get (GDK_ROOT_PARENT(),
849 gdk_atom_intern("STRING", FALSE),
851 sizeof(GdkColor) * GTK_STYLE_NUM_STYLECOLORS(),
856 (guchar **)&data) != TRUE) {
857 g_warning("gdk_property_get() failed in _GTK_STYLE_CHANGED handler\n");
860 if(retfmt != sizeof(gushort)*8) {
861 g_warning("retfmt (%d) != sizeof(gushort)*8 (%d)\n", retfmt,
865 /* We have the color data, now let's interpret it */
866 style_newdefault = gtk_widget_get_default_style();
867 gtk_style_ref(style_newdefault);
868 stylecolors = (GdkColor *) style_newdefault;
870 widget_cmap = gtk_widget_get_colormap(widget);
871 for(i = 0; i < GTK_STYLE_NUM_STYLECOLORS(); i++) {
872 stylecolors[i] = data[i];
873 gdk_color_alloc(widget_cmap, &stylecolors[i]);
876 gtk_widget_set_default_style(style_newdefault);
877 gtk_style_unref(style_newdefault);
879 /* Now we need to redraw everything */
880 gtk_widget_draw(widget, NULL);
881 gtk_widget_draw_children(widget);
885 gtk_window_client_event (GtkWidget *widget,
886 GdkEventClient *event)
888 GdkAtom atom_styleset;
889 g_return_val_if_fail (widget != NULL, FALSE);
890 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
891 g_return_val_if_fail (event != NULL, FALSE);
893 atom_styleset = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
895 if(event->message_type == atom_styleset) {
896 gtk_window_style_set_event(widget, event);
902 gtk_window_need_resize (GtkContainer *container)
907 g_return_val_if_fail (container != NULL, FALSE);
908 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
912 window = GTK_WINDOW (container);
913 if (window->handling_resize)
916 if (GTK_WIDGET_VISIBLE (container))
918 window->need_resize = TRUE;
919 return_val = gtk_window_move_resize (GTK_WIDGET (window));
920 window->need_resize = FALSE;
927 gtk_real_window_move_resize (GtkWindow *window,
934 GtkWidget *resize_container;
935 GSList *resize_widgets;
936 GSList *resize_containers;
940 g_return_val_if_fail (window != NULL, FALSE);
941 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
942 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
946 widget = GTK_WIDGET (window);
948 if ((*x != -1) && (*y != -1))
949 gdk_window_move (widget->window, *x, *y);
951 if ((widget->requisition.width == 0) ||
952 (widget->requisition.height == 0))
954 widget->requisition.width = 200;
955 widget->requisition.height = 200;
958 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
960 resize_containers = NULL;
962 if ((window->auto_shrink &&
963 ((width != widget->requisition.width) ||
964 (height != widget->requisition.height))) ||
965 (width < widget->requisition.width) ||
966 (height < widget->requisition.height))
968 if (window->resize_count == 0)
970 window->resize_count += 1;
971 gdk_window_resize (widget->window,
972 widget->requisition.width,
973 widget->requisition.height);
978 /* The window hasn't changed size but one of its children
979 * queued a resize request. Which means that the allocation
980 * is not sufficient for the requisition of some child.
981 * We've already performed a size request at this point,
982 * so we simply need to run through the list of resize
983 * widgets and reallocate their sizes appropriately. We
984 * make the optimization of not performing reallocation
985 * for a widget who also has a parent in the resize widgets
988 resize_widgets = gtk_object_get_data (GTK_OBJECT (window), "resize_widgets");
989 gtk_object_set_data (GTK_OBJECT (window), "resize_widgets", NULL);
991 tmp_list = resize_widgets;
994 widget = tmp_list->data;
995 tmp_list = tmp_list->next;
997 /* referencing needed? */
998 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
999 gtk_object_unref (GTK_OBJECT (widget));
1001 widget = widget->parent;
1004 ((widget->allocation.width < widget->requisition.width) ||
1005 (widget->allocation.height < widget->requisition.height)))
1006 widget = widget->parent;
1009 GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED);
1012 tmp_list = resize_widgets;
1015 widget = tmp_list->data;
1016 tmp_list = tmp_list->next;
1018 resize_container = widget->parent;
1019 while (resize_container &&
1020 !GTK_WIDGET_RESIZE_NEEDED (resize_container))
1021 resize_container = resize_container->parent;
1023 if (resize_container)
1024 widget = resize_container->parent;
1030 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1032 GTK_WIDGET_UNSET_FLAGS (resize_container, GTK_RESIZE_NEEDED);
1033 resize_container = widget;
1035 widget = widget->parent;
1038 if (resize_container &&
1039 !g_slist_find (resize_containers, resize_container))
1040 resize_containers = g_slist_prepend (resize_containers, resize_container);
1043 g_slist_free (resize_widgets);
1045 tmp_list = resize_containers;
1048 widget = tmp_list->data;
1049 tmp_list = tmp_list->next;
1051 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
1052 gtk_widget_size_allocate (widget, &widget->allocation);
1053 gtk_widget_queue_draw (widget);
1056 g_slist_free (resize_containers);
1063 gtk_window_move_resize (GtkWidget *widget)
1072 g_return_val_if_fail (widget != NULL, FALSE);
1073 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1077 if (GTK_WIDGET_REALIZED (widget))
1079 window = GTK_WINDOW (widget);
1081 /* Remember old size, to know if we have to reset hints */
1082 width = widget->requisition.width;
1083 height = widget->requisition.height;
1084 gtk_widget_size_request (widget, &widget->requisition);
1086 if (GTK_WIDGET_MAPPED (widget) &&
1087 (width != widget->requisition.width ||
1088 height != widget->requisition.height))
1089 gtk_window_set_hints (widget, &widget->requisition);
1093 width = widget->requisition.width;
1094 height = widget->requisition.height;
1096 if (window->use_uposition)
1097 switch (window->position)
1099 case GTK_WIN_POS_CENTER:
1100 x = (gdk_screen_width () - width) / 2;
1101 y = (gdk_screen_height () - height) / 2;
1102 gtk_widget_set_uposition (widget, x, y);
1104 case GTK_WIN_POS_MOUSE:
1105 gdk_window_get_pointer (NULL, &x, &y, NULL);
1110 screen_width = gdk_screen_width ();
1111 screen_height = gdk_screen_height ();
1115 else if (x > (screen_width - width))
1116 x = screen_width - width;
1120 else if (y > (screen_height - height))
1121 y = screen_height - height;
1123 gtk_widget_set_uposition (widget, x, y);
1127 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1128 &x, &y, width, height, &return_val);
1135 gtk_real_window_set_focus (GtkWindow *window,
1138 GdkEventFocus event;
1140 g_return_if_fail (window != NULL);
1141 g_return_if_fail (GTK_IS_WINDOW (window));
1143 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1146 if (window->focus_widget != focus)
1148 if (window->focus_widget)
1150 event.type = GDK_FOCUS_CHANGE;
1151 event.window = window->focus_widget->window;
1154 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1157 window->focus_widget = focus;
1159 if (window->focus_widget)
1161 event.type = GDK_FOCUS_CHANGE;
1162 event.window = window->focus_widget->window;
1165 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1171 gtk_window_set_hints (GtkWidget *widget,
1172 GtkRequisition *requisition)
1175 GtkWidgetAuxInfo *aux_info;
1179 g_return_if_fail (widget != NULL);
1180 g_return_if_fail (GTK_IS_WINDOW (widget));
1181 g_return_if_fail (requisition != NULL);
1183 if (GTK_WIDGET_REALIZED (widget))
1185 window = GTK_WINDOW (widget);
1191 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "aux_info");
1192 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1196 flags |= GDK_HINT_POS;
1198 if (!window->allow_shrink)
1199 flags |= GDK_HINT_MIN_SIZE;
1200 if (!window->allow_grow)
1201 flags |= GDK_HINT_MAX_SIZE;
1203 gdk_window_set_hints (widget->window, ux, uy,
1204 requisition->width, requisition->height,
1205 requisition->width, requisition->height,
1208 if (window->use_uposition && (flags & GDK_HINT_POS))
1210 window->use_uposition = FALSE;
1211 gdk_window_move (widget->window, ux, uy);
1217 gtk_window_check_accelerator (GtkWindow *window,
1221 GtkAcceleratorTable *table;
1224 if ((key >= 0x20) && (key <= 0xFF))
1226 tmp = window->accelerator_tables;
1232 if (gtk_accelerator_table_check (table, key, mods))
1236 if (gtk_accelerator_table_check (NULL, key, mods))