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 typedef gint (*GtkWindowSignal1) (GtkObject *object,
51 typedef void (*GtkWindowSignal2) (GtkObject *object,
55 static void gtk_window_marshal_signal_1 (GtkObject *object,
59 static void gtk_window_marshal_signal_2 (GtkObject *object,
63 static void gtk_window_class_init (GtkWindowClass *klass);
64 static void gtk_window_init (GtkWindow *window);
65 static void gtk_window_set_arg (GtkWindow *window,
68 static void gtk_window_get_arg (GtkWindow *window,
71 static void gtk_window_destroy (GtkObject *object);
72 static void gtk_window_finalize (GtkObject *object);
73 static void gtk_window_show (GtkWidget *widget);
74 static void gtk_window_hide (GtkWidget *widget);
75 static void gtk_window_map (GtkWidget *widget);
76 static void gtk_window_unmap (GtkWidget *widget);
77 static void gtk_window_realize (GtkWidget *widget);
78 static void gtk_window_size_request (GtkWidget *widget,
79 GtkRequisition *requisition);
80 static void gtk_window_size_allocate (GtkWidget *widget,
81 GtkAllocation *allocation);
82 static gint gtk_window_expose_event (GtkWidget *widget,
83 GdkEventExpose *event);
84 static gint gtk_window_configure_event (GtkWidget *widget,
85 GdkEventConfigure *event);
86 static gint gtk_window_key_press_event (GtkWidget *widget,
88 static gint gtk_window_key_release_event (GtkWidget *widget,
90 static gint gtk_window_enter_notify_event (GtkWidget *widget,
91 GdkEventCrossing *event);
92 static gint gtk_window_leave_notify_event (GtkWidget *widget,
93 GdkEventCrossing *event);
94 static gint gtk_window_focus_in_event (GtkWidget *widget,
95 GdkEventFocus *event);
96 static gint gtk_window_focus_out_event (GtkWidget *widget,
97 GdkEventFocus *event);
98 static gint gtk_window_client_event (GtkWidget *widget,
99 GdkEventClient *event);
100 static gint gtk_window_need_resize (GtkContainer *container);
101 static gint gtk_real_window_move_resize (GtkWindow *window,
106 static void gtk_real_window_set_focus (GtkWindow *window,
108 static gint gtk_window_move_resize (GtkWidget *widget);
109 static void gtk_window_set_hints (GtkWidget *widget,
110 GtkRequisition *requisition);
112 static void gtk_window_read_rcfiles (GtkWidget *widget,
113 GdkEventClient *event);
116 static GtkBinClass *parent_class = NULL;
117 static guint window_signals[LAST_SIGNAL] = { 0 };
121 gtk_window_get_type (void)
123 static GtkType window_type = 0;
127 GtkTypeInfo window_info =
131 sizeof (GtkWindowClass),
132 (GtkClassInitFunc) gtk_window_class_init,
133 (GtkObjectInitFunc) gtk_window_init,
134 (GtkArgSetFunc) gtk_window_set_arg,
135 (GtkArgGetFunc) gtk_window_get_arg,
138 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
145 gtk_window_class_init (GtkWindowClass *klass)
147 GtkObjectClass *object_class;
148 GtkWidgetClass *widget_class;
149 GtkContainerClass *container_class;
151 object_class = (GtkObjectClass*) klass;
152 widget_class = (GtkWidgetClass*) klass;
153 container_class = (GtkContainerClass*) klass;
155 parent_class = gtk_type_class (gtk_bin_get_type ());
157 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
158 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
159 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
160 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
161 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
162 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_WIN_POS);
164 window_signals[MOVE_RESIZE] =
165 gtk_signal_new ("move_resize",
168 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
169 gtk_window_marshal_signal_1,
171 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
172 GTK_TYPE_INT, GTK_TYPE_INT);
174 window_signals[SET_FOCUS] =
175 gtk_signal_new ("set_focus",
178 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
179 gtk_window_marshal_signal_2,
183 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
185 object_class->destroy = gtk_window_destroy;
186 object_class->finalize = gtk_window_finalize;
188 widget_class->show = gtk_window_show;
189 widget_class->hide = gtk_window_hide;
190 widget_class->map = gtk_window_map;
191 widget_class->unmap = gtk_window_unmap;
192 widget_class->realize = gtk_window_realize;
193 widget_class->size_request = gtk_window_size_request;
194 widget_class->size_allocate = gtk_window_size_allocate;
195 widget_class->expose_event = gtk_window_expose_event;
196 widget_class->configure_event = gtk_window_configure_event;
197 widget_class->key_press_event = gtk_window_key_press_event;
198 widget_class->key_release_event = gtk_window_key_release_event;
199 widget_class->enter_notify_event = gtk_window_enter_notify_event;
200 widget_class->leave_notify_event = gtk_window_leave_notify_event;
201 widget_class->focus_in_event = gtk_window_focus_in_event;
202 widget_class->focus_out_event = gtk_window_focus_out_event;
203 widget_class->client_event = gtk_window_client_event;
205 container_class->need_resize = gtk_window_need_resize;
207 klass->move_resize = gtk_real_window_move_resize;
208 klass->set_focus = gtk_real_window_set_focus;
212 gtk_window_init (GtkWindow *window)
214 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
215 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
217 window->title = NULL;
218 window->wmclass_name = g_strdup (gdk_progname);
219 window->wmclass_class = g_strdup (gdk_progclass);
220 window->type = GTK_WINDOW_TOPLEVEL;
221 window->focus_widget = NULL;
222 window->default_widget = NULL;
223 window->resize_count = 0;
224 window->need_resize = FALSE;
225 window->allow_shrink = FALSE;
226 window->allow_grow = TRUE;
227 window->auto_shrink = FALSE;
228 window->handling_resize = FALSE;
229 window->position = GTK_WIN_POS_NONE;
230 window->use_uposition = TRUE;
232 gtk_container_register_toplevel (GTK_CONTAINER (window));
236 gtk_window_set_arg (GtkWindow *window,
243 window->type = GTK_VALUE_ENUM (*arg);
246 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
248 case ARG_AUTO_SHRINK:
249 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
250 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
252 case ARG_ALLOW_SHRINK:
253 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
254 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
257 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
258 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
261 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
264 arg->type = GTK_TYPE_INVALID;
270 gtk_window_get_arg (GtkWindow *window,
277 GTK_VALUE_ENUM (*arg) = window->type;
280 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
282 case ARG_AUTO_SHRINK:
283 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
285 case ARG_ALLOW_SHRINK:
286 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
289 GTK_VALUE_BOOL (*arg) = window->allow_grow;
292 GTK_VALUE_ENUM (*arg) = window->position;
295 arg->type = GTK_TYPE_INVALID;
301 gtk_window_new (GtkWindowType type)
305 window = gtk_type_new (gtk_window_get_type ());
309 return GTK_WIDGET (window);
313 gtk_window_set_title (GtkWindow *window,
316 g_return_if_fail (window != NULL);
317 g_return_if_fail (GTK_IS_WINDOW (window));
320 g_free (window->title);
321 window->title = g_strdup (title);
323 if (GTK_WIDGET_REALIZED (window))
324 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
328 gtk_window_set_wmclass (GtkWindow *window,
329 const gchar *wmclass_name,
330 const gchar *wmclass_class)
332 g_return_if_fail (window != NULL);
333 g_return_if_fail (GTK_IS_WINDOW (window));
335 g_free (window->wmclass_name);
336 window->wmclass_name = g_strdup (wmclass_name);
338 g_free (window->wmclass_class);
339 window->wmclass_class = g_strdup (wmclass_class);
341 if (GTK_WIDGET_REALIZED (window))
342 g_warning ("shouldn't set wmclass after window is realized!\n");
346 gtk_window_set_focus (GtkWindow *window,
349 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
353 gtk_window_set_default (GtkWindow *window,
354 GtkWidget *default_widget)
356 g_return_if_fail (window != NULL);
357 g_return_if_fail (GTK_IS_WINDOW (window));
360 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
362 if (window->default_widget != default_widget)
364 if (window->default_widget)
366 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
367 gtk_widget_draw_default (window->default_widget);
370 window->default_widget = default_widget;
372 if (window->default_widget)
374 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
375 gtk_widget_draw_default (window->default_widget);
381 gtk_window_set_policy (GtkWindow *window,
386 g_return_if_fail (window != NULL);
387 g_return_if_fail (GTK_IS_WINDOW (window));
389 window->allow_shrink = (allow_shrink != FALSE);
390 window->allow_grow = (allow_grow != FALSE);
391 window->auto_shrink = (auto_shrink != FALSE);
393 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
397 gtk_window_add_accel_group (GtkWindow *window,
398 GtkAccelGroup *accel_group)
400 g_return_if_fail (window != NULL);
401 g_return_if_fail (GTK_IS_WINDOW (window));
402 g_return_if_fail (accel_group != NULL);
404 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
408 gtk_window_remove_accel_group (GtkWindow *window,
409 GtkAccelGroup *accel_group)
411 g_return_if_fail (window != NULL);
412 g_return_if_fail (GTK_IS_WINDOW (window));
413 g_return_if_fail (accel_group != NULL);
415 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
419 gtk_window_position (GtkWindow *window,
420 GtkWindowPosition position)
422 g_return_if_fail (window != NULL);
423 g_return_if_fail (GTK_IS_WINDOW (window));
425 window->position = position;
429 gtk_window_activate_focus (GtkWindow *window)
431 g_return_val_if_fail (window != NULL, FALSE);
432 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
434 if (window->focus_widget)
436 gtk_widget_activate (window->focus_widget);
444 gtk_window_activate_default (GtkWindow *window)
446 g_return_val_if_fail (window != NULL, FALSE);
447 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
449 if (window->default_widget)
451 gtk_widget_activate (window->default_widget);
459 gtk_window_marshal_signal_1 (GtkObject *object,
464 GtkWindowSignal1 rfunc;
467 rfunc = (GtkWindowSignal1) func;
468 return_val = GTK_RETLOC_BOOL (args[4]);
470 *return_val = (* rfunc) (object,
471 GTK_VALUE_POINTER (args[0]),
472 GTK_VALUE_POINTER (args[1]),
473 GTK_VALUE_INT (args[2]),
474 GTK_VALUE_INT (args[3]),
479 gtk_window_marshal_signal_2 (GtkObject *object,
484 GtkWindowSignal2 rfunc;
486 rfunc = (GtkWindowSignal2) func;
488 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
492 gtk_window_destroy (GtkObject *object)
494 g_return_if_fail (object != NULL);
495 g_return_if_fail (GTK_IS_WINDOW (object));
497 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
499 if (GTK_OBJECT_CLASS (parent_class)->destroy)
500 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
504 gtk_window_finalize (GtkObject *object)
508 g_return_if_fail (object != NULL);
509 g_return_if_fail (GTK_IS_WINDOW (object));
511 window = GTK_WINDOW (object);
512 g_free (window->title);
513 g_free (window->wmclass_name);
514 g_free (window->wmclass_class);
516 GTK_OBJECT_CLASS(parent_class)->finalize (object);
520 gtk_window_show (GtkWidget *widget)
522 g_return_if_fail (widget != NULL);
523 g_return_if_fail (GTK_IS_WINDOW (widget));
525 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
526 gtk_container_need_resize (GTK_CONTAINER (widget));
527 gtk_widget_map (widget);
531 gtk_window_hide (GtkWidget *widget)
533 g_return_if_fail (widget != NULL);
534 g_return_if_fail (GTK_IS_WINDOW (widget));
536 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
537 gtk_widget_unmap (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);
630 gtk_window_size_request (GtkWidget *widget,
631 GtkRequisition *requisition)
635 g_return_if_fail (widget != NULL);
636 g_return_if_fail (GTK_IS_WINDOW (widget));
637 g_return_if_fail (requisition != NULL);
639 window = GTK_WINDOW (widget);
641 if (window->bin.child)
643 requisition->width = GTK_CONTAINER (window)->border_width * 2;
644 requisition->height = GTK_CONTAINER (window)->border_width * 2;
646 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
648 requisition->width += window->bin.child->requisition.width;
649 requisition->height += window->bin.child->requisition.height;
653 if (!GTK_WIDGET_VISIBLE (window))
654 window->need_resize = TRUE;
659 gtk_window_size_allocate (GtkWidget *widget,
660 GtkAllocation *allocation)
663 GtkAllocation child_allocation;
665 g_return_if_fail (widget != NULL);
666 g_return_if_fail (GTK_IS_WINDOW (widget));
667 g_return_if_fail (allocation != NULL);
669 window = GTK_WINDOW (widget);
670 widget->allocation = *allocation;
672 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
674 child_allocation.x = GTK_CONTAINER (window)->border_width;
675 child_allocation.y = GTK_CONTAINER (window)->border_width;
676 child_allocation.width = allocation->width - child_allocation.x * 2;
677 child_allocation.height = allocation->height - child_allocation.y * 2;
679 gtk_widget_size_allocate (window->bin.child, &child_allocation);
684 gtk_window_expose_event (GtkWidget *widget,
685 GdkEventExpose *event)
687 g_return_val_if_fail (widget != NULL, FALSE);
688 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
689 g_return_val_if_fail (event != NULL, FALSE);
691 if (GTK_WIDGET_DRAWABLE (widget))
692 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
693 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
699 gtk_window_configure_event (GtkWidget *widget,
700 GdkEventConfigure *event)
703 GtkAllocation allocation;
705 g_return_val_if_fail (widget != NULL, FALSE);
706 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
707 g_return_val_if_fail (event != NULL, FALSE);
709 window = GTK_WINDOW (widget);
711 /* If the window was merely moved, do nothing */
712 if ((widget->allocation.width == event->width) &&
713 (widget->allocation.height == event->height) &&
714 (window->resize_count == 0))
717 window->handling_resize = TRUE;
721 allocation.width = event->width;
722 allocation.height = event->height;
724 gtk_widget_size_allocate (widget, &allocation);
726 if (window->bin.child &&
727 GTK_WIDGET_VISIBLE (window->bin.child) &&
728 !GTK_WIDGET_MAPPED (window->bin.child))
729 gtk_widget_map (window->bin.child);
731 if (window->resize_count > 0)
732 window->resize_count -= 1;
734 window->handling_resize = FALSE;
740 gtk_window_key_press_event (GtkWidget *widget,
744 GtkDirectionType direction = 0;
747 g_return_val_if_fail (widget != NULL, FALSE);
748 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
749 g_return_val_if_fail (event != NULL, FALSE);
751 window = GTK_WINDOW (widget);
755 if (window->focus_widget)
757 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
760 handled = gtk_bindings_activate (GTK_OBJECT (window->focus_widget),
761 event->keyval, event->state);
765 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
769 switch (event->keyval)
772 if (window->focus_widget)
774 gtk_widget_activate (window->focus_widget);
780 if (window->default_widget)
782 gtk_widget_activate (window->default_widget);
785 else if (window->focus_widget)
787 gtk_widget_activate (window->focus_widget);
796 case GDK_ISO_Left_Tab:
797 switch (event->keyval)
800 direction = GTK_DIR_UP;
803 direction = GTK_DIR_DOWN;
806 direction = GTK_DIR_LEFT;
809 direction = GTK_DIR_RIGHT;
812 case GDK_ISO_Left_Tab:
813 if (event->state & GDK_SHIFT_MASK)
814 direction = GTK_DIR_TAB_BACKWARD;
816 direction = GTK_DIR_TAB_FORWARD;
819 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
822 gtk_container_focus (GTK_CONTAINER (widget), direction);
824 if (!GTK_CONTAINER (window)->focus_child)
825 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
836 gtk_window_key_release_event (GtkWidget *widget,
842 g_return_val_if_fail (widget != NULL, FALSE);
843 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
844 g_return_val_if_fail (event != NULL, FALSE);
846 window = GTK_WINDOW (widget);
848 if (window->focus_widget)
850 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
853 handled = gtk_bindings_activate (GTK_OBJECT (window->focus_widget),
854 event->keyval, event->state | GDK_AFTER_MASK);
861 gtk_window_enter_notify_event (GtkWidget *widget,
862 GdkEventCrossing *event)
864 g_return_val_if_fail (widget != NULL, FALSE);
865 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
866 g_return_val_if_fail (event != NULL, FALSE);
872 gtk_window_leave_notify_event (GtkWidget *widget,
873 GdkEventCrossing *event)
875 g_return_val_if_fail (widget != NULL, FALSE);
876 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
877 g_return_val_if_fail (event != NULL, FALSE);
883 gtk_window_focus_in_event (GtkWidget *widget,
884 GdkEventFocus *event)
887 GdkEventFocus fevent;
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 /* It appears spurious focus in events can occur when
894 * the window is hidden. So we'll just check to see if
895 * the window is visible before actually handling the
898 if (GTK_WIDGET_VISIBLE (widget))
900 window = GTK_WINDOW (widget);
901 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
903 fevent.type = GDK_FOCUS_CHANGE;
904 fevent.window = window->focus_widget->window;
907 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
915 gtk_window_focus_out_event (GtkWidget *widget,
916 GdkEventFocus *event)
919 GdkEventFocus fevent;
921 g_return_val_if_fail (widget != NULL, FALSE);
922 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
923 g_return_val_if_fail (event != NULL, FALSE);
925 window = GTK_WINDOW (widget);
926 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
928 fevent.type = GDK_FOCUS_CHANGE;
929 fevent.window = window->focus_widget->window;
932 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
939 gtk_window_read_rcfiles (GtkWidget *widget,
940 GdkEventClient *event)
944 if (gtk_rc_reparse_all ())
946 toplevels = gdk_window_get_toplevels();
950 gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
953 gtk_widget_reset_rc_styles (widget);
955 toplevels = toplevels->next;
957 g_list_free (toplevels);
962 gtk_window_client_event (GtkWidget *widget,
963 GdkEventClient *event)
965 static GdkAtom atom_rcfiles = GDK_NONE;
966 g_return_val_if_fail (widget != NULL, FALSE);
967 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
968 g_return_val_if_fail (event != NULL, FALSE);
971 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
973 if(event->message_type == atom_rcfiles)
974 gtk_window_read_rcfiles (widget, event);
980 gtk_window_need_resize (GtkContainer *container)
985 g_return_val_if_fail (container != NULL, FALSE);
986 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
990 window = GTK_WINDOW (container);
991 if (window->handling_resize)
994 if (GTK_WIDGET_VISIBLE (container))
995 return_val = gtk_window_move_resize (GTK_WIDGET (window));
997 window->need_resize = TRUE;
1003 gtk_real_window_move_resize (GtkWindow *window,
1010 gboolean needed_resize;
1012 g_return_val_if_fail (window != NULL, FALSE);
1013 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1014 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
1016 widget = GTK_WIDGET (window);
1018 needed_resize = window->need_resize;
1019 window->need_resize = FALSE;
1021 if ((widget->requisition.width == 0) ||
1022 (widget->requisition.height == 0))
1024 widget->requisition.width = 200;
1025 widget->requisition.height = 200;
1028 if (!GTK_WIDGET_REALIZED (window))
1030 GtkAllocation allocation;
1034 allocation.width = widget->requisition.width;
1035 allocation.height = widget->requisition.height;
1037 gtk_widget_size_allocate (widget, &allocation);
1042 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1044 if ((window->auto_shrink &&
1045 ((width != widget->requisition.width) ||
1046 (height != widget->requisition.height))) ||
1047 (width < widget->requisition.width) ||
1048 (height < widget->requisition.height))
1050 window->resize_count += 1;
1051 if ((*x != -1) && (*y != -1))
1052 gdk_window_move_resize (widget->window, *x, *y,
1053 widget->requisition.width,
1054 widget->requisition.height);
1056 gdk_window_resize (widget->window,
1057 widget->requisition.width,
1058 widget->requisition.height);
1060 else if (needed_resize)
1062 /* The windows contents changed size while it was not
1063 * visible, so reallocate everything, since we didn't
1064 * keep track of what changed
1066 GtkAllocation allocation;
1070 allocation.width = widget->requisition.width;
1071 allocation.height = widget->requisition.height;
1073 gtk_widget_size_allocate (widget, &allocation);
1077 /* The window hasn't changed size but one of its children
1078 * queued a resize request. Which means that the allocation
1079 * is not sufficient for the requisition of some child.
1080 * We've already performed a size request at this point,
1081 * so we simply need to run through the list of resize
1082 * widgets and reallocate their sizes appropriately. We
1083 * make the optimization of not performing reallocation
1084 * for a widget who also has a parent in the resize widgets
1085 * list. GTK_RESIZE_NEEDED is used for flagging those
1086 * parents inside this function.
1088 GSList *resize_widgets;
1089 GSList *resize_containers;
1092 if ((*x != -1) && (*y != -1))
1093 gdk_window_move (widget->window, *x, *y);
1095 resize_widgets = GTK_CONTAINER (window)->resize_widgets;
1096 GTK_CONTAINER (window)->resize_widgets = NULL;
1098 for (node = resize_widgets; node; node = node->next)
1100 widget = node->data;
1102 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1104 while (widget && widget->parent &&
1105 ((widget->allocation.width < widget->requisition.width) ||
1106 (widget->allocation.height < widget->requisition.height)))
1107 widget = widget->parent;
1109 GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
1110 node->data = widget;
1113 resize_containers = NULL;
1115 for (node = resize_widgets; node; node = node->next)
1117 GtkWidget *resize_container;
1119 widget = node->data;
1121 if (!GTK_WIDGET_RESIZE_NEEDED (widget))
1124 resize_container = widget->parent;
1126 if (resize_container)
1128 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1129 widget = resize_container->parent;
1133 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1135 GTK_PRIVATE_UNSET_FLAG (resize_container, GTK_RESIZE_NEEDED);
1136 resize_container = widget;
1138 widget = widget->parent;
1142 resize_container = widget;
1144 if (!g_slist_find (resize_containers, resize_container))
1145 resize_containers = g_slist_prepend (resize_containers,
1148 g_slist_free (resize_widgets);
1150 for (node = resize_containers; node; node = node->next)
1152 widget = node->data;
1154 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1155 gtk_widget_size_allocate (widget, &widget->allocation);
1156 gtk_widget_queue_draw (widget);
1158 g_slist_free (resize_containers);
1165 gtk_window_move_resize (GtkWidget *widget)
1174 g_return_val_if_fail (widget != NULL, FALSE);
1175 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1177 window = GTK_WINDOW (widget);
1180 /* Remember old size, to know if we have to reset hints */
1181 width = widget->requisition.width;
1182 height = widget->requisition.height;
1183 gtk_widget_size_request (widget, &widget->requisition);
1185 if ((width != widget->requisition.width ||
1186 height != widget->requisition.height))
1187 gtk_window_set_hints (widget, &widget->requisition);
1191 width = widget->requisition.width;
1192 height = widget->requisition.height;
1194 if (window->use_uposition)
1195 switch (window->position)
1197 case GTK_WIN_POS_CENTER:
1198 x = (gdk_screen_width () - width) / 2;
1199 y = (gdk_screen_height () - height) / 2;
1200 gtk_widget_set_uposition (widget, x, y);
1202 case GTK_WIN_POS_MOUSE:
1203 gdk_window_get_pointer (NULL, &x, &y, NULL);
1208 screen_width = gdk_screen_width ();
1209 screen_height = gdk_screen_height ();
1213 else if (x > (screen_width - width))
1214 x = screen_width - width;
1218 else if (y > (screen_height - height))
1219 y = screen_height - height;
1221 gtk_widget_set_uposition (widget, x, y);
1225 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1226 &x, &y, width, height, &return_val);
1232 gtk_real_window_set_focus (GtkWindow *window,
1235 GdkEventFocus event;
1237 g_return_if_fail (window != NULL);
1238 g_return_if_fail (GTK_IS_WINDOW (window));
1240 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1243 if (window->focus_widget != focus)
1245 if (window->focus_widget)
1247 event.type = GDK_FOCUS_CHANGE;
1248 event.window = window->focus_widget->window;
1251 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1254 window->focus_widget = focus;
1256 if (window->focus_widget)
1258 event.type = GDK_FOCUS_CHANGE;
1259 event.window = window->focus_widget->window;
1262 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1268 gtk_window_set_hints (GtkWidget *widget,
1269 GtkRequisition *requisition)
1272 GtkWidgetAuxInfo *aux_info;
1276 g_return_if_fail (widget != NULL);
1277 g_return_if_fail (GTK_IS_WINDOW (widget));
1278 g_return_if_fail (requisition != NULL);
1280 if (GTK_WIDGET_REALIZED (widget))
1282 window = GTK_WINDOW (widget);
1288 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1289 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1293 flags |= GDK_HINT_POS;
1296 if (!window->allow_shrink)
1297 flags |= GDK_HINT_MIN_SIZE;
1298 if (!window->allow_grow)
1299 flags |= GDK_HINT_MAX_SIZE;
1301 gdk_window_set_hints (widget->window, ux, uy,
1302 requisition->width, requisition->height,
1303 requisition->width, requisition->height,
1306 if (window->use_uposition && (flags & GDK_HINT_POS))
1308 window->use_uposition = FALSE;
1309 gdk_window_move (widget->window, ux, uy);