gtkwindow.c 193 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/. 
 */

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

32
#include "gtkprivate.h"
33
#include "gtkrc.h"
Elliot Lee's avatar
Elliot Lee committed
34
#include "gtkwindow.h"
35
#include "gtkwindow-decorate.h"
Tim Janik's avatar
Tim Janik committed
36
#include "gtkbindings.h"
37
#include "gtkkeyhash.h"
38
#include "gtkmain.h"
39
#include "gtkiconfactory.h"
40
#include "gtkintl.h"
41
#include "gtkmarshalers.h"
42
#include "gtkplug.h"
Elliot Lee's avatar
Elliot Lee committed
43
44

enum {
45
  SET_FOCUS,
46
  FRAME_EVENT,
47
48
49
  ACTIVATE_FOCUS,
  ACTIVATE_DEFAULT,
  MOVE_FOCUS,
50
  KEYS_CHANGED,
Elliot Lee's avatar
Elliot Lee committed
51
52
  LAST_SIGNAL
};
53

54
enum {
55
56
57
58
59
  PROP_0,

  /* Construct */
  PROP_TYPE,

Havoc Pennington's avatar
Havoc Pennington committed
60
  /* Normal Props */
61
62
63
  PROP_TITLE,
  PROP_ALLOW_SHRINK,
  PROP_ALLOW_GROW,
Havoc Pennington's avatar
Havoc Pennington committed
64
  PROP_RESIZABLE,
65
66
67
68
69
  PROP_MODAL,
  PROP_WIN_POS,
  PROP_DEFAULT_WIDTH,
  PROP_DEFAULT_HEIGHT,
  PROP_DESTROY_WITH_PARENT,
Havoc Pennington's avatar
Havoc Pennington committed
70
  PROP_ICON,
71
  PROP_SCREEN,
72
73
74
75
  PROP_TYPE_HINT,
  PROP_SKIP_TASKBAR_HINT,
  PROP_SKIP_PAGER_HINT,
  
76
77
78
  /* Readonly properties */
  PROP_IS_ACTIVE,
  PROP_HAS_TOPLEVEL_FOCUS,
Havoc Pennington's avatar
Havoc Pennington committed
79
  
80
  LAST_ARG
81
};
Elliot Lee's avatar
Elliot Lee committed
82

Havoc Pennington's avatar
Havoc Pennington committed
83
84
85
86
87
88
89
90
91
92
typedef struct
{
  GList     *icon_list;
  GdkPixmap *icon_pixmap;
  GdkPixmap *icon_mask;
  guint      realized : 1;
  guint      using_default_icon : 1;
  guint      using_parent_icon : 1;
} GtkWindowIconInfo;

93
typedef struct {
94
95
  GdkGeometry    geometry; /* Last set of geometry hints we set */
  GdkWindowHints flags;
Havoc Pennington's avatar
Havoc Pennington committed
96
  GdkRectangle   configure_request;
97
98
} GtkWindowLastGeometryInfo;

