gtknotebook.c 258 KB
Newer Older
1
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
Cody Russell's avatar
Cody Russell committed
2
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
3 4 5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
7 8 9 10 11 12
 * 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
13
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16 17 18
 * 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
19
 */
20 21

/*
22
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23 24
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
25
 * GTK+ at ftp:ftp.gtk.org/pub/gtk/.
26 27
 */

28
#include "config.h"
29 30

#include <stdio.h>
Johan Dahlin's avatar
Johan Dahlin committed
31
#include <string.h>
32

33
#include "gtknotebook.h"
34

35 36 37 38
#include "gtkmain.h"
#include "gtkmenu.h"
#include "gtkmenuitem.h"
#include "gtklabel.h"
39
#include "gtkintl.h"
40
#include "gtkmarshalers.h"
41
#include "gtkbindings.h"
42
#include "gtkprivate.h"
43
#include "gtkdnd.h"
Johan Dahlin's avatar
Johan Dahlin committed
44
#include "gtkbuildable.h"
45
#include "gtktypebuiltins.h"
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

/**
 * SECTION:gtknotebook
 * @Short_description: A tabbed notebook container
 * @Title: GtkNotebook
 * @See_also: #GtkContainer
 *
 * The #GtkNotebook widget is a #GtkContainer whose children are pages that
 * can be switched between using tab labels along one edge.
 *
 * There are many configuration options for GtkNotebook. Among other
 * things, you can choose on which edge the tabs appear
 * (see gtk_notebook_set_tab_pos()), whether, if there are too many
 * tabs to fit the notebook should be made bigger or scrolling
 * arrows added (see gtk_notebook_set_scrollable()), and whether there
 * will be a popup menu allowing the users to switch pages.
 * (see gtk_notebook_popup_enable(), gtk_notebook_popup_disable())
 *
 * <refsect2 id="GtkNotebook-BUILDER-UI">
 * <title>GtkNotebook as GtkBuildable</title>
 * <para>
 * The GtkNotebook implementation of the #GtkBuildable interface
 * supports placing children into tabs by specifying "tab" as the
 * "type" attribute of a &lt;child&gt; element. Note that the content
 * of the tab must be created before the tab can be filled.
 * A tab child can be specified without specifying a &lt;child&gt;
 * type attribute.
74
 *
75 76 77
 * To add a child widget in the notebooks action area, specify
 * "action-start" or "action-end" as the "type" attribute of the &lt;child&gt;
 * element.
78
 * </para>
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
 * <example>
 * <title>A UI definition fragment with GtkNotebook</title>
 * <programlisting><![CDATA[
 * <object class="GtkNotebook">
 *   <child>
 *     <object class="GtkLabel" id="notebook-content">
 *       <property name="label">Content</property>
 *     </object>
 *   </child>
 *   <child type="tab">
 *     <object class="GtkLabel" id="notebook-tab">
 *       <property name="label">Tab</property>
 *     </object>
 *   </child>
 * </object>
 * ]]></programlisting>
 * </example>
 * </refsect2>
 */


100
#define SCROLL_DELAY_FACTOR   5
101 102
#define SCROLL_THRESHOLD      12
#define DND_THRESHOLD_MULTIPLIER 4
103 104
#define FRAMES_PER_SECOND     45
#define MSECS_BETWEEN_UPDATES (1000 / FRAMES_PER_SECOND)
Elliot Lee's avatar
Elliot Lee committed
105

106
typedef struct _GtkNotebookPage GtkNotebookPage;
107 108 109 110 111 112 113 114 115 116 117 118 119 120

typedef enum
{
  DRAG_OPERATION_NONE,
  DRAG_OPERATION_REORDER,
  DRAG_OPERATION_DETACH
} GtkNotebookDragOperation;

enum {
  ACTION_WIDGET_START,
  ACTION_WIDGET_END,
  N_ACTION_WIDGETS
};

121
struct _GtkNotebookPrivate
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
{
  GtkNotebookDragOperation   operation;
  GtkNotebookPage           *cur_page;
  GtkNotebookPage           *detached_tab;
  GtkTargetList             *source_targets;
  GtkWidget                 *action_widget[N_ACTION_WIDGETS];
  GtkWidget                 *dnd_window;
  GtkWidget                 *menu;

  GdkWindow               *drag_window;
  GdkWindow               *event_window;

  GList         *children;
  GList         *first_tab;             /* The first tab visible (for scrolling notebooks) */
  GList         *focus_tab;

  gint           drag_begin_x;
  gint           drag_begin_y;
  gint           drag_offset_x;
  gint           drag_offset_y;
  gint           drag_window_x;
  gint           drag_window_y;
  gint           mouse_x;
  gint           mouse_y;
  gint           pressed_button;

148
  GQuark         group;
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180

  guint          dnd_timer;
  guint          switch_tab_timer;

  guint16        tab_hborder;
  guint16        tab_vborder;

  guint32        timer;
  guint32        timestamp;

  guint          button             : 2;
  guint          child_has_focus    : 1;
  guint          click_child        : 3;
  guint          during_detach      : 1;
  guint          during_reorder     : 1;
  guint          focus_out          : 1; /* Flag used by ::move-focus-out implementation */
  guint          has_scrolled       : 1;
  guint          have_visible_child : 1;
  guint          homogeneous        : 1;
  guint          in_child           : 3;
  guint          need_timer         : 1;
  guint          show_border        : 1;
  guint          show_tabs          : 1;
  guint          scrollable         : 1;
  guint          tab_pos            : 2;

  guint          has_before_previous : 1;
  guint          has_before_next     : 1;
  guint          has_after_previous  : 1;
  guint          has_after_next      : 1;
};

