📄 gtkwindow.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <string.h>#include <limits.h>#include "gdk/gdk.h"#include "gdk/gdkkeysyms.h"#include "gdk/gdkx.h"#include "gtkprivate.h"#include "gtkrc.h"#include "gtksignal.h"#include "gtkwindow.h"#include "gtkbindings.h"#include "gtkmain.h"/* TODO: remove this define and assorted code in 1.3 and fix up the * real culprits. */#define FIXME_ZVT_ME_HARDERenum { SET_FOCUS, LAST_SIGNAL};enum { ARG_0, ARG_TYPE, ARG_TITLE, ARG_AUTO_SHRINK, ARG_ALLOW_SHRINK, ARG_ALLOW_GROW, ARG_MODAL, ARG_WIN_POS, ARG_DEFAULT_WIDTH, ARG_DEFAULT_HEIGHT};typedef struct { GdkGeometry geometry; /* Last set of geometry hints we set */ GdkWindowHints flags; gint width; gint height;} GtkWindowLastGeometryInfo;typedef struct { /* Properties that the app has set on the window */ GdkGeometry geometry; /* Geometry hints */ GdkWindowHints mask; GtkWidget *widget; /* subwidget to which hints apply */ gint width; /* Default size */ gint height; GtkWindowLastGeometryInfo last;} GtkWindowGeometryInfo;static void gtk_window_class_init (GtkWindowClass *klass);static void gtk_window_init (GtkWindow *window);static void gtk_window_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_window_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_window_shutdown (GtkObject *object);static void gtk_window_destroy (GtkObject *object);static void gtk_window_finalize (GtkObject *object);static void gtk_window_show (GtkWidget *widget);static void gtk_window_hide (GtkWidget *widget);static void gtk_window_map (GtkWidget *widget);static void gtk_window_unmap (GtkWidget *widget);static void gtk_window_realize (GtkWidget *widget);static void gtk_window_size_request (GtkWidget *widget, GtkRequisition *requisition);static void gtk_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation);static gint gtk_window_configure_event (GtkWidget *widget, GdkEventConfigure *event);static gint gtk_window_key_press_event (GtkWidget *widget, GdkEventKey *event);static gint gtk_window_key_release_event (GtkWidget *widget, GdkEventKey *event);static gint gtk_window_enter_notify_event (GtkWidget *widget, GdkEventCrossing *event);static gint gtk_window_leave_notify_event (GtkWidget *widget, GdkEventCrossing *event);static gint gtk_window_focus_in_event (GtkWidget *widget, GdkEventFocus *event);static gint gtk_window_focus_out_event (GtkWidget *widget, GdkEventFocus *event);static gint gtk_window_client_event (GtkWidget *widget, GdkEventClient *event);static void gtk_window_check_resize (GtkContainer *container);static void gtk_window_real_set_focus (GtkWindow *window, GtkWidget *focus);static void gtk_window_move_resize (GtkWindow *window);static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a, guint flags_a, GdkGeometry *geometry_b, guint flags_b);static void gtk_window_compute_default_size (GtkWindow *window, guint *width, guint *height);static void gtk_window_constrain_size (GtkWindow *window, GdkGeometry *geometry, guint flags, gint width, gint height, gint *new_width, gint *new_height);static void gtk_window_compute_hints (GtkWindow *window, GdkGeometry *new_geometry, guint *new_flags);static void gtk_window_compute_reposition (GtkWindow *window, gint new_width, gint new_height, gint *x, gint *y);static void gtk_window_read_rcfiles (GtkWidget *widget, GdkEventClient *event);static void gtk_window_draw (GtkWidget *widget, GdkRectangle *area);static void gtk_window_paint (GtkWidget *widget, GdkRectangle *area);static gint gtk_window_expose (GtkWidget *widget, GdkEventExpose *event);static void gtk_window_unset_transient_for (GtkWindow *window);static void gtk_window_transient_parent_realized (GtkWidget *parent, GtkWidget *window);static void gtk_window_transient_parent_unrealized (GtkWidget *parent, GtkWidget *window);static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window, gboolean create);static void gtk_window_geometry_destroy (GtkWindowGeometryInfo *info);static GtkBinClass *parent_class = NULL;static guint window_signals[LAST_SIGNAL] = { 0 };GtkTypegtk_window_get_type (void){ static GtkType window_type = 0; if (!window_type) { static const GtkTypeInfo window_info = { "GtkWindow", sizeof (GtkWindow), sizeof (GtkWindowClass), (GtkClassInitFunc) gtk_window_class_init, (GtkObjectInitFunc) gtk_window_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; window_type = gtk_type_unique (gtk_bin_get_type (), &window_info); } return window_type;}static voidgtk_window_class_init (GtkWindowClass *klass){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; object_class = (GtkObjectClass*) klass; widget_class = (GtkWidgetClass*) klass; container_class = (GtkContainerClass*) klass; parent_class = gtk_type_class (gtk_bin_get_type ()); gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE); gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE); gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK); gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK); gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW); gtk_object_add_arg_type ("GtkWindow::modal", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_MODAL); gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS); gtk_object_add_arg_type ("GtkWindow::default_width", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_DEFAULT_WIDTH); gtk_object_add_arg_type ("GtkWindow::default_height", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_DEFAULT_HEIGHT); window_signals[SET_FOCUS] = gtk_signal_new ("set_focus", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL); object_class->set_arg = gtk_window_set_arg; object_class->get_arg = gtk_window_get_arg; object_class->shutdown = gtk_window_shutdown; object_class->destroy = gtk_window_destroy; object_class->finalize = gtk_window_finalize; widget_class->show = gtk_window_show; widget_class->hide = gtk_window_hide; widget_class->map = gtk_window_map; widget_class->unmap = gtk_window_unmap; widget_class->realize = gtk_window_realize; widget_class->size_request = gtk_window_size_request; widget_class->size_allocate = gtk_window_size_allocate; widget_class->configure_event = gtk_window_configure_event; widget_class->key_press_event = gtk_window_key_press_event; widget_class->key_release_event = gtk_window_key_release_event; widget_class->enter_notify_event = gtk_window_enter_notify_event; widget_class->leave_notify_event = gtk_window_leave_notify_event; widget_class->focus_in_event = gtk_window_focus_in_event; widget_class->focus_out_event = gtk_window_focus_out_event; widget_class->client_event = gtk_window_client_event; widget_class->draw = gtk_window_draw; widget_class->expose_event = gtk_window_expose; container_class->check_resize = gtk_window_check_resize; klass->set_focus = gtk_window_real_set_focus;}static voidgtk_window_init (GtkWindow *window){ GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW); GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL); gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE); window->title = NULL; window->wmclass_name = g_strdup (g_get_prgname ()); window->wmclass_class = g_strdup (gdk_progclass); window->type = GTK_WINDOW_TOPLEVEL; window->focus_widget = NULL; window->default_widget = NULL; window->resize_count = 0; window->allow_shrink = FALSE; window->allow_grow = TRUE; window->auto_shrink = FALSE; window->handling_resize = FALSE; window->position = GTK_WIN_POS_NONE; window->use_uposition = TRUE; window->modal = FALSE; gtk_container_register_toplevel (GTK_CONTAINER (window));}static voidgtk_window_set_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkWindow *window; window = GTK_WINDOW (object); switch (arg_id) { case ARG_TYPE: window->type = GTK_VALUE_ENUM (*arg); break; case ARG_TITLE: gtk_window_set_title (window, GTK_VALUE_STRING (*arg)); break; case ARG_AUTO_SHRINK: window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE); gtk_widget_queue_resize (GTK_WIDGET (window)); break; case ARG_ALLOW_SHRINK: window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE); gtk_widget_queue_resize (GTK_WIDGET (window)); break; case ARG_ALLOW_GROW: window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE); gtk_widget_queue_resize (GTK_WIDGET (window)); break; case ARG_MODAL: gtk_window_set_modal (window, GTK_VALUE_BOOL (*arg)); break; case ARG_WIN_POS: gtk_window_set_position (window, GTK_VALUE_ENUM (*arg)); break; case ARG_DEFAULT_WIDTH: gtk_window_set_default_size (window, GTK_VALUE_INT (*arg), -2); break; case ARG_DEFAULT_HEIGHT: gtk_window_set_default_size (window, -2, GTK_VALUE_INT (*arg)); break; default: break; }}static voidgtk_window_get_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkWindow *window; window = GTK_WINDOW (object); switch (arg_id) { GtkWindowGeometryInfo *info; case ARG_TYPE: GTK_VALUE_ENUM (*arg) = window->type; break; case ARG_TITLE: GTK_VALUE_STRING (*arg) = g_strdup (window->title); break; case ARG_AUTO_SHRINK: GTK_VALUE_BOOL (*arg) = window->auto_shrink; break; case ARG_ALLOW_SHRINK: GTK_VALUE_BOOL (*arg) = window->allow_shrink; break; case ARG_ALLOW_GROW: GTK_VALUE_BOOL (*arg) = window->allow_grow; break; case ARG_MODAL: GTK_VALUE_BOOL (*arg) = window->modal; break; case ARG_WIN_POS: GTK_VALUE_ENUM (*arg) = window->position; break; case ARG_DEFAULT_WIDTH: info = gtk_window_get_geometry_info (window, FALSE); if (!info) GTK_VALUE_INT (*arg) = -1; else GTK_VALUE_INT (*arg) = info->width; break; case ARG_DEFAULT_HEIGHT: info = gtk_window_get_geometry_info (window, FALSE); if (!info) GTK_VALUE_INT (*arg) = -1; else GTK_VALUE_INT (*arg) = info->height; break; default: arg->type = GTK_TYPE_INVALID; break; }}GtkWidget*gtk_window_new (GtkWindowType type){ GtkWindow *window; g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL); window = gtk_type_new (GTK_TYPE_WINDOW); window->type = type; return GTK_WIDGET (window);}voidgtk_window_set_title (GtkWindow *window, const gchar *title){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); if (window->title) g_free (window->title); window->title = g_strdup (title); if (GTK_WIDGET_REALIZED (window)) gdk_window_set_title (GTK_WIDGET (window)->window, window->title);}voidgtk_window_set_wmclass (GtkWindow *window, const gchar *wmclass_name, const gchar *wmclass_class){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); g_free (window->wmclass_name); window->wmclass_name = g_strdup (wmclass_name); g_free (window->wmclass_class); window->wmclass_class = g_strdup (wmclass_class); if (GTK_WIDGET_REALIZED (window)) g_warning ("shouldn't set wmclass after window is realized!\n");}voidgtk_window_set_focus (GtkWindow *window, GtkWidget *focus){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); if (focus) { g_return_if_fail (GTK_IS_WIDGET (focus)); g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus)); } if ((window->focus_widget != focus) || (focus && !GTK_WIDGET_HAS_FOCUS (focus))) gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);}voidgtk_window_set_default (GtkWindow *window, GtkWidget *default_widget){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); if (default_widget) g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget)); if (window->default_widget != default_widget) { if (window->default_widget) { GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT); gtk_widget_draw_default (window->default_widget); } window->default_widget = default_widget; if (window->default_widget) { GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT); gtk_widget_draw_default (window->default_widget); } }}voidgtk_window_set_policy (GtkWindow *window, gint allow_shrink, gint allow_grow, gint auto_shrink){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); window->allow_shrink = (allow_shrink != FALSE); window->allow_grow = (allow_grow != FALSE); window->auto_shrink = (auto_shrink != FALSE); gtk_widget_queue_resize (GTK_WIDGET (window));}voidgtk_window_add_accel_group (GtkWindow *window, GtkAccelGroup *accel_group){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (accel_group != NULL); gtk_accel_group_attach (accel_group, GTK_OBJECT (window));}voidgtk_window_remove_accel_group (GtkWindow *window, GtkAccelGroup *accel_group){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (accel_group != NULL); gtk_accel_group_detach (accel_group, GTK_OBJECT (window));}voidgtk_window_set_position (GtkWindow *window, GtkWindowPosition position){ g_return_if_fail (window != NULL); g_return_if_fail (GTK_IS_WINDOW (window)); window->position = position;}gintgtk_window_activate_focus (GtkWindow *window){ g_return_val_if_fail (window != NULL, FALSE); g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); if (window->focus_widget) { gtk_widget_activate (window->focus_widget); return TRUE; } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -