gtkwindow.c 222 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4
/* 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
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * 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
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15 16 17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18
 */
19 20

/*
21
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22 23 24 25 26
 * 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/. 
 */

27
#include <config.h>
Elliot Lee's avatar
Elliot Lee committed
28 29 30 31
#include <string.h>
#include <limits.h>
#include "gdk/gdk.h"
#include "gdk/gdkkeysyms.h"
32

33 34
#include "gtkintl.h"

35
#include "gtkprivate.h"
36
#include "gtkrc.h"
Elliot Lee's avatar
Elliot Lee committed
37
#include "gtkwindow.h"
38
#include "gtkwindow-decorate.h"
Tim Janik's avatar
Tim Janik committed
39
#include "gtkbindings.h"
40
#include "gtkkeyhash.h"
41
#include "gtkmain.h"
42
#include "gtkmnemonichash.h"
43
#include "gtkiconfactory.h"
44
#include "gtkicontheme.h"
45
#include "gtkmarshalers.h"
46
#include "gtkplug.h"
47
#include "gtkalias.h"
Elliot Lee's avatar
Elliot Lee committed
48

49 50 51 52
#ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h"
#endif

Elliot Lee's avatar
Elliot Lee committed
53
enum {
54
  SET_FOCUS,
55
  FRAME_EVENT,
56 57 58
  ACTIVATE_FOCUS,
  ACTIVATE_DEFAULT,
  MOVE_FOCUS,
59
  KEYS_CHANGED,
Elliot Lee's avatar
Elliot Lee committed
60 61
  LAST_SIGNAL
};
62

63
enum {
64 65 66 67 68
  PROP_0,

  /* Construct */
  PROP_TYPE,

Havoc Pennington's avatar
Havoc Pennington committed
69
  /* Normal Props */
70
  PROP_TITLE,
71
  PROP_ROLE,
72 73
  PROP_ALLOW_SHRINK,
  PROP_ALLOW_GROW,
Havoc Pennington's avatar
Havoc Pennington committed
74
  PROP_RESIZABLE,
75 76 77 78 79
  PROP_MODAL,
  PROP_WIN_POS,
  PROP_DEFAULT_WIDTH,
  PROP_DEFAULT_HEIGHT,
  PROP_DESTROY_WITH_PARENT,
Havoc Pennington's avatar
Havoc Pennington committed
80
  PROP_ICON,
81
  PROP_ICON_NAME,
82
  PROP_SCREEN,
83 84 85
  PROP_TYPE_HINT,
  PROP_SKIP_TASKBAR_HINT,
  PROP_SKIP_PAGER_HINT,
86
  PROP_URGENCY_HINT,
87
  PROP_ACCEPT_FOCUS,
88
  PROP_FOCUS_ON_MAP,
89
  PROP_DECORATED,
90
  PROP_DELETABLE,
91
  PROP_GRAVITY,
92
  
93 94 95
  /* Readonly properties */
  PROP_IS_ACTIVE,
  PROP_HAS_TOPLEVEL_FOCUS,
Havoc Pennington's avatar
Havoc Pennington committed
96
  
97
  LAST_ARG
98
};
Elliot Lee's avatar
Elliot Lee committed
99

Havoc Pennington's avatar
Havoc Pennington committed
100 101 102 103 104
typedef struct
{
  GList     *icon_list;
  GdkPixmap *icon_pixmap;
  GdkPixmap *icon_mask;
105
  gchar     *icon_name;
Havoc Pennington's avatar
Havoc Pennington committed
106 107 108
  guint      realized : 1;
  guint      using_default_icon : 1;
  guint      using_parent_icon : 1;
109
  guint      using_themed_icon : 1;
Havoc Pennington's avatar
Havoc Pennington committed
110 111
} GtkWindowIconInfo;

112
typedef struct {
113 114
  GdkGeometry    geometry; /* Last set of geometry hints we set */
  GdkWindowHints flags;
Havoc Pennington's avatar
Havoc Pennington committed
115
  GdkRectangle   configure_request;
116 117
} GtkWindowLastGeometryInfo;