181 182
enum {
  SWITCH_PAGE,
183 184
  FOCUS_TAB,
  SELECT_PAGE,
185
  CHANGE_CURRENT_PAGE,
186
  MOVE_FOCUS_OUT,
187
  REORDER_TAB,
188 189 190
  PAGE_REORDERED,
  PAGE_REMOVED,
  PAGE_ADDED,
191
  CREATE_WINDOW,
192 193 194
  LAST_SIGNAL
};

195 196 197 198 199
enum {
  STEP_PREV,
  STEP_NEXT
};

200 201 202 203 204 205 206 207 208
typedef enum
{
  ARROW_NONE,
  ARROW_LEFT_BEFORE,
  ARROW_RIGHT_BEFORE,
  ARROW_LEFT_AFTER,
  ARROW_RIGHT_AFTER
} GtkNotebookArrow;

209 210 211 212 213 214 215
typedef enum
{
  POINTER_BEFORE,
  POINTER_AFTER,
  POINTER_BETWEEN
} GtkNotebookPointerPosition;

216 217 218
#define ARROW_IS_LEFT(arrow)  ((arrow) == ARROW_LEFT_BEFORE || (arrow) == ARROW_LEFT_AFTER)
#define ARROW_IS_BEFORE(arrow) ((arrow) == ARROW_LEFT_BEFORE || (arrow) == ARROW_RIGHT_BEFORE)

219
enum {
220 221 222 223 224 225 226
  PROP_0,
  PROP_TAB_POS,
  PROP_SHOW_TABS,
  PROP_SHOW_BORDER,
  PROP_SCROLLABLE,
  PROP_PAGE,
  PROP_ENABLE_POPUP,
227
  PROP_GROUP_NAME
228 229 230
};

enum {
Tim Janik's avatar
Tim Janik committed
231 232 233 234 235 236
  CHILD_PROP_0,
  CHILD_PROP_TAB_LABEL,
  CHILD_PROP_MENU_LABEL,
  CHILD_PROP_POSITION,
  CHILD_PROP_TAB_EXPAND,
  CHILD_PROP_TAB_FILL,
237 238
  CHILD_PROP_REORDERABLE,
  CHILD_PROP_DETACHABLE
239 240
};

241 242
#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)((GList *)(_glist_))->data)

243 244 245 246 247 248 249
/* some useful defines for calculating coords */
#define PAGE_LEFT_X(_page_)   (((GtkNotebookPage *) (_page_))->allocation.x)
#define PAGE_RIGHT_X(_page_)  (((GtkNotebookPage *) (_page_))->allocation.x + ((GtkNotebookPage *) (_page_))->allocation.width)
#define PAGE_MIDDLE_X(_page_) (((GtkNotebookPage *) (_page_))->allocation.x + ((GtkNotebookPage *) (_page_))->allocation.width / 2)
#define PAGE_TOP_Y(_page_)    (((GtkNotebookPage *) (_page_))->allocation.y)
#define PAGE_BOTTOM_Y(_page_) (((GtkNotebookPage *) (_page_))->allocation.y + ((GtkNotebookPage *) (_page_))->allocation.height)
#define PAGE_MIDDLE_Y(_page_) (((GtkNotebookPage *) (_page_))->allocation.y + ((GtkNotebookPage *) (_page_))->allocation.height / 2)
250
#define NOTEBOOK_IS_TAB_LABEL_PARENT(_notebook_,_page_) (gtk_widget_get_parent (((GtkNotebookPage *) (_page_))->tab_label) == ((GtkWidget *) (_notebook_)))
251

252 253 254 255 256
struct _GtkNotebookPage
{
  GtkWidget *child;
  GtkWidget *tab_label;
  GtkWidget *menu_label;
257
  GtkWidget *last_focus_child;  /* Last descendant of the page that had focus */
258

259 260
  guint default_menu : 1;       /* If true, we create the menu label ourself */
  guint default_tab  : 1;       /* If true, we create the tab label ourself */
261 262
  guint expand       : 1;
  guint fill         : 1;
263 264
  guint reorderable  : 1;
  guint detachable   : 1;
265

266 267 268 269 270
  /* if true, the tab label was visible on last allocation; we track this so
   * that we know to redraw the tab area if a tab label was hidden then shown
   * without changing position */
  guint tab_allocated_visible : 1;

271 272
  GtkRequisition requisition;
  GtkAllocation allocation;
273

274 275
  gulong mnemonic_activate_signal;
  gulong notify_visible_handler;
276 277
};

278
static const GtkTargetEntry notebook_targets [] = {
279
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
280 281
};

282 283
#ifdef G_DISABLE_CHECKS
#define CHECK_FIND_CHILD(notebook, child)                           \
284
 gtk_notebook_find_child (notebook, child, G_STRLOC)
285 286
#else
#define CHECK_FIND_CHILD(notebook, child)                           \
287
 gtk_notebook_find_child (notebook, child, NULL)
288
#endif
289

290
/*** GtkNotebook Methods ***/
291
static gboolean gtk_notebook_select_page         (GtkNotebook      *notebook,
292
                                                  gboolean          move_focus);
293
static gboolean gtk_notebook_focus_tab           (GtkNotebook      *notebook,
294
                                                  GtkNotebookTab    type);
