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 "gtkprivate.h"
24 #include "gtksignal.h"
25 #include "gtkwindow.h"
42 typedef gint (*GtkWindowSignal1) (GtkObject *object,
48 typedef void (*GtkWindowSignal2) (GtkObject *object,
52 static void gtk_window_marshal_signal_1 (GtkObject *object,
56 static void gtk_window_marshal_signal_2 (GtkObject *object,
60 static void gtk_window_class_init (GtkWindowClass *klass);
61 static void gtk_window_init (GtkWindow *window);
62 static void gtk_window_set_arg (GtkWindow *window,
65 static void gtk_window_get_arg (GtkWindow *window,
68 static void gtk_window_destroy (GtkObject *object);
69 static void gtk_window_finalize (GtkObject *object);
70 static void gtk_window_show (GtkWidget *widget);
71 static void gtk_window_hide (GtkWidget *widget);
72 static void gtk_window_map (GtkWidget *widget);
73 static void gtk_window_unmap (GtkWidget *widget);
74 static void gtk_window_realize (GtkWidget *widget);
75 static void gtk_window_size_request (GtkWidget *widget,
76 GtkRequisition *requisition);
77 static void gtk_window_size_allocate (GtkWidget *widget,
78 GtkAllocation *allocation);
79 static gint gtk_window_expose_event (GtkWidget *widget,
80 GdkEventExpose *event);
81 static gint gtk_window_configure_event (GtkWidget *widget,
82 GdkEventConfigure *event);
83 static gint gtk_window_key_press_event (GtkWidget *widget,
85 static gint gtk_window_key_release_event (GtkWidget *widget,
87 static gint gtk_window_enter_notify_event (GtkWidget *widget,
88 GdkEventCrossing *event);
89 static gint gtk_window_leave_notify_event (GtkWidget *widget,
90 GdkEventCrossing *event);
91 static gint gtk_window_focus_in_event (GtkWidget *widget,
92 GdkEventFocus *event);
93 static gint gtk_window_focus_out_event (GtkWidget *widget,
94 GdkEventFocus *event);
95 static gint gtk_window_client_event (GtkWidget *widget,
96 GdkEventClient *event);
97 static gint gtk_window_need_resize (GtkContainer *container);
98 static gint gtk_real_window_move_resize (GtkWindow *window,
103 static void gtk_real_window_set_focus (GtkWindow *window,
105 static gint gtk_window_move_resize (GtkWidget *widget);
106 static void gtk_window_set_hints (GtkWidget *widget,
107 GtkRequisition *requisition);
108 static gint gtk_window_check_accelerator (GtkWindow *window,
113 static GtkBinClass *parent_class = NULL;
114 static gint window_signals[LAST_SIGNAL] = { 0 };
118 gtk_window_get_type ()
120 static guint window_type = 0;
124 GtkTypeInfo window_info =
128 sizeof (GtkWindowClass),
129 (GtkClassInitFunc) gtk_window_class_init,
130 (GtkObjectInitFunc) gtk_window_init,
131 (GtkArgSetFunc) gtk_window_set_arg,
132 (GtkArgGetFunc) gtk_window_get_arg,
135 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
142 gtk_window_class_init (GtkWindowClass *klass)
144 GtkObjectClass *object_class;
145 GtkWidgetClass *widget_class;
146 GtkContainerClass *container_class;
148 object_class = (GtkObjectClass*) klass;
149 widget_class = (GtkWidgetClass*) klass;
150 container_class = (GtkContainerClass*) klass;
152 parent_class = gtk_type_class (gtk_bin_get_type ());
154 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, ARG_TYPE);
155 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, ARG_TITLE);
156 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, ARG_AUTO_SHRINK);
157 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, ARG_ALLOW_SHRINK);
158 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, ARG_ALLOW_GROW);
159 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_ENUM, ARG_WIN_POS);
161 window_signals[MOVE_RESIZE] =
162 gtk_signal_new ("move_resize",
165 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
166 gtk_window_marshal_signal_1,
168 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
169 GTK_TYPE_INT, GTK_TYPE_INT);
171 window_signals[SET_FOCUS] =
172 gtk_signal_new ("set_focus",
175 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
176 gtk_window_marshal_signal_2,
180 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
182 object_class->destroy = gtk_window_destroy;
183 object_class->finalize = gtk_window_finalize;
185 widget_class->show = gtk_window_show;
186 widget_class->hide = gtk_window_hide;
187 widget_class->map = gtk_window_map;
188 widget_class->unmap = gtk_window_unmap;
189 widget_class->realize = gtk_window_realize;
190 widget_class->size_request = gtk_window_size_request;
191 widget_class->size_allocate = gtk_window_size_allocate;
192 widget_class->expose_event = gtk_window_expose_event;
193 widget_class->configure_event = gtk_window_configure_event;
194 widget_class->key_press_event = gtk_window_key_press_event;
195 widget_class->key_release_event = gtk_window_key_release_event;
196 widget_class->enter_notify_event = gtk_window_enter_notify_event;
197 widget_class->leave_notify_event = gtk_window_leave_notify_event;
198 widget_class->focus_in_event = gtk_window_focus_in_event;
199 widget_class->focus_out_event = gtk_window_focus_out_event;
200 widget_class->client_event = gtk_window_client_event;
202 container_class->need_resize = gtk_window_need_resize;
204 klass->move_resize = gtk_real_window_move_resize;
205 klass->set_focus = gtk_real_window_set_focus;
209 gtk_window_init (GtkWindow *window)
211 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
212 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
214 window->title = NULL;
215 window->wmclass_name = NULL;
216 window->wmclass_class = NULL;
217 window->type = GTK_WINDOW_TOPLEVEL;
218 window->accelerator_tables = NULL;
219 window->focus_widget = NULL;
220 window->default_widget = NULL;
221 window->resize_count = 0;
222 window->need_resize = FALSE;
223 window->allow_shrink = FALSE;
224 window->allow_grow = TRUE;
225 window->auto_shrink = FALSE;
226 window->handling_resize = FALSE;
227 window->position = GTK_WIN_POS_NONE;
228 window->use_uposition = TRUE;
230 gtk_container_register_toplevel (GTK_CONTAINER (window));
234 gtk_window_set_arg (GtkWindow *window,
241 window->type = GTK_VALUE_ENUM (*arg);
244 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
246 case ARG_AUTO_SHRINK:
247 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
249 case ARG_ALLOW_SHRINK:
250 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
253 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
256 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
259 arg->type = GTK_TYPE_INVALID;
265 gtk_window_get_arg (GtkWindow *window,
272 GTK_VALUE_ENUM (*arg) = window->type;
275 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
277 case ARG_AUTO_SHRINK:
278 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
280 case ARG_ALLOW_SHRINK:
281 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
284 GTK_VALUE_BOOL (*arg) = window->allow_grow;
287 GTK_VALUE_ENUM (*arg) = window->position;
290 arg->type = GTK_TYPE_INVALID;
296 gtk_window_new (GtkWindowType type)
300 window = gtk_type_new (gtk_window_get_type ());
304 return GTK_WIDGET (window);
308 gtk_window_set_title (GtkWindow *window,
311 g_return_if_fail (window != NULL);
312 g_return_if_fail (GTK_IS_WINDOW (window));
315 g_free (window->title);
316 window->title = g_strdup (title);
318 if (GTK_WIDGET_REALIZED (window))
319 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
323 gtk_window_set_wmclass (GtkWindow *window,
325 gchar *wmclass_class)
327 g_return_if_fail (window != NULL);
328 g_return_if_fail (GTK_IS_WINDOW (window));
330 if (window->wmclass_name)
331 g_free (window->wmclass_name);
332 window->wmclass_name = g_strdup (wmclass_name);
334 if (window->wmclass_class)
335 g_free (window->wmclass_class);
336 window->wmclass_class = g_strdup (wmclass_class);
338 if (GTK_WIDGET_REALIZED (window))
339 g_warning ("shouldn't set wmclass after window is realized!\n");
343 gtk_window_set_focus (GtkWindow *window,
346 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
350 gtk_window_set_default (GtkWindow *window,
353 g_return_if_fail (window != NULL);
354 g_return_if_fail (GTK_IS_WINDOW (window));
355 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (defaultw));
357 if (window->default_widget != defaultw)
359 if (window->default_widget)
361 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
362 gtk_widget_draw_default (window->default_widget);
365 window->default_widget = defaultw;
367 if (window->default_widget)
369 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
370 gtk_widget_draw_default (window->default_widget);
376 gtk_window_set_policy (GtkWindow *window,
381 g_return_if_fail (window != NULL);
382 g_return_if_fail (GTK_IS_WINDOW (window));
384 window->allow_shrink = (allow_shrink != FALSE);
385 window->allow_grow = (allow_grow != FALSE);
386 window->auto_shrink = (auto_shrink != FALSE);
390 gtk_window_add_accelerator_table (GtkWindow *window,
391 GtkAcceleratorTable *table)
393 g_return_if_fail (window != NULL);
394 g_return_if_fail (GTK_IS_WINDOW (window));
396 gtk_accelerator_table_ref (table);
397 window->accelerator_tables = g_list_prepend (window->accelerator_tables,
402 gtk_window_remove_accelerator_table (GtkWindow *window,
403 GtkAcceleratorTable *table)
405 g_return_if_fail (window != NULL);
406 g_return_if_fail (GTK_IS_WINDOW (window));
408 window->accelerator_tables = g_list_remove (window->accelerator_tables,
410 gtk_accelerator_table_unref (table);
414 gtk_window_position (GtkWindow *window,
415 GtkWindowPosition position)
417 g_return_if_fail (window != NULL);
418 g_return_if_fail (GTK_IS_WINDOW (window));
420 window->position = position;
424 gtk_window_activate_focus (GtkWindow *window)
426 g_return_val_if_fail (window != NULL, FALSE);
427 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
429 if (window->focus_widget)
431 gtk_widget_activate (window->focus_widget);
439 gtk_window_activate_default (GtkWindow *window)
441 g_return_val_if_fail (window != NULL, FALSE);
442 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
444 if (window->default_widget)
446 gtk_widget_activate (window->default_widget);
454 gtk_window_marshal_signal_1 (GtkObject *object,
459 GtkWindowSignal1 rfunc;
462 rfunc = (GtkWindowSignal1) func;
463 return_val = GTK_RETLOC_BOOL (args[4]);
465 *return_val = (* rfunc) (object,
466 GTK_VALUE_POINTER (args[0]),
467 GTK_VALUE_POINTER (args[1]),
468 GTK_VALUE_INT (args[2]),
469 GTK_VALUE_INT (args[3]),
474 gtk_window_marshal_signal_2 (GtkObject *object,
479 GtkWindowSignal2 rfunc;
481 rfunc = (GtkWindowSignal2) func;
483 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
487 gtk_window_destroy (GtkObject *object)
489 g_return_if_fail (object != NULL);
490 g_return_if_fail (GTK_IS_WINDOW (object));
492 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
494 if (GTK_OBJECT_CLASS (parent_class)->destroy)
495 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
499 gtk_window_finalize (GtkObject *object)
503 g_return_if_fail (object != NULL);
504 g_return_if_fail (GTK_IS_WINDOW (object));
506 window = GTK_WINDOW (object);
507 g_free (window->title);
509 GTK_OBJECT_CLASS(parent_class)->finalize (object);
513 gtk_window_show (GtkWidget *widget)
515 g_return_if_fail (widget != NULL);
516 g_return_if_fail (GTK_IS_WINDOW (widget));
518 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
519 gtk_container_need_resize (GTK_CONTAINER (widget));
520 gtk_widget_map (widget);
524 gtk_window_hide (GtkWidget *widget)
526 g_return_if_fail (widget != NULL);
527 g_return_if_fail (GTK_IS_WINDOW (widget));
529 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
530 gtk_widget_unmap (widget);
534 gtk_window_map (GtkWidget *widget)
538 g_return_if_fail (widget != NULL);
539 g_return_if_fail (GTK_IS_WINDOW (widget));
541 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
543 gtk_window_move_resize (widget);
544 window = GTK_WINDOW (widget);
546 if (window->bin.child &&
547 GTK_WIDGET_VISIBLE (window->bin.child) &&
548 !GTK_WIDGET_MAPPED (window->bin.child))
549 gtk_widget_map (window->bin.child);
551 gtk_window_set_hints (widget, &widget->requisition);
552 gdk_window_show (widget->window);
556 gtk_window_unmap (GtkWidget *widget)
560 g_return_if_fail (widget != NULL);
561 g_return_if_fail (GTK_IS_WINDOW (widget));
563 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
564 gdk_window_hide (widget->window);
566 window = GTK_WINDOW (widget);
567 window->use_uposition = TRUE;
571 gtk_window_realize (GtkWidget *widget)
574 GdkWindowAttr attributes;
575 gint attributes_mask;
577 g_return_if_fail (widget != NULL);
578 g_return_if_fail (GTK_IS_WINDOW (widget));
580 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
581 window = GTK_WINDOW (widget);
583 switch (window->type)
585 case GTK_WINDOW_TOPLEVEL:
586 attributes.window_type = GDK_WINDOW_TOPLEVEL;
588 case GTK_WINDOW_DIALOG:
589 attributes.window_type = GDK_WINDOW_DIALOG;
591 case GTK_WINDOW_POPUP:
592 attributes.window_type = GDK_WINDOW_TEMP;
596 attributes.title = window->title;
597 attributes.wmclass_name = window->wmclass_name;
598 attributes.wmclass_class = window->wmclass_class;
599 attributes.width = widget->allocation.width;
600 attributes.height = widget->allocation.height;
601 attributes.wclass = GDK_INPUT_OUTPUT;
602 attributes.visual = gtk_widget_get_visual (widget);
603 attributes.colormap = gtk_widget_get_colormap (widget);
604 attributes.event_mask = gtk_widget_get_events (widget);
605 attributes.event_mask |= (GDK_EXPOSURE_MASK |
607 GDK_ENTER_NOTIFY_MASK |
608 GDK_LEAVE_NOTIFY_MASK |
609 GDK_FOCUS_CHANGE_MASK |
612 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
613 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
614 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
616 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
617 gdk_window_set_user_data (widget->window, window);
619 widget->style = gtk_style_attach (widget->style, widget->window);
620 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
624 gtk_window_size_request (GtkWidget *widget,
625 GtkRequisition *requisition)
629 g_return_if_fail (widget != NULL);
630 g_return_if_fail (GTK_IS_WINDOW (widget));
631 g_return_if_fail (requisition != NULL);
633 window = GTK_WINDOW (widget);
635 if (window->bin.child)
637 requisition->width = GTK_CONTAINER (window)->border_width * 2;
638 requisition->height = GTK_CONTAINER (window)->border_width * 2;
640 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
642 requisition->width += window->bin.child->requisition.width;
643 requisition->height += window->bin.child->requisition.height;
647 if (!GTK_WIDGET_VISIBLE (window))
648 window->need_resize = TRUE;
653 gtk_window_size_allocate (GtkWidget *widget,
654 GtkAllocation *allocation)
657 GtkAllocation child_allocation;
659 g_return_if_fail (widget != NULL);
660 g_return_if_fail (GTK_IS_WINDOW (widget));
661 g_return_if_fail (allocation != NULL);
663 window = GTK_WINDOW (widget);
664 widget->allocation = *allocation;
666 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
668 child_allocation.x = GTK_CONTAINER (window)->border_width;
669 child_allocation.y = GTK_CONTAINER (window)->border_width;
670 child_allocation.width = allocation->width - child_allocation.x * 2;
671 child_allocation.height = allocation->height - child_allocation.y * 2;
673 gtk_widget_size_allocate (window->bin.child, &child_allocation);
678 gtk_window_expose_event (GtkWidget *widget,
679 GdkEventExpose *event)
681 g_return_val_if_fail (widget != NULL, FALSE);
682 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
683 g_return_val_if_fail (event != NULL, FALSE);
685 if (GTK_WIDGET_DRAWABLE (widget))
686 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
687 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
693 gtk_window_configure_event (GtkWidget *widget,
694 GdkEventConfigure *event)
697 GtkAllocation allocation;
699 g_return_val_if_fail (widget != NULL, FALSE);
700 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
701 g_return_val_if_fail (event != NULL, FALSE);
703 window = GTK_WINDOW (widget);
704 window->handling_resize = TRUE;
708 allocation.width = event->width;
709 allocation.height = event->height;
711 gtk_widget_size_allocate (widget, &allocation);
713 if (window->bin.child &&
714 GTK_WIDGET_VISIBLE (window->bin.child) &&
715 !GTK_WIDGET_MAPPED (window->bin.child))
716 gtk_widget_map (window->bin.child);
718 window->resize_count -= 1;
719 if (window->resize_count == 0)
721 if ((event->width != widget->requisition.width) ||
722 (event->height != widget->requisition.height))
724 window->resize_count += 1;
725 gdk_window_resize (widget->window,
726 widget->requisition.width,
727 widget->requisition.height);
730 else if (window->resize_count < 0)
732 window->resize_count = 0;
735 window->handling_resize = FALSE;
741 gtk_window_key_press_event (GtkWidget *widget,
745 GtkDirectionType direction = 0;
748 g_return_val_if_fail (widget != NULL, FALSE);
749 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
750 g_return_val_if_fail (event != NULL, FALSE);
752 window = GTK_WINDOW (widget);
755 if (window->focus_widget)
756 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
758 if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
763 switch (event->keyval)
766 if (window->focus_widget)
768 gtk_widget_activate (window->focus_widget);
774 if (window->default_widget)
776 gtk_widget_activate (window->default_widget);
779 else if (window->focus_widget)
781 gtk_widget_activate (window->focus_widget);
790 switch (event->keyval)
793 direction = GTK_DIR_UP;
796 direction = GTK_DIR_DOWN;
799 direction = GTK_DIR_LEFT;
802 direction = GTK_DIR_RIGHT;
805 if (event->state & GDK_SHIFT_MASK)
806 direction = GTK_DIR_TAB_BACKWARD;
808 direction = GTK_DIR_TAB_FORWARD;
811 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
814 gtk_container_focus (GTK_CONTAINER (widget), direction);
816 if (!GTK_CONTAINER (window)->focus_child)
817 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
828 gtk_window_key_release_event (GtkWidget *widget,
834 g_return_val_if_fail (widget != NULL, FALSE);
835 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
836 g_return_val_if_fail (event != NULL, FALSE);
838 window = GTK_WINDOW (widget);
840 if (window->focus_widget)
841 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
847 gtk_window_enter_notify_event (GtkWidget *widget,
848 GdkEventCrossing *event)
850 g_return_val_if_fail (widget != NULL, FALSE);
851 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
852 g_return_val_if_fail (event != NULL, FALSE);
858 gtk_window_leave_notify_event (GtkWidget *widget,
859 GdkEventCrossing *event)
861 g_return_val_if_fail (widget != NULL, FALSE);
862 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
863 g_return_val_if_fail (event != NULL, FALSE);
869 gtk_window_focus_in_event (GtkWidget *widget,
870 GdkEventFocus *event)
873 GdkEventFocus fevent;
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);
879 /* It appears spurious focus in events can occur when
880 * the window is hidden. So we'll just check to see if
881 * the window is visible before actually handling the
884 if (GTK_WIDGET_VISIBLE (widget))
886 window = GTK_WINDOW (widget);
887 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
889 fevent.type = GDK_FOCUS_CHANGE;
890 fevent.window = window->focus_widget->window;
893 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
901 gtk_window_focus_out_event (GtkWidget *widget,
902 GdkEventFocus *event)
905 GdkEventFocus fevent;
907 g_return_val_if_fail (widget != NULL, FALSE);
908 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
909 g_return_val_if_fail (event != NULL, FALSE);
911 window = GTK_WINDOW (widget);
912 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
914 fevent.type = GDK_FOCUS_CHANGE;
915 fevent.window = window->focus_widget->window;
918 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
925 gtk_window_style_set_event (GtkWidget *widget,
926 GdkEventClient *event)
928 GdkAtom atom_default_colors;
929 GtkStyle *style_newdefault;
932 GdkColor *data, *stylecolors;
934 GdkColormap *widget_cmap;
936 atom_default_colors = gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE);
938 if(gdk_property_get (GDK_ROOT_PARENT(),
940 gdk_atom_intern("STRING", FALSE),
942 sizeof(GdkColor) * GTK_STYLE_NUM_STYLECOLORS(),
947 (guchar **)&data) != TRUE) {
948 g_warning("gdk_property_get() failed in _GTK_STYLE_CHANGED handler\n");
951 if(retfmt != sizeof(gushort)*8) {
952 g_warning("retfmt (%d) != sizeof(gushort)*8 (%d)\n", retfmt,
956 /* We have the color data, now let's interpret it */
957 style_newdefault = gtk_widget_get_default_style();
958 gtk_style_ref(style_newdefault);
959 stylecolors = (GdkColor *) style_newdefault;
961 widget_cmap = gtk_widget_get_colormap(widget);
962 for(i = 0; i < GTK_STYLE_NUM_STYLECOLORS(); i++) {
963 stylecolors[i] = data[i];
964 gdk_color_alloc(widget_cmap, &stylecolors[i]);
967 gtk_widget_set_default_style(style_newdefault);
968 gtk_style_unref(style_newdefault);
970 /* Now we need to redraw everything */
971 gtk_widget_draw(widget, NULL);
972 gtk_widget_draw_children(widget);
976 gtk_window_client_event (GtkWidget *widget,
977 GdkEventClient *event)
979 GdkAtom atom_styleset;
980 g_return_val_if_fail (widget != NULL, FALSE);
981 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
982 g_return_val_if_fail (event != NULL, FALSE);
984 atom_styleset = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
986 if(event->message_type == atom_styleset) {
987 gtk_window_style_set_event(widget, event);
993 gtk_window_need_resize (GtkContainer *container)
998 g_return_val_if_fail (container != NULL, FALSE);
999 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
1003 window = GTK_WINDOW (container);
1004 if (window->handling_resize)
1007 if (GTK_WIDGET_VISIBLE (container))
1009 window->need_resize = TRUE;
1010 return_val = gtk_window_move_resize (GTK_WIDGET (window));
1011 window->need_resize = FALSE;
1018 gtk_real_window_move_resize (GtkWindow *window,
1025 GtkWidget *resize_container, *child;
1026 GSList *resize_containers;
1030 g_return_val_if_fail (window != NULL, FALSE);
1031 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1032 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
1036 widget = GTK_WIDGET (window);
1038 if ((*x != -1) && (*y != -1))
1039 gdk_window_move (widget->window, *x, *y);
1041 if ((widget->requisition.width == 0) ||
1042 (widget->requisition.height == 0))
1044 widget->requisition.width = 200;
1045 widget->requisition.height = 200;
1048 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1050 resize_containers = 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 if (window->resize_count == 0)
1060 window->resize_count += 1;
1061 gdk_window_resize (widget->window,
1062 widget->requisition.width,
1063 widget->requisition.height);
1068 /* The window hasn't changed size but one of its children
1069 * queued a resize request. Which means that the allocation
1070 * is not sufficient for the requisition of some child.
1071 * We've already performed a size request at this point,
1072 * so we simply need to run through the list of resize
1073 * widgets and reallocate their sizes appropriately. We
1074 * make the optimization of not performing reallocation
1075 * for a widget who also has a parent in the resize widgets
1076 * list. GTK_RESIZE_NEEDED is used for flagging those
1077 * parents inside this function.
1079 GSList *resize_widgets, *node;
1081 resize_widgets = GTK_CONTAINER (window)->resize_widgets;
1082 GTK_CONTAINER (window)->resize_widgets = NULL;
1084 for (node = resize_widgets; node; node = node->next)
1086 child = (GtkWidget *)node->data;
1088 GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
1090 widget = child->parent;
1092 ((widget->allocation.width < widget->requisition.width) ||
1093 (widget->allocation.height < widget->requisition.height)))
1094 widget = widget->parent;
1097 GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
1100 for (node = resize_widgets; node; node = node->next)
1102 child = (GtkWidget *)node->data;
1104 resize_container = child->parent;
1105 while (resize_container &&
1106 !GTK_WIDGET_RESIZE_NEEDED (resize_container))
1107 resize_container = resize_container->parent;
1109 if (resize_container)
1110 widget = resize_container->parent;
1116 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1118 GTK_PRIVATE_UNSET_FLAG (resize_container, GTK_RESIZE_NEEDED);
1119 resize_container = widget;
1121 widget = widget->parent;
1124 if (resize_container &&
1125 !g_slist_find (resize_containers, resize_container))
1126 resize_containers = g_slist_prepend (resize_containers,
1130 g_slist_free (resize_widgets);
1132 tmp_list = resize_containers;
1135 widget = tmp_list->data;
1136 tmp_list = tmp_list->next;
1138 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1139 gtk_widget_size_allocate (widget, &widget->allocation);
1140 gtk_widget_queue_draw (widget);
1143 g_slist_free (resize_containers);
1150 gtk_window_move_resize (GtkWidget *widget)
1159 g_return_val_if_fail (widget != NULL, FALSE);
1160 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1164 if (GTK_WIDGET_REALIZED (widget))
1166 window = GTK_WINDOW (widget);
1168 /* Remember old size, to know if we have to reset hints */
1169 width = widget->requisition.width;
1170 height = widget->requisition.height;
1171 gtk_widget_size_request (widget, &widget->requisition);
1173 if (GTK_WIDGET_MAPPED (widget) &&
1174 (width != widget->requisition.width ||
1175 height != widget->requisition.height))
1176 gtk_window_set_hints (widget, &widget->requisition);
1180 width = widget->requisition.width;
1181 height = widget->requisition.height;
1183 if (window->use_uposition)
1184 switch (window->position)
1186 case GTK_WIN_POS_CENTER:
1187 x = (gdk_screen_width () - width) / 2;
1188 y = (gdk_screen_height () - height) / 2;
1189 gtk_widget_set_uposition (widget, x, y);
1191 case GTK_WIN_POS_MOUSE:
1192 gdk_window_get_pointer (NULL, &x, &y, NULL);
1197 screen_width = gdk_screen_width ();
1198 screen_height = gdk_screen_height ();
1202 else if (x > (screen_width - width))
1203 x = screen_width - width;
1207 else if (y > (screen_height - height))
1208 y = screen_height - height;
1210 gtk_widget_set_uposition (widget, x, y);
1214 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1215 &x, &y, width, height, &return_val);
1222 gtk_real_window_set_focus (GtkWindow *window,
1225 GdkEventFocus event;
1227 g_return_if_fail (window != NULL);
1228 g_return_if_fail (GTK_IS_WINDOW (window));
1230 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1233 if (window->focus_widget != focus)
1235 if (window->focus_widget)
1237 event.type = GDK_FOCUS_CHANGE;
1238 event.window = window->focus_widget->window;
1241 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1244 window->focus_widget = focus;
1246 if (window->focus_widget)
1248 event.type = GDK_FOCUS_CHANGE;
1249 event.window = window->focus_widget->window;
1252 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1258 gtk_window_set_hints (GtkWidget *widget,
1259 GtkRequisition *requisition)
1262 GtkWidgetAuxInfo *aux_info;
1266 g_return_if_fail (widget != NULL);
1267 g_return_if_fail (GTK_IS_WINDOW (widget));
1268 g_return_if_fail (requisition != NULL);
1270 if (GTK_WIDGET_REALIZED (widget))
1272 window = GTK_WINDOW (widget);
1278 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1279 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1283 flags |= GDK_HINT_POS;
1285 if (!window->allow_shrink)
1286 flags |= GDK_HINT_MIN_SIZE;
1287 if (!window->allow_grow)
1288 flags |= GDK_HINT_MAX_SIZE;
1290 gdk_window_set_hints (widget->window, ux, uy,
1291 requisition->width, requisition->height,
1292 requisition->width, requisition->height,
1295 if (window->use_uposition && (flags & GDK_HINT_POS))
1297 window->use_uposition = FALSE;
1298 gdk_window_move (widget->window, ux, uy);
1304 gtk_window_check_accelerator (GtkWindow *window,
1308 GtkAcceleratorTable *table;
1311 if ((key >= 0x20) && (key <= 0xFF))
1313 tmp = window->accelerator_tables;
1319 if (gtk_accelerator_table_check (table, key, mods))
1323 if (gtk_accelerator_table_check (NULL, key, mods))