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"
44 typedef gint (*GtkWindowSignal1) (GtkObject *object,
50 typedef void (*GtkWindowSignal2) (GtkObject *object,
54 static void gtk_window_marshal_signal_1 (GtkObject *object,
58 static void gtk_window_marshal_signal_2 (GtkObject *object,
62 static void gtk_window_class_init (GtkWindowClass *klass);
63 static void gtk_window_init (GtkWindow *window);
64 static void gtk_window_set_arg (GtkWindow *window,
67 static void gtk_window_get_arg (GtkWindow *window,
70 static void gtk_window_destroy (GtkObject *object);
71 static void gtk_window_finalize (GtkObject *object);
72 static void gtk_window_show (GtkWidget *widget);
73 static void gtk_window_hide (GtkWidget *widget);
74 static void gtk_window_map (GtkWidget *widget);
75 static void gtk_window_unmap (GtkWidget *widget);
76 static void gtk_window_realize (GtkWidget *widget);
77 static void gtk_window_size_request (GtkWidget *widget,
78 GtkRequisition *requisition);
79 static void gtk_window_size_allocate (GtkWidget *widget,
80 GtkAllocation *allocation);
81 static gint gtk_window_expose_event (GtkWidget *widget,
82 GdkEventExpose *event);
83 static gint gtk_window_configure_event (GtkWidget *widget,
84 GdkEventConfigure *event);
85 static gint gtk_window_key_press_event (GtkWidget *widget,
87 static gint gtk_window_key_release_event (GtkWidget *widget,
89 static gint gtk_window_enter_notify_event (GtkWidget *widget,
90 GdkEventCrossing *event);
91 static gint gtk_window_leave_notify_event (GtkWidget *widget,
92 GdkEventCrossing *event);
93 static gint gtk_window_focus_in_event (GtkWidget *widget,
94 GdkEventFocus *event);
95 static gint gtk_window_focus_out_event (GtkWidget *widget,
96 GdkEventFocus *event);
97 static gint gtk_window_client_event (GtkWidget *widget,
98 GdkEventClient *event);
99 static gint gtk_window_need_resize (GtkContainer *container);
100 static gint gtk_real_window_move_resize (GtkWindow *window,
105 static void gtk_real_window_set_focus (GtkWindow *window,
107 static gint gtk_window_move_resize (GtkWidget *widget);
108 static void gtk_window_set_hints (GtkWidget *widget,
109 GtkRequisition *requisition);
110 static gint gtk_window_check_accelerator (GtkWindow *window,
114 static void gtk_window_read_rcfiles (GtkWidget *widget,
115 GdkEventClient *event);
118 static GtkBinClass *parent_class = NULL;
119 static guint window_signals[LAST_SIGNAL] = { 0 };
123 gtk_window_get_type (void)
125 static GtkType window_type = 0;
129 GtkTypeInfo window_info =
133 sizeof (GtkWindowClass),
134 (GtkClassInitFunc) gtk_window_class_init,
135 (GtkObjectInitFunc) gtk_window_init,
136 (GtkArgSetFunc) gtk_window_set_arg,
137 (GtkArgGetFunc) gtk_window_get_arg,
140 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
147 gtk_window_class_init (GtkWindowClass *klass)
149 GtkObjectClass *object_class;
150 GtkWidgetClass *widget_class;
151 GtkContainerClass *container_class;
153 object_class = (GtkObjectClass*) klass;
154 widget_class = (GtkWidgetClass*) klass;
155 container_class = (GtkContainerClass*) klass;
157 parent_class = gtk_type_class (gtk_bin_get_type ());
159 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
160 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
161 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
162 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
163 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
164 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_WIN_POS);
166 window_signals[MOVE_RESIZE] =
167 gtk_signal_new ("move_resize",
170 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
171 gtk_window_marshal_signal_1,
173 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
174 GTK_TYPE_INT, GTK_TYPE_INT);
176 window_signals[SET_FOCUS] =
177 gtk_signal_new ("set_focus",
180 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
181 gtk_window_marshal_signal_2,
185 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
187 object_class->destroy = gtk_window_destroy;
188 object_class->finalize = gtk_window_finalize;
190 widget_class->show = gtk_window_show;
191 widget_class->hide = gtk_window_hide;
192 widget_class->map = gtk_window_map;
193 widget_class->unmap = gtk_window_unmap;
194 widget_class->realize = gtk_window_realize;
195 widget_class->size_request = gtk_window_size_request;
196 widget_class->size_allocate = gtk_window_size_allocate;
197 widget_class->expose_event = gtk_window_expose_event;
198 widget_class->configure_event = gtk_window_configure_event;
199 widget_class->key_press_event = gtk_window_key_press_event;
200 widget_class->key_release_event = gtk_window_key_release_event;
201 widget_class->enter_notify_event = gtk_window_enter_notify_event;
202 widget_class->leave_notify_event = gtk_window_leave_notify_event;
203 widget_class->focus_in_event = gtk_window_focus_in_event;
204 widget_class->focus_out_event = gtk_window_focus_out_event;
205 widget_class->client_event = gtk_window_client_event;
207 container_class->need_resize = gtk_window_need_resize;
209 klass->move_resize = gtk_real_window_move_resize;
210 klass->set_focus = gtk_real_window_set_focus;
214 gtk_window_init (GtkWindow *window)
216 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
217 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
219 window->title = NULL;
220 window->wmclass_name = g_strdup (gdk_progname);
221 window->wmclass_class = g_strdup (gdk_progclass);
222 window->type = GTK_WINDOW_TOPLEVEL;
223 window->accelerator_tables = NULL;
224 window->focus_widget = NULL;
225 window->default_widget = NULL;
226 window->resize_count = 0;
227 window->need_resize = FALSE;
228 window->allow_shrink = FALSE;
229 window->allow_grow = TRUE;
230 window->auto_shrink = FALSE;
231 window->handling_resize = FALSE;
232 window->position = GTK_WIN_POS_NONE;
233 window->use_uposition = TRUE;
235 gtk_container_register_toplevel (GTK_CONTAINER (window));
239 gtk_window_set_arg (GtkWindow *window,
246 window->type = GTK_VALUE_ENUM (*arg);
249 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
251 case ARG_AUTO_SHRINK:
252 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
253 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
255 case ARG_ALLOW_SHRINK:
256 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
257 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
260 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
261 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
264 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
267 arg->type = GTK_TYPE_INVALID;
273 gtk_window_get_arg (GtkWindow *window,
280 GTK_VALUE_ENUM (*arg) = window->type;
283 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
285 case ARG_AUTO_SHRINK:
286 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
288 case ARG_ALLOW_SHRINK:
289 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
292 GTK_VALUE_BOOL (*arg) = window->allow_grow;
295 GTK_VALUE_ENUM (*arg) = window->position;
298 arg->type = GTK_TYPE_INVALID;
304 gtk_window_new (GtkWindowType type)
308 window = gtk_type_new (gtk_window_get_type ());
312 return GTK_WIDGET (window);
316 gtk_window_set_title (GtkWindow *window,
319 g_return_if_fail (window != NULL);
320 g_return_if_fail (GTK_IS_WINDOW (window));
323 g_free (window->title);
324 window->title = g_strdup (title);
326 if (GTK_WIDGET_REALIZED (window))
327 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
331 gtk_window_set_wmclass (GtkWindow *window,
333 gchar *wmclass_class)
335 g_return_if_fail (window != NULL);
336 g_return_if_fail (GTK_IS_WINDOW (window));
338 g_free (window->wmclass_name);
339 window->wmclass_name = g_strdup (wmclass_name);
341 g_free (window->wmclass_class);
342 window->wmclass_class = g_strdup (wmclass_class);
344 if (GTK_WIDGET_REALIZED (window))
345 g_warning ("shouldn't set wmclass after window is realized!\n");
349 gtk_window_set_focus (GtkWindow *window,
352 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
356 gtk_window_set_default (GtkWindow *window,
357 GtkWidget *default_widget)
359 g_return_if_fail (window != NULL);
360 g_return_if_fail (GTK_IS_WINDOW (window));
363 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
365 if (window->default_widget != default_widget)
367 if (window->default_widget)
369 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
370 gtk_widget_draw_default (window->default_widget);
373 window->default_widget = default_widget;
375 if (window->default_widget)
377 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
378 gtk_widget_draw_default (window->default_widget);
384 gtk_window_set_policy (GtkWindow *window,
389 g_return_if_fail (window != NULL);
390 g_return_if_fail (GTK_IS_WINDOW (window));
392 window->allow_shrink = (allow_shrink != FALSE);
393 window->allow_grow = (allow_grow != FALSE);
394 window->auto_shrink = (auto_shrink != FALSE);
396 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
400 gtk_window_add_accelerator_table (GtkWindow *window,
401 GtkAcceleratorTable *table)
403 g_return_if_fail (window != NULL);
404 g_return_if_fail (GTK_IS_WINDOW (window));
405 g_return_if_fail (table != NULL);
407 gtk_accelerator_table_ref (table);
408 window->accelerator_tables = g_list_prepend (window->accelerator_tables,
413 gtk_window_remove_accelerator_table (GtkWindow *window,
414 GtkAcceleratorTable *table)
418 g_return_if_fail (window != NULL);
419 g_return_if_fail (GTK_IS_WINDOW (window));
420 g_return_if_fail (table != NULL);
422 for (list = window->accelerator_tables; list; list = list->next)
424 if (list->data == table)
426 gtk_accelerator_table_unref (table);
427 window->accelerator_tables = g_list_remove_link (window->accelerator_tables, list);
428 g_list_free_1 (list);
435 gtk_window_position (GtkWindow *window,
436 GtkWindowPosition position)
438 g_return_if_fail (window != NULL);
439 g_return_if_fail (GTK_IS_WINDOW (window));
441 window->position = position;
445 gtk_window_activate_focus (GtkWindow *window)
447 g_return_val_if_fail (window != NULL, FALSE);
448 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
450 if (window->focus_widget)
452 gtk_widget_activate (window->focus_widget);
460 gtk_window_activate_default (GtkWindow *window)
462 g_return_val_if_fail (window != NULL, FALSE);
463 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
465 if (window->default_widget)
467 gtk_widget_activate (window->default_widget);
475 gtk_window_marshal_signal_1 (GtkObject *object,
480 GtkWindowSignal1 rfunc;
483 rfunc = (GtkWindowSignal1) func;
484 return_val = GTK_RETLOC_BOOL (args[4]);
486 *return_val = (* rfunc) (object,
487 GTK_VALUE_POINTER (args[0]),
488 GTK_VALUE_POINTER (args[1]),
489 GTK_VALUE_INT (args[2]),
490 GTK_VALUE_INT (args[3]),
495 gtk_window_marshal_signal_2 (GtkObject *object,
500 GtkWindowSignal2 rfunc;
502 rfunc = (GtkWindowSignal2) func;
504 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
508 gtk_window_destroy (GtkObject *object)
512 g_return_if_fail (object != NULL);
513 g_return_if_fail (GTK_IS_WINDOW (object));
515 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
517 for (list = GTK_WINDOW (object)->accelerator_tables; list; list = list->next)
518 gtk_accelerator_table_unref (list->data);
519 g_list_free (GTK_WINDOW (object)->accelerator_tables);
520 GTK_WINDOW (object)->accelerator_tables = NULL;
522 if (GTK_OBJECT_CLASS (parent_class)->destroy)
523 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
527 gtk_window_finalize (GtkObject *object)
531 g_return_if_fail (object != NULL);
532 g_return_if_fail (GTK_IS_WINDOW (object));
534 window = GTK_WINDOW (object);
535 g_free (window->title);
536 g_free (window->wmclass_name);
537 g_free (window->wmclass_class);
539 GTK_OBJECT_CLASS(parent_class)->finalize (object);
543 gtk_window_show (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_VISIBLE);
549 gtk_container_need_resize (GTK_CONTAINER (widget));
550 gtk_widget_map (widget);
554 gtk_window_hide (GtkWidget *widget)
556 g_return_if_fail (widget != NULL);
557 g_return_if_fail (GTK_IS_WINDOW (widget));
559 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
560 gtk_widget_unmap (widget);
564 gtk_window_map (GtkWidget *widget)
568 g_return_if_fail (widget != NULL);
569 g_return_if_fail (GTK_IS_WINDOW (widget));
571 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
573 window = GTK_WINDOW (widget);
575 if (window->bin.child &&
576 GTK_WIDGET_VISIBLE (window->bin.child) &&
577 !GTK_WIDGET_MAPPED (window->bin.child))
578 gtk_widget_map (window->bin.child);
580 gtk_window_set_hints (widget, &widget->requisition);
581 gdk_window_show (widget->window);
585 gtk_window_unmap (GtkWidget *widget)
589 g_return_if_fail (widget != NULL);
590 g_return_if_fail (GTK_IS_WINDOW (widget));
592 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
593 gdk_window_hide (widget->window);
595 window = GTK_WINDOW (widget);
596 window->use_uposition = TRUE;
600 gtk_window_realize (GtkWidget *widget)
603 GdkWindowAttr attributes;
604 gint attributes_mask;
606 g_return_if_fail (widget != NULL);
607 g_return_if_fail (GTK_IS_WINDOW (widget));
609 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
610 window = GTK_WINDOW (widget);
612 switch (window->type)
614 case GTK_WINDOW_TOPLEVEL:
615 attributes.window_type = GDK_WINDOW_TOPLEVEL;
617 case GTK_WINDOW_DIALOG:
618 attributes.window_type = GDK_WINDOW_DIALOG;
620 case GTK_WINDOW_POPUP:
621 attributes.window_type = GDK_WINDOW_TEMP;
625 attributes.title = window->title;
626 attributes.wmclass_name = window->wmclass_name;
627 attributes.wmclass_class = window->wmclass_class;
628 attributes.width = widget->allocation.width;
629 attributes.height = widget->allocation.height;
630 attributes.wclass = GDK_INPUT_OUTPUT;
631 attributes.visual = gtk_widget_get_visual (widget);
632 attributes.colormap = gtk_widget_get_colormap (widget);
633 attributes.event_mask = gtk_widget_get_events (widget);
634 attributes.event_mask |= (GDK_EXPOSURE_MASK |
636 GDK_ENTER_NOTIFY_MASK |
637 GDK_LEAVE_NOTIFY_MASK |
638 GDK_FOCUS_CHANGE_MASK |
641 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
642 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
643 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
645 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
646 gdk_window_set_user_data (widget->window, window);
648 widget->style = gtk_style_attach (widget->style, widget->window);
649 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
653 gtk_window_size_request (GtkWidget *widget,
654 GtkRequisition *requisition)
658 g_return_if_fail (widget != NULL);
659 g_return_if_fail (GTK_IS_WINDOW (widget));
660 g_return_if_fail (requisition != NULL);
662 window = GTK_WINDOW (widget);
664 if (window->bin.child)
666 requisition->width = GTK_CONTAINER (window)->border_width * 2;
667 requisition->height = GTK_CONTAINER (window)->border_width * 2;
669 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
671 requisition->width += window->bin.child->requisition.width;
672 requisition->height += window->bin.child->requisition.height;
676 if (!GTK_WIDGET_VISIBLE (window))
677 window->need_resize = TRUE;
682 gtk_window_size_allocate (GtkWidget *widget,
683 GtkAllocation *allocation)
686 GtkAllocation child_allocation;
688 g_return_if_fail (widget != NULL);
689 g_return_if_fail (GTK_IS_WINDOW (widget));
690 g_return_if_fail (allocation != NULL);
692 window = GTK_WINDOW (widget);
693 widget->allocation = *allocation;
695 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
697 child_allocation.x = GTK_CONTAINER (window)->border_width;
698 child_allocation.y = GTK_CONTAINER (window)->border_width;
699 child_allocation.width = allocation->width - child_allocation.x * 2;
700 child_allocation.height = allocation->height - child_allocation.y * 2;
702 gtk_widget_size_allocate (window->bin.child, &child_allocation);
707 gtk_window_expose_event (GtkWidget *widget,
708 GdkEventExpose *event)
710 g_return_val_if_fail (widget != NULL, FALSE);
711 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
712 g_return_val_if_fail (event != NULL, FALSE);
714 if (GTK_WIDGET_DRAWABLE (widget))
715 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
716 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
722 gtk_window_configure_event (GtkWidget *widget,
723 GdkEventConfigure *event)
726 GtkAllocation allocation;
728 g_return_val_if_fail (widget != NULL, FALSE);
729 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
730 g_return_val_if_fail (event != NULL, FALSE);
732 window = GTK_WINDOW (widget);
734 /* If the window was merely moved, do nothing */
735 if ((widget->allocation.width == event->width) &&
736 (widget->allocation.height == event->height) &&
737 (window->resize_count == 0))
740 window->handling_resize = TRUE;
744 allocation.width = event->width;
745 allocation.height = event->height;
747 gtk_widget_size_allocate (widget, &allocation);
749 if (window->bin.child &&
750 GTK_WIDGET_VISIBLE (window->bin.child) &&
751 !GTK_WIDGET_MAPPED (window->bin.child))
752 gtk_widget_map (window->bin.child);
754 if (window->resize_count > 0)
755 window->resize_count -= 1;
757 window->handling_resize = FALSE;
763 gtk_window_key_press_event (GtkWidget *widget,
767 GtkDirectionType direction = 0;
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);
774 window = GTK_WINDOW (widget);
777 if (window->focus_widget)
778 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
780 if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
785 switch (event->keyval)
788 if (window->focus_widget)
790 gtk_widget_activate (window->focus_widget);
796 if (window->default_widget)
798 gtk_widget_activate (window->default_widget);
801 else if (window->focus_widget)
803 gtk_widget_activate (window->focus_widget);
812 case GDK_ISO_Left_Tab:
813 switch (event->keyval)
816 direction = GTK_DIR_UP;
819 direction = GTK_DIR_DOWN;
822 direction = GTK_DIR_LEFT;
825 direction = GTK_DIR_RIGHT;
828 case GDK_ISO_Left_Tab:
829 if (event->state & GDK_SHIFT_MASK)
830 direction = GTK_DIR_TAB_BACKWARD;
832 direction = GTK_DIR_TAB_FORWARD;
835 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
838 gtk_container_focus (GTK_CONTAINER (widget), direction);
840 if (!GTK_CONTAINER (window)->focus_child)
841 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
852 gtk_window_key_release_event (GtkWidget *widget,
858 g_return_val_if_fail (widget != NULL, FALSE);
859 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
860 g_return_val_if_fail (event != NULL, FALSE);
862 window = GTK_WINDOW (widget);
864 if (window->focus_widget)
865 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
871 gtk_window_enter_notify_event (GtkWidget *widget,
872 GdkEventCrossing *event)
874 g_return_val_if_fail (widget != NULL, FALSE);
875 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
876 g_return_val_if_fail (event != NULL, FALSE);
882 gtk_window_leave_notify_event (GtkWidget *widget,
883 GdkEventCrossing *event)
885 g_return_val_if_fail (widget != NULL, FALSE);
886 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
887 g_return_val_if_fail (event != NULL, FALSE);
893 gtk_window_focus_in_event (GtkWidget *widget,
894 GdkEventFocus *event)
897 GdkEventFocus fevent;
899 g_return_val_if_fail (widget != NULL, FALSE);
900 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
901 g_return_val_if_fail (event != NULL, FALSE);
903 /* It appears spurious focus in events can occur when
904 * the window is hidden. So we'll just check to see if
905 * the window is visible before actually handling the
908 if (GTK_WIDGET_VISIBLE (widget))
910 window = GTK_WINDOW (widget);
911 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
913 fevent.type = GDK_FOCUS_CHANGE;
914 fevent.window = window->focus_widget->window;
917 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
925 gtk_window_focus_out_event (GtkWidget *widget,
926 GdkEventFocus *event)
929 GdkEventFocus fevent;
931 g_return_val_if_fail (widget != NULL, FALSE);
932 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
933 g_return_val_if_fail (event != NULL, FALSE);
935 window = GTK_WINDOW (widget);
936 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
938 fevent.type = GDK_FOCUS_CHANGE;
939 fevent.window = window->focus_widget->window;
942 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
949 gtk_window_read_rcfiles (GtkWidget *widget,
950 GdkEventClient *event)
954 if (gtk_rc_reparse_all ())
956 toplevels = gdk_window_get_toplevels();
960 gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
963 gtk_widget_reset_rc_styles (widget);
965 toplevels = toplevels->next;
967 g_list_free (toplevels);
972 gtk_window_client_event (GtkWidget *widget,
973 GdkEventClient *event)
975 static GdkAtom atom_rcfiles = GDK_NONE;
976 g_return_val_if_fail (widget != NULL, FALSE);
977 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
978 g_return_val_if_fail (event != NULL, FALSE);
981 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
983 if(event->message_type == atom_rcfiles)
984 gtk_window_read_rcfiles (widget, event);
990 gtk_window_need_resize (GtkContainer *container)
995 g_return_val_if_fail (container != NULL, FALSE);
996 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
1000 window = GTK_WINDOW (container);
1001 if (window->handling_resize)
1004 if (GTK_WIDGET_VISIBLE (container))
1006 window->need_resize = TRUE;
1007 return_val = gtk_window_move_resize (GTK_WIDGET (window));
1008 window->need_resize = FALSE;
1015 gtk_real_window_move_resize (GtkWindow *window,
1023 g_return_val_if_fail (window != NULL, FALSE);
1024 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1025 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
1027 widget = GTK_WIDGET (window);
1029 if ((widget->requisition.width == 0) ||
1030 (widget->requisition.height == 0))
1032 widget->requisition.width = 200;
1033 widget->requisition.height = 200;
1036 if (!GTK_WIDGET_REALIZED (window))
1038 GtkAllocation allocation;
1042 allocation.width = widget->requisition.width;
1043 allocation.height = widget->requisition.height;
1045 gtk_widget_size_allocate (widget, &allocation);
1050 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1052 if ((window->auto_shrink &&
1053 ((width != widget->requisition.width) ||
1054 (height != widget->requisition.height))) ||
1055 (width < widget->requisition.width) ||
1056 (height < widget->requisition.height))
1058 window->resize_count += 1;
1059 if ((*x != -1) && (*y != -1))
1060 gdk_window_move_resize (widget->window, *x, *y,
1061 widget->requisition.width,
1062 widget->requisition.height);
1064 gdk_window_resize (widget->window,
1065 widget->requisition.width,
1066 widget->requisition.height);
1070 /* The window hasn't changed size but one of its children
1071 * queued a resize request. Which means that the allocation
1072 * is not sufficient for the requisition of some child.
1073 * We've already performed a size request at this point,
1074 * so we simply need to run through the list of resize
1075 * widgets and reallocate their sizes appropriately. We
1076 * make the optimization of not performing reallocation
1077 * for a widget who also has a parent in the resize widgets
1078 * list. GTK_RESIZE_NEEDED is used for flagging those
1079 * parents inside this function.
1081 GSList *resize_widgets;
1082 GSList *resize_containers;
1085 if ((*x != -1) && (*y != -1))
1086 gdk_window_move (widget->window, *x, *y);
1088 resize_widgets = GTK_CONTAINER (window)->resize_widgets;
1089 GTK_CONTAINER (window)->resize_widgets = NULL;
1091 for (node = resize_widgets; node; node = node->next)
1093 widget = node->data;
1095 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1097 while (widget && widget->parent &&
1098 ((widget->allocation.width < widget->requisition.width) ||
1099 (widget->allocation.height < widget->requisition.height)))
1100 widget = widget->parent;
1102 GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
1103 node->data = widget;
1106 resize_containers = NULL;
1108 for (node = resize_widgets; node; node = node->next)
1110 GtkWidget *resize_container;
1112 widget = node->data;
1114 if (!GTK_WIDGET_RESIZE_NEEDED (widget))
1117 resize_container = widget->parent;
1119 if (resize_container)
1121 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1122 widget = resize_container->parent;
1126 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1128 GTK_PRIVATE_UNSET_FLAG (resize_container, GTK_RESIZE_NEEDED);
1129 resize_container = widget;
1131 widget = widget->parent;
1135 resize_container = widget;
1137 if (!g_slist_find (resize_containers, resize_container))
1138 resize_containers = g_slist_prepend (resize_containers,
1141 g_slist_free (resize_widgets);
1143 for (node = resize_containers; node; node = node->next)
1145 widget = node->data;
1147 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1148 gtk_widget_size_allocate (widget, &widget->allocation);
1149 gtk_widget_queue_draw (widget);
1151 g_slist_free (resize_containers);
1158 gtk_window_move_resize (GtkWidget *widget)
1167 g_return_val_if_fail (widget != NULL, FALSE);
1168 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1170 window = GTK_WINDOW (widget);
1173 /* Remember old size, to know if we have to reset hints */
1174 width = widget->requisition.width;
1175 height = widget->requisition.height;
1176 gtk_widget_size_request (widget, &widget->requisition);
1178 if ((width != widget->requisition.width ||
1179 height != widget->requisition.height))
1180 gtk_window_set_hints (widget, &widget->requisition);
1184 width = widget->requisition.width;
1185 height = widget->requisition.height;
1187 if (window->use_uposition)
1188 switch (window->position)
1190 case GTK_WIN_POS_CENTER:
1191 x = (gdk_screen_width () - width) / 2;
1192 y = (gdk_screen_height () - height) / 2;
1193 gtk_widget_set_uposition (widget, x, y);
1195 case GTK_WIN_POS_MOUSE:
1196 gdk_window_get_pointer (NULL, &x, &y, NULL);
1201 screen_width = gdk_screen_width ();
1202 screen_height = gdk_screen_height ();
1206 else if (x > (screen_width - width))
1207 x = screen_width - width;
1211 else if (y > (screen_height - height))
1212 y = screen_height - height;
1214 gtk_widget_set_uposition (widget, x, y);
1218 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1219 &x, &y, width, height, &return_val);
1225 gtk_real_window_set_focus (GtkWindow *window,
1228 GdkEventFocus event;
1230 g_return_if_fail (window != NULL);
1231 g_return_if_fail (GTK_IS_WINDOW (window));
1233 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1236 if (window->focus_widget != focus)
1238 if (window->focus_widget)
1240 event.type = GDK_FOCUS_CHANGE;
1241 event.window = window->focus_widget->window;
1244 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1247 window->focus_widget = focus;
1249 if (window->focus_widget)
1251 event.type = GDK_FOCUS_CHANGE;
1252 event.window = window->focus_widget->window;
1255 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1261 gtk_window_set_hints (GtkWidget *widget,
1262 GtkRequisition *requisition)
1265 GtkWidgetAuxInfo *aux_info;
1269 g_return_if_fail (widget != NULL);
1270 g_return_if_fail (GTK_IS_WINDOW (widget));
1271 g_return_if_fail (requisition != NULL);
1273 if (GTK_WIDGET_REALIZED (widget))
1275 window = GTK_WINDOW (widget);
1281 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1282 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1286 flags |= GDK_HINT_POS;
1289 if (!window->allow_shrink)
1290 flags |= GDK_HINT_MIN_SIZE;
1291 if (!window->allow_grow)
1292 flags |= GDK_HINT_MAX_SIZE;
1294 gdk_window_set_hints (widget->window, ux, uy,
1295 requisition->width, requisition->height,
1296 requisition->width, requisition->height,
1299 if (window->use_uposition && (flags & GDK_HINT_POS))
1301 window->use_uposition = FALSE;
1302 gdk_window_move (widget->window, ux, uy);
1308 gtk_window_check_accelerator (GtkWindow *window,
1312 GtkAcceleratorTable *table;
1315 if ((key >= 0x20) && (key <= 0xFF))
1317 tmp = window->accelerator_tables;
1323 if (gtk_accelerator_table_check (table, key, mods))
1327 if (gtk_accelerator_table_check (NULL, key, mods))