99
100
struct _GtkWindowGeometryInfo
{
101
102
103
104
105
  /* 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
106
107
108
109
110
  /* from last gtk_window_resize () - if > 0, indicates that
   * we should resize to this size.
   */
  gint           resize_width;  
  gint           resize_height;
111

Havoc Pennington's avatar
Havoc Pennington committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  /* 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;
129
130
131
132
133
134

  /* 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
135
  
136
  GtkWindowLastGeometryInfo last;
137
};
138

139
140
141
typedef struct _GtkWindowMnemonic GtkWindowMnemonic;

struct _GtkWindowMnemonic {
142
143
144
145
  GtkWindow *window;
  guint keyval;

  GSList *targets;
146
};
147

148
149
150
151
152
153
154
155
typedef struct _GtkWindowPrivate GtkWindowPrivate;

struct _GtkWindowPrivate
{
  guint fullscreen_initially : 1;
  guint skips_taskbar : 1;
  guint skips_pager : 1;
};
156

Elliot Lee's avatar
Elliot Lee committed
157
158
static void gtk_window_class_init         (GtkWindowClass    *klass);
static void gtk_window_init               (GtkWindow         *window);
Tim Janik's avatar
Tim Janik committed
159
static void gtk_window_dispose            (GObject           *object);
160
static void gtk_window_destroy            (GtkObject         *object);
161
static void gtk_window_finalize           (GObject           *object);
162
static void gtk_window_private_finalize   (GtkWindowPrivate  *priv);
Elliot Lee's avatar
Elliot Lee committed
163
164
165
166
167
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);
168
static void gtk_window_unrealize          (GtkWidget         *widget);
Elliot Lee's avatar
Elliot Lee committed
169
170
171
172
static void gtk_window_size_request       (GtkWidget         *widget,
					   GtkRequisition    *requisition);
static void gtk_window_size_allocate      (GtkWidget         *widget,
					   GtkAllocation     *allocation);
173
174
static gint gtk_window_event              (GtkWidget *widget,
					   GdkEvent *event);
175
static gboolean gtk_window_frame_event    (GtkWindow *window,
176
					   GdkEvent *event);
Elliot Lee's avatar
Elliot Lee committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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
192
					   GdkEventClient    *event);
193
static void gtk_window_check_resize       (GtkContainer      *container);
194
static gint gtk_window_focus              (GtkWidget        *widget,
195
				           GtkDirectionType  direction);
196
static void gtk_window_real_set_focus     (GtkWindow         *window,
197
					   GtkWidget         *focus);
198

199
200
201
202
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);
203
static void gtk_window_keys_changed          (GtkWindow         *window);
204
205
static void gtk_window_read_rcfiles       (GtkWidget         *widget,
					   GdkEventClient    *event);
206
207
static void gtk_window_paint              (GtkWidget         *widget,
					   GdkRectangle      *area);
Owen Taylor's avatar
Owen Taylor committed
208
209
static gint gtk_window_expose             (GtkWidget         *widget,
				           GdkEventExpose    *event);
210
211
212
213
214
215
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);

Havoc Pennington's avatar
Havoc Pennington committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
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,
248
249
                                                      gint          height,
						      gboolean      is_geometry);
Elliot Lee's avatar
Elliot Lee committed
250

Havoc Pennington's avatar
Havoc Pennington committed
251
252
static void     gtk_window_realize_icon               (GtkWindow    *window);
static void     gtk_window_unrealize_icon             (GtkWindow    *window);
253
254
255
256

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);
257

258
static GSList      *toplevel_list = NULL;
259
static GHashTable  *mnemonic_hash_table = NULL;
Elliot Lee's avatar
Elliot Lee committed
260
static GtkBinClass *parent_class = NULL;
261
static guint        window_signals[LAST_SIGNAL] = { 0 };
Havoc Pennington's avatar
Havoc Pennington committed
262
static GList       *default_icon_list = NULL;
263
static guint        default_icon_serial = 0;
264
265
static gboolean     disable_startup_notification = FALSE;
static gboolean     sent_startup_notification = FALSE;
Elliot Lee's avatar
Elliot Lee committed
266

267
268
269
270
271
272
273
274
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
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305

static guint
mnemonic_hash (gconstpointer key)
{
  const GtkWindowMnemonic *k;
  guint h;
  
  k = (GtkWindowMnemonic *)key;
  
  h = (gulong) k->window;
  h ^= k->keyval << 16;
  h ^= k->keyval >> 16;

  return h;
}

static gboolean
mnemonic_equal (gconstpointer a, gconstpointer b)
{
  const GtkWindowMnemonic *ka;
  const GtkWindowMnemonic *kb;
  
  ka = (GtkWindowMnemonic *)a;
  kb = (GtkWindowMnemonic *)b;

  return
    (ka->window == kb->window) &&
    (ka->keyval == kb->keyval);
}

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
GtkWindowPrivate*
gtk_window_get_private (GtkWindow *window)
{
  GtkWindowPrivate *private;
  static GQuark private_quark = 0;

  if (!private_quark)
    private_quark = g_quark_from_static_string ("gtk-window-private");

  private = g_object_get_qdata (G_OBJECT (window), private_quark);

  if (!private)
    {
      private = g_new0 (GtkWindowPrivate, 1);

      private->fullscreen_initially = FALSE;
      private->skips_pager = FALSE;
      private->skips_taskbar = FALSE;
      
      g_object_set_qdata_full (G_OBJECT (window), private_quark,
			       private,
                               (GDestroyNotify) gtk_window_private_finalize);
    }

  return private;
}

Manish Singh's avatar
Manish Singh committed
333
GType
334
gtk_window_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
335
{
Manish Singh's avatar
Manish Singh committed
336
  static GType window_type = 0;
Elliot Lee's avatar
Elliot Lee committed
337
338
339

  if (!window_type)
    {
Manish Singh's avatar
Manish Singh committed
340
      static const GTypeInfo window_info =
Elliot Lee's avatar
Elliot Lee committed
341
342
      {
	sizeof (GtkWindowClass),
Manish Singh's avatar
Manish Singh committed
343
344
345
346
347
348
349
350
	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
351
352
      };

Manish Singh's avatar
Manish Singh committed
353
354
      window_type = g_type_register_static (GTK_TYPE_BIN, "GtkWindow",
					    &window_info, 0);
Elliot Lee's avatar
Elliot Lee committed
355
356
357
358
359
    }

  return window_type;
}

360
361
362
363
364
365
366
367
368
369
370
371
372
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);
}

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
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
395
396
397
static void
gtk_window_class_init (GtkWindowClass *klass)
{
398
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Elliot Lee's avatar
Elliot Lee committed
399
400
401
  GtkObjectClass *object_class;
  GtkWidgetClass *widget_class;
  GtkContainerClass *container_class;
402
403
  GtkBindingSet *binding_set;
  
Elliot Lee's avatar
Elliot Lee committed
404
405
406
  object_class = (GtkObjectClass*) klass;
  widget_class = (GtkWidgetClass*) klass;
  container_class = (GtkContainerClass*) klass;
407
  
Manish Singh's avatar
Manish Singh committed
408
  parent_class = g_type_class_peek_parent (klass);
Elliot Lee's avatar
Elliot Lee committed
409

410
411
  mnemonic_hash_table = g_hash_table_new (mnemonic_hash, mnemonic_equal);

Tim Janik's avatar
Tim Janik committed
412
  gobject_class->dispose = gtk_window_dispose;
413
414
  gobject_class->finalize = gtk_window_finalize;

415
416
417
  gobject_class->set_property = gtk_window_set_property;
  gobject_class->get_property = gtk_window_get_property;
  
418
  object_class->destroy = gtk_window_destroy;
Elliot Lee's avatar
Elliot Lee committed
419
420
421
422
423
424

  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;
425
  widget_class->unrealize = gtk_window_unrealize;
Elliot Lee's avatar
Elliot Lee committed
426
427
428
429
430
431
432
433
434
435
  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;
436
  widget_class->focus = gtk_window_focus;
437
  
438
439
  widget_class->expose_event = gtk_window_expose;
   
440
  container_class->check_resize = gtk_window_check_resize;
Elliot Lee's avatar
Elliot Lee committed
441

442
  klass->set_focus = gtk_window_real_set_focus;
443
  klass->frame_event = gtk_window_frame_event;
444

445
446
447
  klass->activate_default = gtk_window_real_activate_default;
  klass->activate_focus = gtk_window_real_activate_focus;
  klass->move_focus = gtk_window_move_focus;
448
  klass->keys_changed = gtk_window_keys_changed;
449
  
450
451
452
453
454
455
456
457
458
459
  /* Construct */
  g_object_class_install_property (gobject_class,
                                   PROP_TYPE,
                                   g_param_spec_enum ("type",
						      _("Window Type"),
						      _("The type of the window"),
						      GTK_TYPE_WINDOW_TYPE,
						      GTK_WINDOW_TOPLEVEL,
						      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));

Havoc Pennington's avatar
Havoc Pennington committed
460
  /* Regular Props */
461
462
463
464
465
466
467
468
469
470
471
472
  g_object_class_install_property (gobject_class,
                                   PROP_TITLE,
                                   g_param_spec_string ("title",
                                                        _("Window Title"),
                                                        _("The title of the window"),
                                                        NULL,
                                                        G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_ALLOW_SHRINK,
                                   g_param_spec_boolean ("allow_shrink",
							 _("Allow Shrink"),
473
							 /* xgettext:no-c-format */
Soren Sandmann's avatar
Soren Sandmann committed
474
							 _("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
475
476
477
478
479
480
481
							 FALSE,
							 G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_ALLOW_GROW,
                                   g_param_spec_boolean ("allow_grow",
							 _("Allow Grow"),
Soren Sandmann's avatar
Soren Sandmann committed
482
							 _("If TRUE, users can expand the window beyond its minimum size"),
483
484
485
							 TRUE,
							 G_PARAM_READWRITE));

Havoc Pennington's avatar
Havoc Pennington committed
486
487
488
489
  g_object_class_install_property (gobject_class,
                                   PROP_RESIZABLE,
                                   g_param_spec_boolean ("resizable",
							 _("Resizable"),
Soren Sandmann's avatar
Soren Sandmann committed
490
							 _("If TRUE, users can resize the window"),
Havoc Pennington's avatar
Havoc Pennington committed
491
492
493
							 TRUE,
							 G_PARAM_READWRITE));
  
494
495
496
497
  g_object_class_install_property (gobject_class,
                                   PROP_MODAL,
                                   g_param_spec_boolean ("modal",
							 _("Modal"),
Soren Sandmann's avatar
Soren Sandmann committed
498
							 _("If TRUE, the window is modal (other windows are not usable while this one is up)"),
499
500
501
502
503
504
505
							 FALSE,
							 G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_WIN_POS,
                                   g_param_spec_enum ("window_position",
						      _("Window Position"),
Soren Sandmann's avatar
Soren Sandmann committed
506
						      _("The initial position of the window"),
507
508
509
510
511
512
513
514
						      GTK_TYPE_WINDOW_POSITION,
						      GTK_WIN_POS_NONE,
						      G_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_DEFAULT_WIDTH,
                                   g_param_spec_int ("default_width",
						     _("Default Width"),
Soren Sandmann's avatar
Soren Sandmann committed
515
						     _("The default width of the window, used when initially showing the window"),
Havoc Pennington's avatar
Havoc Pennington committed
516
						     -1,
517
						     G_MAXINT,
Havoc Pennington's avatar
Havoc Pennington committed
518
						     -1,
519
						     G_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
520
  
521
522
523
524
  g_object_class_install_property (gobject_class,
                                   PROP_DEFAULT_HEIGHT,
                                   g_param_spec_int ("default_height",
						     _("Default Height"),
Soren Sandmann's avatar
Soren Sandmann committed
525
						     _("The default height of the window, used when initially showing the window"),
Havoc Pennington's avatar
Havoc Pennington committed
526
						     -1,
527
						     G_MAXINT,
Havoc Pennington's avatar
Havoc Pennington committed
528
						     -1,
529
						     G_PARAM_READWRITE));
Havoc Pennington's avatar
Havoc Pennington committed
530
  
531
532
533
534
  g_object_class_install_property (gobject_class,
                                   PROP_DESTROY_WITH_PARENT,
                                   g_param_spec_boolean ("destroy_with_parent",
							 _("Destroy with Parent"),
535
							 _("If this window should be destroyed when the parent is destroyed"),
536
537
538
                                                         FALSE,
							 G_PARAM_READWRITE));

Havoc Pennington's avatar
Havoc Pennington committed
539
540
541
542
543
544
545
546
  g_object_class_install_property (gobject_class,
                                   PROP_ICON,
                                   g_param_spec_object ("icon",
                                                        _("Icon"),
                                                        _("Icon for this window"),
                                                        GDK_TYPE_PIXBUF,
                                                        G_PARAM_READWRITE));
  
547
548
549
550
  g_object_class_install_property (gobject_class,
				   PROP_SCREEN,
				   g_param_spec_object ("screen",
 							_("Screen"),
Soren Sandmann's avatar
Soren Sandmann committed
551
 							_("The screen where this window will be displayed"),
552
553
554
							GDK_TYPE_SCREEN,
 							G_PARAM_READWRITE));

555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
  g_object_class_install_property (gobject_class,
                                   PROP_IS_ACTIVE,
                                   g_param_spec_boolean ("is_active",
							 _("Is Active"),
							 _("Whether the toplevel is the current active window"),
							 FALSE,
							 G_PARAM_READABLE));
  
  g_object_class_install_property (gobject_class,
                                   PROP_HAS_TOPLEVEL_FOCUS,
                                   g_param_spec_boolean ("has_toplevel_focus",
							 _("Focus in Toplevel"),
							 _("Whether the input focus is within this GtkWindow"),
							 FALSE,
							 G_PARAM_READABLE));
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

  g_object_class_install_property (gobject_class,
				   PROP_TYPE_HINT,
				   g_param_spec_enum ("type_hint",
                                                      _("Type hint"),
                                                      _("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
                                                      GDK_TYPE_WINDOW_TYPE_HINT,
                                                      GDK_WINDOW_TYPE_HINT_NORMAL,
                                                      G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
				   PROP_SKIP_TASKBAR_HINT,
				   g_param_spec_boolean ("skip_taskbar_hint",
                                                         _("Skip taskbar"),
                                                         _("TRUE if the window should not be in the task bar."),
                                                         FALSE,
                                                         G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
				   PROP_SKIP_PAGER_HINT,
				   g_param_spec_boolean ("skip_pager_hint",
                                                         _("Skip pager"),
                                                         _("TRUE if the window should not be in the pager."),
                                                         FALSE,
                                                         G_PARAM_READWRITE));  

596
  window_signals[SET_FOCUS] =
597
    g_signal_new ("set_focus",
Manish Singh's avatar
Manish Singh committed
598
                  G_TYPE_FROM_CLASS (gobject_class),
599
600
601
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkWindowClass, set_focus),
                  NULL, NULL,
602
                  _gtk_marshal_VOID__OBJECT,
603
604
                  G_TYPE_NONE, 1,
                  GTK_TYPE_WIDGET);
605
606
  
  window_signals[FRAME_EVENT] =
607
    g_signal_new ("frame_event",
Manish Singh's avatar
Manish Singh committed
608
                  G_TYPE_FROM_CLASS (gobject_class),
609
610
611
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET(GtkWindowClass, frame_event),
                  _gtk_boolean_handled_accumulator, NULL,
612
                  _gtk_marshal_BOOLEAN__BOXED,
613
614
                  G_TYPE_BOOLEAN, 1,
                  GDK_TYPE_EVENT);
615

616
  window_signals[ACTIVATE_FOCUS] =
617
    g_signal_new ("activate_focus",
Manish Singh's avatar
Manish Singh committed
618
                  G_TYPE_FROM_CLASS (gobject_class),
619
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
620
                  G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
621
                  NULL, NULL,
622
                  _gtk_marshal_VOID__VOID,
623
624
                  G_TYPE_NONE,
                  0);
625
626

  window_signals[ACTIVATE_DEFAULT] =
627
    g_signal_new ("activate_default",
Manish Singh's avatar
Manish Singh committed
628
                  G_TYPE_FROM_CLASS (gobject_class),
629
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
630
                  G_STRUCT_OFFSET (GtkWindowClass, activate_default),
631
                  NULL, NULL,
632
                  _gtk_marshal_VOID__VOID,
633
634
                  G_TYPE_NONE,
                  0);
635
636

  window_signals[MOVE_FOCUS] =
637
    g_signal_new ("move_focus",
Manish Singh's avatar
Manish Singh committed
638
                  G_TYPE_FROM_CLASS (gobject_class),
639
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
Manish Singh's avatar
Manish Singh committed
640
                  G_STRUCT_OFFSET (GtkWindowClass, move_focus),
641
                  NULL, NULL,
642
                  _gtk_marshal_VOID__ENUM,
643
644
645
                  G_TYPE_NONE,
                  1,
                  GTK_TYPE_DIRECTION_TYPE);
646

647
648
  window_signals[KEYS_CHANGED] =
    g_signal_new ("keys_changed",
Manish Singh's avatar
Manish Singh committed
649
                  G_TYPE_FROM_CLASS (gobject_class),
650
                  G_SIGNAL_RUN_FIRST,
Manish Singh's avatar
Manish Singh committed
651
                  G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
652
                  NULL, NULL,
Manish Singh's avatar
Manish Singh committed
653
                  _gtk_marshal_VOID__VOID,
654
655
                  G_TYPE_NONE,
                  0);
656
657
658
659
660
661
662
663
664

  /*
   * Key bindings
   */

  binding_set = gtk_binding_set_by_class (klass);

  gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
                                "activate_focus", 0);
665
666
667
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
                                "activate_focus", 0);
  
668
669
670
671
672
673
  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);

674
675
676
677
  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);
678

679
680
681
682
  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
683
684
685
686
687
}

static void
gtk_window_init (GtkWindow *window)
{
688
689
  GdkColormap *colormap;
  
Elliot Lee's avatar
Elliot Lee committed
690
  GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
691
  GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
Elliot Lee's avatar
Elliot Lee committed
692

Owen Taylor's avatar
Owen Taylor committed
693
694
  GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);

695
696
  gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);

Elliot Lee's avatar
Elliot Lee committed
697
  window->title = NULL;
698
  window->wmclass_name = g_strdup (g_get_prgname ());
699
  window->wmclass_class = g_strdup (gdk_get_program_class ());
700
701
  window->wm_role = NULL;
  window->geometry_info = NULL;
Elliot Lee's avatar
Elliot Lee committed
702
703
704
  window->type = GTK_WINDOW_TOPLEVEL;
  window->focus_widget = NULL;
  window->default_widget = NULL;
Havoc Pennington's avatar
Havoc Pennington committed
705
  window->configure_request_count = 0;
Elliot Lee's avatar
Elliot Lee committed
706
707
  window->allow_shrink = FALSE;
  window->allow_grow = TRUE;
Havoc Pennington's avatar
Havoc Pennington committed
708
  window->configure_notify_received = FALSE;
Elliot Lee's avatar
Elliot Lee committed
709
  window->position = GTK_WIN_POS_NONE;
Havoc Pennington's avatar
Havoc Pennington committed
710
711
  window->need_default_size = TRUE;
  window->need_default_position = TRUE;
712
  window->modal = FALSE;
713
714
715
716
717
718
  window->frame = NULL;
  window->has_frame = FALSE;
  window->frame_left = 0;
  window->frame_right = 0;
  window->frame_top = 0;
  window->frame_bottom = 0;
719
  window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
720
  window->gravity = GDK_GRAVITY_NORTH_WEST;
721
  window->decorated = TRUE;
722
  window->mnemonic_modifier = GDK_MOD1_MASK;
Owen Taylor's avatar
Owen Taylor committed
723
  window->screen = gdk_screen_get_default ();
724
  
725
726
727
728
  colormap = _gtk_widget_peek_colormap ();
  if (colormap)
    gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
  
Manish Singh's avatar
Manish Singh committed
729
  g_object_ref (window);
730
731
732
  gtk_object_sink (GTK_OBJECT (window));
  window->has_user_ref_count = TRUE;
  toplevel_list = g_slist_prepend (toplevel_list, window);
733
734
735

  gtk_decorated_window_init (window);

Manish Singh's avatar
Manish Singh committed
736
737
738
739
  g_signal_connect (window,
		    "event",
		    G_CALLBACK (gtk_window_event),
		    NULL);
Elliot Lee's avatar
Elliot Lee committed
740
741
742
}

static void
743
744
745
746
gtk_window_set_property (GObject      *object,
			 guint         prop_id,
			 const GValue *value,
			 GParamSpec   *pspec)
Elliot Lee's avatar
Elliot Lee committed
747
{
748
  GtkWindow  *window;
Havoc Pennington's avatar
Havoc Pennington committed
749
  
750
751
  window = GTK_WINDOW (object);

752
  switch (prop_id)
Elliot Lee's avatar
Elliot Lee committed
753
    {
754
755
    case PROP_TYPE:
      window->type = g_value_get_enum (value);
756
      break;
757
758
    case PROP_TITLE:
      gtk_window_set_title (window, g_value_get_string (value));
759
      break;
760
761
    case PROP_ALLOW_SHRINK:
      window->allow_shrink = g_value_get_boolean (value);
762
      gtk_widget_queue_resize (GTK_WIDGET (window));
763
      break;
764
765
    case PROP_ALLOW_GROW:
      window->allow_grow = g_value_get_boolean (value);
766
      gtk_widget_queue_resize (GTK_WIDGET (window));
Havoc Pennington's avatar
Havoc Pennington committed
767
768
769
770
771
772
      g_object_notify (G_OBJECT (window), "resizable");
      break;
    case PROP_RESIZABLE:
      window->allow_grow = g_value_get_boolean (value);
      gtk_widget_queue_resize (GTK_WIDGET (window));
      g_object_notify (G_OBJECT (window), "allow_grow");
773
      break;
774
775
    case PROP_MODAL:
      gtk_window_set_modal (window, g_value_get_boolean (value));
776
      break;
777
778
    case PROP_WIN_POS:
      gtk_window_set_position (window, g_value_get_enum (value));
779
      break;
780
    case PROP_DEFAULT_WIDTH:
Havoc Pennington's avatar
Havoc Pennington committed
781
782
      gtk_window_set_default_size_internal (window,
                                            TRUE, g_value_get_int (value),
783
                                            FALSE, -1, FALSE);
784
      break;
785
    case PROP_DEFAULT_HEIGHT:
Havoc Pennington's avatar
Havoc Pennington committed
786
787
      gtk_window_set_default_size_internal (window,
                                            FALSE, -1,
788
                                            TRUE, g_value_get_int (value), FALSE);
789
      break;
790
791
    case PROP_DESTROY_WITH_PARENT:
      gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
792
      break;
Havoc Pennington's avatar
Havoc Pennington committed
793
794
795
796
    case PROP_ICON:
      gtk_window_set_icon (window,
                           g_value_get_object (value));
      break;
797
798
799
    case PROP_SCREEN:
      gtk_window_set_screen (window, g_value_get_object (value));
      break;
800
801
802
803
804
805
806
807
808
809
810
811
812
    case PROP_TYPE_HINT:
      gtk_window_set_type_hint (window,
                                g_value_get_enum (value));
      break;
    case PROP_SKIP_TASKBAR_HINT:
      gtk_window_set_skip_taskbar_hint (window,
                                        g_value_get_boolean (value));
      break;
    case PROP_SKIP_PAGER_HINT:
      gtk_window_set_skip_pager_hint (window,
                                      g_value_get_boolean (value));
      break;
      
Tim Janik's avatar
Tim Janik committed
813
814
    default:
      break;
Elliot Lee's avatar
Elliot Lee committed
815
816
817
    }
}

818
static void
819
820
821
822
gtk_window_get_property (GObject      *object,
			 guint         prop_id,
			 GValue       *value,
			 GParamSpec   *pspec)
823
{
824
825
826
827
  GtkWindow  *window;

  window = GTK_WINDOW (object);

828
  switch (prop_id)
829
    {
830
      GtkWindowGeometryInfo *info;
831
832
    case PROP_TYPE:
      g_value_set_enum (value, window->type);
833
      break;
834
835
    case PROP_TITLE:
      g_value_set_string (value, window->title);
836
      break;
837
838
    case PROP_ALLOW_SHRINK:
      g_value_set_boolean (value, window->allow_shrink);
839
      break;
840
841
    case PROP_ALLOW_GROW:
      g_value_set_boolean (value, window->allow_grow);
842
      break;
Havoc Pennington's avatar
Havoc Pennington committed
843
844
845
    case PROP_RESIZABLE:
      g_value_set_boolean (value, window->allow_grow);
      break;
846
847
    case PROP_MODAL:
      g_value_set_boolean (value, window->modal);
848
      break;
849
850
    case PROP_WIN_POS:
      g_value_set_enum (value, window->position);
851
      break;
852
    case PROP_DEFAULT_WIDTH:
853
854
      info = gtk_window_get_geometry_info (window, FALSE);
      if (!info)
Havoc Pennington's avatar
Havoc Pennington committed
855
	g_value_set_int (value, -1);
856
      else
Havoc Pennington's avatar
Havoc Pennington committed
857
	g_value_set_int (value, info->default_width);
858
      break;
859
    case PROP_DEFAULT_HEIGHT:
860
861
      info = gtk_window_get_geometry_info (window, FALSE);
      if (!info)
Havoc Pennington's avatar
Havoc Pennington committed
862
	g_value_set_int (value, -1);
863
      else
Havoc Pennington's avatar
Havoc Pennington committed
864
	g_value_set_int (value, info->default_height);
865
      break;
866
867
    case PROP_DESTROY_WITH_PARENT:
      g_value_set_boolean (value, window->destroy_with_parent);
868
      break;
Havoc Pennington's avatar
Havoc Pennington committed
869
    case PROP_ICON:
870
      g_value_set_object (value, gtk_window_get_icon (window));
Havoc Pennington's avatar
Havoc Pennington committed
871
      break;
872
873
874
    case PROP_SCREEN:
      g_value_set_object (value, window->screen);
      break;
875
876
877
878
879
880
    case PROP_IS_ACTIVE:
      g_value_set_boolean (value, window->is_active);
      break;
    case PROP_HAS_TOPLEVEL_FOCUS:
      g_value_set_boolean (value, window->has_toplevel_focus);
      break;
881
882
883
884
885
886
887
888
889
890
891
892
    case PROP_TYPE_HINT:
      g_value_set_enum (value,
                        window->type_hint);
      break;
    case PROP_SKIP_TASKBAR_HINT:
      g_value_set_boolean (value,
                           gtk_window_get_skip_taskbar_hint (window));
      break;
    case PROP_SKIP_PAGER_HINT:
      g_value_set_boolean (value,
                           gtk_window_get_skip_pager_hint (window));
      break;
893
    default:
894
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
895
896
897
898
      break;
    }
}

899
900
901
902
903
904
905
906
/**
 * gtk_window_new:
 * @type: type of window
 * 
 * Creates a new #GtkWindow, which is a toplevel window that can
 * contain other widgets. Nearly always, the type of the window should
 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
907
 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
908
 * dialogs, though in some other toolkits dialogs are called "popups".
909
 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
910
911
 * On X11, popup windows are not controlled by the <link
 * linkend="gtk-X11-arch">window manager</link>.
912
913
914
 *
 * If you simply want an undecorated window (no window borders), use
 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
915
916
917
 * 
 * Return value: a new #GtkWindow.
 **/
Elliot Lee's avatar
Elliot Lee committed
918
919
920
921
922
GtkWidget*
gtk_window_new (GtkWindowType type)
{
  GtkWindow *window;

923
924
  g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);

Manish Singh's avatar
Manish Singh committed
925
  window = g_object_new (GTK_TYPE_WINDOW, NULL);
Elliot Lee's avatar
Elliot Lee committed
926
927
928
929
930
931

  window->type = type;

  return GTK_WIDGET (window);
}

932
933
934
935
936
/**
 * gtk_window_set_title:
 * @window: a #GtkWindow
 * @title: title of the window
 * 
937
938
939
940
941
942
943
944
 * Sets the title of the #GtkWindow. The title of a window will be
 * displayed in its title bar; on the X Window System, the title bar
 * is rendered by the <link linkend="gtk-X11-arch">window
 * manager</link>, so exactly how the title appears to users may vary
 * according to a user's exact configuration. The title should help a
 * user distinguish this window from other windows they may have
 * open. A good title might include the application name and current
 * document filename, for example.
945
946
 * 
 **/
Elliot Lee's avatar
Elliot Lee committed
947
948
949
950
951
952
953
954
955
956
957
void
gtk_window_set_title (GtkWindow   *window,
		      const gchar *title)
{
  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))
958
959
960
961
962
    {
      gdk_window_set_title (GTK_WIDGET (window)->window, window->title);

      gtk_decorated_window_set_title (window, title);
    }
963
964