295
static gboolean gtk_notebook_change_current_page (GtkNotebook      *notebook,
296
                                                  gint              offset);
297
static void     gtk_notebook_move_focus_out      (GtkNotebook      *notebook,
298
                                                  GtkDirectionType  direction_type);
299
static gboolean gtk_notebook_reorder_tab         (GtkNotebook      *notebook,
300 301
                                                  GtkDirectionType  direction_type,
                                                  gboolean          move_to_last);
302
static void     gtk_notebook_remove_tab_label    (GtkNotebook      *notebook,
303
                                                  GtkNotebookPage  *page);
304 305 306
static void     gtk_notebook_set_tab_label_packing   (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean      expand,
307
                                                      gboolean      fill);
308 309 310
static void     gtk_notebook_query_tab_label_packing (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean     *expand,
311
                                                      gboolean     *fill);
312

313
/*** GObject Methods ***/
314 315 316 317 318 319 320 321
static void gtk_notebook_set_property        (GObject         *object,
                                              guint            prop_id,
                                              const GValue    *value,
                                              GParamSpec      *pspec);
static void gtk_notebook_get_property        (GObject         *object,
                                              guint            prop_id,
                                              GValue          *value,
                                              GParamSpec      *pspec);
322

323
/*** GtkWidget Methods ***/
324
static void gtk_notebook_destroy             (GtkWidget        *widget);
325 326 327
static void gtk_notebook_map                 (GtkWidget        *widget);
static void gtk_notebook_unmap               (GtkWidget        *widget);
static void gtk_notebook_realize             (GtkWidget        *widget);
328
static void gtk_notebook_unrealize           (GtkWidget        *widget);
329
static void gtk_notebook_get_preferred_width (GtkWidget        *widget,
330 331
                                              gint             *minimum,
                                              gint             *natural);
332
static void gtk_notebook_get_preferred_height(GtkWidget        *widget,
333 334
                                              gint             *minimum,
                                              gint             *natural);
335
static void gtk_notebook_size_allocate       (GtkWidget        *widget,
336
                                              GtkAllocation    *allocation);
Benjamin Otte's avatar
Benjamin Otte committed
337 338
static gint gtk_notebook_draw                (GtkWidget        *widget,
                                              cairo_t          *cr);
339
static gint gtk_notebook_button_press        (GtkWidget        *widget,
340
                                              GdkEventButton   *event);
341
static gint gtk_notebook_button_release      (GtkWidget        *widget,
342
                                              GdkEventButton   *event);
343
static gboolean gtk_notebook_popup_menu      (GtkWidget        *widget);
344
static gint gtk_notebook_leave_notify        (GtkWidget        *widget,
345
                                              GdkEventCrossing *event);
346
static gint gtk_notebook_motion_notify       (GtkWidget        *widget,
347
                                              GdkEventMotion   *event);
348
static gint gtk_notebook_focus_in            (GtkWidget        *widget,
349
                                              GdkEventFocus    *event);
350
static gint gtk_notebook_focus_out           (GtkWidget        *widget,
351
                                              GdkEventFocus    *event);
Matthias Clasen's avatar
Matthias Clasen committed
352
static void gtk_notebook_grab_notify         (GtkWidget          *widget,
353
                                              gboolean            was_grabbed);
354
static void gtk_notebook_state_flags_changed (GtkWidget          *widget,
355
                                              GtkStateFlags       previous_state);
356
static gint gtk_notebook_focus               (GtkWidget        *widget,
357
                                              GtkDirectionType  direction);
358
static void gtk_notebook_style_updated       (GtkWidget        *widget);
359

360 361
/*** Drag and drop Methods ***/
static void gtk_notebook_drag_begin          (GtkWidget        *widget,
362
                                              GdkDragContext   *context);
363
static void gtk_notebook_drag_end            (GtkWidget        *widget,
364
                                              GdkDragContext   *context);
365
static gboolean gtk_notebook_drag_failed     (GtkWidget        *widget,
366 367
                                              GdkDragContext   *context,
                                              GtkDragResult     result);
368
static gboolean gtk_notebook_drag_motion     (GtkWidget        *widget,
369 370 371 372
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              guint             time);
373
static void gtk_notebook_drag_leave          (GtkWidget        *widget,
374 375
                                              GdkDragContext   *context,
                                              guint             time);
376
static gboolean gtk_notebook_drag_drop       (GtkWidget        *widget,
377 378 379 380
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              guint             time);
381
static void gtk_notebook_drag_data_get       (GtkWidget        *widget,
382 383 384 385
                                              GdkDragContext   *context,
                                              GtkSelectionData *data,
                                              guint             info,
                                              guint             time);
386
static void gtk_notebook_drag_data_received  (GtkWidget        *widget,
387 388 389 390 391 392
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              GtkSelectionData *data,
                                              guint             info,
                                              guint             time);
393

394
/*** GtkContainer Methods ***/
Tim Janik's avatar
Tim Janik committed
395
static void gtk_notebook_set_child_property  (GtkContainer     *container,
396 397 398 399
                                              GtkWidget        *child,
                                              guint             property_id,
                                              const GValue     *value,
                                              GParamSpec       *pspec);
Tim Janik's avatar
Tim Janik committed
400
static void gtk_notebook_get_child_property  (GtkContainer     *container,
401 402 403 404
                                              GtkWidget        *child,
                                              guint             property_id,
                                              GValue           *value,
                                              GParamSpec       *pspec);