118 119
struct _GtkWindowGeometryInfo
{
120 121 122 123 124
  /* Properties that the app has set on the window
   */
  GdkGeometry    geometry;	/* Geometry hints */
  GdkWindowHints mask;
  GtkWidget     *widget;	/* subwidget to which hints apply */
Havoc Pennington's avatar
Havoc Pennington committed
125 126 127 128 129
  /* from last gtk_window_resize () - if > 0, indicates that
   * we should resize to this size.
   */
  gint           resize_width;  
  gint           resize_height;
130

Havoc Pennington's avatar
Havoc Pennington committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
  /* From last gtk_window_move () prior to mapping -
   * only used if initial_pos_set
   */
  gint           initial_x;
  gint           initial_y;
  
  /* Default size - used only the FIRST time we map a window,
   * only if > 0.
   */
  gint           default_width; 
  gint           default_height;
  /* whether to use initial_x, initial_y */
  guint          initial_pos_set : 1;
  /* CENTER_ALWAYS or other position constraint changed since
   * we sent the last configure request.
   */
  guint          position_constraints_changed : 1;
148 149 150 151 152 153

  /* if true, default_width, height come from gtk_window_parse_geometry,
   * and thus should be multiplied by the increments and affect the
   * geometry widget only
   */
  guint          default_is_geometry : 1;
Havoc Pennington's avatar
Havoc Pennington committed
154
  
155
  GtkWindowLastGeometryInfo last;
156
};
157

158 159
#define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))

160 161 162 163
typedef struct _GtkWindowPrivate GtkWindowPrivate;

struct _GtkWindowPrivate
{
164 165
  GtkMnemonicHash *mnemonic_hash;
  
166 167
  guint above_initially : 1;
  guint below_initially : 1;
168 169 170
  guint fullscreen_initially : 1;
  guint skips_taskbar : 1;
  guint skips_pager : 1;
171
  guint urgent : 1;
172
  guint accept_focus : 1;
173
  guint focus_on_map : 1;
174
  guint deletable : 1;
175
};
176

Elliot Lee's avatar
Elliot Lee committed
177 178
static void gtk_window_class_init         (GtkWindowClass    *klass);
static void gtk_window_init               (GtkWindow         *window);
Tim Janik's avatar
Tim Janik committed
179
static void gtk_window_dispose            (GObject           *object);
180
static void gtk_window_destroy            (GtkObject         *object);
181
static void gtk_window_finalize           (GObject           *object);
Elliot Lee's avatar
Elliot Lee committed
182 183 184 185 186
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);
187
static void gtk_window_unrealize          (GtkWidget         *widget);
Elliot Lee's avatar
Elliot Lee committed
188 189 190 191
static void gtk_window_size_request       (GtkWidget         *widget,
					   GtkRequisition    *requisition);
static void gtk_window_size_allocate      (GtkWidget         *widget,
					   GtkAllocation     *allocation);
192 193
static gint gtk_window_event              (GtkWidget *widget,
					   GdkEvent *event);
194 195
static gboolean gtk_window_map_event      (GtkWidget         *widget,
                                           GdkEventAny       *event);
196
static gboolean gtk_window_frame_event    (GtkWindow *window,
197
					   GdkEvent *event);
Elliot Lee's avatar
Elliot Lee committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
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,
Elliot Lee's avatar
Elliot Lee committed
213
					   GdkEventClient    *event);
214
static void gtk_window_check_resize       (GtkContainer      *container);
215
static gint gtk_window_focus              (GtkWidget        *widget,
216
				           GtkDirectionType  direction);
217
static void gtk_window_real_set_focus     (GtkWindow         *window,
218
					   GtkWidget         *focus);
219

220 221 222 223
static void gtk_window_real_activate_default (GtkWindow         *window);
static void gtk_window_real_activate_focus   (GtkWindow         *window);
static void gtk_window_move_focus            (GtkWindow         *window,
                                              GtkDirectionType   dir);
224
static void gtk_window_keys_changed          (GtkWindow         *window);
225 226 227 228
static void gtk_window_paint                 (GtkWidget         *widget,
					      GdkRectangle      *area);
static gint gtk_window_expose                (GtkWidget         *widget,
					      GdkEventExpose    *event);
229 230 231 232 233 234
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);

235 236
static GdkScreen *gtk_window_check_screen (GtkWindow *window);

