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"
44 typedef gint (*GtkWindowSignal1) (GtkObject *object,
50 typedef void (*GtkWindowSignal2) (GtkObject *object,
54 static void gtk_window_marshal_signal_2 (GtkObject *object,
58 static void gtk_window_class_init (GtkWindowClass *klass);
59 static void gtk_window_init (GtkWindow *window);
60 static void gtk_window_set_arg (GtkWindow *window,
63 static void gtk_window_get_arg (GtkWindow *window,
66 static void gtk_window_destroy (GtkObject *object);
67 static void gtk_window_finalize (GtkObject *object);
68 static void gtk_window_show (GtkWidget *widget);
69 static void gtk_window_hide (GtkWidget *widget);
70 static void gtk_window_map (GtkWidget *widget);
71 static void gtk_window_unmap (GtkWidget *widget);
72 static void gtk_window_realize (GtkWidget *widget);
73 static void gtk_window_size_request (GtkWidget *widget,
74 GtkRequisition *requisition);
75 static void gtk_window_size_allocate (GtkWidget *widget,
76 GtkAllocation *allocation);
77 static gint gtk_window_expose_event (GtkWidget *widget,
78 GdkEventExpose *event);
79 static gint gtk_window_configure_event (GtkWidget *widget,
80 GdkEventConfigure *event);
81 static gint gtk_window_key_press_event (GtkWidget *widget,
83 static gint gtk_window_key_release_event (GtkWidget *widget,
85 static gint gtk_window_enter_notify_event (GtkWidget *widget,
86 GdkEventCrossing *event);
87 static gint gtk_window_leave_notify_event (GtkWidget *widget,
88 GdkEventCrossing *event);
89 static gint gtk_window_focus_in_event (GtkWidget *widget,
90 GdkEventFocus *event);
91 static gint gtk_window_focus_out_event (GtkWidget *widget,
92 GdkEventFocus *event);
93 static gint gtk_window_client_event (GtkWidget *widget,
94 GdkEventClient *event);
95 static void gtk_window_check_resize (GtkContainer *container);
96 static void gtk_real_window_set_focus (GtkWindow *window,
98 static void gtk_window_move_resize (GtkWindow *window);
99 static void gtk_window_set_hints (GtkWidget *widget,
100 GtkRequisition *requisition);
102 static void gtk_window_read_rcfiles (GtkWidget *widget,
103 GdkEventClient *event);
106 static GtkBinClass *parent_class = NULL;
107 static guint window_signals[LAST_SIGNAL] = { 0 };
111 gtk_window_get_type (void)
113 static GtkType window_type = 0;
117 GtkTypeInfo window_info =
121 sizeof (GtkWindowClass),
122 (GtkClassInitFunc) gtk_window_class_init,
123 (GtkObjectInitFunc) gtk_window_init,
124 (GtkArgSetFunc) gtk_window_set_arg,
125 (GtkArgGetFunc) gtk_window_get_arg,
128 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
135 gtk_window_class_init (GtkWindowClass *klass)
137 GtkObjectClass *object_class;
138 GtkWidgetClass *widget_class;
139 GtkContainerClass *container_class;
141 object_class = (GtkObjectClass*) klass;
142 widget_class = (GtkWidgetClass*) klass;
143 container_class = (GtkContainerClass*) klass;
145 parent_class = gtk_type_class (gtk_bin_get_type ());
147 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
148 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
149 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
150 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
151 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
152 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
154 window_signals[SET_FOCUS] =
155 gtk_signal_new ("set_focus",
158 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
159 gtk_window_marshal_signal_2,
163 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
165 object_class->destroy = gtk_window_destroy;
166 object_class->finalize = gtk_window_finalize;
168 widget_class->show = gtk_window_show;
169 widget_class->hide = gtk_window_hide;
170 widget_class->map = gtk_window_map;
171 widget_class->unmap = gtk_window_unmap;
172 widget_class->realize = gtk_window_realize;
173 widget_class->size_request = gtk_window_size_request;
174 widget_class->size_allocate = gtk_window_size_allocate;
175 widget_class->expose_event = gtk_window_expose_event;
176 widget_class->configure_event = gtk_window_configure_event;
177 widget_class->key_press_event = gtk_window_key_press_event;
178 widget_class->key_release_event = gtk_window_key_release_event;
179 widget_class->enter_notify_event = gtk_window_enter_notify_event;
180 widget_class->leave_notify_event = gtk_window_leave_notify_event;
181 widget_class->focus_in_event = gtk_window_focus_in_event;
182 widget_class->focus_out_event = gtk_window_focus_out_event;
183 widget_class->client_event = gtk_window_client_event;
185 container_class->check_resize = gtk_window_check_resize;
187 klass->set_focus = gtk_real_window_set_focus;
191 gtk_window_init (GtkWindow *window)
193 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
194 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
196 window->title = NULL;
197 window->wmclass_name = g_strdup (gdk_progname);
198 window->wmclass_class = g_strdup (gdk_progclass);
199 window->type = GTK_WINDOW_TOPLEVEL;
200 window->focus_widget = NULL;
201 window->default_widget = NULL;
202 window->resize_count = 0;
203 window->allow_shrink = FALSE;
204 window->allow_grow = TRUE;
205 window->auto_shrink = FALSE;
206 window->handling_resize = FALSE;
207 window->position = GTK_WIN_POS_NONE;
208 window->use_uposition = TRUE;
210 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
211 gtk_container_register_toplevel (GTK_CONTAINER (window));
215 gtk_window_set_arg (GtkWindow *window,
222 window->type = GTK_VALUE_ENUM (*arg);
225 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
227 case ARG_AUTO_SHRINK:
228 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
229 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
231 case ARG_ALLOW_SHRINK:
232 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
233 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
236 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
237 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
240 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
248 gtk_window_get_arg (GtkWindow *window,
255 GTK_VALUE_ENUM (*arg) = window->type;
258 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
260 case ARG_AUTO_SHRINK:
261 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
263 case ARG_ALLOW_SHRINK:
264 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
267 GTK_VALUE_BOOL (*arg) = window->allow_grow;
270 GTK_VALUE_ENUM (*arg) = window->position;
273 arg->type = GTK_TYPE_INVALID;
279 gtk_window_new (GtkWindowType type)
283 window = gtk_type_new (gtk_window_get_type ());
287 return GTK_WIDGET (window);
291 gtk_window_set_title (GtkWindow *window,
294 g_return_if_fail (window != NULL);
295 g_return_if_fail (GTK_IS_WINDOW (window));
298 g_free (window->title);
299 window->title = g_strdup (title);
301 if (GTK_WIDGET_REALIZED (window))
302 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
306 gtk_window_set_wmclass (GtkWindow *window,
307 const gchar *wmclass_name,
308 const gchar *wmclass_class)
310 g_return_if_fail (window != NULL);
311 g_return_if_fail (GTK_IS_WINDOW (window));
313 g_free (window->wmclass_name);
314 window->wmclass_name = g_strdup (wmclass_name);
316 g_free (window->wmclass_class);
317 window->wmclass_class = g_strdup (wmclass_class);
319 if (GTK_WIDGET_REALIZED (window))
320 g_warning ("shouldn't set wmclass after window is realized!\n");
324 gtk_window_set_focus (GtkWindow *window,
327 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
331 gtk_window_set_default (GtkWindow *window,
332 GtkWidget *default_widget)
334 g_return_if_fail (window != NULL);
335 g_return_if_fail (GTK_IS_WINDOW (window));
338 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
340 if (window->default_widget != default_widget)
342 if (window->default_widget)
344 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
345 gtk_widget_draw_default (window->default_widget);
348 window->default_widget = default_widget;
350 if (window->default_widget)
352 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
353 gtk_widget_draw_default (window->default_widget);
359 gtk_window_set_policy (GtkWindow *window,
364 g_return_if_fail (window != NULL);
365 g_return_if_fail (GTK_IS_WINDOW (window));
367 window->allow_shrink = (allow_shrink != FALSE);
368 window->allow_grow = (allow_grow != FALSE);
369 window->auto_shrink = (auto_shrink != FALSE);
371 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
375 gtk_window_add_accel_group (GtkWindow *window,
376 GtkAccelGroup *accel_group)
378 g_return_if_fail (window != NULL);
379 g_return_if_fail (GTK_IS_WINDOW (window));
380 g_return_if_fail (accel_group != NULL);
382 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
386 gtk_window_remove_accel_group (GtkWindow *window,
387 GtkAccelGroup *accel_group)
389 g_return_if_fail (window != NULL);
390 g_return_if_fail (GTK_IS_WINDOW (window));
391 g_return_if_fail (accel_group != NULL);
393 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
397 gtk_window_position (GtkWindow *window,
398 GtkWindowPosition position)
400 g_return_if_fail (window != NULL);
401 g_return_if_fail (GTK_IS_WINDOW (window));
403 window->position = position;
407 gtk_window_activate_focus (GtkWindow *window)
409 g_return_val_if_fail (window != NULL, FALSE);
410 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
412 if (window->focus_widget)
414 gtk_widget_activate (window->focus_widget);
422 gtk_window_activate_default (GtkWindow *window)
424 g_return_val_if_fail (window != NULL, FALSE);
425 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
427 if (window->default_widget)
429 gtk_widget_activate (window->default_widget);
437 gtk_window_marshal_signal_2 (GtkObject *object,
442 GtkWindowSignal2 rfunc;
444 rfunc = (GtkWindowSignal2) func;
446 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
450 gtk_window_destroy (GtkObject *object)
452 g_return_if_fail (object != NULL);
453 g_return_if_fail (GTK_IS_WINDOW (object));
455 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
457 if (GTK_OBJECT_CLASS (parent_class)->destroy)
458 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
462 gtk_window_finalize (GtkObject *object)
466 g_return_if_fail (object != NULL);
467 g_return_if_fail (GTK_IS_WINDOW (object));
469 window = GTK_WINDOW (object);
470 g_free (window->title);
471 g_free (window->wmclass_name);
472 g_free (window->wmclass_class);
474 GTK_OBJECT_CLASS(parent_class)->finalize (object);
478 gtk_window_show (GtkWidget *widget)
480 g_return_if_fail (widget != NULL);
481 g_return_if_fail (GTK_IS_WINDOW (widget));
483 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
484 gtk_container_check_resize (GTK_CONTAINER (widget));
485 gtk_widget_map (widget);
489 gtk_window_hide (GtkWidget *widget)
491 g_return_if_fail (widget != NULL);
492 g_return_if_fail (GTK_IS_WINDOW (widget));
494 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
495 gtk_widget_unmap (widget);
499 gtk_window_map (GtkWidget *widget)
503 g_return_if_fail (widget != NULL);
504 g_return_if_fail (GTK_IS_WINDOW (widget));
506 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
508 window = GTK_WINDOW (widget);
510 if (window->bin.child &&
511 GTK_WIDGET_VISIBLE (window->bin.child) &&
512 !GTK_WIDGET_MAPPED (window->bin.child))
513 gtk_widget_map (window->bin.child);
515 gtk_window_set_hints (widget, &widget->requisition);
516 gdk_window_show (widget->window);
520 gtk_window_unmap (GtkWidget *widget)
524 g_return_if_fail (widget != NULL);
525 g_return_if_fail (GTK_IS_WINDOW (widget));
527 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
528 gdk_window_hide (widget->window);
530 window = GTK_WINDOW (widget);
531 window->use_uposition = TRUE;
535 gtk_window_realize (GtkWidget *widget)
538 GdkWindowAttr attributes;
539 gint attributes_mask;
541 g_return_if_fail (widget != NULL);
542 g_return_if_fail (GTK_IS_WINDOW (widget));
544 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
545 window = GTK_WINDOW (widget);
547 switch (window->type)
549 case GTK_WINDOW_TOPLEVEL:
550 attributes.window_type = GDK_WINDOW_TOPLEVEL;
552 case GTK_WINDOW_DIALOG:
553 attributes.window_type = GDK_WINDOW_DIALOG;
555 case GTK_WINDOW_POPUP:
556 attributes.window_type = GDK_WINDOW_TEMP;
560 attributes.title = window->title;
561 attributes.wmclass_name = window->wmclass_name;
562 attributes.wmclass_class = window->wmclass_class;
563 attributes.width = widget->allocation.width;
564 attributes.height = widget->allocation.height;
565 attributes.wclass = GDK_INPUT_OUTPUT;
566 attributes.visual = gtk_widget_get_visual (widget);
567 attributes.colormap = gtk_widget_get_colormap (widget);
568 attributes.event_mask = gtk_widget_get_events (widget);
569 attributes.event_mask |= (GDK_EXPOSURE_MASK |
571 GDK_ENTER_NOTIFY_MASK |
572 GDK_LEAVE_NOTIFY_MASK |
573 GDK_FOCUS_CHANGE_MASK |
576 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
577 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
578 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
580 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
581 gdk_window_set_user_data (widget->window, window);
583 widget->style = gtk_style_attach (widget->style, widget->window);
584 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
588 gtk_window_size_request (GtkWidget *widget,
589 GtkRequisition *requisition)
593 g_return_if_fail (widget != NULL);
594 g_return_if_fail (GTK_IS_WINDOW (widget));
595 g_return_if_fail (requisition != NULL);
597 window = GTK_WINDOW (widget);
599 if (window->bin.child)
601 requisition->width = GTK_CONTAINER (window)->border_width * 2;
602 requisition->height = GTK_CONTAINER (window)->border_width * 2;
604 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
606 requisition->width += window->bin.child->requisition.width;
607 requisition->height += window->bin.child->requisition.height;
611 if (!GTK_WIDGET_VISIBLE (window))
612 GTK_CONTAINER (window)->need_resize = TRUE;
617 gtk_window_size_allocate (GtkWidget *widget,
618 GtkAllocation *allocation)
621 GtkAllocation child_allocation;
623 g_return_if_fail (widget != NULL);
624 g_return_if_fail (GTK_IS_WINDOW (widget));
625 g_return_if_fail (allocation != NULL);
627 window = GTK_WINDOW (widget);
628 widget->allocation = *allocation;
630 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
632 child_allocation.x = GTK_CONTAINER (window)->border_width;
633 child_allocation.y = GTK_CONTAINER (window)->border_width;
634 child_allocation.width = allocation->width - child_allocation.x * 2;
635 child_allocation.height = allocation->height - child_allocation.y * 2;
637 gtk_widget_size_allocate (window->bin.child, &child_allocation);
642 gtk_window_expose_event (GtkWidget *widget,
643 GdkEventExpose *event)
645 g_return_val_if_fail (widget != NULL, FALSE);
646 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
647 g_return_val_if_fail (event != NULL, FALSE);
649 if (GTK_WIDGET_DRAWABLE (widget))
650 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
651 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
657 gtk_window_configure_event (GtkWidget *widget,
658 GdkEventConfigure *event)
661 GtkAllocation allocation;
663 g_return_val_if_fail (widget != NULL, FALSE);
664 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
665 g_return_val_if_fail (event != NULL, FALSE);
667 window = GTK_WINDOW (widget);
669 /* If the window was merely moved, do nothing */
670 if ((widget->allocation.width == event->width) &&
671 (widget->allocation.height == event->height) &&
672 (window->resize_count == 0))
675 window->handling_resize = TRUE;
679 allocation.width = event->width;
680 allocation.height = event->height;
682 gtk_widget_size_allocate (widget, &allocation);
684 if (window->bin.child &&
685 GTK_WIDGET_VISIBLE (window->bin.child) &&
686 !GTK_WIDGET_MAPPED (window->bin.child))
687 gtk_widget_map (window->bin.child);
689 if (window->resize_count > 0)
690 window->resize_count -= 1;
692 window->handling_resize = FALSE;
698 gtk_window_key_press_event (GtkWidget *widget,
702 GtkDirectionType direction = 0;
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);
713 if (window->focus_widget)
715 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
719 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
723 switch (event->keyval)
726 if (window->focus_widget)
728 gtk_widget_activate (window->focus_widget);
734 if (window->default_widget)
736 gtk_widget_activate (window->default_widget);
739 else if (window->focus_widget)
741 gtk_widget_activate (window->focus_widget);
750 case GDK_ISO_Left_Tab:
751 switch (event->keyval)
754 direction = GTK_DIR_UP;
757 direction = GTK_DIR_DOWN;
760 direction = GTK_DIR_LEFT;
763 direction = GTK_DIR_RIGHT;
766 case GDK_ISO_Left_Tab:
767 if (event->state & GDK_SHIFT_MASK)
768 direction = GTK_DIR_TAB_BACKWARD;
770 direction = GTK_DIR_TAB_FORWARD;
773 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
776 gtk_container_focus (GTK_CONTAINER (widget), direction);
778 if (!GTK_CONTAINER (window)->focus_child)
779 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
786 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
787 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
793 gtk_window_key_release_event (GtkWidget *widget,
799 g_return_val_if_fail (widget != NULL, FALSE);
800 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
801 g_return_val_if_fail (event != NULL, FALSE);
803 window = GTK_WINDOW (widget);
805 if (window->focus_widget)
807 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
810 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
811 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
817 gtk_window_enter_notify_event (GtkWidget *widget,
818 GdkEventCrossing *event)
820 g_return_val_if_fail (widget != NULL, FALSE);
821 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
822 g_return_val_if_fail (event != NULL, FALSE);
828 gtk_window_leave_notify_event (GtkWidget *widget,
829 GdkEventCrossing *event)
831 g_return_val_if_fail (widget != NULL, FALSE);
832 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
833 g_return_val_if_fail (event != NULL, FALSE);
839 gtk_window_focus_in_event (GtkWidget *widget,
840 GdkEventFocus *event)
843 GdkEventFocus fevent;
845 g_return_val_if_fail (widget != NULL, FALSE);
846 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
847 g_return_val_if_fail (event != NULL, FALSE);
849 /* It appears spurious focus in events can occur when
850 * the window is hidden. So we'll just check to see if
851 * the window is visible before actually handling the
854 if (GTK_WIDGET_VISIBLE (widget))
856 window = GTK_WINDOW (widget);
857 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
859 fevent.type = GDK_FOCUS_CHANGE;
860 fevent.window = window->focus_widget->window;
863 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
871 gtk_window_focus_out_event (GtkWidget *widget,
872 GdkEventFocus *event)
875 GdkEventFocus fevent;
877 g_return_val_if_fail (widget != NULL, FALSE);
878 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
879 g_return_val_if_fail (event != NULL, FALSE);
881 window = GTK_WINDOW (widget);
882 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
884 fevent.type = GDK_FOCUS_CHANGE;
885 fevent.window = window->focus_widget->window;
888 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
895 gtk_window_read_rcfiles (GtkWidget *widget,
896 GdkEventClient *event)
900 if (gtk_rc_reparse_all ())
902 toplevels = gdk_window_get_toplevels();
906 gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
909 gtk_widget_reset_rc_styles (widget);
911 toplevels = toplevels->next;
913 g_list_free (toplevels);
918 gtk_window_client_event (GtkWidget *widget,
919 GdkEventClient *event)
921 static GdkAtom atom_rcfiles = GDK_NONE;
922 g_return_val_if_fail (widget != NULL, FALSE);
923 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
924 g_return_val_if_fail (event != NULL, FALSE);
927 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
929 if(event->message_type == atom_rcfiles)
930 gtk_window_read_rcfiles (widget, event);
936 gtk_window_check_resize (GtkContainer *container)
940 g_return_if_fail (container != NULL);
941 g_return_if_fail (GTK_IS_WINDOW (container));
943 window = GTK_WINDOW (container);
944 if (!window->handling_resize)
946 if (GTK_WIDGET_VISIBLE (container))
947 gtk_window_move_resize (window);
949 GTK_CONTAINER (window)->need_resize = TRUE;
953 /* FIXME: we leave container->resize_widgets set under some
956 gtk_window_move_resize (GtkWindow *window)
959 GtkContainer *container;
964 gboolean needed_resize;
966 g_return_if_fail (window != NULL);
967 g_return_if_fail (GTK_IS_WINDOW (window));
969 widget = GTK_WIDGET (window);
970 container = GTK_CONTAINER (widget);
972 /* Remember old size, to know if we have to reset hints */
973 width = widget->requisition.width;
974 height = widget->requisition.height;
975 gtk_widget_size_request (widget, &widget->requisition);
977 if ((width != widget->requisition.width ||
978 height != widget->requisition.height))
979 gtk_window_set_hints (widget, &widget->requisition);
983 width = widget->requisition.width;
984 height = widget->requisition.height;
986 if (window->use_uposition)
987 switch (window->position)
989 case GTK_WIN_POS_CENTER:
990 x = (gdk_screen_width () - width) / 2;
991 y = (gdk_screen_height () - height) / 2;
992 gtk_widget_set_uposition (widget, x, y);
994 case GTK_WIN_POS_MOUSE:
995 gdk_window_get_pointer (NULL, &x, &y, NULL);
1000 screen_width = gdk_screen_width ();
1001 screen_height = gdk_screen_height ();
1005 else if (x > (screen_width - width))
1006 x = screen_width - width;
1010 else if (y > (screen_height - height))
1011 y = screen_height - height;
1013 gtk_widget_set_uposition (widget, x, y);
1017 /* Now, do the resizing */
1019 needed_resize = container->need_resize;
1020 container->need_resize = FALSE;
1022 if ((widget->requisition.width == 0) ||
1023 (widget->requisition.height == 0))
1025 widget->requisition.width = 200;
1026 widget->requisition.height = 200;
1029 if (!GTK_WIDGET_REALIZED (window))
1031 GtkAllocation allocation;
1035 allocation.width = widget->requisition.width;
1036 allocation.height = widget->requisition.height;
1038 gtk_widget_size_allocate (widget, &allocation);
1043 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1045 if ((window->auto_shrink &&
1046 ((width != widget->requisition.width) ||
1047 (height != widget->requisition.height))) ||
1048 (width < widget->requisition.width) ||
1049 (height < widget->requisition.height))
1051 window->resize_count += 1;
1052 if ((x != -1) && (y != -1))
1053 gdk_window_move_resize (widget->window, x, y,
1054 widget->requisition.width,
1055 widget->requisition.height);
1057 gdk_window_resize (widget->window,
1058 widget->requisition.width,
1059 widget->requisition.height);
1061 else if (needed_resize)
1063 /* The windows contents changed size while it was not
1064 * visible, so reallocate everything, since we didn't
1065 * keep track of what changed
1067 GtkAllocation allocation;
1071 allocation.width = widget->requisition.width;
1072 allocation.height = widget->requisition.height;
1074 gtk_widget_size_allocate (widget, &allocation);
1075 gtk_container_clear_resize_widgets (GTK_CONTAINER (window));
1079 if ((x != -1) && (y != -1))
1080 gdk_window_move (widget->window, x, y);
1082 gtk_container_resize_children (GTK_CONTAINER (window));
1087 gtk_real_window_set_focus (GtkWindow *window,
1090 GdkEventFocus event;
1092 g_return_if_fail (window != NULL);
1093 g_return_if_fail (GTK_IS_WINDOW (window));
1095 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1098 if (window->focus_widget != focus)
1100 if (window->focus_widget)
1102 event.type = GDK_FOCUS_CHANGE;
1103 event.window = window->focus_widget->window;
1106 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1109 window->focus_widget = focus;
1111 if (window->focus_widget)
1113 event.type = GDK_FOCUS_CHANGE;
1114 event.window = window->focus_widget->window;
1117 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1123 gtk_window_set_hints (GtkWidget *widget,
1124 GtkRequisition *requisition)
1127 GtkWidgetAuxInfo *aux_info;
1131 g_return_if_fail (widget != NULL);
1132 g_return_if_fail (GTK_IS_WINDOW (widget));
1133 g_return_if_fail (requisition != NULL);
1135 if (GTK_WIDGET_REALIZED (widget))
1137 window = GTK_WINDOW (widget);
1143 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1144 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1148 flags |= GDK_HINT_POS;
1151 if (!window->allow_shrink)
1152 flags |= GDK_HINT_MIN_SIZE;
1153 if (!window->allow_grow)
1154 flags |= GDK_HINT_MAX_SIZE;
1156 gdk_window_set_hints (widget->window, ux, uy,
1157 requisition->width, requisition->height,
1158 requisition->width, requisition->height,
1161 if (window->use_uposition && (flags & GDK_HINT_POS))
1163 window->use_uposition = FALSE;
1164 gdk_window_move (widget->window, ux, uy);