405
static void gtk_notebook_add                 (GtkContainer     *container,
406
                                              GtkWidget        *widget);
407
static void gtk_notebook_remove              (GtkContainer     *container,
408
                                              GtkWidget        *widget);
409
static void gtk_notebook_set_focus_child     (GtkContainer     *container,
410
                                              GtkWidget        *child);
Manish Singh's avatar
Manish Singh committed
411
static GType gtk_notebook_child_type       (GtkContainer     *container);
412
static void gtk_notebook_forall              (GtkContainer     *container,
413 414 415
                                              gboolean          include_internals,
                                              GtkCallback       callback,
                                              gpointer          callback_data);
416 417
static GtkWidgetPath * gtk_notebook_get_path_for_child (GtkContainer *container,
                                                        GtkWidget    *widget);
418

419 420
/*** GtkNotebook Methods ***/
static gint gtk_notebook_real_insert_page    (GtkNotebook      *notebook,
421 422 423 424
                                              GtkWidget        *child,
                                              GtkWidget        *tab_label,
                                              GtkWidget        *menu_label,
                                              gint              position);
425

426 427 428 429 430
static GtkNotebook *gtk_notebook_create_window (GtkNotebook    *notebook,
                                                GtkWidget      *page,
                                                gint            x,
                                                gint            y);

431
/*** GtkNotebook Private Functions ***/
432 433
static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
434
static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
435
                                              GList            *list);
436 437
static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
static gint gtk_notebook_timer               (GtkNotebook      *notebook);
438
static void gtk_notebook_set_scroll_timer    (GtkNotebook *notebook);
439
static gint gtk_notebook_page_compare        (gconstpointer     a,
440
                                              gconstpointer     b);
441
static GList* gtk_notebook_find_child        (GtkNotebook      *notebook,
442 443
                                              GtkWidget        *child,
                                              const gchar      *function);
444
static GList * gtk_notebook_search_page      (GtkNotebook      *notebook,
445 446 447
                                              GList            *list,
                                              gint              direction,
                                              gboolean          find_visible);
448
static void  gtk_notebook_child_reordered    (GtkNotebook      *notebook,
449
                                              GtkNotebookPage  *page);
450

451
/*** GtkNotebook Drawing Functions ***/
452
static void gtk_notebook_paint               (GtkWidget        *widget,
453
                                              cairo_t          *cr);
454
static void gtk_notebook_draw_tab            (GtkNotebook      *notebook,
455 456
                                              GtkNotebookPage  *page,
                                              cairo_t          *cr,
457
                                              GtkRegionFlags    flags);
458
static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
459
                                              cairo_t          *cr,
460
                                              GtkNotebookArrow  arrow);
461

462
/*** GtkNotebook Size Allocate Functions ***/
463
static void gtk_notebook_pages_allocate      (GtkNotebook      *notebook);
464
static gboolean gtk_notebook_page_allocate   (GtkNotebook      *notebook,
465
                                              GtkNotebookPage  *page);
466
static void gtk_notebook_calc_tabs           (GtkNotebook      *notebook,
467 468 469 470
                                              GList            *start,
                                              GList           **end,
                                              gint             *tab_space,
                                              guint             direction);
471

472
/*** GtkNotebook Page Switch Methods ***/
473
static void gtk_notebook_real_switch_page    (GtkNotebook      *notebook,
474 475
                                              GtkWidget        *child,
                                              guint             page_num);
476

477
/*** GtkNotebook Page Switch Functions ***/
478
static void gtk_notebook_switch_page         (GtkNotebook      *notebook,
479
                                              GtkNotebookPage  *page);
480
static gint gtk_notebook_page_select         (GtkNotebook      *notebook,
481
                                              gboolean          move_focus);
482 483
static void gtk_notebook_switch_focus_tab    (GtkNotebook      *notebook,
                                              GList            *new_child);
484
static void gtk_notebook_menu_switch_page    (GtkWidget        *widget,
485
                                              GtkNotebookPage  *page);
486

487
/*** GtkNotebook Menu Functions ***/
488
static void gtk_notebook_menu_item_create    (GtkNotebook      *notebook,
489
                                              GList            *list);
490
static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
491
                                              gpointer          data);
492
static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
493
                                              GtkMenu          *menu);
494

495
/*** GtkNotebook Private Setters ***/
496 497
static void gtk_notebook_update_tab_states             (GtkNotebook *notebook);
static gboolean gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
498 499
                                                            gboolean overload,
                                                            gpointer data);
500

501 502
static gboolean focus_tabs_in  (GtkNotebook      *notebook);
static gboolean focus_child_in (GtkNotebook      *notebook,
503
                                GtkDirectionType  direction);
Elliot Lee's avatar
Elliot Lee committed
504

505
static void stop_scrolling (GtkNotebook *notebook);
506
static void do_detach_tab  (GtkNotebook *from,
507 508 509 510
                            GtkNotebook *to,
                            GtkWidget   *child,
                            gint         x,
                            gint         y);
511

Johan Dahlin's avatar
Johan Dahlin committed
512 513
/* GtkBuildable */
static void gtk_notebook_buildable_init           (GtkBuildableIface *iface);
514
static void gtk_notebook_buildable_add_child      (GtkBuildable *buildable,
515 516 517
                                                   GtkBuilder   *builder,
                                                   GObject      *child,
                                                   const gchar  *type);
518

519
static guint notebook_signals[LAST_SIGNAL] = { 0 };
Elliot Lee's avatar
Elliot Lee committed
520

