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
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gdk/gdkkeysyms.h"
24 #include "gtkprivate.h"
26 #include "gtksignal.h"
27 #include "gtkwindow.h"
28 #include "gtkbindings.h"
45 static void gtk_window_class_init (GtkWindowClass *klass);
46 static void gtk_window_init (GtkWindow *window);
47 static void gtk_window_set_arg (GtkObject *object,
50 static void gtk_window_get_arg (GtkObject *object,
53 static void gtk_window_shutdown (GtkObject *object);
54 static void gtk_window_destroy (GtkObject *object);
55 static void gtk_window_finalize (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 void gtk_window_check_resize (GtkContainer *container);
84 static void gtk_real_window_set_focus (GtkWindow *window,
86 static void gtk_window_move_resize (GtkWindow *window);
87 static void gtk_window_set_hints (GtkWidget *widget,
88 GtkRequisition *requisition);
90 static void gtk_window_read_rcfiles (GtkWidget *widget,
91 GdkEventClient *event);
92 static void gtk_window_draw (GtkWidget *widget,
94 static gint gtk_window_expose (GtkWidget *widget,
95 GdkEventExpose *event);
96 static void gtk_window_style_set (GtkWidget *widget,
97 GtkStyle *previous_style);
102 static GtkBinClass *parent_class = NULL;
103 static guint window_signals[LAST_SIGNAL] = { 0 };
107 gtk_window_get_type (void)
109 static GtkType window_type = 0;
113 GtkTypeInfo window_info =
117 sizeof (GtkWindowClass),
118 (GtkClassInitFunc) gtk_window_class_init,
119 (GtkObjectInitFunc) gtk_window_init,
120 /* reserved_1 */ NULL,
121 /* reserved_2 */ NULL,
122 (GtkClassInitFunc) NULL,
125 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
132 gtk_window_class_init (GtkWindowClass *klass)
134 GtkObjectClass *object_class;
135 GtkWidgetClass *widget_class;
136 GtkContainerClass *container_class;
138 object_class = (GtkObjectClass*) klass;
139 widget_class = (GtkWidgetClass*) klass;
140 container_class = (GtkContainerClass*) klass;
142 parent_class = gtk_type_class (gtk_bin_get_type ());
144 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
145 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
146 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
147 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
148 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
149 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
151 window_signals[SET_FOCUS] =
152 gtk_signal_new ("set_focus",
155 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
156 gtk_marshal_NONE__POINTER,
160 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
162 object_class->set_arg = gtk_window_set_arg;
163 object_class->get_arg = gtk_window_get_arg;
164 object_class->shutdown = gtk_window_shutdown;
165 object_class->destroy = gtk_window_destroy;
166 object_class->finalize = gtk_window_finalize;
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;
184 widget_class->style_set = gtk_window_style_set;
186 widget_class->draw = gtk_window_draw;
187 widget_class->expose_event = gtk_window_expose;
189 container_class->check_resize = gtk_window_check_resize;
191 klass->set_focus = gtk_real_window_set_focus;
195 gtk_window_init (GtkWindow *window)
197 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
198 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
200 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
202 window->title = NULL;
203 window->wmclass_name = g_strdup (g_get_prgname ());
204 window->wmclass_class = g_strdup (gdk_progclass);
205 window->type = GTK_WINDOW_TOPLEVEL;
206 window->focus_widget = NULL;
207 window->default_widget = NULL;
208 window->resize_count = 0;
209 window->allow_shrink = FALSE;
210 window->allow_grow = TRUE;
211 window->auto_shrink = FALSE;
212 window->handling_resize = FALSE;
213 window->position = GTK_WIN_POS_NONE;
214 window->use_uposition = TRUE;
215 window->modal = FALSE;
217 gtk_container_register_toplevel (GTK_CONTAINER (window));
221 gtk_window_set_arg (GtkObject *object,
227 window = GTK_WINDOW (object);
232 window->type = GTK_VALUE_ENUM (*arg);
235 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
237 case ARG_AUTO_SHRINK:
238 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
239 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
241 case ARG_ALLOW_SHRINK:
242 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
243 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
246 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
247 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
250 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
258 gtk_window_get_arg (GtkObject *object,
264 window = GTK_WINDOW (object);
269 GTK_VALUE_ENUM (*arg) = window->type;
272 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
274 case ARG_AUTO_SHRINK:
275 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
277 case ARG_ALLOW_SHRINK:
278 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
281 GTK_VALUE_BOOL (*arg) = window->allow_grow;
284 GTK_VALUE_ENUM (*arg) = window->position;
287 arg->type = GTK_TYPE_INVALID;
293 gtk_window_new (GtkWindowType type)
297 window = gtk_type_new (gtk_window_get_type ());
301 return GTK_WIDGET (window);
305 gtk_window_set_title (GtkWindow *window,
308 g_return_if_fail (window != NULL);
309 g_return_if_fail (GTK_IS_WINDOW (window));
312 g_free (window->title);
313 window->title = g_strdup (title);
315 if (GTK_WIDGET_REALIZED (window))
316 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
320 gtk_window_set_wmclass (GtkWindow *window,
321 const gchar *wmclass_name,
322 const gchar *wmclass_class)
324 g_return_if_fail (window != NULL);
325 g_return_if_fail (GTK_IS_WINDOW (window));
327 g_free (window->wmclass_name);
328 window->wmclass_name = g_strdup (wmclass_name);
330 g_free (window->wmclass_class);
331 window->wmclass_class = g_strdup (wmclass_class);
333 if (GTK_WIDGET_REALIZED (window))
334 g_warning ("shouldn't set wmclass after window is realized!\n");
338 gtk_window_set_focus (GtkWindow *window,
341 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
345 gtk_window_set_default (GtkWindow *window,
346 GtkWidget *default_widget)
348 g_return_if_fail (window != NULL);
349 g_return_if_fail (GTK_IS_WINDOW (window));
352 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
354 if (window->default_widget != default_widget)
356 if (window->default_widget)
358 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
359 gtk_widget_draw_default (window->default_widget);
362 window->default_widget = default_widget;
364 if (window->default_widget)
366 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
367 gtk_widget_draw_default (window->default_widget);
373 gtk_window_set_policy (GtkWindow *window,
378 g_return_if_fail (window != NULL);
379 g_return_if_fail (GTK_IS_WINDOW (window));
381 window->allow_shrink = (allow_shrink != FALSE);
382 window->allow_grow = (allow_grow != FALSE);
383 window->auto_shrink = (auto_shrink != FALSE);
385 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
389 gtk_window_add_accel_group (GtkWindow *window,
390 GtkAccelGroup *accel_group)
392 g_return_if_fail (window != NULL);
393 g_return_if_fail (GTK_IS_WINDOW (window));
394 g_return_if_fail (accel_group != NULL);
396 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
400 gtk_window_remove_accel_group (GtkWindow *window,
401 GtkAccelGroup *accel_group)
403 g_return_if_fail (window != NULL);
404 g_return_if_fail (GTK_IS_WINDOW (window));
405 g_return_if_fail (accel_group != NULL);
407 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
411 gtk_window_position (GtkWindow *window,
412 GtkWindowPosition position)
414 g_return_if_fail (window != NULL);
415 g_return_if_fail (GTK_IS_WINDOW (window));
417 window->position = position;
421 gtk_window_activate_focus (GtkWindow *window)
423 g_return_val_if_fail (window != NULL, FALSE);
424 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
426 if (window->focus_widget)
428 gtk_widget_activate (window->focus_widget);
436 gtk_window_activate_default (GtkWindow *window)
438 g_return_val_if_fail (window != NULL, FALSE);
439 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
441 if (window->default_widget)
443 gtk_widget_activate (window->default_widget);
451 gtk_window_set_modal (GtkWindow *window, gboolean modal)
453 g_return_if_fail (window != NULL);
454 g_return_if_fail (GTK_IS_WINDOW (window));
456 /* If the widget was showed already, adjust it's grab state */
457 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(window)))
459 if (window->modal && !modal)
460 gtk_grab_remove (GTK_WIDGET(window));
461 else if (!window->modal && modal)
462 gtk_grab_add (GTK_WIDGET(window));
465 window->modal = modal;
469 gtk_window_shutdown (GtkObject *object)
473 g_return_if_fail (object != NULL);
474 g_return_if_fail (GTK_IS_WINDOW (object));
476 window = GTK_WINDOW (object);
478 gtk_window_set_focus (window, NULL);
479 gtk_window_set_default (window, NULL);
481 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
485 gtk_window_destroy (GtkObject *object)
487 g_return_if_fail (object != NULL);
488 g_return_if_fail (GTK_IS_WINDOW (object));
490 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
492 GTK_OBJECT_CLASS (parent_class)->destroy (object);
496 gtk_window_finalize (GtkObject *object)
500 g_return_if_fail (object != NULL);
501 g_return_if_fail (GTK_IS_WINDOW (object));
503 window = GTK_WINDOW (object);
504 g_free (window->title);
505 g_free (window->wmclass_name);
506 g_free (window->wmclass_class);
508 GTK_OBJECT_CLASS(parent_class)->finalize (object);
512 gtk_window_show (GtkWidget *widget)
514 g_return_if_fail (widget != NULL);
515 g_return_if_fail (GTK_IS_WINDOW (widget));
517 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
518 gtk_container_check_resize (GTK_CONTAINER (widget));
519 gtk_widget_map (widget);
521 if (GTK_WINDOW(widget)->modal)
522 gtk_grab_add(widget);
527 gtk_window_hide (GtkWidget *widget)
529 g_return_if_fail (widget != NULL);
530 g_return_if_fail (GTK_IS_WINDOW (widget));
532 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
533 gtk_widget_unmap (widget);
535 if (GTK_WINDOW(widget)->modal)
536 gtk_grab_remove(widget);
541 gtk_window_map (GtkWidget *widget)
545 g_return_if_fail (widget != NULL);
546 g_return_if_fail (GTK_IS_WINDOW (widget));
548 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
550 window = GTK_WINDOW (widget);
552 if (window->bin.child &&
553 GTK_WIDGET_VISIBLE (window->bin.child) &&
554 !GTK_WIDGET_MAPPED (window->bin.child))
555 gtk_widget_map (window->bin.child);
557 gtk_window_set_hints (widget, &widget->requisition);
558 gdk_window_show (widget->window);
562 gtk_window_unmap (GtkWidget *widget)
566 g_return_if_fail (widget != NULL);
567 g_return_if_fail (GTK_IS_WINDOW (widget));
569 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
570 gdk_window_hide (widget->window);
572 window = GTK_WINDOW (widget);
573 window->use_uposition = TRUE;
577 gtk_window_realize (GtkWidget *widget)
580 GdkWindowAttr attributes;
581 gint attributes_mask;
583 g_return_if_fail (widget != NULL);
584 g_return_if_fail (GTK_IS_WINDOW (widget));
586 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
587 window = GTK_WINDOW (widget);
589 switch (window->type)
591 case GTK_WINDOW_TOPLEVEL:
592 attributes.window_type = GDK_WINDOW_TOPLEVEL;
594 case GTK_WINDOW_DIALOG:
595 attributes.window_type = GDK_WINDOW_DIALOG;
597 case GTK_WINDOW_POPUP:
598 attributes.window_type = GDK_WINDOW_TEMP;
602 attributes.title = window->title;
603 attributes.wmclass_name = window->wmclass_name;
604 attributes.wmclass_class = window->wmclass_class;
605 attributes.width = widget->allocation.width;
606 attributes.height = widget->allocation.height;
607 attributes.wclass = GDK_INPUT_OUTPUT;
608 attributes.visual = gtk_widget_get_visual (widget);
609 attributes.colormap = gtk_widget_get_colormap (widget);
610 attributes.event_mask = gtk_widget_get_events (widget);
611 attributes.event_mask |= (GDK_EXPOSURE_MASK |
613 GDK_ENTER_NOTIFY_MASK |
614 GDK_LEAVE_NOTIFY_MASK |
615 GDK_FOCUS_CHANGE_MASK |
618 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
619 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
620 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
622 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
623 gdk_window_set_user_data (widget->window, window);
625 widget->style = gtk_style_attach (widget->style, widget->window);
626 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
627 gtk_window_paint (widget, NULL);
631 gtk_window_size_request (GtkWidget *widget,
632 GtkRequisition *requisition)
636 g_return_if_fail (widget != NULL);
637 g_return_if_fail (GTK_IS_WINDOW (widget));
638 g_return_if_fail (requisition != NULL);
640 window = GTK_WINDOW (widget);
642 if (window->bin.child)
644 requisition->width = GTK_CONTAINER (window)->border_width * 2;
645 requisition->height = GTK_CONTAINER (window)->border_width * 2;
647 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
649 requisition->width += window->bin.child->requisition.width;
650 requisition->height += window->bin.child->requisition.height;
654 if (!GTK_WIDGET_VISIBLE (window))
655 GTK_CONTAINER (window)->need_resize = TRUE;
660 gtk_window_size_allocate (GtkWidget *widget,
661 GtkAllocation *allocation)
664 GtkAllocation child_allocation;
666 g_return_if_fail (widget != NULL);
667 g_return_if_fail (GTK_IS_WINDOW (widget));
668 g_return_if_fail (allocation != NULL);
670 window = GTK_WINDOW (widget);
671 widget->allocation = *allocation;
673 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
675 child_allocation.x = GTK_CONTAINER (window)->border_width;
676 child_allocation.y = GTK_CONTAINER (window)->border_width;
677 child_allocation.width = allocation->width - child_allocation.x * 2;
678 child_allocation.height = allocation->height - child_allocation.y * 2;
680 gtk_widget_size_allocate (window->bin.child, &child_allocation);
685 gtk_window_expose_event (GtkWidget *widget,
686 GdkEventExpose *event)
688 g_return_val_if_fail (widget != NULL, FALSE);
689 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
690 g_return_val_if_fail (event != NULL, FALSE);
692 if (GTK_WIDGET_DRAWABLE (widget))
693 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
694 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
700 gtk_window_configure_event (GtkWidget *widget,
701 GdkEventConfigure *event)
704 GtkAllocation allocation;
705 gboolean need_expose = FALSE;
707 g_return_val_if_fail (widget != NULL, FALSE);
708 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
709 g_return_val_if_fail (event != NULL, FALSE);
711 window = GTK_WINDOW (widget);
713 /* If the window was merely moved, do nothing */
714 if ((widget->allocation.width == event->width) &&
715 (widget->allocation.height == event->height))
717 if (window->resize_count == 0) /* The window was merely moved */
721 /* We asked for a new size, which was rejected, so the
722 * WM sent us a synthetic configure event. We won't
723 * get the expose event we would normally get (since
724 * we have ForgetGravity), so we need to fake it.
731 window->handling_resize = TRUE;
735 allocation.width = event->width;
736 allocation.height = event->height;
738 gtk_widget_size_allocate (widget, &allocation);
740 if (window->bin.child &&
741 GTK_WIDGET_VISIBLE (window->bin.child) &&
742 !GTK_WIDGET_MAPPED (window->bin.child))
743 gtk_widget_map (window->bin.child);
745 if (window->resize_count > 0)
746 window->resize_count -= 1;
751 temp_event.type = GDK_EXPOSE;
752 temp_event.expose.window = widget->window;
753 temp_event.expose.send_event = TRUE;
754 temp_event.expose.area.x = 0;
755 temp_event.expose.area.y = 0;
756 temp_event.expose.area.width = event->width;
757 temp_event.expose.area.height = event->height;
758 temp_event.expose.count = 0;
760 gtk_widget_event (widget, &temp_event);
763 window->handling_resize = FALSE;
769 gtk_window_key_press_event (GtkWidget *widget,
773 GtkDirectionType direction = 0;
776 g_return_val_if_fail (widget != NULL, FALSE);
777 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
778 g_return_val_if_fail (event != NULL, FALSE);
780 window = GTK_WINDOW (widget);
784 if (window->focus_widget)
786 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
790 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
794 switch (event->keyval)
797 if (window->focus_widget)
799 gtk_widget_activate (window->focus_widget);
805 if (window->default_widget)
807 gtk_widget_activate (window->default_widget);
810 else if (window->focus_widget)
812 gtk_widget_activate (window->focus_widget);
821 case GDK_ISO_Left_Tab:
822 switch (event->keyval)
825 direction = GTK_DIR_UP;
828 direction = GTK_DIR_DOWN;
831 direction = GTK_DIR_LEFT;
834 direction = GTK_DIR_RIGHT;
837 case GDK_ISO_Left_Tab:
838 if (event->state & GDK_SHIFT_MASK)
839 direction = GTK_DIR_TAB_BACKWARD;
841 direction = GTK_DIR_TAB_FORWARD;
844 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
847 gtk_container_focus (GTK_CONTAINER (widget), direction);
849 if (!GTK_CONTAINER (window)->focus_child)
850 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
857 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
858 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
864 gtk_window_key_release_event (GtkWidget *widget,
870 g_return_val_if_fail (widget != NULL, FALSE);
871 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
872 g_return_val_if_fail (event != NULL, FALSE);
874 window = GTK_WINDOW (widget);
876 if (window->focus_widget)
878 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
881 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
882 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
888 gtk_window_enter_notify_event (GtkWidget *widget,
889 GdkEventCrossing *event)
891 g_return_val_if_fail (widget != NULL, FALSE);
892 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
893 g_return_val_if_fail (event != NULL, FALSE);
899 gtk_window_leave_notify_event (GtkWidget *widget,
900 GdkEventCrossing *event)
902 g_return_val_if_fail (widget != NULL, FALSE);
903 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
904 g_return_val_if_fail (event != NULL, FALSE);
910 gtk_window_focus_in_event (GtkWidget *widget,
911 GdkEventFocus *event)
914 GdkEventFocus fevent;
916 g_return_val_if_fail (widget != NULL, FALSE);
917 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
918 g_return_val_if_fail (event != NULL, FALSE);
920 /* It appears spurious focus in events can occur when
921 * the window is hidden. So we'll just check to see if
922 * the window is visible before actually handling the
925 if (GTK_WIDGET_VISIBLE (widget))
927 window = GTK_WINDOW (widget);
928 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
930 fevent.type = GDK_FOCUS_CHANGE;
931 fevent.window = window->focus_widget->window;
934 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
942 gtk_window_focus_out_event (GtkWidget *widget,
943 GdkEventFocus *event)
946 GdkEventFocus fevent;
948 g_return_val_if_fail (widget != NULL, FALSE);
949 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
950 g_return_val_if_fail (event != NULL, FALSE);
952 window = GTK_WINDOW (widget);
953 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
955 fevent.type = GDK_FOCUS_CHANGE;
956 fevent.window = window->focus_widget->window;
959 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
965 static GdkAtom atom_rcfiles = GDK_NONE;
968 gtk_window_read_rcfiles (GtkWidget *widget,
969 GdkEventClient *event)
971 GList *embedded_windows;
973 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
974 if (embedded_windows)
979 for(i = 0; i < 5; i++)
981 sev.data_format = 32;
982 sev.message_type = atom_rcfiles;
984 while (embedded_windows)
986 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
987 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
988 embedded_windows = embedded_windows->next;
992 if (gtk_rc_reparse_all ())
994 /* If the above returned true, some of our RC files are out
995 * of date, so we need to reset all our widgets. Our other
996 * toplevel windows will also get the message, but by
997 * then, the RC file will up to date, so we have to tell
1002 toplevels = gtk_container_get_toplevels();
1005 gtk_widget_reset_rc_styles (toplevels->data);
1006 toplevels = toplevels->next;
1012 gtk_window_client_event (GtkWidget *widget,
1013 GdkEventClient *event)
1015 g_return_val_if_fail (widget != NULL, FALSE);
1016 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1017 g_return_val_if_fail (event != NULL, FALSE);
1020 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
1022 if(event->message_type == atom_rcfiles)
1023 gtk_window_read_rcfiles (widget, event);
1029 gtk_window_check_resize (GtkContainer *container)
1033 g_return_if_fail (container != NULL);
1034 g_return_if_fail (GTK_IS_WINDOW (container));
1036 window = GTK_WINDOW (container);
1037 if (!window->handling_resize)
1039 if (GTK_WIDGET_VISIBLE (container))
1040 gtk_window_move_resize (window);
1042 GTK_CONTAINER (window)->need_resize = TRUE;
1046 /* FIXME: we leave container->resize_widgets set under some
1049 gtk_window_move_resize (GtkWindow *window)
1052 GtkContainer *container;
1057 gboolean needed_resize;
1058 gboolean size_changed;
1060 g_return_if_fail (window != NULL);
1061 g_return_if_fail (GTK_IS_WINDOW (window));
1063 widget = GTK_WIDGET (window);
1064 container = GTK_CONTAINER (widget);
1066 /* Remember old size, to know if we have to reset hints */
1067 width = widget->requisition.width;
1068 height = widget->requisition.height;
1069 gtk_widget_size_request (widget, &widget->requisition);
1071 size_changed = ((width != widget->requisition.width) ||
1072 (height != widget->requisition.height));
1076 gboolean saved_use_upos;
1078 saved_use_upos = window->use_uposition;
1079 gtk_window_set_hints (widget, &widget->requisition);
1080 window->use_uposition = saved_use_upos;
1085 width = widget->requisition.width;
1086 height = widget->requisition.height;
1088 if (window->use_uposition)
1089 switch (window->position)
1091 case GTK_WIN_POS_CENTER:
1092 x = (gdk_screen_width () - width) / 2;
1093 y = (gdk_screen_height () - height) / 2;
1094 gtk_widget_set_uposition (widget, x, y);
1096 case GTK_WIN_POS_MOUSE:
1097 gdk_window_get_pointer (NULL, &x, &y, NULL);
1102 screen_width = gdk_screen_width ();
1103 screen_height = gdk_screen_height ();
1107 else if (x > (screen_width - width))
1108 x = screen_width - width;
1112 else if (y > (screen_height - height))
1113 y = screen_height - height;
1115 gtk_widget_set_uposition (widget, x, y);
1119 /* Now, do the resizing */
1121 needed_resize = container->need_resize;
1122 container->need_resize = FALSE;
1124 if ((widget->requisition.width == 0) ||
1125 (widget->requisition.height == 0))
1127 widget->requisition.width = 200;
1128 widget->requisition.height = 200;
1131 if (!GTK_WIDGET_REALIZED (window))
1133 GtkAllocation allocation;
1137 allocation.width = widget->requisition.width;
1138 allocation.height = widget->requisition.height;
1140 gtk_widget_size_allocate (widget, &allocation);
1145 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1147 /* As an optimization, we don't try to get a new size from the
1148 * window manager if we asked for the same size last time and
1152 (((window->auto_shrink &&
1153 ((width != widget->requisition.width) ||
1154 (height != widget->requisition.height)))) ||
1155 ((width < widget->requisition.width) ||
1156 (height < widget->requisition.height))))
1158 window->resize_count += 1;
1159 if ((x != -1) && (y != -1))
1160 gdk_window_move_resize (widget->window, x, y,
1161 widget->requisition.width,
1162 widget->requisition.height);
1164 gdk_window_resize (widget->window,
1165 widget->requisition.width,
1166 widget->requisition.height);
1168 else if (needed_resize)
1170 /* The windows contents changed size while it was not
1171 * visible, so reallocate everything, since we didn't
1172 * keep track of what changed
1174 GtkAllocation allocation;
1178 allocation.width = widget->requisition.width;
1179 allocation.height = widget->requisition.height;
1181 gtk_widget_size_allocate (widget, &allocation);
1185 if ((x != -1) && (y != -1))
1186 gdk_window_move (widget->window, x, y);
1188 gtk_container_resize_children (GTK_CONTAINER (window));
1193 gtk_real_window_set_focus (GtkWindow *window,
1196 GdkEventFocus event;
1198 g_return_if_fail (window != NULL);
1199 g_return_if_fail (GTK_IS_WINDOW (window));
1201 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1204 if (window->focus_widget != focus)
1206 if (window->focus_widget)
1208 event.type = GDK_FOCUS_CHANGE;
1209 event.window = window->focus_widget->window;
1212 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1215 window->focus_widget = focus;
1217 if (window->focus_widget)
1219 event.type = GDK_FOCUS_CHANGE;
1220 event.window = window->focus_widget->window;
1223 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1229 gtk_window_set_hints (GtkWidget *widget,
1230 GtkRequisition *requisition)
1233 GtkWidgetAuxInfo *aux_info;
1237 g_return_if_fail (widget != NULL);
1238 g_return_if_fail (GTK_IS_WINDOW (widget));
1239 g_return_if_fail (requisition != NULL);
1241 if (GTK_WIDGET_REALIZED (widget))
1243 window = GTK_WINDOW (widget);
1249 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1250 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1254 flags |= GDK_HINT_POS;
1257 if (!window->allow_shrink)
1258 flags |= GDK_HINT_MIN_SIZE;
1259 if (!window->allow_grow)
1260 flags |= GDK_HINT_MAX_SIZE;
1262 gdk_window_set_hints (widget->window, ux, uy,
1263 requisition->width, requisition->height,
1264 requisition->width, requisition->height,
1267 if (window->use_uposition && (flags & GDK_HINT_POS))
1269 window->use_uposition = FALSE;
1270 gdk_window_move (widget->window, ux, uy);
1276 gtk_window_paint (GtkWidget *widget,
1279 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
1280 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
1284 gtk_window_expose (GtkWidget *widget,
1285 GdkEventExpose *event)
1287 g_return_val_if_fail (widget != NULL, FALSE);
1288 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1289 g_return_val_if_fail (event != NULL, FALSE);
1291 gtk_window_paint (widget, &event->area);
1293 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
1294 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
1300 gtk_window_draw (GtkWidget *widget,
1303 gtk_window_paint (widget, area);
1305 if (GTK_WIDGET_CLASS (parent_class)->draw)
1306 (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
1310 gtk_window_style_set (GtkWidget *widget,
1311 GtkStyle *previous_style)
1315 if (GTK_WIDGET_REALIZED (widget) &&
1316 !GTK_WIDGET_NO_WINDOW (widget))
1318 gtk_style_set_background (widget->style, widget->window, widget->state);
1322 area.width = widget->allocation.width;
1323 area.height = widget->allocation.height;
1324 gtk_window_draw(widget, &area);
1326 if (GTK_WIDGET_DRAWABLE (widget))
1327 gdk_window_clear (widget->window);