Havoc Pennington's avatar
Havoc Pennington committed
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
static GtkWindowGeometryInfo* gtk_window_get_geometry_info         (GtkWindow    *window,
                                                                    gboolean      create);

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_constrain_size            (GtkWindow    *window,
                                                      GdkGeometry  *geometry,
                                                      guint         flags,
                                                      gint          width,
                                                      gint          height,
                                                      gint         *new_width,
                                                      gint         *new_height);
static void     gtk_window_constrain_position        (GtkWindow    *window,
                                                      gint          new_width,
                                                      gint          new_height,
                                                      gint         *x,
                                                      gint         *y);
static void     gtk_window_compute_hints             (GtkWindow    *window,
                                                      GdkGeometry  *new_geometry,
                                                      guint        *new_flags);
static void     gtk_window_compute_configure_request (GtkWindow    *window,
                                                      GdkRectangle *request,
                                                      GdkGeometry  *geometry,
                                                      guint        *flags);

static void     gtk_window_set_default_size_internal (GtkWindow    *window,
                                                      gboolean      change_width,
                                                      gint          width,
                                                      gboolean      change_height,
269 270
                                                      gint          height,
						      gboolean      is_geometry);
Elliot Lee's avatar
Elliot Lee committed
271

272 273 274 275
static void     update_themed_icon                    (GtkIconTheme *theme,
				                       GtkWindow    *window);
static GList   *icon_list_from_theme                  (GtkWidget    *widget,
						       const gchar  *name);
Havoc Pennington's avatar
Havoc Pennington committed
276 277
static void     gtk_window_realize_icon               (GtkWindow    *window);
static void     gtk_window_unrealize_icon             (GtkWindow    *window);
278 279 280 281

static void        gtk_window_notify_keys_changed (GtkWindow   *window);
static GtkKeyHash *gtk_window_get_key_hash        (GtkWindow   *window);
static void        gtk_window_free_key_hash       (GtkWindow   *window);
282

283
static GSList      *toplevel_list = NULL;
Elliot Lee's avatar
Elliot Lee committed
284
static GtkBinClass *parent_class = NULL;
285
static guint        window_signals[LAST_SIGNAL] = { 0 };
Havoc Pennington's avatar
Havoc Pennington committed
286
static GList       *default_icon_list = NULL;
287
static gchar       *default_icon_name = NULL;
288
static guint        default_icon_serial = 0;
289 290
static gboolean     disable_startup_notification = FALSE;
static gboolean     sent_startup_notification = FALSE;
Elliot Lee's avatar
Elliot Lee committed
291

292 293 294 295 296
static GQuark       quark_gtk_embedded = 0;
static GQuark       quark_gtk_window_key_hash = 0;
static GQuark       quark_gtk_window_default_icon_pixmap = 0;
static GQuark       quark_gtk_window_icon_info = 0;

297 298 299 300 301 302 303 304
static void gtk_window_set_property (GObject         *object,
				     guint            prop_id,
				     const GValue    *value,
				     GParamSpec      *pspec);
static void gtk_window_get_property (GObject         *object,
				     guint            prop_id,
				     GValue          *value,
				     GParamSpec      *pspec);
Elliot Lee's avatar
Elliot Lee committed
305

306

Manish Singh's avatar
Manish Singh committed
307
GType
308
gtk_window_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
309
{
Manish Singh's avatar
Manish Singh committed
310
  static GType window_type = 0;
Elliot Lee's avatar
Elliot Lee committed
311 312 313

  if (!window_type)
    {
Manish Singh's avatar
Manish Singh committed
314
      static const GTypeInfo window_info =
Elliot Lee's avatar
Elliot Lee committed
315 316
      {
	sizeof (GtkWindowClass),
Manish Singh's avatar
Manish Singh committed
317 318 319 320 321 322 323 324
	NULL,		/* base_init */
	NULL,		/* base_finalize */
	(GClassInitFunc) gtk_window_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
	sizeof (GtkWindow),
	0,		/* n_preallocs */
	(GInstanceInitFunc) gtk_window_init,
Elliot Lee's avatar
Elliot Lee committed
325 326
      };

Matthias Clasen's avatar
Matthias Clasen committed
327
      window_type = g_type_register_static (GTK_TYPE_BIN, I_("GtkWindow"),
Manish Singh's avatar
Manish Singh committed
328
					    &window_info, 0);
Elliot Lee's avatar
Elliot Lee committed
329 330 331 332 333
    }

  return window_type;
}

