1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gdk/gdkkeysyms.h"
24 #include "gtkprivate.h"
26 #include "gtksignal.h"
27 #include "gtkwindow.h"
28 #include "gtkbindings.h"
45 static void gtk_window_class_init (GtkWindowClass *klass);
46 static void gtk_window_init (GtkWindow *window);
47 static void gtk_window_set_arg (GtkObject *object,
50 static void gtk_window_get_arg (GtkObject *object,
53 static void gtk_window_shutdown (GtkObject *object);
54 static void gtk_window_destroy (GtkObject *object);
55 static void gtk_window_finalize (GtkObject *object);
56 static void gtk_window_show (GtkWidget *widget);
57 static void gtk_window_hide (GtkWidget *widget);
58 static void gtk_window_map (GtkWidget *widget);
59 static void gtk_window_unmap (GtkWidget *widget);
60 static void gtk_window_realize (GtkWidget *widget);
61 static void gtk_window_size_request (GtkWidget *widget,
62 GtkRequisition *requisition);
63 static void gtk_window_size_allocate (GtkWidget *widget,
64 GtkAllocation *allocation);
65 static gint gtk_window_expose_event (GtkWidget *widget,
66 GdkEventExpose *event);
67 static gint gtk_window_configure_event (GtkWidget *widget,
68 GdkEventConfigure *event);
69 static gint gtk_window_key_press_event (GtkWidget *widget,
71 static gint gtk_window_key_release_event (GtkWidget *widget,
73 static gint gtk_window_enter_notify_event (GtkWidget *widget,
74 GdkEventCrossing *event);
75 static gint gtk_window_leave_notify_event (GtkWidget *widget,
76 GdkEventCrossing *event);
77 static gint gtk_window_focus_in_event (GtkWidget *widget,
78 GdkEventFocus *event);
79 static gint gtk_window_focus_out_event (GtkWidget *widget,
80 GdkEventFocus *event);
81 static gint gtk_window_client_event (GtkWidget *widget,
82 GdkEventClient *event);
83 static void gtk_window_check_resize (GtkContainer *container);
84 static void gtk_real_window_set_focus (GtkWindow *window,
86 static void gtk_window_move_resize (GtkWindow *window);
87 static void gtk_window_set_hints (GtkWidget *widget,
88 GtkRequisition *requisition);
90 static void gtk_window_read_rcfiles (GtkWidget *widget,
91 GdkEventClient *event);
92 static void gtk_window_draw (GtkWidget *widget,
94 static void gtk_window_paint (GtkWidget *widget,
96 static gint gtk_window_expose (GtkWidget *widget,
97 GdkEventExpose *event);
98 static void gtk_window_style_set (GtkWidget *widget,
99 GtkStyle *previous_style);
101 static GtkBinClass *parent_class = NULL;
102 static guint window_signals[LAST_SIGNAL] = { 0 };
106 gtk_window_get_type (void)
108 static GtkType window_type = 0;
112 GtkTypeInfo window_info =
116 sizeof (GtkWindowClass),
117 (GtkClassInitFunc) gtk_window_class_init,
118 (GtkObjectInitFunc) gtk_window_init,
119 /* reserved_1 */ NULL,
120 /* reserved_2 */ NULL,
121 (GtkClassInitFunc) NULL,
124 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
131 gtk_window_class_init (GtkWindowClass *klass)
133 GtkObjectClass *object_class;
134 GtkWidgetClass *widget_class;
135 GtkContainerClass *container_class;
137 object_class = (GtkObjectClass*) klass;
138 widget_class = (GtkWidgetClass*) klass;
139 container_class = (GtkContainerClass*) klass;
141 parent_class = gtk_type_class (gtk_bin_get_type ());
143 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
144 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
145 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
146 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
147 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
148 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
150 window_signals[SET_FOCUS] =
151 gtk_signal_new ("set_focus",
154 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
155 gtk_marshal_NONE__POINTER,
159 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
161 object_class->set_arg = gtk_window_set_arg;
162 object_class->get_arg = gtk_window_get_arg;
163 object_class->shutdown = gtk_window_shutdown;
164 object_class->destroy = gtk_window_destroy;
165 object_class->finalize = gtk_window_finalize;
167 widget_class->show = gtk_window_show;
168 widget_class->hide = gtk_window_hide;
169 widget_class->map = gtk_window_map;
170 widget_class->unmap = gtk_window_unmap;
171 widget_class->realize = gtk_window_realize;
172 widget_class->size_request = gtk_window_size_request;
173 widget_class->size_allocate = gtk_window_size_allocate;
174 widget_class->expose_event = gtk_window_expose_event;
175 widget_class->configure_event = gtk_window_configure_event;
176 widget_class->key_press_event = gtk_window_key_press_event;
177 widget_class->key_release_event = gtk_window_key_release_event;
178 widget_class->enter_notify_event = gtk_window_enter_notify_event;
179 widget_class->leave_notify_event = gtk_window_leave_notify_event;
180 widget_class->focus_in_event = gtk_window_focus_in_event;
181 widget_class->focus_out_event = gtk_window_focus_out_event;
182 widget_class->client_event = gtk_window_client_event;
183 widget_class->style_set = gtk_window_style_set;
185 widget_class->draw = gtk_window_draw;
186 widget_class->expose_event = gtk_window_expose;
188 container_class->check_resize = gtk_window_check_resize;
190 klass->set_focus = gtk_real_window_set_focus;
194 gtk_window_init (GtkWindow *window)
196 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
197 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
199 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
201 window->title = NULL;
202 window->wmclass_name = g_strdup (g_get_prgname ());
203 window->wmclass_class = g_strdup (gdk_progclass);
204 window->type = GTK_WINDOW_TOPLEVEL;
205 window->focus_widget = NULL;
206 window->default_widget = NULL;
207 window->resize_count = 0;
208 window->allow_shrink = FALSE;
209 window->allow_grow = TRUE;
210 window->auto_shrink = FALSE;
211 window->handling_resize = FALSE;
212 window->position = GTK_WIN_POS_NONE;
213 window->use_uposition = TRUE;
214 window->modal = FALSE;
216 gtk_container_register_toplevel (GTK_CONTAINER (window));
220 gtk_window_set_arg (GtkObject *object,
226 window = GTK_WINDOW (object);
231 window->type = GTK_VALUE_ENUM (*arg);
234 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
236 case ARG_AUTO_SHRINK:
237 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
238 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
240 case ARG_ALLOW_SHRINK:
241 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
242 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
245 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
246 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
249 gtk_window_set_position (window, GTK_VALUE_ENUM (*arg));
257 gtk_window_get_arg (GtkObject *object,
263 window = GTK_WINDOW (object);
268 GTK_VALUE_ENUM (*arg) = window->type;
271 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
273 case ARG_AUTO_SHRINK:
274 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
276 case ARG_ALLOW_SHRINK:
277 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
280 GTK_VALUE_BOOL (*arg) = window->allow_grow;
283 GTK_VALUE_ENUM (*arg) = window->position;
286 arg->type = GTK_TYPE_INVALID;
292 gtk_window_new (GtkWindowType type)
296 window = gtk_type_new (gtk_window_get_type ());
300 return GTK_WIDGET (window);
304 gtk_window_set_title (GtkWindow *window,
307 g_return_if_fail (window != NULL);
308 g_return_if_fail (GTK_IS_WINDOW (window));
311 g_free (window->title);
312 window->title = g_strdup (title);
314 if (GTK_WIDGET_REALIZED (window))
315 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
319 gtk_window_set_wmclass (GtkWindow *window,
320 const gchar *wmclass_name,
321 const gchar *wmclass_class)
323 g_return_if_fail (window != NULL);
324 g_return_if_fail (GTK_IS_WINDOW (window));
326 g_free (window->wmclass_name);
327 window->wmclass_name = g_strdup (wmclass_name);
329 g_free (window->wmclass_class);
330 window->wmclass_class = g_strdup (wmclass_class);
332 if (GTK_WIDGET_REALIZED (window))
333 g_warning ("shouldn't set wmclass after window is realized!\n");
337 gtk_window_set_focus (GtkWindow *window,
340 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
344 gtk_window_set_default (GtkWindow *window,
345 GtkWidget *default_widget)
347 g_return_if_fail (window != NULL);
348 g_return_if_fail (GTK_IS_WINDOW (window));
351 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
353 if (window->default_widget != default_widget)
355 if (window->default_widget)
357 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
358 gtk_widget_draw_default (window->default_widget);
361 window->default_widget = default_widget;
363 if (window->default_widget)
365 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
366 gtk_widget_draw_default (window->default_widget);
372 gtk_window_set_policy (GtkWindow *window,
377 g_return_if_fail (window != NULL);
378 g_return_if_fail (GTK_IS_WINDOW (window));
380 window->allow_shrink = (allow_shrink != FALSE);
381 window->allow_grow = (allow_grow != FALSE);
382 window->auto_shrink = (auto_shrink != FALSE);
384 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
388 gtk_window_add_accel_group (GtkWindow *window,
389 GtkAccelGroup *accel_group)
391 g_return_if_fail (window != NULL);
392 g_return_if_fail (GTK_IS_WINDOW (window));
393 g_return_if_fail (accel_group != NULL);
395 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
399 gtk_window_remove_accel_group (GtkWindow *window,
400 GtkAccelGroup *accel_group)
402 g_return_if_fail (window != NULL);
403 g_return_if_fail (GTK_IS_WINDOW (window));
404 g_return_if_fail (accel_group != NULL);
406 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
410 gtk_window_set_position (GtkWindow *window,
411 GtkWindowPosition position)
413 g_return_if_fail (window != NULL);
414 g_return_if_fail (GTK_IS_WINDOW (window));
416 window->position = position;
420 gtk_window_activate_focus (GtkWindow *window)
422 g_return_val_if_fail (window != NULL, FALSE);
423 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
425 if (window->focus_widget)
427 gtk_widget_activate (window->focus_widget);
435 gtk_window_activate_default (GtkWindow *window)
437 g_return_val_if_fail (window != NULL, FALSE);
438 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
440 if (window->default_widget)
442 gtk_widget_activate (window->default_widget);
450 gtk_window_set_modal (GtkWindow *window, gboolean modal)
452 g_return_if_fail (window != NULL);
453 g_return_if_fail (GTK_IS_WINDOW (window));
455 /* If the widget was showed already, adjust it's grab state */
456 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(window)))
458 if (window->modal && !modal)
459 gtk_grab_remove (GTK_WIDGET(window));
460 else if (!window->modal && modal)
461 gtk_grab_add (GTK_WIDGET(window));
464 window->modal = modal;
468 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
470 GList *embedded_windows;
472 g_return_if_fail (window != NULL);
473 g_return_if_fail (GTK_IS_WINDOW (window));
475 g_print ("add %#x\n", xid);
477 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
478 if (embedded_windows)
479 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
480 g_quark_from_static_string ("gtk-embedded"));
481 embedded_windows = g_list_prepend (embedded_windows,
482 GUINT_TO_POINTER (xid));
484 gtk_object_set_data_full (GTK_OBJECT (window), "gtk-embedded",
487 (GtkDestroyNotify) g_list_free : NULL);
491 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
493 GList *embedded_windows;
496 g_return_if_fail (window != NULL);
497 g_return_if_fail (GTK_IS_WINDOW (window));
499 g_print ("remove %#x\n", xid);
501 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
502 if (embedded_windows)
503 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
504 g_quark_from_static_string ("gtk-embedded"));
506 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
509 embedded_windows = g_list_remove_link (embedded_windows, node);
510 g_list_free_1 (node);
513 gtk_object_set_data_full (GTK_OBJECT (window),
514 "gtk-embedded", embedded_windows,
516 (GtkDestroyNotify) g_list_free : NULL);
520 gtk_window_shutdown (GtkObject *object)
524 g_return_if_fail (object != NULL);
525 g_return_if_fail (GTK_IS_WINDOW (object));
527 window = GTK_WINDOW (object);
529 gtk_window_set_focus (window, NULL);
530 gtk_window_set_default (window, NULL);
532 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
536 gtk_window_destroy (GtkObject *object)
538 g_return_if_fail (object != NULL);
539 g_return_if_fail (GTK_IS_WINDOW (object));
541 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
543 GTK_OBJECT_CLASS (parent_class)->destroy (object);
547 gtk_window_finalize (GtkObject *object)
551 g_return_if_fail (object != NULL);
552 g_return_if_fail (GTK_IS_WINDOW (object));
554 window = GTK_WINDOW (object);
555 g_free (window->title);
556 g_free (window->wmclass_name);
557 g_free (window->wmclass_class);
559 GTK_OBJECT_CLASS(parent_class)->finalize (object);
563 gtk_window_show (GtkWidget *widget)
565 g_return_if_fail (widget != NULL);
566 g_return_if_fail (GTK_IS_WINDOW (widget));
568 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
569 gtk_container_check_resize (GTK_CONTAINER (widget));
570 gtk_widget_map (widget);
572 if (GTK_WINDOW(widget)->modal)
573 gtk_grab_add(widget);
578 gtk_window_hide (GtkWidget *widget)
580 g_return_if_fail (widget != NULL);
581 g_return_if_fail (GTK_IS_WINDOW (widget));
583 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
584 gtk_widget_unmap (widget);
586 if (GTK_WINDOW(widget)->modal)
587 gtk_grab_remove(widget);
592 gtk_window_map (GtkWidget *widget)
596 g_return_if_fail (widget != NULL);
597 g_return_if_fail (GTK_IS_WINDOW (widget));
599 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
601 window = GTK_WINDOW (widget);
603 if (window->bin.child &&
604 GTK_WIDGET_VISIBLE (window->bin.child) &&
605 !GTK_WIDGET_MAPPED (window->bin.child))
606 gtk_widget_map (window->bin.child);
608 gtk_window_set_hints (widget, &widget->requisition);
609 gdk_window_show (widget->window);
613 gtk_window_unmap (GtkWidget *widget)
617 g_return_if_fail (widget != NULL);
618 g_return_if_fail (GTK_IS_WINDOW (widget));
620 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
621 gdk_window_hide (widget->window);
623 window = GTK_WINDOW (widget);
624 window->use_uposition = TRUE;
628 gtk_window_realize (GtkWidget *widget)
631 GdkWindowAttr attributes;
632 gint attributes_mask;
634 g_return_if_fail (widget != NULL);
635 g_return_if_fail (GTK_IS_WINDOW (widget));
637 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
638 window = GTK_WINDOW (widget);
640 switch (window->type)
642 case GTK_WINDOW_TOPLEVEL:
643 attributes.window_type = GDK_WINDOW_TOPLEVEL;
645 case GTK_WINDOW_DIALOG:
646 attributes.window_type = GDK_WINDOW_DIALOG;
648 case GTK_WINDOW_POPUP:
649 attributes.window_type = GDK_WINDOW_TEMP;
653 attributes.title = window->title;
654 attributes.wmclass_name = window->wmclass_name;
655 attributes.wmclass_class = window->wmclass_class;
656 attributes.width = widget->allocation.width;
657 attributes.height = widget->allocation.height;
658 attributes.wclass = GDK_INPUT_OUTPUT;
659 attributes.visual = gtk_widget_get_visual (widget);
660 attributes.colormap = gtk_widget_get_colormap (widget);
661 attributes.event_mask = gtk_widget_get_events (widget);
662 attributes.event_mask |= (GDK_EXPOSURE_MASK |
664 GDK_ENTER_NOTIFY_MASK |
665 GDK_LEAVE_NOTIFY_MASK |
666 GDK_FOCUS_CHANGE_MASK |
669 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
670 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
671 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
673 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
674 gdk_window_set_user_data (widget->window, window);
676 widget->style = gtk_style_attach (widget->style, widget->window);
677 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
678 gtk_window_paint (widget, NULL);
682 gtk_window_size_request (GtkWidget *widget,
683 GtkRequisition *requisition)
687 g_return_if_fail (widget != NULL);
688 g_return_if_fail (GTK_IS_WINDOW (widget));
689 g_return_if_fail (requisition != NULL);
691 window = GTK_WINDOW (widget);
693 if (window->bin.child)
695 requisition->width = GTK_CONTAINER (window)->border_width * 2;
696 requisition->height = GTK_CONTAINER (window)->border_width * 2;
698 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
700 requisition->width += window->bin.child->requisition.width;
701 requisition->height += window->bin.child->requisition.height;
705 if (!GTK_WIDGET_VISIBLE (window))
706 GTK_CONTAINER (window)->need_resize = TRUE;
711 gtk_window_size_allocate (GtkWidget *widget,
712 GtkAllocation *allocation)
715 GtkAllocation child_allocation;
717 g_return_if_fail (widget != NULL);
718 g_return_if_fail (GTK_IS_WINDOW (widget));
719 g_return_if_fail (allocation != NULL);
721 window = GTK_WINDOW (widget);
722 widget->allocation = *allocation;
724 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
726 child_allocation.x = GTK_CONTAINER (window)->border_width;
727 child_allocation.y = GTK_CONTAINER (window)->border_width;
728 child_allocation.width = allocation->width - child_allocation.x * 2;
729 child_allocation.height = allocation->height - child_allocation.y * 2;
731 gtk_widget_size_allocate (window->bin.child, &child_allocation);
736 gtk_window_expose_event (GtkWidget *widget,
737 GdkEventExpose *event)
739 g_return_val_if_fail (widget != NULL, FALSE);
740 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
741 g_return_val_if_fail (event != NULL, FALSE);
743 if (GTK_WIDGET_DRAWABLE (widget))
744 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
745 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
751 gtk_window_configure_event (GtkWidget *widget,
752 GdkEventConfigure *event)
755 GtkAllocation allocation;
756 gboolean need_expose = FALSE;
758 g_return_val_if_fail (widget != NULL, FALSE);
759 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
760 g_return_val_if_fail (event != NULL, FALSE);
762 window = GTK_WINDOW (widget);
764 /* If the window was merely moved, do nothing */
765 if ((widget->allocation.width == event->width) &&
766 (widget->allocation.height == event->height))
768 if (window->resize_count == 0) /* The window was merely moved */
772 /* We asked for a new size, which was rejected, so the
773 * WM sent us a synthetic configure event. We won't
774 * get the expose event we would normally get (since
775 * we have ForgetGravity), so we need to fake it.
782 window->handling_resize = TRUE;
786 allocation.width = event->width;
787 allocation.height = event->height;
789 gtk_widget_size_allocate (widget, &allocation);
791 if (window->bin.child &&
792 GTK_WIDGET_VISIBLE (window->bin.child) &&
793 !GTK_WIDGET_MAPPED (window->bin.child))
794 gtk_widget_map (window->bin.child);
796 if (window->resize_count > 0)
797 window->resize_count -= 1;
802 temp_event.type = GDK_EXPOSE;
803 temp_event.expose.window = widget->window;
804 temp_event.expose.send_event = TRUE;
805 temp_event.expose.area.x = 0;
806 temp_event.expose.area.y = 0;
807 temp_event.expose.area.width = event->width;
808 temp_event.expose.area.height = event->height;
809 temp_event.expose.count = 0;
811 gtk_widget_event (widget, &temp_event);
814 window->handling_resize = FALSE;
820 gtk_window_key_press_event (GtkWidget *widget,
824 GtkDirectionType direction = 0;
827 g_return_val_if_fail (widget != NULL, FALSE);
828 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
829 g_return_val_if_fail (event != NULL, FALSE);
831 window = GTK_WINDOW (widget);
835 if (window->focus_widget)
837 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
841 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
845 switch (event->keyval)
848 if (window->focus_widget)
850 gtk_widget_activate (window->focus_widget);
856 if (window->default_widget)
858 gtk_widget_activate (window->default_widget);
861 else if (window->focus_widget)
863 gtk_widget_activate (window->focus_widget);
872 case GDK_ISO_Left_Tab:
873 switch (event->keyval)
876 direction = GTK_DIR_UP;
879 direction = GTK_DIR_DOWN;
882 direction = GTK_DIR_LEFT;
885 direction = GTK_DIR_RIGHT;
888 case GDK_ISO_Left_Tab:
889 if (event->state & GDK_SHIFT_MASK)
890 direction = GTK_DIR_TAB_BACKWARD;
892 direction = GTK_DIR_TAB_FORWARD;
895 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
898 gtk_container_focus (GTK_CONTAINER (widget), direction);
900 if (!GTK_CONTAINER (window)->focus_child)
901 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
908 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
909 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
915 gtk_window_key_release_event (GtkWidget *widget,
921 g_return_val_if_fail (widget != NULL, FALSE);
922 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
923 g_return_val_if_fail (event != NULL, FALSE);
925 window = GTK_WINDOW (widget);
927 if (window->focus_widget)
929 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
932 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
933 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
939 gtk_window_enter_notify_event (GtkWidget *widget,
940 GdkEventCrossing *event)
942 g_return_val_if_fail (widget != NULL, FALSE);
943 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
944 g_return_val_if_fail (event != NULL, FALSE);
950 gtk_window_leave_notify_event (GtkWidget *widget,
951 GdkEventCrossing *event)
953 g_return_val_if_fail (widget != NULL, FALSE);
954 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
955 g_return_val_if_fail (event != NULL, FALSE);
961 gtk_window_focus_in_event (GtkWidget *widget,
962 GdkEventFocus *event)
965 GdkEventFocus fevent;
967 g_return_val_if_fail (widget != NULL, FALSE);
968 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
969 g_return_val_if_fail (event != NULL, FALSE);
971 /* It appears spurious focus in events can occur when
972 * the window is hidden. So we'll just check to see if
973 * the window is visible before actually handling the
976 if (GTK_WIDGET_VISIBLE (widget))
978 window = GTK_WINDOW (widget);
979 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
981 fevent.type = GDK_FOCUS_CHANGE;
982 fevent.window = window->focus_widget->window;
985 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
993 gtk_window_focus_out_event (GtkWidget *widget,
994 GdkEventFocus *event)
997 GdkEventFocus fevent;
999 g_return_val_if_fail (widget != NULL, FALSE);
1000 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1001 g_return_val_if_fail (event != NULL, FALSE);
1003 window = GTK_WINDOW (widget);
1004 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
1006 fevent.type = GDK_FOCUS_CHANGE;
1007 fevent.window = window->focus_widget->window;
1010 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
1016 static GdkAtom atom_rcfiles = GDK_NONE;
1019 gtk_window_read_rcfiles (GtkWidget *widget,
1020 GdkEventClient *event)
1022 GList *embedded_windows;
1024 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
1025 if (embedded_windows)
1030 for(i = 0; i < 5; i++)
1032 sev.data_format = 32;
1033 sev.message_type = atom_rcfiles;
1035 while (embedded_windows)
1037 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
1038 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
1039 embedded_windows = embedded_windows->next;
1043 if (gtk_rc_reparse_all ())
1045 /* If the above returned true, some of our RC files are out
1046 * of date, so we need to reset all our widgets. Our other
1047 * toplevel windows will also get the message, but by
1048 * then, the RC file will up to date, so we have to tell
1053 toplevels = gtk_container_get_toplevels();
1056 gtk_widget_reset_rc_styles (toplevels->data);
1057 toplevels = toplevels->next;
1063 gtk_window_client_event (GtkWidget *widget,
1064 GdkEventClient *event)
1066 g_return_val_if_fail (widget != NULL, FALSE);
1067 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1068 g_return_val_if_fail (event != NULL, FALSE);
1071 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
1073 if(event->message_type == atom_rcfiles)
1074 gtk_window_read_rcfiles (widget, event);
1080 gtk_window_check_resize (GtkContainer *container)
1084 g_return_if_fail (container != NULL);
1085 g_return_if_fail (GTK_IS_WINDOW (container));
1087 window = GTK_WINDOW (container);
1088 if (!window->handling_resize)
1090 if (GTK_WIDGET_VISIBLE (container))
1091 gtk_window_move_resize (window);
1093 GTK_CONTAINER (window)->need_resize = TRUE;
1097 /* FIXME: we leave container->resize_widgets set under some
1100 gtk_window_move_resize (GtkWindow *window)
1103 GtkContainer *container;
1108 gboolean needed_resize;
1109 gboolean size_changed;
1111 g_return_if_fail (window != NULL);
1112 g_return_if_fail (GTK_IS_WINDOW (window));
1114 widget = GTK_WIDGET (window);
1115 container = GTK_CONTAINER (widget);
1117 /* Remember old size, to know if we have to reset hints */
1118 width = widget->requisition.width;
1119 height = widget->requisition.height;
1120 gtk_widget_size_request (widget, &widget->requisition);
1122 size_changed = ((width != widget->requisition.width) ||
1123 (height != widget->requisition.height));
1127 gboolean saved_use_upos;
1129 saved_use_upos = window->use_uposition;
1130 gtk_window_set_hints (widget, &widget->requisition);
1131 window->use_uposition = saved_use_upos;
1136 width = widget->requisition.width;
1137 height = widget->requisition.height;
1139 if (window->use_uposition)
1140 switch (window->position)
1142 case GTK_WIN_POS_CENTER:
1143 x = (gdk_screen_width () - width) / 2;
1144 y = (gdk_screen_height () - height) / 2;
1145 gtk_widget_set_uposition (widget, x, y);
1147 case GTK_WIN_POS_MOUSE:
1148 gdk_window_get_pointer (NULL, &x, &y, NULL);
1153 screen_width = gdk_screen_width ();
1154 screen_height = gdk_screen_height ();
1158 else if (x > (screen_width - width))
1159 x = screen_width - width;
1163 else if (y > (screen_height - height))
1164 y = screen_height - height;
1166 gtk_widget_set_uposition (widget, x, y);
1170 /* Now, do the resizing */
1172 needed_resize = container->need_resize;
1173 container->need_resize = FALSE;
1175 if ((widget->requisition.width == 0) ||
1176 (widget->requisition.height == 0))
1178 widget->requisition.width = 200;
1179 widget->requisition.height = 200;
1182 if (!GTK_WIDGET_REALIZED (window))
1184 GtkAllocation allocation;
1188 allocation.width = widget->requisition.width;
1189 allocation.height = widget->requisition.height;
1191 gtk_widget_size_allocate (widget, &allocation);
1196 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1198 /* As an optimization, we don't try to get a new size from the
1199 * window manager if we asked for the same size last time and
1203 (((window->auto_shrink &&
1204 ((width != widget->requisition.width) ||
1205 (height != widget->requisition.height)))) ||
1206 ((width < widget->requisition.width) ||
1207 (height < widget->requisition.height))))
1209 window->resize_count += 1;
1210 if ((x != -1) && (y != -1))
1211 gdk_window_move_resize (widget->window, x, y,
1212 widget->requisition.width,
1213 widget->requisition.height);
1215 gdk_window_resize (widget->window,
1216 widget->requisition.width,
1217 widget->requisition.height);
1219 else if (needed_resize)
1221 /* The windows contents changed size while it was not
1222 * visible, so reallocate everything, since we didn't
1223 * keep track of what changed
1225 GtkAllocation allocation;
1229 allocation.width = widget->requisition.width;
1230 allocation.height = widget->requisition.height;
1232 gtk_widget_size_allocate (widget, &allocation);
1236 if ((x != -1) && (y != -1))
1237 gdk_window_move (widget->window, x, y);
1239 gtk_container_resize_children (GTK_CONTAINER (window));
1244 gtk_real_window_set_focus (GtkWindow *window,
1247 GdkEventFocus event;
1249 g_return_if_fail (window != NULL);
1250 g_return_if_fail (GTK_IS_WINDOW (window));
1252 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1255 if (window->focus_widget != focus)
1257 if (window->focus_widget)
1259 event.type = GDK_FOCUS_CHANGE;
1260 event.window = window->focus_widget->window;
1263 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1266 window->focus_widget = focus;
1268 if (window->focus_widget)
1270 event.type = GDK_FOCUS_CHANGE;
1271 event.window = window->focus_widget->window;
1274 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1280 gtk_window_set_hints (GtkWidget *widget,
1281 GtkRequisition *requisition)
1284 GtkWidgetAuxInfo *aux_info;
1288 g_return_if_fail (widget != NULL);
1289 g_return_if_fail (GTK_IS_WINDOW (widget));
1290 g_return_if_fail (requisition != NULL);
1292 if (GTK_WIDGET_REALIZED (widget))
1294 window = GTK_WINDOW (widget);
1300 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1301 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1305 flags |= GDK_HINT_POS;
1308 if (!window->allow_shrink)
1309 flags |= GDK_HINT_MIN_SIZE;
1310 if (!window->allow_grow)
1311 flags |= GDK_HINT_MAX_SIZE;
1313 gdk_window_set_hints (widget->window, ux, uy,
1314 requisition->width, requisition->height,
1315 requisition->width, requisition->height,
1318 if (window->use_uposition && (flags & GDK_HINT_POS))
1320 window->use_uposition = FALSE;
1321 gdk_window_move (widget->window, ux, uy);
1327 gtk_window_paint (GtkWidget *widget,
1330 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
1331 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
1335 gtk_window_expose (GtkWidget *widget,
1336 GdkEventExpose *event)
1338 g_return_val_if_fail (widget != NULL, FALSE);
1339 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1340 g_return_val_if_fail (event != NULL, FALSE);
1342 gtk_window_paint (widget, &event->area);
1344 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
1345 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
1351 gtk_window_draw (GtkWidget *widget,
1354 gtk_window_paint (widget, area);
1356 if (GTK_WIDGET_CLASS (parent_class)->draw)
1357 (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
1361 gtk_window_style_set (GtkWidget *widget,
1362 GtkStyle *previous_style)
1366 if (GTK_WIDGET_REALIZED (widget) &&
1367 !GTK_WIDGET_NO_WINDOW (widget))
1369 gtk_style_set_background (widget->style, widget->window, widget->state);
1373 area.width = widget->allocation.width;
1374 area.height = widget->allocation.height;
1375 gtk_window_draw(widget, &area);
1377 if (GTK_WIDGET_DRAWABLE (widget))
1378 gdk_window_clear (widget->window);