  g_object_notify (G_OBJECT (window), "title");
Elliot Lee's avatar
Elliot Lee committed
965
966
}

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
/**
 * gtk_window_get_title:
 * @window: a #GtkWindow
 *
 * Retrieves the title of the window. See gtk_window_set_title().
 *
 * Return value: the title of the window, or %NULL if none has
 *    been set explicitely. The returned string is owned by the widget
 *    and must not be modified or freed.
 **/
G_CONST_RETURN gchar *
gtk_window_get_title (GtkWindow *window)
{
  g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);

  return window->title;
}

985
986
987
988
989
990
/**
 * gtk_window_set_wmclass:
 * @window: a #GtkWindow
 * @wmclass_name: window name hint
 * @wmclass_class: window class hint
 *
991
992
993
 * Don't use this function. It sets the X Window System "class" and
 * "name" hints for a window.  According to the ICCCM, you should
 * always set these to the same value for all windows in an
Matthias Clasen's avatar
Matthias Clasen committed
994
 * application, and GTK+ sets them to that value by default, so calling
995
996
997
998
 * this function is sort of pointless. However, you may want to call
 * gtk_window_set_role() on each window in your application, for the
 * benefit of the session manager. Setting the role allows the window
 * manager to restore window positions when loading a saved session.
999
1000
 * 
 **/
Elliot Lee's avatar
Elliot Lee committed
1001
1002
void
gtk_window_set_wmclass (GtkWindow *window,
1003
1004
			const gchar *wmclass_name,
			const gchar *wmclass_class)
Elliot Lee's avatar
Elliot Lee committed
1005
1006
1007
{
  g_return_if_fail (GTK_IS_WINDOW (window));

Tim Janik's avatar
Tim Janik committed
1008
  g_free (window->wmclass_name);
Elliot Lee's avatar
Elliot Lee committed
1009
1010
  window->wmclass_name = g_strdup (wmclass_name);

Tim Janik's avatar
Tim Janik committed
1011
  g_free (window->wmclass_class);
Elliot Lee's avatar
Elliot Lee committed
1012
1013
1014
  window->wmclass_class = g_strdup (wmclass_class);

  if (GTK_WIDGET_REALIZED (window))
1015
1016
1017
1018
1019
1020
1021
1022
    g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
}

/**
 * gtk_window_set_role:
 * @window: a #GtkWindow
 * @role: unique identifier for the window to be used when restoring a session
 *
1023
1024
 * This function is only useful on X11, not with other GTK+ targets.
 * 
1025
 * In combination with the window title, the window role allows a
1026
1027
1028
1029
1030
 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
 * same" window when an application is restarted. So for example you
 * might set the "toolbox" role on your app's toolbox window, so that
 * when the user restarts their session, the window manager can put
 * the toolbox back in the same place.
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
 *
 * If a window already has a unique title, you don't need to set the
 * role, since the WM can use the title to identify the window when
 * restoring the session.
 * 
 **/