Johan Dahlin's avatar
Johan Dahlin committed
521
G_DEFINE_TYPE_WITH_CODE (GtkNotebook, gtk_notebook, GTK_TYPE_CONTAINER,
522 523
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                gtk_notebook_buildable_init))
Elliot Lee's avatar
Elliot Lee committed
524

525 526
static void
add_tab_bindings (GtkBindingSet    *binding_set,
527 528
                  GdkModifierType   modifiers,
                  GtkDirectionType  direction)
529
{
530
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
531 532
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
533
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
534 535 536 537 538 539
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

static void
add_arrow_bindings (GtkBindingSet    *binding_set,
540 541
                    guint             keysym,
                    GtkDirectionType  direction)
542
{
543
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
544

545 546 547 548 549 550 551 552
  gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

553 554
static void
add_reorder_bindings (GtkBindingSet    *binding_set,
555 556 557
                      guint             keysym,
                      GtkDirectionType  direction,
                      gboolean          move_to_last)
558
{
559
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
560 561

  gtk_binding_entry_add_signal (binding_set, keysym, GDK_MOD1_MASK,
562 563 564
                                "reorder_tab", 2,
                                GTK_TYPE_DIRECTION_TYPE, direction,
                                G_TYPE_BOOLEAN, move_to_last);
565
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_MOD1_MASK,
566 567 568
                                "reorder_tab", 2,
                                GTK_TYPE_DIRECTION_TYPE, direction,
                                G_TYPE_BOOLEAN, move_to_last);
569 570
}

571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
static gboolean
gtk_object_handled_accumulator (GSignalInvocationHint *ihint,
                                GValue                *return_accu,
                                const GValue          *handler_return,
                                gpointer               dummy)
{
  gboolean continue_emission;
  GObject *object;

  object = g_value_get_object (handler_return);
  g_value_set_object (return_accu, object);
  continue_emission = !object;

  return continue_emission;
}

587
static void
588 589 590
gtk_notebook_compute_expand (GtkWidget *widget,
                             gboolean  *hexpand_p,
                             gboolean  *vexpand_p)
591
{
592
  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
  GtkNotebookPrivate *priv = notebook->priv;
  gboolean hexpand;
  gboolean vexpand;
  GList *list;
  GtkNotebookPage *page;

  hexpand = FALSE;
  vexpand = FALSE;

  for (list = priv->children; list; list = list->next)
    {
      page = list->data;

      hexpand = hexpand ||
        gtk_widget_compute_expand (page->child, GTK_ORIENTATION_HORIZONTAL);

      vexpand = vexpand ||
        gtk_widget_compute_expand (page->child, GTK_ORIENTATION_VERTICAL);

      if (hexpand & vexpand)
        break;
    }

  *hexpand_p = hexpand;
  *vexpand_p = vexpand;
}

Elliot Lee's avatar
Elliot Lee committed
620 621 622
static void
gtk_notebook_class_init (GtkNotebookClass *class)
{
Tim Janik's avatar
Tim Janik committed
623 624 625
  GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
626
  GtkBindingSet *binding_set;
627

628 629
  gobject_class->set_property = gtk_notebook_set_property;
  gobject_class->get_property = gtk_notebook_get_property;
630

631
  widget_class->destroy = gtk_notebook_destroy;
Elliot Lee's avatar
Elliot Lee committed
632 633 634
  widget_class->map = gtk_notebook_map;
  widget_class->unmap = gtk_notebook_unmap;
  widget_class->realize = gtk_notebook_realize;
635
  widget_class->unrealize = gtk_notebook_unrealize;
636 637
  widget_class->get_preferred_width = gtk_notebook_get_preferred_width;
  widget_class->get_preferred_height = gtk_notebook_get_preferred_height;
Elliot Lee's avatar
Elliot Lee committed
638
  widget_class->size_allocate = gtk_notebook_size_allocate;
Benjamin Otte's avatar
Benjamin Otte committed
639
  widget_class->draw = gtk_notebook_draw;
Elliot Lee's avatar
Elliot Lee committed
640
  widget_class->button_press_event = gtk_notebook_button_press;
641
  widget_class->button_release_event = gtk_notebook_button_release;
642
  widget_class->popup_menu = gtk_notebook_popup_menu;
643 644
  widget_class->leave_notify_event = gtk_notebook_leave_notify;
  widget_class->motion_notify_event = gtk_notebook_motion_notify;
Matthias Clasen's avatar
Matthias Clasen committed
645
  widget_class->grab_notify = gtk_notebook_grab_notify;
646
  widget_class->state_flags_changed = gtk_notebook_state_flags_changed;
647
  widget_class->focus_in_event = gtk_notebook_focus_in;
648
  widget_class->focus_out_event = gtk_notebook_focus_out;
649
  widget_class->focus = gtk_notebook_focus;
650
  widget_class->style_updated = gtk_notebook_style_updated;
651
  widget_class->drag_begin = gtk_notebook_drag_begin;
652
  widget_class->drag_end = gtk_notebook_drag_end;
653
  widget_class->drag_motion = gtk_notebook_drag_motion;
654
  widget_class->drag_leave = gtk_notebook_drag_leave;
655 656 657
  widget_class->drag_drop = gtk_notebook_drag_drop;
  widget_class->drag_data_get = gtk_notebook_drag_data_get;
  widget_class->drag_data_received = gtk_notebook_drag_data_received;
658
  widget_class->drag_failed = gtk_notebook_drag_failed;
659
  widget_class->compute_expand = gtk_notebook_compute_expand;
660

Elliot Lee's avatar
Elliot Lee committed
661 662
  container_class->add = gtk_notebook_add;
  container_class->remove = gtk_notebook_remove;
663
  container_class->forall = gtk_notebook_forall;
Lars Hamann's avatar
Lars Hamann committed
664
  container_class->set_focus_child = gtk_notebook_set_focus_child;
Tim Janik's avatar
Tim Janik committed
665 666
  container_class->get_child_property = gtk_notebook_get_child_property;
  container_class->set_child_property = gtk_notebook_set_child_property;
667
  container_class->child_type = gtk_notebook_child_type;
668
  container_class->get_path_for_child = gtk_notebook_get_path_for_child;
669

670
  class->switch_page = gtk_notebook_real_switch_page;
671
  class->insert_page = gtk_notebook_real_insert_page;
672

673 674
  class->focus_tab = gtk_notebook_focus_tab;
  class->select_page = gtk_notebook_select_page;
675
  class->change_current_page = gtk_notebook_change_current_page;
676
  class->move_focus_out = gtk_notebook_move_focus_out;
677
  class->reorder_tab = gtk_notebook_reorder_tab;
678
  class->create_window = gtk_notebook_create_window;
679

680
  g_object_class_install_property (gobject_class,
681 682 683 684 685 686 687 688
                                   PROP_PAGE,
                                   g_param_spec_int ("page",
                                                     P_("Page"),
                                                     P_("The index of the current page"),
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
                                                     GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
689
  g_object_class_install_property (gobject_class,
690 691 692 693 694 695 696
                                   PROP_TAB_POS,
                                   g_param_spec_enum ("tab-pos",
                                                      P_("Tab Position"),
                                                      P_("Which side of the notebook holds the tabs"),
                                                      GTK_TYPE_POSITION_TYPE,
                                                      GTK_POS_TOP,
                                                      GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
697
  g_object_class_install_property (gobject_class,
698 699 700 701 702 703
                                   PROP_SHOW_TABS,
                                   g_param_spec_boolean ("show-tabs",
                                                         P_("Show Tabs"),
                                                         P_("Whether tabs should be shown"),
                                                         TRUE,
                                                         GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
704
  g_object_class_install_property (gobject_class,
705 706 707 708 709 710
                                   PROP_SHOW_BORDER,
                                   g_param_spec_boolean ("show-border",
                                                         P_("Show Border"),
                                                         P_("Whether the border should be shown"),
                                                         TRUE,
                                                         GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
711
  g_object_class_install_property (gobject_class,
712 713 714 715 716 717
                                   PROP_SCROLLABLE,
                                   g_param_spec_boolean ("scrollable",
                                                         P_("Scrollable"),
                                                         P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
                                                         FALSE,
                                                         GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
718
  g_object_class_install_property (gobject_class,
719 720 721 722 723 724
                                   PROP_ENABLE_POPUP,
                                   g_param_spec_boolean ("enable-popup",
                                                         P_("Enable Popup"),
                                                         P_("If TRUE, pressing the right mouse button on the notebook pops up a menu that you can use to go to a page"),
                                                         FALSE,
                                                         GTK_PARAM_READWRITE));
Matthias Clasen's avatar
Matthias Clasen committed
725 726

  /**
727
   * GtkNotebook:group-name:
Matthias Clasen's avatar
Matthias Clasen committed
728
   *
729
   * Group name for tab drag and drop.
Matthias Clasen's avatar
Matthias Clasen committed
730 731
   *
   * Since: 2.24
732
   */
733
  g_object_class_install_property (gobject_class,
734 735 736 737
                                   PROP_GROUP_NAME,
                                   g_param_spec_string ("group-name",
                                                        P_("Group Name"),
                                                        P_("Group name for tab drag and drop"),
738
                                                        NULL,
739
                                                        GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
740 741

  gtk_container_class_install_child_property (container_class,
742 743 744 745 746 747
                                              CHILD_PROP_TAB_LABEL,
                                              g_param_spec_string ("tab-label",
                                                                   P_("Tab label"),
                                                                   P_("The string displayed on the child's tab label"),
                                                                   NULL,
                                                                   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
748
  gtk_container_class_install_child_property (container_class,
749 750 751 752 753 754
                                              CHILD_PROP_MENU_LABEL,
                                              g_param_spec_string ("menu-label",
                                                                   P_("Menu label"),
                                                                   P_("The string displayed in the child's menu entry"),
                                                                   NULL,
                                                                   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
755
  gtk_container_class_install_child_property (container_class,
756 757 758 759 760 761
                                              CHILD_PROP_POSITION,
                                              g_param_spec_int ("position",
                                                                P_("Position"),
                                                                P_("The index of the child in the parent"),
                                                                -1, G_MAXINT, 0,
                                                                GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
762
  gtk_container_class_install_child_property (container_class,
763 764 765 766 767 768
                                              CHILD_PROP_TAB_EXPAND,
                                              g_param_spec_boolean ("tab-expand",
                                                                    P_("Tab expand"),
                                                                    P_("Whether to expand the child's tab"),
                                                                    FALSE,
                                                                    GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
769
  gtk_container_class_install_child_property (container_class,
770 771 772 773 774 775
                                              CHILD_PROP_TAB_FILL,
                                              g_param_spec_boolean ("tab-fill",
                                                                    P_("Tab fill"),
                                                                    P_("Whether the child's tab should fill the allocated area"),
                                                                    TRUE,
                                                                    GTK_PARAM_READWRITE));
776

777
  gtk_container_class_install_child_property (container_class,
778 779 780 781 782 783
                                              CHILD_PROP_REORDERABLE,
                                              g_param_spec_boolean ("reorderable",
                                                                    P_("Tab reorderable"),
                                                                    P_("Whether the tab is reorderable by user action"),
                                                                    FALSE,
                                                                    GTK_PARAM_READWRITE));
784
  gtk_container_class_install_child_property (container_class,
785 786 787 788 789 790
                                              CHILD_PROP_DETACHABLE,
                                              g_param_spec_boolean ("detachable",
                                                                    P_("Tab detachable"),
                                                                    P_("Whether the tab is detachable"),
                                                                    FALSE,
                                                                    GTK_PARAM_READWRITE));
791 792 793 794

/**
 * GtkNotebook:has-secondary-backward-stepper:
 *
795 796
 * The "has-secondary-backward-stepper" property determines whether
 * a second backward arrow button is displayed on the opposite end
797 798 799
 * of the tab area.
 *
 * Since: 2.4
800
 */
801
  gtk_widget_class_install_style_property (widget_class,
802 803 804 805 806
                                           g_param_spec_boolean ("has-secondary-backward-stepper",
                                                                 P_("Secondary backward stepper"),
                                                                 P_("Display a second backward arrow button on the opposite end of the tab area"),
                                                                 FALSE,
                                                                 GTK_PARAM_READABLE));
807

808 809 810
/**
 * GtkNotebook:has-secondary-forward-stepper:
 *
811 812
 * The "has-secondary-forward-stepper" property determines whether
 * a second forward arrow button is displayed on the opposite end
813 814 815
 * of the tab area.
 *
 * Since: 2.4
816
 */
817
  gtk_widget_class_install_style_property (widget_class,
818 819 820 821 822
                                           g_param_spec_boolean ("has-secondary-forward-stepper",
                                                                 P_("Secondary forward stepper"),
                                                                 P_("Display a second forward arrow button on the opposite end of the tab area"),
                                                                 FALSE,
                                                                 GTK_PARAM_READABLE));
823

824 825 826
/**
 * GtkNotebook:has-backward-stepper:
 *
827
 * The "has-backward-stepper" property determines whether
828 829 830
 * the standard backward arrow button is displayed.
 *
 * Since: 2.4
831
 */
832
  gtk_widget_class_install_style_property (widget_class,
833 834 835 836 837
                                           g_param_spec_boolean ("has-backward-stepper",
                                                                 P_("Backward stepper"),
                                                                 P_("Display the standard backward arrow button"),
                                                                 TRUE,
                                                                 GTK_PARAM_READABLE));
838

839 840 841
/**
 * GtkNotebook:has-forward-stepper:
 *
842
 * The "has-forward-stepper" property determines whether
843 844 845
 * the standard forward arrow button is displayed.
 *
 * Since: 2.4
846
 */
847
  gtk_widget_class_install_style_property (widget_class,
848 849 850 851 852 853
                                           g_param_spec_boolean ("has-forward-stepper",
                                                                 P_("Forward stepper"),
                                                                 P_("Display the standard forward arrow button"),
                                                                 TRUE,
                                                                 GTK_PARAM_READABLE));

854 855 856 857 858 859 860
/**
 * GtkNotebook:tab-overlap:
 *
 * The "tab-overlap" property defines size of tab overlap
 * area.
 *
 * Since: 2.10
861
 */
862
  gtk_widget_class_install_style_property (widget_class,
863 864 865 866 867 868 869
                                           g_param_spec_int ("tab-overlap",
                                                             P_("Tab overlap"),
                                                             P_("Size of tab overlap area"),
                                                             G_MININT,
                                                             G_MAXINT,
                                                             2,
                                                             GTK_PARAM_READABLE));
870 871 872 873 874 875 876

/**
 * GtkNotebook:tab-curvature:
 *
 * The "tab-curvature" property defines size of tab curvature.
 *
 * Since: 2.10
877
 */
878
  gtk_widget_class_install_style_property (widget_class,
879 880 881 882 883 884 885
                                           g_param_spec_int ("tab-curvature",
                                                             P_("Tab curvature"),
                                                             P_("Size of tab curvature"),
                                                             0,
                                                             G_MAXINT,
                                                             1,
                                                             GTK_PARAM_READABLE));
886

887 888 889
  /**
   * GtkNotebook:arrow-spacing:
   *
890
   * The "arrow-spacing" property defines the spacing between the scroll
891 892 893 894 895 896
   * arrows and the tabs.
   *
   * Since: 2.10
   */
  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("arrow-spacing",
897 898
                                                             P_("Arrow spacing"),
                                                             P_("Scroll arrow spacing"),
899 900 901 902 903
                                                             0,
                                                             G_MAXINT,
                                                             0,
                                                             GTK_PARAM_READABLE));

904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
  /**
   * GtkNotebook:initial-gap:
   *
   * The "initial-gap" property defines the minimum size for the initial
   * gap between the first tab.
   *
   * Since: 3.2
   */
  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("initial-gap",
                                                             P_("Initial gap"),
                                                             P_("Initial gap before the first tab"),
                                                             0,
                                                             G_MAXINT,
                                                             0,
                                                             GTK_PARAM_READABLE));

921 922 923 924 925 926 927 928
  /**
   * GtkNotebook::switch-page:
   * @notebook: the object which received the signal.
   * @page: the new current page
   * @page_num: the index of the page
   *
   * Emitted when the user or a function changes the current page.
   */
929
  notebook_signals[SWITCH_PAGE] =
930
    g_signal_new (I_("switch-page"),
931 932 933 934 935 936 937 938 939
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkNotebookClass, switch_page),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
                  G_TYPE_NONE, 2,
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
  notebook_signals[FOCUS_TAB] =
940
    g_signal_new (I_("focus-tab"),
Manish Singh's avatar
Manish Singh committed
941
                  G_TYPE_FROM_CLASS (gobject_class),
942 943 944
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                  NULL, NULL,
945
                  _gtk_marshal_BOOLEAN__ENUM,
946
                  G_TYPE_BOOLEAN, 1,
947
                  GTK_TYPE_NOTEBOOK_TAB);
948
  notebook_signals[SELECT_PAGE] =
949
    g_signal_new (I_("select-page"),
Manish Singh's avatar
Manish Singh committed
950
                  G_TYPE_FROM_CLASS (gobject_class),
951 952 953
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                  NULL, NULL,
954 955
                  _gtk_marshal_BOOLEAN__BOOLEAN,
                  G_TYPE_BOOLEAN, 1,
956
                  G_TYPE_BOOLEAN);
957
  notebook_signals[CHANGE_CURRENT_PAGE] =
958
    g_signal_new (I_("change-current-page"),
Manish Singh's avatar
Manish Singh committed
959
                  G_TYPE_FROM_CLASS (gobject_class),
960 961 962
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                  NULL, NULL,
963 964
                  _gtk_marshal_BOOLEAN__INT,
                  G_TYPE_BOOLEAN, 1,
965
                  G_TYPE_INT);
966
  notebook_signals[MOVE_FOCUS_OUT] =
967
    g_signal_new (I_("move-focus-out"),
Manish Singh's avatar
Manish Singh committed
968
                  G_TYPE_FROM_CLASS (gobject_class),
969 970 971 972 973 974
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, move_focus_out),
                  NULL, NULL,
                  _gtk_marshal_VOID__ENUM,
                  G_TYPE_NONE, 1,
                  GTK_TYPE_DIRECTION_TYPE);
975
  notebook_signals[REORDER_TAB] =
976
    g_signal_new (I_("reorder-tab"),
977 978 979 980
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, reorder_tab),
                  NULL, NULL,
981 982
                  _gtk_marshal_BOOLEAN__ENUM_BOOLEAN,
                  G_TYPE_BOOLEAN, 2,
983
                  GTK_TYPE_DIRECTION_TYPE,
984
                  G_TYPE_BOOLEAN);
985
  /**
986
   * GtkNotebook::page-reordered:
987 988 989 990
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
991 992
   * the ::page-reordered signal is emitted in the notebook
   * right after a page has been reordered.
993 994
   *
   * Since: 2.10
995
   */
996
  notebook_signals[PAGE_REORDERED] =
997
    g_signal_new (I_("page-reordered"),
998
                  G_TYPE_FROM_CLASS (gobject_class),
999
                  G_SIGNAL_RUN_LAST,
1000 1001 1002
                  G_STRUCT_OFFSET (GtkNotebookClass, page_reordered),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1003
                  G_TYPE_NONE, 2,
1004 1005
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1006
  /**
1007
   * GtkNotebook::page-removed:
1008 1009 1010 1011
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the @child page number
   *
1012
   * the ::page-removed signal is emitted in the notebook
1013
   * right after a page is removed from the notebook.
1014 1015
   *
   * Since: 2.10
1016
   */
1017
  notebook_signals[PAGE_REMOVED] =
1018
    g_signal_new (I_("page-removed"),
1019
                  G_TYPE_FROM_CLASS (gobject_class),
1020
                  G_SIGNAL_RUN_LAST,
1021 1022 1023
                  G_STRUCT_OFFSET (GtkNotebookClass, page_removed),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1024
                  G_TYPE_NONE, 2,
1025 1026
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1027
  /**
1028
   * GtkNotebook::page-added:
1029 1030 1031 1032
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
1033 1034
   * the ::page-added signal is emitted in the notebook
   * right after a page is added to the notebook.
1035 1036
   *
   * Since: 2.10
1037
   */
1038
  notebook_signals[PAGE_ADDED] =
1039
    g_signal_new (I_("page-added"),
1040
                  G_TYPE_FROM_CLASS (gobject_class),
1041
                  G_SIGNAL_RUN_LAST,
1042 1043 1044
                  G_STRUCT_OFFSET (GtkNotebookClass, page_added),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1045
                  G_TYPE_NONE, 2,
1046 1047
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1048

1049 1050 1051 1052 1053 1054 1055 1056
  /**
   * GtkNotebook::create-window:
   * @notebook: the #GtkNotebook emitting the signal
   * @page: the tab of @notebook that is being detached
   * @x: the X coordinate where the drop happens
   * @y: the Y coordinate where the drop happens
   *
   * The ::create-window signal is emitted when a detachable
1057
   * tab is dropped on the root window.
1058
   *
1059 1060 1061 1062
   * A handler for this signal can create a window containing
   * a notebook where the tab will be attached. It is also
   * responsible for moving/resizing the window and adding the
   * necessary properties to the notebook (e.g. the
1063
   * #GtkNotebook:group ).
1064
   *