📄 gtkwindow.c
字号:
if (window->handling_resize) { GtkAllocation allocation; /* if we are just responding to a configure event, which * might be due to a resize by the window manager, the * user, or a response to a resizing request we made * earlier, we go ahead, allocate the new size and we're done * (see gtk_window_configure_event() for more details). */ window->handling_resize = FALSE; allocation = widget->allocation; gtk_widget_size_allocate (widget, &allocation); gtk_widget_queue_draw (widget);#ifdef FIXME_ZVT_ME_HARDER if ((default_size_changed || hints_changed) && (width != new_width || height != new_height)) { /* We could be here for two reasons * 1) We coincidentally got a resize while handling * another resize. * 2) Our computation of default_size_changed was completely * screwed up, probably because one of our children * is broken (i.e. changes requisition during * size allocation). It's probably a zvt widget. * * For 1), we could just go ahead and ask for the * new size right now, but doing that for 2) * might well be fighting the user (and can even * trigger a loop). Since we really don't want to * do that, we requeue a resize in hopes that * by the time it gets handled, the child has seen * the light and is willing to go along with the * new size. (this happens for the zvt widget, since * the size_allocate() above will have stored the * requisition corresponding to the new size in the * zvt widget) * * This doesn't buy us anything for 1), but it shouldn't * hurt us too badly, since it is what would have * happened if we had gotten the configure event before * the new size had been set. */ if (x != -1 && y != -1) gdk_window_move (widget->window, x, y); /* we have to preserve the values and flags that are used * for computation of default_size_changed and hints_changed */ info->last = saved_last_info; gtk_widget_queue_resize (widget); return; }#endif /* FIXME_ZVT_ME_HARDER */ } /* Now set hints if necessary */ if (hints_changed) gdk_window_set_geometry_hints (widget->window, &new_geometry, new_flags); if ((default_size_changed || hints_changed) && (width != new_width || height != new_height)) { /* given that (width != new_width || height != new_height), we are in one * of the following situations: * * default_size_changed * our requisition has changed and we need a different window size, * so we request it from the window manager. * * !default_size_changed * the window manager wouldn't assign us the size we requested, in this * case we don't try to request a new size with every resize. * * !default_size_changed && hints_changed * the window manager rejects our size, but we have just changed the * window manager hints, so there's a certain chance our request will * be honoured this time, so we try again. */ /* request a new window size */ if (x != -1 && y != -1) gdk_window_move_resize (GTK_WIDGET (window)->window, x, y, new_width, new_height); else gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height); window->resize_count += 1; /* we are now awaiting the new configure event in response to our * resizing request. the configure event will cause a new resize * with ->handling_resize=TRUE. * until then, we want to * - discard expose events * - coalesce resizes for our children * - defer any window resizes until the configure event arrived * to achive this, we queue a resize for the window, but remove its * resizing handler, so resizing will not be handled from the next * idle handler but when the configure event arrives. * * FIXME: we should also dequeue the pending redraws here, since * we handle those ourselves in ->handling_resize==TRUE. */ gtk_widget_queue_resize (GTK_WIDGET (container)); if (container->resize_mode == GTK_RESIZE_QUEUE) gtk_container_dequeue_resize_handler (container); } else { if (x != -1 && y != -1) gdk_window_move (widget->window, x, y); if (container->resize_widgets) gtk_container_resize_children (GTK_CONTAINER (window)); }}/* Compare two sets of Geometry hints for equality. */static gbooleangtk_window_compare_hints (GdkGeometry *geometry_a, guint flags_a, GdkGeometry *geometry_b, guint flags_b){ if (flags_a != flags_b) return FALSE; if ((flags_a & GDK_HINT_MIN_SIZE) && (geometry_a->min_width != geometry_b->min_width || geometry_a->min_height != geometry_b->min_height)) return FALSE; if ((flags_a & GDK_HINT_MAX_SIZE) && (geometry_a->max_width != geometry_b->max_width || geometry_a->max_height != geometry_b->max_height)) return FALSE; if ((flags_a & GDK_HINT_BASE_SIZE) && (geometry_a->base_width != geometry_b->base_width || geometry_a->base_height != geometry_b->base_height)) return FALSE; if ((flags_a & GDK_HINT_ASPECT) && (geometry_a->min_aspect != geometry_b->min_aspect || geometry_a->max_aspect != geometry_b->max_aspect)) return FALSE; if ((flags_a & GDK_HINT_RESIZE_INC) && (geometry_a->width_inc != geometry_b->width_inc || geometry_a->height_inc != geometry_b->height_inc)) return FALSE; return TRUE;}/* Compute the default_size for a window. The result will * be stored in *width and *height. The default size is * the size the window should have when initially mapped. * This routine does not attempt to constrain the size * to obey the geometry hints - that must be done elsewhere. */static void gtk_window_compute_default_size (GtkWindow *window, guint *width, guint *height){ GtkRequisition requisition; GtkWindowGeometryInfo *info; gtk_widget_get_child_requisition (GTK_WIDGET (window), &requisition); *width = requisition.width; *height = requisition.height; info = gtk_window_get_geometry_info (window, FALSE); if (*width == 0 && *height == 0) { /* empty window */ *width = 200; *height = 200; } if (info) { *width = info->width > 0 ? info->width : *width; *height = info->height > 0 ? info->height : *height; }}/* Constrain a window size to obey the hints passed in geometry * and flags. The result will be stored in *new_width and *new_height * * This routine is partially borrowed from fvwm. * * Copyright 1993, Robert Nation * You may use this code for any purpose, as long as the original * copyright remains in the source code and all documentation * * which in turn borrows parts of the algorithm from uwm */static void gtk_window_constrain_size (GtkWindow *window, GdkGeometry *geometry, guint flags, gint width, gint height, gint *new_width, gint *new_height){ gint min_width = 0; gint min_height = 0; gint base_width = 0; gint base_height = 0; gint xinc = 1; gint yinc = 1; gint max_width = G_MAXINT; gint max_height = G_MAXINT; #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) ) if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE)) { base_width = geometry->base_width; base_height = geometry->base_height; min_width = geometry->min_width; min_height = geometry->min_height; } else if (flags & GDK_HINT_BASE_SIZE) { base_width = geometry->base_width; base_height = geometry->base_height; min_width = geometry->base_width; min_height = geometry->base_height; } else if (flags & GDK_HINT_MIN_SIZE) { base_width = geometry->min_width; base_height = geometry->min_height; min_width = geometry->min_width; min_height = geometry->min_height; } if (flags & GDK_HINT_MAX_SIZE) { max_width = geometry->max_width ; max_height = geometry->max_height; } if (flags & GDK_HINT_RESIZE_INC) { xinc = MAX (xinc, geometry->width_inc); yinc = MAX (yinc, geometry->height_inc); } /* clamp width and height to min and max values */ width = CLAMP (width, min_width, max_width); height = CLAMP (height, min_height, max_height); /* shrink to base + N * inc */ width = base_width + FLOOR (width - base_width, xinc); height = base_height + FLOOR (height - base_height, yinc); /* constrain aspect ratio, according to: * * width * min_aspect <= -------- <= max_aspect * height */ if (flags & GDK_HINT_ASPECT && geometry->min_aspect > 0 && geometry->max_aspect > 0) { gint delta; if (geometry->min_aspect * height > width) { delta = FLOOR (height - width * geometry->min_aspect, yinc); if (height - delta >= min_height) height -= delta; else { delta = FLOOR (height * geometry->min_aspect - width, xinc); if (width + delta <= max_width) width += delta; } } if (geometry->max_aspect * height < width) { delta = FLOOR (width - height * geometry->max_aspect, xinc); if (width - delta >= min_width) width -= delta; else { delta = FLOOR (width / geometry->max_aspect - height, yinc); if (height + delta <= max_height) height += delta; } } }#undef FLOOR *new_width = width; *new_height = height;}/* Compute the set of geometry hints and flags for a window * based on the application set geometry, and requisiition * of the window. gtk_widget_size_request() must have been * called first. */static voidgtk_window_compute_hints (GtkWindow *window, GdkGeometry *new_geometry, guint *new_flags){ GtkWidget *widget; GtkWidgetAuxInfo *aux_info; gint ux, uy; gint extra_width = 0; gint extra_height = 0; GtkWindowGeometryInfo *geometry_info; GtkRequisition requisition; g_return_if_fail (GTK_IS_WINDOW (window)); widget = GTK_WIDGET (window); gtk_widget_get_child_requisition (widget, &requisition); geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE); g_return_if_fail (geometry_info != NULL); *new_flags = geometry_info->mask; *new_geometry = geometry_info->geometry; if (geometry_info->widget) { extra_width = widget->requisition.width - geometry_info->widget->requisition.width; extra_height = widget->requisition.height - geometry_info->widget->requisition.height; } ux = 0; uy = 0; aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info"); if (aux_info && (aux_info->x != -1) && (aux_info->y != -1)) { ux = aux_info->x; uy = aux_info->y; *new_flags |= GDK_HINT_POS; } if (*new_flags & GDK_HINT_BASE_SIZE) { new_geometry->base_width += extra_width; new_geometry->base_height += extra_height; } else if (!(*new_flags & GDK_HINT_MIN_SIZE) && (*new_flags & GDK_HINT_RESIZE_INC) && ((extra_width != 0) || (extra_height != 0))) { *new_flags |= GDK_HINT_BASE_SIZE; new_geometry->base_width = extra_width; new_geometry->base_height = extra_height; } if (*new_flags & GDK_HINT_MIN_SIZE) { new_geometry->min_width += extra_width; new_geometry->min_height += extra_height; } else if (!window->allow_shrink) { *new_flags |= GDK_HINT_MIN_SIZE; new_geometry->min_width = requisition.width; new_geometry->min_height = requisition.height; } if (*new_flags & GDK_HINT_MAX_SIZE) { new_geometry->max_width += extra_width; new_geometry->max_height += extra_height; } else if (!window->allow_grow) { *new_flags |= GDK_HINT_MAX_SIZE; new_geometry->max_width = requisition.width; new_geometry->max_height = requisition.height; }}/* Compute a new position for the window based on a new * size. *x and *y will be set to the new coordinates, or to -1 if the * window does not need to be moved */static void gtk_window_compute_reposition (GtkWindow *window, gint new_width, gint new_height, gint *x, gint *y){ GtkWidget *widget; widget = GTK_WIDGET (window); *x = -1; *y = -1; switch (window->position) { case GTK_WIN_POS_CENTER: case GTK_WIN_POS_CENTER_ALWAYS: if (window->use_uposition) { gint screen_width = gdk_screen_width (); gint screen_height = gdk_screen_height (); *x = (screen_width - new_width) / 2; *y = (screen_height - new_height) / 2; } break; case GTK_WIN_POS_MOUSE: if (window->use_uposition) { gint screen_width = gdk_screen_width (); gint screen_height = gdk_screen_height (); gdk_window_get_pointer (NULL, x, y, NULL); *x -= new_width / 2; *y -= new_height / 2; *x = CLAMP (*x, 0, screen_width - new_width); *y = CLAMP (*y, 0, screen_height - new_height); } break; default: if (window->use_uposition) { GtkWidgetAuxInfo *aux_info; aux_info = gtk_object_get_data (GTK_OBJECT (window), "gtk-aux-info"); if (aux_info && aux_info->x != -1 && aux_info->y != -1 && aux_info->x != -2 && aux_info->y != -2) { *x = aux_info->x; *y = aux_info->y; } } break; } if (*x != -1 && *y != -1) { GtkWidgetAuxInfo *aux_info; /* we handle necessary window positioning by hand here, * so we can coalesce the window movement with possible * resizes to get only one configure event. * keep this in sync with gtk_widget_set_uposition() * and gtk_window_reposition(). */ gtk_widget_set_uposition (widget, -1, -1); /* ensure we have aux_info */ aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info"); aux_info->x = *x; aux_info->y = *y; window->use_uposition = FALSE; }}/*********************** * Redrawing functions * ***********************/static voidgtk_window_paint (GtkWidget *widget, GdkRectangle *area){ gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);}static gintgtk_window_expose (GtkWidget *widget, GdkEventExpose *event){ g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); if (!GTK_WIDGET_APP_PAINTABLE (widget)) gtk_window_paint (widget, &event->area); if (GTK_WIDGET_CLASS (parent_class)->expose_event) return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); return TRUE;}static voidgtk_window_draw (GtkWidget *widget, GdkRectangle *area){ if (!GTK_WIDGET_APP_PAINTABLE (widget)) gtk_window_paint (widget, area); if (GTK_WIDGET_CLASS (parent_class)->draw) (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -