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"
25 #include "gtksignal.h"
26 #include "gtkwindow.h"
43 typedef gint (*GtkWindowSignal1) (GtkObject *object,
49 typedef void (*GtkWindowSignal2) (GtkObject *object,
53 static void gtk_window_marshal_signal_1 (GtkObject *object,
57 static void gtk_window_marshal_signal_2 (GtkObject *object,
61 static void gtk_window_class_init (GtkWindowClass *klass);
62 static void gtk_window_init (GtkWindow *window);
63 static void gtk_window_set_arg (GtkWindow *window,
66 static void gtk_window_get_arg (GtkWindow *window,
69 static void gtk_window_destroy (GtkObject *object);
70 static void gtk_window_finalize (GtkObject *object);
71 static void gtk_window_show (GtkWidget *widget);
72 static void gtk_window_hide (GtkWidget *widget);
73 static void gtk_window_map (GtkWidget *widget);
74 static void gtk_window_unmap (GtkWidget *widget);
75 static void gtk_window_realize (GtkWidget *widget);
76 static void gtk_window_size_request (GtkWidget *widget,
77 GtkRequisition *requisition);
78 static void gtk_window_size_allocate (GtkWidget *widget,
79 GtkAllocation *allocation);
80 static gint gtk_window_expose_event (GtkWidget *widget,
81 GdkEventExpose *event);
82 static gint gtk_window_configure_event (GtkWidget *widget,
83 GdkEventConfigure *event);
84 static gint gtk_window_key_press_event (GtkWidget *widget,
86 static gint gtk_window_key_release_event (GtkWidget *widget,
88 static gint gtk_window_enter_notify_event (GtkWidget *widget,
89 GdkEventCrossing *event);
90 static gint gtk_window_leave_notify_event (GtkWidget *widget,
91 GdkEventCrossing *event);
92 static gint gtk_window_focus_in_event (GtkWidget *widget,
93 GdkEventFocus *event);
94 static gint gtk_window_focus_out_event (GtkWidget *widget,
95 GdkEventFocus *event);
96 static gint gtk_window_client_event (GtkWidget *widget,
97 GdkEventClient *event);
98 static gint gtk_window_need_resize (GtkContainer *container);
99 static gint gtk_real_window_move_resize (GtkWindow *window,
104 static void gtk_real_window_set_focus (GtkWindow *window,
106 static gint gtk_window_move_resize (GtkWidget *widget);
107 static void gtk_window_set_hints (GtkWidget *widget,
108 GtkRequisition *requisition);
109 static gint gtk_window_check_accelerator (GtkWindow *window,
114 static GtkBinClass *parent_class = NULL;
115 static guint window_signals[LAST_SIGNAL] = { 0 };
119 gtk_window_get_type ()
121 static guint window_type = 0;
125 GtkTypeInfo window_info =
129 sizeof (GtkWindowClass),
130 (GtkClassInitFunc) gtk_window_class_init,
131 (GtkObjectInitFunc) gtk_window_init,
132 (GtkArgSetFunc) gtk_window_set_arg,
133 (GtkArgGetFunc) gtk_window_get_arg,
136 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
143 gtk_window_class_init (GtkWindowClass *klass)
145 GtkObjectClass *object_class;
146 GtkWidgetClass *widget_class;
147 GtkContainerClass *container_class;
149 object_class = (GtkObjectClass*) klass;
150 widget_class = (GtkWidgetClass*) klass;
151 container_class = (GtkContainerClass*) klass;
153 parent_class = gtk_type_class (gtk_bin_get_type ());
155 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
156 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
157 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
158 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
159 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
160 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_WIN_POS);
162 window_signals[MOVE_RESIZE] =
163 gtk_signal_new ("move_resize",
166 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
167 gtk_window_marshal_signal_1,
169 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
170 GTK_TYPE_INT, GTK_TYPE_INT);
172 window_signals[SET_FOCUS] =
173 gtk_signal_new ("set_focus",
176 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
177 gtk_window_marshal_signal_2,
181 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
183 object_class->destroy = gtk_window_destroy;
184 object_class->finalize = gtk_window_finalize;
186 widget_class->show = gtk_window_show;
187 widget_class->hide = gtk_window_hide;
188 widget_class->map = gtk_window_map;
189 widget_class->unmap = gtk_window_unmap;
190 widget_class->realize = gtk_window_realize;
191 widget_class->size_request = gtk_window_size_request;
192 widget_class->size_allocate = gtk_window_size_allocate;
193 widget_class->expose_event = gtk_window_expose_event;
194 widget_class->configure_event = gtk_window_configure_event;
195 widget_class->key_press_event = gtk_window_key_press_event;
196 widget_class->key_release_event = gtk_window_key_release_event;
197 widget_class->enter_notify_event = gtk_window_enter_notify_event;
198 widget_class->leave_notify_event = gtk_window_leave_notify_event;
199 widget_class->focus_in_event = gtk_window_focus_in_event;
200 widget_class->focus_out_event = gtk_window_focus_out_event;
201 widget_class->client_event = gtk_window_client_event;
203 container_class->need_resize = gtk_window_need_resize;
205 klass->move_resize = gtk_real_window_move_resize;
206 klass->set_focus = gtk_real_window_set_focus;
210 gtk_window_init (GtkWindow *window)
212 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
213 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
215 window->title = NULL;
216 window->wmclass_name = g_strdup (gdk_progname);
217 window->wmclass_class = g_strdup (gdk_progclass);
218 window->type = GTK_WINDOW_TOPLEVEL;
219 window->accelerator_tables = NULL;
220 window->focus_widget = NULL;
221 window->default_widget = NULL;
222 window->resize_count = 0;
223 window->need_resize = FALSE;
224 window->allow_shrink = FALSE;
225 window->allow_grow = TRUE;
226 window->auto_shrink = FALSE;
227 window->handling_resize = FALSE;
228 window->position = GTK_WIN_POS_NONE;
229 window->use_uposition = TRUE;
231 gtk_container_register_toplevel (GTK_CONTAINER (window));
235 gtk_window_set_arg (GtkWindow *window,
242 window->type = GTK_VALUE_ENUM (*arg);
245 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
247 case ARG_AUTO_SHRINK:
248 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
249 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
251 case ARG_ALLOW_SHRINK:
252 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
253 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
256 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
257 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
260 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
263 arg->type = GTK_TYPE_INVALID;
269 gtk_window_get_arg (GtkWindow *window,
276 GTK_VALUE_ENUM (*arg) = window->type;
279 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
281 case ARG_AUTO_SHRINK:
282 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
284 case ARG_ALLOW_SHRINK:
285 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
288 GTK_VALUE_BOOL (*arg) = window->allow_grow;
291 GTK_VALUE_ENUM (*arg) = window->position;
294 arg->type = GTK_TYPE_INVALID;
300 gtk_window_new (GtkWindowType type)
304 window = gtk_type_new (gtk_window_get_type ());
308 return GTK_WIDGET (window);
312 gtk_window_set_title (GtkWindow *window,
315 g_return_if_fail (window != NULL);
316 g_return_if_fail (GTK_IS_WINDOW (window));
319 g_free (window->title);
320 window->title = g_strdup (title);
322 if (GTK_WIDGET_REALIZED (window))
323 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
327 gtk_window_set_wmclass (GtkWindow *window,
329 gchar *wmclass_class)
331 g_return_if_fail (window != NULL);
332 g_return_if_fail (GTK_IS_WINDOW (window));
334 g_free (window->wmclass_name);
335 window->wmclass_name = g_strdup (wmclass_name);
337 g_free (window->wmclass_class);
338 window->wmclass_class = g_strdup (wmclass_class);
340 if (GTK_WIDGET_REALIZED (window))
341 g_warning ("shouldn't set wmclass after window is realized!\n");
345 gtk_window_set_focus (GtkWindow *window,
348 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
352 gtk_window_set_default (GtkWindow *window,
353 GtkWidget *default_widget)
355 g_return_if_fail (window != NULL);
356 g_return_if_fail (GTK_IS_WINDOW (window));
359 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
361 if (window->default_widget != default_widget)
363 if (window->default_widget)
365 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
366 gtk_widget_draw_default (window->default_widget);
369 window->default_widget = default_widget;
371 if (window->default_widget)
373 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
374 gtk_widget_draw_default (window->default_widget);
380 gtk_window_set_policy (GtkWindow *window,
385 g_return_if_fail (window != NULL);
386 g_return_if_fail (GTK_IS_WINDOW (window));
388 window->allow_shrink = (allow_shrink != FALSE);
389 window->allow_grow = (allow_grow != FALSE);
390 window->auto_shrink = (auto_shrink != FALSE);
392 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
396 gtk_window_add_accelerator_table (GtkWindow *window,
397 GtkAcceleratorTable *table)
399 g_return_if_fail (window != NULL);
400 g_return_if_fail (GTK_IS_WINDOW (window));
401 g_return_if_fail (table != NULL);
403 gtk_accelerator_table_ref (table);
404 window->accelerator_tables = g_list_prepend (window->accelerator_tables,
409 gtk_window_remove_accelerator_table (GtkWindow *window,
410 GtkAcceleratorTable *table)
414 g_return_if_fail (window != NULL);
415 g_return_if_fail (GTK_IS_WINDOW (window));
416 g_return_if_fail (table != NULL);
418 for (list = window->accelerator_tables; list; list = list->next)
420 if (list->data == table)
422 gtk_accelerator_table_unref (table);
423 window->accelerator_tables = g_list_remove_link (window->accelerator_tables, list);
424 g_list_free_1 (list);
431 gtk_window_position (GtkWindow *window,
432 GtkWindowPosition position)
434 g_return_if_fail (window != NULL);
435 g_return_if_fail (GTK_IS_WINDOW (window));
437 window->position = position;
441 gtk_window_activate_focus (GtkWindow *window)
443 g_return_val_if_fail (window != NULL, FALSE);
444 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
446 if (window->focus_widget)
448 gtk_widget_activate (window->focus_widget);
456 gtk_window_activate_default (GtkWindow *window)
458 g_return_val_if_fail (window != NULL, FALSE);
459 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
461 if (window->default_widget)
463 gtk_widget_activate (window->default_widget);
471 gtk_window_marshal_signal_1 (GtkObject *object,
476 GtkWindowSignal1 rfunc;
479 rfunc = (GtkWindowSignal1) func;
480 return_val = GTK_RETLOC_BOOL (args[4]);
482 *return_val = (* rfunc) (object,
483 GTK_VALUE_POINTER (args[0]),
484 GTK_VALUE_POINTER (args[1]),
485 GTK_VALUE_INT (args[2]),
486 GTK_VALUE_INT (args[3]),
491 gtk_window_marshal_signal_2 (GtkObject *object,
496 GtkWindowSignal2 rfunc;
498 rfunc = (GtkWindowSignal2) func;
500 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
504 gtk_window_destroy (GtkObject *object)
508 g_return_if_fail (object != NULL);
509 g_return_if_fail (GTK_IS_WINDOW (object));
511 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
513 for (list = GTK_WINDOW (object)->accelerator_tables; list; list = list->next)
514 gtk_accelerator_table_unref (list->data);
515 g_list_free (GTK_WINDOW (object)->accelerator_tables);
516 GTK_WINDOW (object)->accelerator_tables = NULL;
518 if (GTK_OBJECT_CLASS (parent_class)->destroy)
519 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
523 gtk_window_finalize (GtkObject *object)
527 g_return_if_fail (object != NULL);
528 g_return_if_fail (GTK_IS_WINDOW (object));
530 window = GTK_WINDOW (object);
531 g_free (window->title);
532 g_free (window->wmclass_name);
533 g_free (window->wmclass_class);
535 GTK_OBJECT_CLASS(parent_class)->finalize (object);
539 gtk_window_show (GtkWidget *widget)
541 g_return_if_fail (widget != NULL);
542 g_return_if_fail (GTK_IS_WINDOW (widget));
544 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
545 gtk_container_need_resize (GTK_CONTAINER (widget));
546 gtk_widget_map (widget);
550 gtk_window_hide (GtkWidget *widget)
552 g_return_if_fail (widget != NULL);
553 g_return_if_fail (GTK_IS_WINDOW (widget));
555 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
556 gtk_widget_unmap (widget);
560 gtk_window_map (GtkWidget *widget)
564 g_return_if_fail (widget != NULL);
565 g_return_if_fail (GTK_IS_WINDOW (widget));
567 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
569 window = GTK_WINDOW (widget);
571 if (window->bin.child &&
572 GTK_WIDGET_VISIBLE (window->bin.child) &&
573 !GTK_WIDGET_MAPPED (window->bin.child))
574 gtk_widget_map (window->bin.child);
576 gtk_window_set_hints (widget, &widget->requisition);
577 gdk_window_show (widget->window);
581 gtk_window_unmap (GtkWidget *widget)
585 g_return_if_fail (widget != NULL);
586 g_return_if_fail (GTK_IS_WINDOW (widget));
588 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
589 gdk_window_hide (widget->window);
591 window = GTK_WINDOW (widget);
592 window->use_uposition = TRUE;
596 gtk_window_realize (GtkWidget *widget)
599 GdkWindowAttr attributes;
600 gint attributes_mask;
602 g_return_if_fail (widget != NULL);
603 g_return_if_fail (GTK_IS_WINDOW (widget));
605 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
606 window = GTK_WINDOW (widget);
608 switch (window->type)
610 case GTK_WINDOW_TOPLEVEL:
611 attributes.window_type = GDK_WINDOW_TOPLEVEL;
613 case GTK_WINDOW_DIALOG:
614 attributes.window_type = GDK_WINDOW_DIALOG;
616 case GTK_WINDOW_POPUP:
617 attributes.window_type = GDK_WINDOW_TEMP;
621 attributes.title = window->title;
622 attributes.wmclass_name = window->wmclass_name;
623 attributes.wmclass_class = window->wmclass_class;
624 attributes.width = widget->allocation.width;
625 attributes.height = widget->allocation.height;
626 attributes.wclass = GDK_INPUT_OUTPUT;
627 attributes.visual = gtk_widget_get_visual (widget);
628 attributes.colormap = gtk_widget_get_colormap (widget);
629 attributes.event_mask = gtk_widget_get_events (widget);
630 attributes.event_mask |= (GDK_EXPOSURE_MASK |
632 GDK_ENTER_NOTIFY_MASK |
633 GDK_LEAVE_NOTIFY_MASK |
634 GDK_FOCUS_CHANGE_MASK |
637 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
638 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
639 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
641 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
642 gdk_window_set_user_data (widget->window, window);
644 widget->style = gtk_style_attach (widget->style, widget->window);
645 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
649 gtk_window_size_request (GtkWidget *widget,
650 GtkRequisition *requisition)
654 g_return_if_fail (widget != NULL);
655 g_return_if_fail (GTK_IS_WINDOW (widget));
656 g_return_if_fail (requisition != NULL);
658 window = GTK_WINDOW (widget);
660 if (window->bin.child)
662 requisition->width = GTK_CONTAINER (window)->border_width * 2;
663 requisition->height = GTK_CONTAINER (window)->border_width * 2;
665 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
667 requisition->width += window->bin.child->requisition.width;
668 requisition->height += window->bin.child->requisition.height;
672 if (!GTK_WIDGET_VISIBLE (window))
673 window->need_resize = TRUE;
678 gtk_window_size_allocate (GtkWidget *widget,
679 GtkAllocation *allocation)
682 GtkAllocation child_allocation;
684 g_return_if_fail (widget != NULL);
685 g_return_if_fail (GTK_IS_WINDOW (widget));
686 g_return_if_fail (allocation != NULL);
688 window = GTK_WINDOW (widget);
689 widget->allocation = *allocation;
691 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
693 child_allocation.x = GTK_CONTAINER (window)->border_width;
694 child_allocation.y = GTK_CONTAINER (window)->border_width;
695 child_allocation.width = allocation->width - child_allocation.x * 2;
696 child_allocation.height = allocation->height - child_allocation.y * 2;
698 gtk_widget_size_allocate (window->bin.child, &child_allocation);
703 gtk_window_expose_event (GtkWidget *widget,
704 GdkEventExpose *event)
706 g_return_val_if_fail (widget != NULL, FALSE);
707 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
708 g_return_val_if_fail (event != NULL, FALSE);
710 if (GTK_WIDGET_DRAWABLE (widget))
711 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
712 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
718 gtk_window_configure_event (GtkWidget *widget,
719 GdkEventConfigure *event)
722 GtkAllocation allocation;
724 g_return_val_if_fail (widget != NULL, FALSE);
725 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
726 g_return_val_if_fail (event != NULL, FALSE);
728 window = GTK_WINDOW (widget);
730 /* If the window was merely moved, do nothing */
731 if ((widget->allocation.width == event->width) &&
732 (widget->allocation.height == event->height) &&
733 (window->resize_count == 0))
736 window->handling_resize = TRUE;
740 allocation.width = event->width;
741 allocation.height = event->height;
743 gtk_widget_size_allocate (widget, &allocation);
745 if (window->bin.child &&
746 GTK_WIDGET_VISIBLE (window->bin.child) &&
747 !GTK_WIDGET_MAPPED (window->bin.child))
748 gtk_widget_map (window->bin.child);
750 if (window->resize_count > 0)
751 window->resize_count -= 1;
753 window->handling_resize = FALSE;
759 gtk_window_key_press_event (GtkWidget *widget,
763 GtkDirectionType direction = 0;
766 g_return_val_if_fail (widget != NULL, FALSE);
767 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
768 g_return_val_if_fail (event != NULL, FALSE);
770 window = GTK_WINDOW (widget);
773 if (window->focus_widget)
774 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
776 if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
781 switch (event->keyval)
784 if (window->focus_widget)
786 gtk_widget_activate (window->focus_widget);
792 if (window->default_widget)
794 gtk_widget_activate (window->default_widget);
797 else if (window->focus_widget)
799 gtk_widget_activate (window->focus_widget);
808 case GDK_ISO_Left_Tab:
809 switch (event->keyval)
812 direction = GTK_DIR_UP;
815 direction = GTK_DIR_DOWN;
818 direction = GTK_DIR_LEFT;
821 direction = GTK_DIR_RIGHT;
824 case GDK_ISO_Left_Tab:
825 if (event->state & GDK_SHIFT_MASK)
826 direction = GTK_DIR_TAB_BACKWARD;
828 direction = GTK_DIR_TAB_FORWARD;
831 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
834 gtk_container_focus (GTK_CONTAINER (widget), direction);
836 if (!GTK_CONTAINER (window)->focus_child)
837 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
848 gtk_window_key_release_event (GtkWidget *widget,
854 g_return_val_if_fail (widget != NULL, FALSE);
855 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
856 g_return_val_if_fail (event != NULL, FALSE);
858 window = GTK_WINDOW (widget);
860 if (window->focus_widget)
861 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
867 gtk_window_enter_notify_event (GtkWidget *widget,
868 GdkEventCrossing *event)
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);
878 gtk_window_leave_notify_event (GtkWidget *widget,
879 GdkEventCrossing *event)
881 g_return_val_if_fail (widget != NULL, FALSE);
882 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
883 g_return_val_if_fail (event != NULL, FALSE);
889 gtk_window_focus_in_event (GtkWidget *widget,
890 GdkEventFocus *event)
893 GdkEventFocus fevent;
895 g_return_val_if_fail (widget != NULL, FALSE);
896 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
897 g_return_val_if_fail (event != NULL, FALSE);
899 /* It appears spurious focus in events can occur when
900 * the window is hidden. So we'll just check to see if
901 * the window is visible before actually handling the
904 if (GTK_WIDGET_VISIBLE (widget))
906 window = GTK_WINDOW (widget);
907 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
909 fevent.type = GDK_FOCUS_CHANGE;
910 fevent.window = window->focus_widget->window;
913 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
921 gtk_window_focus_out_event (GtkWidget *widget,
922 GdkEventFocus *event)
925 GdkEventFocus fevent;
927 g_return_val_if_fail (widget != NULL, FALSE);
928 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
929 g_return_val_if_fail (event != NULL, FALSE);
931 window = GTK_WINDOW (widget);
932 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
934 fevent.type = GDK_FOCUS_CHANGE;
935 fevent.window = window->focus_widget->window;
938 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
945 gtk_window_style_set_event (GtkWidget *widget,
946 GdkEventClient *event)
948 GdkAtom atom_default_colors;
949 GtkStyle *style_newdefault;
952 GdkColor *data, *stylecolors;
954 GdkColormap *widget_cmap;
956 atom_default_colors = gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE);
958 if(gdk_property_get (GDK_ROOT_PARENT(),
960 gdk_atom_intern("STRING", FALSE),
962 sizeof(GdkColor) * GTK_STYLE_NUM_STYLECOLORS(),
967 (guchar **)&data) != TRUE) {
968 g_warning("gdk_property_get() failed in _GTK_STYLE_CHANGED handler\n");
971 if(retfmt != sizeof(gushort)*8) {
972 g_warning("retfmt (%d) != sizeof(gushort)*8 (%d)\n", retfmt,
976 /* We have the color data, now let's interpret it */
977 style_newdefault = gtk_widget_get_default_style();
978 gtk_style_ref(style_newdefault);
979 stylecolors = (GdkColor *) style_newdefault;
981 widget_cmap = gtk_widget_get_colormap(widget);
982 for(i = 0; i < GTK_STYLE_NUM_STYLECOLORS(); i++) {
983 stylecolors[i] = data[i];
984 gdk_color_alloc(widget_cmap, &stylecolors[i]);
987 gtk_widget_set_default_style(style_newdefault);
988 gtk_style_unref(style_newdefault);
990 /* Now we need to redraw everything */
991 gtk_widget_draw(widget, NULL);
992 gtk_widget_draw_children(widget);
996 gtk_window_client_event (GtkWidget *widget,
997 GdkEventClient *event)
999 GdkAtom atom_styleset;
1000 g_return_val_if_fail (widget != NULL, FALSE);
1001 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1002 g_return_val_if_fail (event != NULL, FALSE);
1004 atom_styleset = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
1006 if(event->message_type == atom_styleset) {
1007 gtk_window_style_set_event(widget, event);
1013 gtk_window_need_resize (GtkContainer *container)
1018 g_return_val_if_fail (container != NULL, FALSE);
1019 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
1023 window = GTK_WINDOW (container);
1024 if (window->handling_resize)
1027 if (GTK_WIDGET_VISIBLE (container))
1029 window->need_resize = TRUE;
1030 return_val = gtk_window_move_resize (GTK_WIDGET (window));
1031 window->need_resize = FALSE;
1038 gtk_real_window_move_resize (GtkWindow *window,
1046 g_return_val_if_fail (window != NULL, FALSE);
1047 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1048 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
1050 widget = GTK_WIDGET (window);
1052 if ((widget->requisition.width == 0) ||
1053 (widget->requisition.height == 0))
1055 widget->requisition.width = 200;
1056 widget->requisition.height = 200;
1059 if (!GTK_WIDGET_REALIZED (window))
1061 GtkAllocation allocation;
1065 allocation.width = widget->requisition.width;
1066 allocation.height = widget->requisition.height;
1068 gtk_widget_size_allocate (widget, &allocation);
1073 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1075 if ((window->auto_shrink &&
1076 ((width != widget->requisition.width) ||
1077 (height != widget->requisition.height))) ||
1078 (width < widget->requisition.width) ||
1079 (height < widget->requisition.height))
1081 window->resize_count += 1;
1082 if ((*x != -1) && (*y != -1))
1083 gdk_window_move_resize (widget->window, *x, *y,
1084 widget->requisition.width,
1085 widget->requisition.height);
1087 gdk_window_resize (widget->window,
1088 widget->requisition.width,
1089 widget->requisition.height);
1093 /* The window hasn't changed size but one of its children
1094 * queued a resize request. Which means that the allocation
1095 * is not sufficient for the requisition of some child.
1096 * We've already performed a size request at this point,
1097 * so we simply need to run through the list of resize
1098 * widgets and reallocate their sizes appropriately. We
1099 * make the optimization of not performing reallocation
1100 * for a widget who also has a parent in the resize widgets
1101 * list. GTK_RESIZE_NEEDED is used for flagging those
1102 * parents inside this function.
1104 GSList *resize_widgets;
1105 GSList *resize_containers;
1108 if ((*x != -1) && (*y != -1))
1109 gdk_window_move (widget->window, *x, *y);
1111 resize_widgets = GTK_CONTAINER (window)->resize_widgets;
1112 GTK_CONTAINER (window)->resize_widgets = NULL;
1114 for (node = resize_widgets; node; node = node->next)
1116 widget = node->data;
1118 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1120 while (widget && widget->parent &&
1121 ((widget->allocation.width < widget->requisition.width) ||
1122 (widget->allocation.height < widget->requisition.height)))
1123 widget = widget->parent;
1125 GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
1126 node->data = widget;
1129 resize_containers = NULL;
1131 for (node = resize_widgets; node; node = node->next)
1133 GtkWidget *resize_container;
1135 widget = node->data;
1137 if (!GTK_WIDGET_RESIZE_NEEDED (widget))
1140 resize_container = widget->parent;
1142 if (resize_container)
1144 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1145 widget = resize_container->parent;
1149 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1151 GTK_PRIVATE_UNSET_FLAG (resize_container, GTK_RESIZE_NEEDED);
1152 resize_container = widget;
1154 widget = widget->parent;
1158 resize_container = widget;
1160 if (!g_slist_find (resize_containers, resize_container))
1161 resize_containers = g_slist_prepend (resize_containers,
1164 g_slist_free (resize_widgets);
1166 for (node = resize_containers; node; node = node->next)
1168 widget = node->data;
1170 GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
1171 gtk_widget_size_allocate (widget, &widget->allocation);
1172 gtk_widget_queue_draw (widget);
1174 g_slist_free (resize_containers);
1181 gtk_window_move_resize (GtkWidget *widget)
1190 g_return_val_if_fail (widget != NULL, FALSE);
1191 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1193 window = GTK_WINDOW (widget);
1196 /* Remember old size, to know if we have to reset hints */
1197 width = widget->requisition.width;
1198 height = widget->requisition.height;
1199 gtk_widget_size_request (widget, &widget->requisition);
1201 if ((width != widget->requisition.width ||
1202 height != widget->requisition.height))
1203 gtk_window_set_hints (widget, &widget->requisition);
1207 width = widget->requisition.width;
1208 height = widget->requisition.height;
1210 if (window->use_uposition)
1211 switch (window->position)
1213 case GTK_WIN_POS_CENTER:
1214 x = (gdk_screen_width () - width) / 2;
1215 y = (gdk_screen_height () - height) / 2;
1216 gtk_widget_set_uposition (widget, x, y);
1218 case GTK_WIN_POS_MOUSE:
1219 gdk_window_get_pointer (NULL, &x, &y, NULL);
1224 screen_width = gdk_screen_width ();
1225 screen_height = gdk_screen_height ();
1229 else if (x > (screen_width - width))
1230 x = screen_width - width;
1234 else if (y > (screen_height - height))
1235 y = screen_height - height;
1237 gtk_widget_set_uposition (widget, x, y);
1241 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1242 &x, &y, width, height, &return_val);
1248 gtk_real_window_set_focus (GtkWindow *window,
1251 GdkEventFocus event;
1253 g_return_if_fail (window != NULL);
1254 g_return_if_fail (GTK_IS_WINDOW (window));
1256 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1259 if (window->focus_widget != focus)
1261 if (window->focus_widget)
1263 event.type = GDK_FOCUS_CHANGE;
1264 event.window = window->focus_widget->window;
1267 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1270 window->focus_widget = focus;
1272 if (window->focus_widget)
1274 event.type = GDK_FOCUS_CHANGE;
1275 event.window = window->focus_widget->window;
1278 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1284 gtk_window_set_hints (GtkWidget *widget,
1285 GtkRequisition *requisition)
1288 GtkWidgetAuxInfo *aux_info;
1292 g_return_if_fail (widget != NULL);
1293 g_return_if_fail (GTK_IS_WINDOW (widget));
1294 g_return_if_fail (requisition != NULL);
1296 if (GTK_WIDGET_REALIZED (widget))
1298 window = GTK_WINDOW (widget);
1304 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1305 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1309 flags |= GDK_HINT_POS;
1312 if (!window->allow_shrink)
1313 flags |= GDK_HINT_MIN_SIZE;
1314 if (!window->allow_grow)
1315 flags |= GDK_HINT_MAX_SIZE;
1317 gdk_window_set_hints (widget->window, ux, uy,
1318 requisition->width, requisition->height,
1319 requisition->width, requisition->height,
1322 if (window->use_uposition && (flags & GDK_HINT_POS))
1324 window->use_uposition = FALSE;
1325 gdk_window_move (widget->window, ux, uy);
1331 gtk_window_check_accelerator (GtkWindow *window,
1335 GtkAcceleratorTable *table;
1338 if ((key >= 0x20) && (key <= 0xFF))
1340 tmp = window->accelerator_tables;
1346 if (gtk_accelerator_table_check (table, key, mods))
1350 if (gtk_accelerator_table_check (NULL, key, mods))