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 "gtksignal.h"
24 #include "gtkwindow.h"
32 typedef gint (*GtkWindowSignal1) (GtkObject *object,
40 static void gtk_window_marshal_signal_1 (GtkObject *object,
45 static void gtk_window_class_init (GtkWindowClass *klass);
46 static void gtk_window_init (GtkWindow *window);
47 static void gtk_window_arg (GtkWindow *window,
49 static void gtk_window_destroy (GtkObject *object);
50 static void gtk_window_show (GtkWidget *widget);
51 static void gtk_window_hide (GtkWidget *widget);
52 static void gtk_window_map (GtkWidget *widget);
53 static void gtk_window_unmap (GtkWidget *widget);
54 static void gtk_window_realize (GtkWidget *widget);
55 static void gtk_window_size_request (GtkWidget *widget,
56 GtkRequisition *requisition);
57 static void gtk_window_size_allocate (GtkWidget *widget,
58 GtkAllocation *allocation);
59 static gint gtk_window_expose_event (GtkWidget *widget,
60 GdkEventExpose *event);
61 static gint gtk_window_configure_event (GtkWidget *widget,
62 GdkEventConfigure *event);
63 static gint gtk_window_key_press_event (GtkWidget *widget,
65 static gint gtk_window_key_release_event (GtkWidget *widget,
67 static gint gtk_window_enter_notify_event (GtkWidget *widget,
68 GdkEventCrossing *event);
69 static gint gtk_window_leave_notify_event (GtkWidget *widget,
70 GdkEventCrossing *event);
71 static gint gtk_window_focus_in_event (GtkWidget *widget,
72 GdkEventFocus *event);
73 static gint gtk_window_focus_out_event (GtkWidget *widget,
74 GdkEventFocus *event);
75 static gint gtk_window_client_event (GtkWidget *widget,
76 GdkEventClient *event);
77 static gint gtk_window_need_resize (GtkContainer *container);
78 static gint gtk_real_window_move_resize (GtkWindow *window,
83 static gint gtk_window_move_resize (GtkWidget *widget);
84 static void gtk_window_set_hints (GtkWidget *widget,
85 GtkRequisition *requisition);
86 static gint gtk_window_check_accelerator (GtkWindow *window,
91 static GtkBinClass *parent_class = NULL;
92 static gint window_signals[LAST_SIGNAL] = { 0 };
96 gtk_window_get_type ()
98 static guint window_type = 0;
102 GtkTypeInfo window_info =
106 sizeof (GtkWindowClass),
107 (GtkClassInitFunc) gtk_window_class_init,
108 (GtkObjectInitFunc) gtk_window_init,
109 (GtkArgFunc) gtk_window_arg,
112 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
119 gtk_window_class_init (GtkWindowClass *klass)
121 GtkObjectClass *object_class;
122 GtkWidgetClass *widget_class;
123 GtkContainerClass *container_class;
125 object_class = (GtkObjectClass*) klass;
126 widget_class = (GtkWidgetClass*) klass;
127 container_class = (GtkContainerClass*) klass;
129 parent_class = gtk_type_class (gtk_bin_get_type ());
131 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE);
132 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING);
133 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL);
134 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL);
135 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL);
137 window_signals[MOVE_RESIZE] =
138 gtk_signal_new ("move_resize",
141 GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
142 gtk_window_marshal_signal_1,
144 GTK_TYPE_POINTER, GTK_TYPE_POINTER,
145 GTK_TYPE_INT, GTK_TYPE_INT);
147 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
149 object_class->destroy = gtk_window_destroy;
151 widget_class->show = gtk_window_show;
152 widget_class->hide = gtk_window_hide;
153 widget_class->map = gtk_window_map;
154 widget_class->unmap = gtk_window_unmap;
155 widget_class->realize = gtk_window_realize;
156 widget_class->size_request = gtk_window_size_request;
157 widget_class->size_allocate = gtk_window_size_allocate;
158 widget_class->expose_event = gtk_window_expose_event;
159 widget_class->configure_event = gtk_window_configure_event;
160 widget_class->key_press_event = gtk_window_key_press_event;
161 widget_class->key_release_event = gtk_window_key_release_event;
162 widget_class->enter_notify_event = gtk_window_enter_notify_event;
163 widget_class->leave_notify_event = gtk_window_leave_notify_event;
164 widget_class->focus_in_event = gtk_window_focus_in_event;
165 widget_class->focus_out_event = gtk_window_focus_out_event;
166 widget_class->client_event = gtk_window_client_event;
168 container_class->need_resize = gtk_window_need_resize;
170 klass->move_resize = gtk_real_window_move_resize;
174 gtk_window_init (GtkWindow *window)
176 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
177 GTK_WIDGET_SET_FLAGS (window, GTK_ANCHORED);
179 window->title = NULL;
180 window->wmclass_name = NULL;
181 window->wmclass_class = NULL;
182 window->type = GTK_WINDOW_TOPLEVEL;
183 window->accelerator_tables = NULL;
184 window->focus_widget = NULL;
185 window->default_widget = NULL;
186 window->resize_count = 0;
187 window->need_resize = FALSE;
188 window->allow_shrink = FALSE;
189 window->allow_grow = TRUE;
190 window->auto_shrink = FALSE;
191 window->handling_resize = FALSE;
192 window->position = GTK_WIN_POS_NONE;
193 window->use_uposition = TRUE;
197 gtk_window_arg (GtkWindow *window,
200 if (strcmp (arg->name, "type") == 0)
202 window->type = GTK_VALUE_ENUM(*arg);
204 else if (strcmp (arg->name, "title") == 0)
206 gtk_window_set_title (window, GTK_VALUE_STRING(*arg));
208 else if (strcmp (arg->name, "auto_shrink") == 0)
210 window->auto_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
212 else if (strcmp (arg->name, "allow_shrink") == 0)
214 window->allow_shrink = (GTK_VALUE_BOOL(*arg) != FALSE);
216 else if (strcmp (arg->name, "allow_grow") == 0)
218 window->allow_grow = (GTK_VALUE_BOOL(*arg) != FALSE);
223 gtk_window_new (GtkWindowType type)
227 window = gtk_type_new (gtk_window_get_type ());
231 return GTK_WIDGET (window);
235 gtk_window_set_title (GtkWindow *window,
238 g_return_if_fail (window != NULL);
239 g_return_if_fail (GTK_IS_WINDOW (window));
242 g_free (window->title);
243 window->title = g_strdup (title);
245 if (GTK_WIDGET_REALIZED (window))
246 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
250 gtk_window_set_wmclass (GtkWindow *window,
252 gchar *wmclass_class)
254 g_return_if_fail (window != NULL);
255 g_return_if_fail (GTK_IS_WINDOW (window));
257 if (window->wmclass_name)
258 g_free (window->wmclass_name);
259 window->wmclass_name = g_strdup (wmclass_name);
261 if (window->wmclass_class)
262 g_free (window->wmclass_class);
263 window->wmclass_class = g_strdup (wmclass_class);
265 if (GTK_WIDGET_REALIZED (window))
266 g_warning ("shouldn't set wmclass after window is realized!\n");
270 gtk_window_set_focus (GtkWindow *window,
275 g_return_if_fail (window != NULL);
276 g_return_if_fail (GTK_IS_WINDOW (window));
278 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
281 if (window->focus_widget != focus)
283 if (window->focus_widget)
285 event.type = GDK_FOCUS_CHANGE;
286 event.window = window->focus_widget->window;
289 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
292 window->focus_widget = focus;
294 if (window->focus_widget)
296 event.type = GDK_FOCUS_CHANGE;
297 event.window = window->focus_widget->window;
300 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
306 gtk_window_set_default (GtkWindow *window,
309 g_return_if_fail (window != NULL);
310 g_return_if_fail (GTK_IS_WINDOW (window));
311 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (defaultw));
313 if (window->default_widget != defaultw)
315 if (window->default_widget)
317 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
318 gtk_widget_draw_default (window->default_widget);
321 window->default_widget = defaultw;
323 if (window->default_widget)
325 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
326 gtk_widget_draw_default (window->default_widget);
332 gtk_window_set_policy (GtkWindow *window,
337 g_return_if_fail (window != NULL);
338 g_return_if_fail (GTK_IS_WINDOW (window));
340 window->allow_shrink = (allow_shrink != FALSE);
341 window->allow_grow = (allow_grow != FALSE);
342 window->auto_shrink = (auto_shrink != FALSE);
346 gtk_window_add_accelerator_table (GtkWindow *window,
347 GtkAcceleratorTable *table)
349 g_return_if_fail (window != NULL);
350 g_return_if_fail (GTK_IS_WINDOW (window));
352 gtk_accelerator_table_ref (table);
353 window->accelerator_tables = g_list_prepend (window->accelerator_tables, table);
357 gtk_window_remove_accelerator_table (GtkWindow *window,
358 GtkAcceleratorTable *table)
360 g_return_if_fail (window != NULL);
361 g_return_if_fail (GTK_IS_WINDOW (window));
363 window->accelerator_tables = g_list_remove (window->accelerator_tables, table);
364 gtk_accelerator_table_unref (table);
368 gtk_window_position (GtkWindow *window,
369 GtkWindowPosition position)
371 g_return_if_fail (window != NULL);
372 g_return_if_fail (GTK_IS_WINDOW (window));
374 window->position = position;
378 gtk_window_marshal_signal_1 (GtkObject *object,
383 GtkWindowSignal1 rfunc;
386 rfunc = (GtkWindowSignal1) func;
387 return_val = GTK_RETLOC_BOOL (args[4]);
389 *return_val = (* rfunc) (object,
390 GTK_VALUE_POINTER (args[0]),
391 GTK_VALUE_POINTER (args[1]),
392 GTK_VALUE_INT (args[2]),
393 GTK_VALUE_INT (args[3]),
398 gtk_window_destroy (GtkObject *object)
402 g_return_if_fail (object != NULL);
403 g_return_if_fail (GTK_IS_WINDOW (object));
405 window = GTK_WINDOW (object);
406 g_free (window->title);
408 if (GTK_OBJECT_CLASS (parent_class)->destroy)
409 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
413 gtk_window_show (GtkWidget *widget)
415 g_return_if_fail (widget != NULL);
416 g_return_if_fail (GTK_IS_WINDOW (widget));
418 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
419 gtk_widget_map (widget);
423 gtk_window_hide (GtkWidget *widget)
425 g_return_if_fail (widget != NULL);
426 g_return_if_fail (GTK_IS_WINDOW (widget));
428 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
429 gtk_widget_unmap (widget);
433 gtk_window_map (GtkWidget *widget)
437 g_return_if_fail (widget != NULL);
438 g_return_if_fail (GTK_IS_WINDOW (widget));
440 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
441 GTK_WIDGET_UNSET_FLAGS (widget, GTK_UNMAPPED);
443 gtk_window_move_resize (widget);
444 window = GTK_WINDOW (widget);
446 if (window->bin.child &&
447 GTK_WIDGET_VISIBLE (window->bin.child) &&
448 !GTK_WIDGET_MAPPED (window->bin.child))
449 gtk_widget_map (window->bin.child);
451 gtk_window_set_hints (widget, &widget->requisition);
452 gdk_window_show (widget->window);
456 gtk_window_unmap (GtkWidget *widget)
460 g_return_if_fail (widget != NULL);
461 g_return_if_fail (GTK_IS_WINDOW (widget));
463 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
464 GTK_WIDGET_SET_FLAGS (widget, GTK_UNMAPPED);
465 gdk_window_hide (widget->window);
467 window = GTK_WINDOW (widget);
468 window->use_uposition = TRUE;
472 gtk_window_realize (GtkWidget *widget)
475 GdkWindowAttr attributes;
476 gint attributes_mask;
478 g_return_if_fail (widget != NULL);
479 g_return_if_fail (GTK_IS_WINDOW (widget));
481 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
482 window = GTK_WINDOW (widget);
484 switch (window->type)
486 case GTK_WINDOW_TOPLEVEL:
487 attributes.window_type = GDK_WINDOW_TOPLEVEL;
489 case GTK_WINDOW_DIALOG:
490 attributes.window_type = GDK_WINDOW_DIALOG;
492 case GTK_WINDOW_POPUP:
493 attributes.window_type = GDK_WINDOW_TEMP;
497 attributes.title = window->title;
498 attributes.wmclass_name = window->wmclass_name;
499 attributes.wmclass_class = window->wmclass_class;
500 attributes.width = widget->allocation.width;
501 attributes.height = widget->allocation.height;
502 attributes.wclass = GDK_INPUT_OUTPUT;
503 attributes.visual = gtk_widget_get_visual (widget);
504 attributes.colormap = gtk_widget_get_colormap (widget);
505 attributes.event_mask = gtk_widget_get_events (widget);
506 attributes.event_mask |= (GDK_EXPOSURE_MASK |
508 GDK_ENTER_NOTIFY_MASK |
509 GDK_LEAVE_NOTIFY_MASK |
510 GDK_FOCUS_CHANGE_MASK |
513 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
514 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
515 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
517 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
518 gdk_window_set_user_data (widget->window, window);
520 widget->style = gtk_style_attach (widget->style, widget->window);
521 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
525 gtk_window_size_request (GtkWidget *widget,
526 GtkRequisition *requisition)
530 g_return_if_fail (widget != NULL);
531 g_return_if_fail (GTK_IS_WINDOW (widget));
532 g_return_if_fail (requisition != NULL);
534 window = GTK_WINDOW (widget);
536 if (window->bin.child)
538 requisition->width = GTK_CONTAINER (window)->border_width * 2;
539 requisition->height = GTK_CONTAINER (window)->border_width * 2;
541 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
543 requisition->width += window->bin.child->requisition.width;
544 requisition->height += window->bin.child->requisition.height;
548 if (!GTK_WIDGET_VISIBLE (window))
549 window->need_resize = TRUE;
554 gtk_window_size_allocate (GtkWidget *widget,
555 GtkAllocation *allocation)
558 GtkAllocation child_allocation;
560 g_return_if_fail (widget != NULL);
561 g_return_if_fail (GTK_IS_WINDOW (widget));
562 g_return_if_fail (allocation != NULL);
564 window = GTK_WINDOW (widget);
565 widget->allocation = *allocation;
567 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
569 child_allocation.x = GTK_CONTAINER (window)->border_width;
570 child_allocation.y = GTK_CONTAINER (window)->border_width;
571 child_allocation.width = allocation->width - child_allocation.x * 2;
572 child_allocation.height = allocation->height - child_allocation.y * 2;
574 gtk_widget_size_allocate (window->bin.child, &child_allocation);
579 gtk_window_expose_event (GtkWidget *widget,
580 GdkEventExpose *event)
582 g_return_val_if_fail (widget != NULL, FALSE);
583 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
584 g_return_val_if_fail (event != NULL, FALSE);
586 if (!GTK_WIDGET_UNMAPPED (widget))
587 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
589 if (GTK_WIDGET_DRAWABLE (widget))
590 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
591 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
597 gtk_window_configure_event (GtkWidget *widget,
598 GdkEventConfigure *event)
601 GtkAllocation allocation;
603 g_return_val_if_fail (widget != NULL, FALSE);
604 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
605 g_return_val_if_fail (event != NULL, FALSE);
607 window = GTK_WINDOW (widget);
608 window->handling_resize = TRUE;
612 allocation.width = event->width;
613 allocation.height = event->height;
615 gtk_widget_size_allocate (widget, &allocation);
617 if (window->bin.child &&
618 GTK_WIDGET_VISIBLE (window->bin.child) &&
619 !GTK_WIDGET_MAPPED (window->bin.child))
620 gtk_widget_map (window->bin.child);
622 window->resize_count -= 1;
623 if (window->resize_count == 0)
625 if ((event->width != widget->requisition.width) ||
626 (event->height != widget->requisition.height))
628 window->resize_count += 1;
629 gdk_window_resize (widget->window,
630 widget->requisition.width,
631 widget->requisition.height);
634 else if (window->resize_count < 0)
636 window->resize_count = 0;
639 window->handling_resize = FALSE;
645 gtk_window_key_press_event (GtkWidget *widget,
649 GtkDirectionType direction = 0;
652 g_return_val_if_fail (widget != NULL, FALSE);
653 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
654 g_return_val_if_fail (event != NULL, FALSE);
656 window = GTK_WINDOW (widget);
659 if (window->focus_widget)
660 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
662 if (!return_val && gtk_window_check_accelerator (window, event->keyval, event->state))
667 switch (event->keyval)
670 if (window->focus_widget)
672 gtk_widget_activate (window->focus_widget);
678 if (window->default_widget)
680 gtk_widget_activate (window->default_widget);
683 else if (window->focus_widget)
685 gtk_widget_activate (window->focus_widget);
694 switch (event->keyval)
697 direction = GTK_DIR_UP;
700 direction = GTK_DIR_DOWN;
703 direction = GTK_DIR_LEFT;
706 direction = GTK_DIR_RIGHT;
709 if (event->state & GDK_SHIFT_MASK)
710 direction = GTK_DIR_TAB_BACKWARD;
712 direction = GTK_DIR_TAB_FORWARD;
715 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
718 gtk_container_focus (GTK_CONTAINER (widget), direction);
720 if (!GTK_CONTAINER (window)->focus_child)
721 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
732 gtk_window_key_release_event (GtkWidget *widget,
738 g_return_val_if_fail (widget != NULL, FALSE);
739 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
740 g_return_val_if_fail (event != NULL, FALSE);
742 window = GTK_WINDOW (widget);
743 if (window->focus_widget)
744 return_val = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
750 gtk_window_enter_notify_event (GtkWidget *widget,
751 GdkEventCrossing *event)
753 g_return_val_if_fail (widget != NULL, FALSE);
754 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
755 g_return_val_if_fail (event != NULL, FALSE);
761 gtk_window_leave_notify_event (GtkWidget *widget,
762 GdkEventCrossing *event)
764 g_return_val_if_fail (widget != NULL, FALSE);
765 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
766 g_return_val_if_fail (event != NULL, FALSE);
772 gtk_window_focus_in_event (GtkWidget *widget,
773 GdkEventFocus *event)
776 GdkEventFocus fevent;
778 g_return_val_if_fail (widget != NULL, FALSE);
779 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
780 g_return_val_if_fail (event != NULL, FALSE);
782 /* It appears spurious focus in events can occur when
783 * the window is hidden. So we'll just check to see if
784 * the window is visible before actually handling the
787 if (GTK_WIDGET_VISIBLE (widget))
789 window = GTK_WINDOW (widget);
790 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
792 fevent.type = GDK_FOCUS_CHANGE;
793 fevent.window = window->focus_widget->window;
796 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
804 gtk_window_focus_out_event (GtkWidget *widget,
805 GdkEventFocus *event)
808 GdkEventFocus fevent;
810 g_return_val_if_fail (widget != NULL, FALSE);
811 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
812 g_return_val_if_fail (event != NULL, FALSE);
814 window = GTK_WINDOW (widget);
815 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
817 fevent.type = GDK_FOCUS_CHANGE;
818 fevent.window = window->focus_widget->window;
821 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
828 gtk_window_style_set_event (GtkWidget *widget,
829 GdkEventClient *event)
831 GdkAtom atom_default_colors;
832 GtkStyle *style_newdefault;
835 GdkColor *data, *stylecolors;
837 GdkColormap *widget_cmap;
839 atom_default_colors = gdk_atom_intern("_GTK_DEFAULT_COLORS", FALSE);
841 if(gdk_property_get (GDK_ROOT_PARENT(),
845 sizeof(GdkColor) * GTK_STYLE_NUM_STYLECOLORS(),
850 (guchar **)&data) != TRUE
851 || retfmt != sizeof(gushort)) {
852 g_warning("gdk_property_get() failed in _GTK_STYLE_CHANGED\n");
855 /* We have the color data, now let's interpret it */
856 style_newdefault = gtk_widget_get_default_style();
857 gtk_style_ref(style_newdefault);
858 stylecolors = (GdkColor *) style_newdefault;
860 widget_cmap = gtk_widget_get_colormap(widget);
861 for(i = 0; i < GTK_STYLE_NUM_STYLECOLORS(); i++) {
862 stylecolors[i] = data[i];
863 gdk_color_alloc(widget_cmap, &stylecolors[i]);
866 gtk_widget_set_default_style(style_newdefault);
867 gtk_style_unref(style_newdefault);
869 /* Now we need to redraw everything */
870 gtk_widget_draw(widget, NULL);
871 gtk_widget_draw_children(widget);
875 gtk_window_client_event (GtkWidget *widget,
876 GdkEventClient *event)
878 GdkAtom atom_styleset;
879 g_return_val_if_fail (widget != NULL, FALSE);
880 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
881 g_return_val_if_fail (event != NULL, FALSE);
883 atom_styleset = gdk_atom_intern("_GTK_STYLE_CHANGED", FALSE);
885 if(event->message_type == atom_styleset) {
886 gtk_window_style_set_event(widget, event);
892 gtk_window_need_resize (GtkContainer *container)
897 g_return_val_if_fail (container != NULL, FALSE);
898 g_return_val_if_fail (GTK_IS_WINDOW (container), FALSE);
902 window = GTK_WINDOW (container);
903 if (window->handling_resize)
906 if (GTK_WIDGET_VISIBLE (container))
908 window->need_resize = TRUE;
909 return_val = gtk_window_move_resize (GTK_WIDGET (window));
910 window->need_resize = FALSE;
917 gtk_real_window_move_resize (GtkWindow *window,
924 GtkWidget *resize_container;
925 GSList *resize_widgets;
926 GSList *resize_containers;
930 g_return_val_if_fail (window != NULL, FALSE);
931 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
932 g_return_val_if_fail ((x != NULL) || (y != NULL), FALSE);
936 widget = GTK_WIDGET (window);
938 if ((*x != -1) && (*y != -1))
939 gdk_window_move (widget->window, *x, *y);
941 if ((widget->requisition.width == 0) ||
942 (widget->requisition.height == 0))
944 widget->requisition.width = 200;
945 widget->requisition.height = 200;
948 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
950 resize_containers = NULL;
952 if ((window->auto_shrink &&
953 ((width != widget->requisition.width) ||
954 (height != widget->requisition.height))) ||
955 (width < widget->requisition.width) ||
956 (height < widget->requisition.height))
958 if (window->resize_count == 0)
960 window->resize_count += 1;
961 gdk_window_resize (widget->window,
962 widget->requisition.width,
963 widget->requisition.height);
968 /* The window hasn't changed size but one of its children
969 * queued a resize request. Which means that the allocation
970 * is not sufficient for the requisition of some child.
971 * We've already performed a size request at this point,
972 * so we simply need to run through the list of resize
973 * widgets and reallocate their sizes appropriately. We
974 * make the optimization of not performing reallocation
975 * for a widget who also has a parent in the resize widgets
978 resize_widgets = gtk_object_get_data (GTK_OBJECT (window), "resize_widgets");
979 gtk_object_set_data (GTK_OBJECT (window), "resize_widgets", NULL);
981 tmp_list = resize_widgets;
984 widget = tmp_list->data;
985 tmp_list = tmp_list->next;
987 /* referencing needed? */
988 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
989 gtk_object_unref (GTK_OBJECT (widget));
991 widget = widget->parent;
994 ((widget->allocation.width < widget->requisition.width) ||
995 (widget->allocation.height < widget->requisition.height)))
996 widget = widget->parent;
999 GTK_WIDGET_SET_FLAGS (widget, GTK_RESIZE_NEEDED);
1002 tmp_list = resize_widgets;
1005 widget = tmp_list->data;
1006 tmp_list = tmp_list->next;
1008 resize_container = widget->parent;
1009 while (resize_container &&
1010 !GTK_WIDGET_RESIZE_NEEDED (resize_container))
1011 resize_container = resize_container->parent;
1013 if (resize_container)
1014 widget = resize_container->parent;
1020 if (GTK_WIDGET_RESIZE_NEEDED (widget))
1022 GTK_WIDGET_UNSET_FLAGS (resize_container, GTK_RESIZE_NEEDED);
1023 resize_container = widget;
1025 widget = widget->parent;
1028 if (resize_container &&
1029 !g_slist_find (resize_containers, resize_container))
1030 resize_containers = g_slist_prepend (resize_containers, resize_container);
1033 g_slist_free (resize_widgets);
1035 tmp_list = resize_containers;
1038 widget = tmp_list->data;
1039 tmp_list = tmp_list->next;
1041 GTK_WIDGET_UNSET_FLAGS (widget, GTK_RESIZE_NEEDED);
1042 gtk_widget_size_allocate (widget, &widget->allocation);
1043 gtk_widget_queue_draw (widget);
1046 g_slist_free (resize_containers);
1053 gtk_window_move_resize (GtkWidget *widget)
1062 g_return_val_if_fail (widget != NULL, FALSE);
1063 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1067 if (GTK_WIDGET_REALIZED (widget))
1069 window = GTK_WINDOW (widget);
1071 /* Remember old size, to know if we have to reset hints */
1072 width = widget->requisition.width;
1073 height = widget->requisition.height;
1074 gtk_widget_size_request (widget, &widget->requisition);
1076 if (GTK_WIDGET_MAPPED (widget) &&
1077 (width != widget->requisition.width ||
1078 height != widget->requisition.height))
1079 gtk_window_set_hints (widget, &widget->requisition);
1083 width = widget->requisition.width;
1084 height = widget->requisition.height;
1086 if (window->use_uposition)
1087 switch (window->position)
1089 case GTK_WIN_POS_CENTER:
1090 x = (gdk_screen_width () - width) / 2;
1091 y = (gdk_screen_height () - height) / 2;
1092 gtk_widget_set_uposition (widget, x, y);
1094 case GTK_WIN_POS_MOUSE:
1095 gdk_window_get_pointer (NULL, &x, &y, NULL);
1100 screen_width = gdk_screen_width ();
1101 screen_height = gdk_screen_height ();
1105 else if (x > (screen_width - width))
1106 x = screen_width - width;
1110 else if (y > (screen_height - height))
1111 y = screen_height - height;
1113 gtk_widget_set_uposition (widget, x, y);
1117 gtk_signal_emit (GTK_OBJECT (widget), window_signals[MOVE_RESIZE],
1118 &x, &y, width, height, &return_val);
1125 gtk_window_set_hints (GtkWidget *widget,
1126 GtkRequisition *requisition)
1129 GtkWidgetAuxInfo *aux_info;
1133 g_return_if_fail (widget != NULL);
1134 g_return_if_fail (GTK_IS_WINDOW (widget));
1135 g_return_if_fail (requisition != NULL);
1137 if (GTK_WIDGET_REALIZED (widget))
1139 window = GTK_WINDOW (widget);
1145 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "aux_info");
1146 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1150 flags |= GDK_HINT_POS;
1152 if (!window->allow_shrink)
1153 flags |= GDK_HINT_MIN_SIZE;
1154 if (!window->allow_grow)
1155 flags |= GDK_HINT_MAX_SIZE;
1157 gdk_window_set_hints (widget->window, ux, uy,
1158 requisition->width, requisition->height,
1159 requisition->width, requisition->height,
1162 if (window->use_uposition && (flags & GDK_HINT_POS))
1164 window->use_uposition = FALSE;
1165 gdk_window_move (widget->window, ux, uy);
1171 gtk_window_check_accelerator (GtkWindow *window,
1175 GtkAcceleratorTable *table;
1178 if ((key >= 0x20) && (key <= 0xFF))
1180 tmp = window->accelerator_tables;
1186 if (gtk_accelerator_table_check (table, key, mods))
1190 if (gtk_accelerator_table_check (NULL, key, mods))