void
gtk_window_set_role (GtkWindow   *window,
                     const gchar *role)
{
  g_return_if_fail (GTK_IS_WINDOW (window));

  if (role == window->wm_role)
    return;
  
  g_free (window->wm_role);
  window->wm_role = g_strdup (role);
  
  if (GTK_WIDGET_REALIZED (window))
    g_warning ("gtk_window_set_role(): shouldn't set role after window is realized!\n");
Elliot Lee's avatar
Elliot Lee committed
1051
1052
}

1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
/**
 * gtk_window_get_role:
 * @window: a #GtkWindow
 *
 * Returns the role of the window. See gtk_window_set_role() for
 * further explanation.
 *
 * Return value: the role of the window if set, or %NULL. The
 *   returned is owned by the widget and must not be modified
 *   or freed.
 **/
G_CONST_RETURN gchar *
gtk_window_get_role (GtkWindow *window)
{
  g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);

  return window->wm_role;
}

1072
1073
1074
/**
 * gtk_window_set_focus:
 * @window: a #GtkWindow
1075
1076
 * @focus: widget to be the new focus widget, or %NULL to unset
 *   any focus widget for the toplevel window.
1077
 *
1078
1079
1080
1081
1082
 * If @focus is not the current focus widget, and is focusable, sets
 * it as the focus widget for the window. If @focus is %NULL, unsets
 * the focus widget for this window. To set the focus to a particular
 * widget in the toplevel, it is usually more convenient to use
 * gtk_widget_grab_focus() instead of this function.
1083
 **/