334 335 336 337 338 339 340 341 342 343 344 345 346
static void
add_tab_bindings (GtkBindingSet    *binding_set,
		  GdkModifierType   modifiers,
		  GtkDirectionType  direction)
{
  gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
static void
add_arrow_bindings (GtkBindingSet    *binding_set,
		    guint             keysym,
		    GtkDirectionType  direction)
{
  guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
  
  gtk_binding_entry_add_signal (binding_set, keysym, 0,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
                                "move_focus", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}


Elliot Lee's avatar
Elliot Lee committed
369 370 371
static void
gtk_window_class_init (GtkWindowClass *klass)
{
372
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Elliot Lee's avatar
Elliot Lee committed
373 374 375
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;
376 377
  GtkBindingSet *binding_set;
  
Elliot Lee's avatar
Elliot Lee committed
378 379 380
  object_class = (GtkObjectClass*) klass;
  widget_class = (GtkWidgetClass*) klass;
  container_class = (GtkContainerClass*) klass;
381
  
Manish Singh's avatar
Manish Singh committed
382
  parent_class = g_type_class_peek_parent (klass);
Elliot Lee's avatar
Elliot Lee committed
383

384 385 386 387 388
  quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
  quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
  quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
  quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");

Tim Janik's avatar
Tim Janik committed
389
  gobject_class->dispose = gtk_window_dispose;
390 391
  gobject_class->finalize = gtk_window_finalize;

392 393 394
  gobject_class->set_property = gtk_window_set_property;
  gobject_class->get_property = gtk_window_get_property;
  
395
  object_class->destroy = gtk_window_destroy;
Elliot Lee's avatar
Elliot Lee committed
396 397 398 399

  widget_class->show = gtk_window_show;
  widget_class->hide = gtk_window_hide;
  widget_class->map = gtk_window_map;
400
  widget_class->map_event = gtk_window_map_event;
Elliot Lee's avatar
Elliot Lee committed
401 402
  widget_class->unmap = gtk_window_unmap;
  widget_class->realize = gtk_window_realize;
403
  widget_class->unrealize = gtk_window_unrealize;
Elliot Lee's avatar
Elliot Lee committed
404 405 406 407 408 409 410 411 412 413
  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;
414
  widget_class->focus = gtk_window_focus;
415
  
416 417
  widget_class->expose_event = gtk_window_expose;
   
418
  container_class->check_resize = gtk_window_check_resize;
Elliot Lee's avatar
Elliot Lee committed
419

420
  klass->set_focus = gtk_window_real_set_focus;
421
  klass->frame_event = gtk_window_frame_event;
422

423 424 425
  klass->activate_default = gtk_window_real_activate_default;
  klass->activate_focus = gtk_window_real_activate_focus;
  klass->move_focus = gtk_window_move_focus;
426
  klass->keys_changed = gtk_window_keys_changed;
427
  
428 429
  g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
  
430 431 432 433
  /* Construct */
  g_object_class_install_property (gobject_class,
                                   PROP_TYPE,
                                   g_param_spec_enum ("type",
434 435
						      P_("Window Type"),
						      P_("The type of the window"),
436 437
						      GTK_TYPE_WINDOW_TYPE,
						      GTK_WINDOW_TOPLEVEL,
438
						      GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Havoc Pennington's avatar
Havoc Pennington committed
439
  /* Regular Props */
440 441 442
  g_object_class_install_property (gobject_class,
                                   PROP_TITLE,
                                   g_param_spec_string ("title",
443 444
                                                        P_("Window Title"),
                                                        P_("The title of the window"),
445
                                                        NULL,
446
                                                        GTK_PARAM_READWRITE));
447

448 449 450
  g_object_class_install_property (gobject_class,
                                   PROP_ROLE,
                                   g_param_spec_string ("role",
451 452
							P_("Window Role"),
							P_("Unique identifier for the window to be used when restoring a session"),
453
							NULL,
454
							GTK_PARAM_READWRITE));
455

456 457
  g_object_class_install_property (gobject_class,
                                   PROP_ALLOW_SHRINK,
Matthias Clasen's avatar
x  
Matthias Clasen committed
458
                                   g_param_spec_boolean ("allow-shrink",
459
							 P_("Allow Shrink"),
460
							 /* xgettext:no-c-format */
461
							 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
462
							 FALSE,
463
							 GTK_PARAM_READWRITE));
464 465 466

  g_object_class_install_property (gobject_class,
                                   PROP_ALLOW_GROW,
Matthias Clasen's avatar
x  
Matthias Clasen committed
467
                                   g_param_spec_boolean ("allow-grow",
468 469
							 P_("Allow Grow"),
							 P_("If TRUE, users can expand the window beyond its minimum size"),
470
							 TRUE,
471
							 GTK_PARAM_READWRITE));
472

Havoc Pennington's avatar
Havoc Pennington committed
473 474 475
  g_object_class_install_property (gobject_class,
                                   PROP_RESIZABLE,
                                   g_param_spec_boolean ("resizable",
476 477
							 P_("Resizable"),
							 P_("If TRUE, users can resize the window"),
Havoc Pennington's avatar
Havoc Pennington committed
478
							 TRUE,
479
							 GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
480
  
481 482 483
  g_object_class_install_property (gobject_class,
                                   PROP_MODAL,
                                   g_param_spec_boolean ("modal",
484 485
							 P_("Modal"),
							 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
486
							 FALSE,
487
							 GTK_PARAM_READWRITE));
488 489 490

  g_object_class_install_property (gobject_class,
                                   PROP_WIN_POS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
491
                                   g_param_spec_enum ("window-position",
492 493
						      P_("Window Position"),
						      P_("The initial position of the window"),
494 495
						      GTK_TYPE_WINDOW_POSITION,
						      GTK_WIN_POS_NONE,
496
						      GTK_PARAM_READWRITE));
497 498 499
 
  g_object_class_install_property (gobject_class,
                                   PROP_DEFAULT_WIDTH,
Matthias Clasen's avatar
x  
Matthias Clasen committed
500
                                   g_param_spec_int ("default-width",
501 502
						     P_("Default Width"),
						     P_("The default width of the window, used when initially showing the window"),
Havoc Pennington's avatar
Havoc Pennington committed
503
						     -1,
504
						     G_MAXINT,
Havoc Pennington's avatar
Havoc Pennington committed
505
						     -1,
506
						     GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
507
  
508 509
  g_object_class_install_property (gobject_class,
                                   PROP_DEFAULT_HEIGHT,
Matthias Clasen's avatar
x  
Matthias Clasen committed
510
                                   g_param_spec_int ("default-height",
511 512
						     P_("Default Height"),
						     P_("The default height of the window, used when initially showing the window"),
Havoc Pennington's avatar
Havoc Pennington committed
513
						     -1,
514
						     G_MAXINT,
Havoc Pennington's avatar
Havoc Pennington committed
515
						     -1,
516
						     GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
517
  
518 519
  g_object_class_install_property (gobject_class,
                                   PROP_DESTROY_WITH_PARENT,
Matthias Clasen's avatar
x  
Matthias Clasen committed
520
                                   g_param_spec_boolean ("destroy-with-parent",
521 522
							 P_("Destroy with Parent"),
							 P_("If this window should be destroyed when the parent is destroyed"),
523
                                                         FALSE,
524
							 GTK_PARAM_READWRITE));
525

Havoc Pennington's avatar
Havoc Pennington committed
526 527 528
  g_object_class_install_property (gobject_class,
                                   PROP_ICON,
                                   g_param_spec_object ("icon",
529 530
                                                        P_("Icon"),
                                                        P_("Icon for this window"),
Havoc Pennington's avatar
Havoc Pennington committed
531
                                                        GDK_TYPE_PIXBUF,
532
                                                        GTK_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
533
  
534 535 536 537 538 539 540 541 542 543
  /**
   * GtkWindow:icon-name:
   *
   * The :icon-name property specifies the name of the themed icon to
   * use as the window icon. See #GtkIconTheme for more details.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
                                   PROP_ICON_NAME,
Matthias Clasen's avatar
x  
Matthias Clasen committed
544
                                   g_param_spec_string ("icon-name",
545 546 547
                                                        P_("Icon Name"),
                                                        P_("Name of the themed icon for this window"),
							NULL,
548
                                                        GTK_PARAM_READWRITE));
549
  
550 551 552
  g_object_class_install_property (gobject_class,
				   PROP_SCREEN,
				   g_param_spec_object ("screen",
553 554
 							P_("Screen"),
 							P_("The screen where this window will be displayed"),
555
							GDK_TYPE_SCREEN,
556
 							GTK_PARAM_READWRITE));
557

558 559
  g_object_class_install_property (gobject_class,
                                   PROP_IS_ACTIVE,
Matthias Clasen's avatar
x  
Matthias Clasen committed
560
                                   g_param_spec_boolean ("is-active",
561 562
							 P_("Is Active"),
							 P_("Whether the toplevel is the current active window"),
563
							 FALSE,
564
							 GTK_PARAM_READABLE));
565 566 567
  
  g_object_class_install_property (gobject_class,
                                   PROP_HAS_TOPLEVEL_FOCUS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
568
                                   g_param_spec_boolean ("has-toplevel-focus",
569 570
							 P_("Focus in Toplevel"),
							 P_("Whether the input focus is within this GtkWindow"),
571
							 FALSE,
572
							 GTK_PARAM_READABLE));
573 574 575

  g_object_class_install_property (gobject_class,
				   PROP_TYPE_HINT,
Matthias Clasen's avatar
x  
Matthias Clasen committed
576
				   g_param_spec_enum ("type-hint",
577 578
                                                      P_("Type hint"),
                                                      P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
579 580
                                                      GDK_TYPE_WINDOW_TYPE_HINT,
                                                      GDK_WINDOW_TYPE_HINT_NORMAL,
581
                                                      GTK_PARAM_READWRITE));
582 583 584

  g_object_class_install_property (gobject_class,
				   PROP_SKIP_TASKBAR_HINT,
Matthias Clasen's avatar
x  
Matthias Clasen committed
585
				   g_param_spec_boolean ("skip-taskbar-hint",
586 587
                                                         P_("Skip taskbar"),
                                                         P_("TRUE if the window should not be in the task bar."),
588
                                                         FALSE,
589
                                                         GTK_PARAM_READWRITE));
590 591 592

  g_object_class_install_property (gobject_class,
				   PROP_SKIP_PAGER_HINT,
Matthias Clasen's avatar
x  
Matthias Clasen committed
593
				   g_param_spec_boolean ("skip-pager-hint",
594 595
                                                         P_("Skip pager"),
                                                         P_("TRUE if the window should not be in the pager."),
596
                                                         FALSE,
597
                                                         GTK_PARAM_READWRITE));  
598

599 600 601 602 603 604 605 606
  g_object_class_install_property (gobject_class,
				   PROP_URGENCY_HINT,
				   g_param_spec_boolean ("urgency-hint",
                                                         P_("Urgent"),
                                                         P_("TRUE if the window should be brought to the user's attention."),
                                                         FALSE,
                                                         GTK_PARAM_READWRITE));  

607 608 609 610 611 612 613 614 615
  /**
   * GtkWindow:accept-focus-hint:
   *
   * Whether the window should receive the input focus.
   *
   * Since: 2.4
   */
  g_object_class_install_property (gobject_class,
				   PROP_ACCEPT_FOCUS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
616
				   g_param_spec_boolean ("accept-focus",
617 618
                                                         P_("Accept focus"),
                                                         P_("TRUE if the window should receive the input focus."),
619
                                                         TRUE,
620
                                                         GTK_PARAM_READWRITE));  
621

622 623 624 625 626 627 628 629 630
  /**
   * GtkWindow:focus-on-map-hint:
   *
   * Whether the window should receive the input focus when mapped.
   *
   * Since: 2.6
   */
  g_object_class_install_property (gobject_class,
				   PROP_FOCUS_ON_MAP,
Matthias Clasen's avatar
x  
Matthias Clasen committed
631
				   g_param_spec_boolean ("focus-on-map",
632 633 634
                                                         P_("Focus on map"),
                                                         P_("TRUE if the window should receive the input focus when mapped."),
                                                         TRUE,
635
                                                         GTK_PARAM_READWRITE));  
636

637 638 639 640 641 642 643 644 645 646
  /**
   * GtkWindow:decorated:
   *
   * Whether the window should be decorated by the window manager.
   *
   * Since: 2.4
   */
  g_object_class_install_property (gobject_class,
                                   PROP_DECORATED,
                                   g_param_spec_boolean ("decorated",
647 648
							 P_("Decorated"),
							 P_("Whether the window should be decorated by the window manager"),
649
							 TRUE,
650
							 GTK_PARAM_READWRITE));
651

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
  /**
   * GtkWindow:deletable:
   *
   * Whether the window frame should have a close button.
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_DELETABLE,
                                   g_param_spec_boolean ("deletable",
							 P_("Deletable"),
							 P_("Whether the window frame should have a close button"),
							 TRUE,
							 GTK_PARAM_READWRITE));


668 669 670 671 672 673 674 675 676 677 678
  /**
   * GtkWindow:gravity:
   *
   * The window gravity of the window. See gtk_window_move() and #GdkGravity for
   * more details about window gravity.
   *
   * Since: 2.4
   */
  g_object_class_install_property (gobject_class,
                                   PROP_GRAVITY,
                                   g_param_spec_enum ("gravity",
679 680
						      P_("Gravity"),
						      P_("The window gravity of the window"),
681 682
						      GDK_TYPE_GRAVITY,
						      GDK_GRAVITY_NORTH_WEST,
683
						      GTK_PARAM_READWRITE));
684

685
  window_signals[SET_FOCUS] =
Matthias Clasen's avatar
Matthias Clasen committed
686
    g_signal_new (I_("set_focus"),
Manish Singh's avatar
Manish Singh committed
687
                  G_TYPE_FROM_CLASS (gobject_class),
688 689 690
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkWindowClass, set_focus),
                  NULL, NULL,
691
                  _gtk_marshal_VOID__OBJECT,
692 693
                  G_TYPE_NONE, 1,
                  GTK_TYPE_WIDGET);
694 695
  
  window_signals[FRAME_EVENT] =
Matthias Clasen's avatar
Matthias Clasen committed
696
    g_signal_new (I_("frame_event"),
Manish Singh's avatar
Manish Singh committed
697
                  G_TYPE_FROM_CLASS (gobject_class),
698 699 700
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET(GtkWindowClass, frame_event),
                  _gtk_boolean_handled_accumulator, NULL,
701
                  _gtk_marshal_BOOLEAN__BOXED,
702 703
                  G_TYPE_BOOLEAN, 1,
                  GDK_TYPE_EVENT);
704

705
  window_signals[ACTIVATE_FOCUS] =
Matthias Clasen's avatar
Matthias Clasen committed
706
    g_signal_new (I_("activate_focus"),
Manish Singh's avatar
Manish Singh committed
707
                  G_TYPE_FROM_CLASS (gobject_class),
708
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
709
                  G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
710
                  NULL, NULL,
711
                  _gtk_marshal_VOID__VOID,
712 713
                  G_TYPE_NONE,
                  0);
714 715

  window_signals[ACTIVATE_DEFAULT] =
Matthias Clasen's avatar
Matthias Clasen committed
716
    g_signal_new (I_("activate_default"),
Manish Singh's avatar
Manish Singh committed
717
                  G_TYPE_FROM_CLASS (gobject_class),
718
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
719
                  G_STRUCT_OFFSET (GtkWindowClass, activate_default),
720
                  NULL, NULL,
721
                  _gtk_marshal_VOID__VOID,
722 723
                  G_TYPE_NONE,
                  0);
724 725

  window_signals[MOVE_FOCUS] =
Matthias Clasen's avatar
Matthias Clasen committed
726
    g_signal_new (I_("move_focus"),
Manish Singh's avatar
Manish Singh committed
727
                  G_TYPE_FROM_CLASS (gobject_class),
728
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
729
                  G_STRUCT_OFFSET (GtkWindowClass, move_focus),
730
                  NULL, NULL,
731
                  _gtk_marshal_VOID__ENUM,
732 733 734
                  G_TYPE_NONE,
                  1,
                  GTK_TYPE_DIRECTION_TYPE);
735

736
  window_signals[KEYS_CHANGED] =
Matthias Clasen's avatar
Matthias Clasen committed
737
    g_signal_new (I_("keys_changed"),
Manish Singh's avatar
Manish Singh committed
738
                  G_TYPE_FROM_CLASS (gobject_class),
739
                  G_SIGNAL_RUN_FIRST,
Manish Singh's avatar
Manish Singh committed
740
                  G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
741
                  NULL, NULL,
Manish Singh's avatar
Manish Singh committed
742
                  _gtk_marshal_VOID__VOID,
743 744
                  G_TYPE_NONE,
                  0);
745 746 747 748 749 750 751 752 753

  /*
   * Key bindings
   */

  binding_set = gtk_binding_set_by_class (klass);

  gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
                                "activate_focus", 0);
754 755 756
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
                                "activate_focus", 0);
  
757 758 759 760 761 762
  gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
                                "activate_default", 0);

  gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
                                "activate_default", 0);

763 764 765 766
  add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
  add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
  add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
  add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
767

768 769 770 771
  add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
  add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
  add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
  add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
Elliot Lee's avatar
Elliot Lee committed
772 773 774 775 776
}

static void
gtk_window_init (GtkWindow *window)
{
777
  GdkColormap *colormap;
778
  GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
779
  
Elliot Lee's avatar
Elliot Lee committed
780
  GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
781
  GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
Elliot Lee's avatar
Elliot Lee committed
782

Owen Taylor's avatar
Owen Taylor committed
783 784
  GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);

785 786
  gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);

Elliot Lee's avatar
Elliot Lee committed
787
  window->title = NULL;
788
  window->wmclass_name = g_strdup (g_get_prgname ());
789
  window->wmclass_class = g_strdup (gdk_get_program_class ());
790 791
  window->wm_role = NULL;
  window->geometry_info = NULL;
Elliot Lee's avatar
Elliot Lee committed
792 793 794
  window->type = GTK_WINDOW_TOPLEVEL;
  window->focus_widget = NULL;
  window->default_widget = NULL;
Havoc Pennington's avatar
Havoc Pennington committed
795
  window->configure_request_count = 0;
Elliot Lee's avatar
Elliot Lee committed
796 797
  window->allow_shrink = FALSE;
  window->allow_grow = TRUE;
Havoc Pennington's avatar
Havoc Pennington committed
798
  window->configure_notify_received = FALSE;
Elliot Lee's avatar
Elliot Lee committed
799
  window->position = GTK_WIN_POS_NONE;
Havoc Pennington's avatar
Havoc Pennington committed
800 801
  window->need_default_size = TRUE;
  window->need_default_position = TRUE;
802
  window->modal = FALSE;
803 804 805 806 807 808
  window->frame = NULL;
  window->has_frame = FALSE;
  window->frame_left = 0;
  window->frame_right = 0;
  window->frame_top = 0;
  window->frame_bottom = 0;
809
  window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
810
  window->gravity = GDK_GRAVITY_NORTH_WEST;
811
  window->decorated = TRUE;
812
  window->mnemonic_modifier = GDK_MOD1_MASK;
Owen Taylor's avatar
Owen Taylor committed
813
  window->screen = gdk_screen_get_default ();
814 815

  priv->accept_focus = TRUE;
816
  priv->focus_on_map = TRUE;
817
  priv->deletable = TRUE;
818

819 820 821 822
  colormap = _gtk_widget_peek_colormap ();
  if (colormap)
    gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
  
823
  g_object_ref_sink (window);
824 825
  window->has_user_ref_count = TRUE;
  toplevel_list = g_slist_prepend (toplevel_list, window);
826 827 828

  gtk_decorated_window_init (window);

Elliot Lee's avatar
Elliot Lee committed
829 830 831
}

static void
832 833 834 835
gtk_window_set_property (GObject      *object,
			 guint         prop_id,
			 const GValue *value,
			 GParamSpec   *pspec)
Elliot Lee's avatar
Elliot Lee committed
836
{
837
  GtkWindow  *window;
Havoc Pennington's avatar
Havoc Pennington committed
838
  
839 840
  window = GTK_WINDOW (object);

841
  switch (prop_id)
Elliot Lee's avatar
Elliot Lee committed
842
    {
843 844
    case PROP_TYPE:
      window->type = g_value_get_enum (value);
845
      break;
846 847
    case PROP_TITLE:
      gtk_window_set_title (window, g_value_get_string (value));
848
      break;
849 850 851
    case PROP_ROLE:
      gtk_window_set_role (window, g_value_get_string (value));
      break;
852 853
    case PROP_ALLOW_SHRINK:
      window->allow_shrink = g_value_get_boolean (value);
854
      gtk_widget_queue_resize (GTK_WIDGET (window));
855
      break;