Elliot Lee's avatar
Elliot Lee committed
1084
1085
1086
1087
void
gtk_window_set_focus (GtkWindow *window,
		      GtkWidget *focus)
{
1088
1089
1090
1091
1092
1093
1094
  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));
    }

1095
1096
1097
  if (focus)
    gtk_widget_grab_focus (focus);
  else
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
    {
      /* Clear the existing focus chain, so that when we focus into
       * the window again, we start at the beginnning.
       */
      GtkWidget *widget = window->focus_widget;
      if (widget)
	{
	  while (widget->parent)
	    {
	      widget = widget->parent;
	      gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
	    }
	}
      
      _gtk_window_internal_set_focus (window, NULL);
    }
1114
1115
1116
1117
1118
1119
1120
1121
}

void
_gtk_window_internal_set_focus (GtkWindow *window,
				GtkWidget *focus)
{
  g_return_if_fail (GTK_IS_WINDOW (window));

1122
1123
  if ((window->focus_widget != focus) ||
      (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
Manish Singh's avatar
Manish Singh committed
1124
    g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
Elliot Lee's avatar
Elliot Lee committed
1125
1126
}

1127
1128
1129
/**
 * gtk_window_set_default:
 * @window: a #GtkWindow
1130
1131
 * @default_widget: widget to be the default, or %NULL to unset the
 *                  default widget for the toplevel.
1132
1133
 *
 * The default widget is the widget that's activated when the user
1134
1135
1136
1137
1138
1139
 * presses Enter in a dialog (for example). This function sets or
 * unsets the default widget for a #GtkWindow about. When setting
 * (rather than unsetting) the default widget it's generally easier to
 * call gtk_widget_grab_focus() on the widget. Before making a widget
 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1140
 **/
Elliot Lee's avatar
Elliot Lee committed
1141
1142
void
gtk_window_set_default (GtkWindow *window,
1143
			GtkWidget *default_widget)
Elliot Lee's avatar
Elliot Lee committed
1144
1145
1146
{
  g_return_if_fail (GTK_IS_WINDOW (window));

1147
1148
  if (default_widget)
    g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1149
  
1150
  if (window->default_widget != default_widget)
Elliot Lee's avatar
Elliot Lee committed
1151
    {
1152
1153
1154
1155
1156
      GtkWidget *old_default_widget = NULL;
      
      if (default_widget)
	g_object_ref (default_widget);
      
Elliot Lee's avatar
Elliot Lee committed
1157
1158
      if (window->default_widget)
	{
1159
1160
	  old_default_widget = window->default_widget;
	  
1161
1162
1163
	  if (window->focus_widget != window->default_widget ||
	      !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
	    GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1164
	  gtk_widget_queue_draw (window->default_widget);
Elliot Lee's avatar
Elliot Lee committed
1165
1166
	}

1167
      window->default_widget = default_widget;
Elliot Lee's avatar
Elliot Lee committed
1168
1169
1170

      if (window->default_widget)
	{
1171
1172
1173
	  if (window->focus_widget == NULL ||
	      !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
	    GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1174
	  gtk_widget_queue_draw (window->default_widget);
Elliot Lee's avatar
Elliot Lee committed
1175
	}
1176
1177
1178
1179
1180
1181
1182
1183
1184

      if (old_default_widget)
	g_object_notify (G_OBJECT (old_default_widget), "has_default");
      
      if (default_widget)
	{
	  g_object_notify (G_OBJECT (default_widget), "has_default");
	  g_object_unref (default_widget);
	}
Elliot Lee's avatar
Elliot Lee committed
1185
1186
1187
1188
1189
    }
}

void
gtk_window_set_policy (GtkWindow *window,
1190
1191
1192
		       gboolean   allow_shrink,
		       gboolean   allow_grow,
		       gboolean   auto_shrink)
Elliot Lee's avatar
Elliot Lee committed
1193
1194
1195
1196
1197
{
  g_return_if_fail (GTK_IS_WINDOW (window));

  window->allow_shrink = (allow_shrink != FALSE);
  window->allow_grow = (allow_grow != FALSE);
Tim Janik's avatar
Tim Janik committed
1198

1199
  g_object_freeze_notify (G_OBJECT (window));
1200
1201
  g_object_notify (G_OBJECT (window), "allow_shrink");
  g_object_notify (G_OBJECT (window), "allow_grow");
Havoc Pennington's avatar
Havoc Pennington committed
1202
  g_object_notify (G_OBJECT (window), "resizable");
1203
  g_object_thaw_notify (G_OBJECT (window));
1204
  
1205
  gtk_widget_queue_resize (GTK_WIDGET (window));
Elliot Lee's avatar
Elliot Lee committed
1206
1207
}

1208
static gboolean
1209
handle_keys_changed (gpointer data)