gtknotebook.c 259 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
Javier Jardon's avatar
Javier Jardon committed
16
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
17
 */
18 19

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

26
#include "config.h"
27 28

#include <stdio.h>
29
#include <string.h>
30
#include <math.h>
31

32
#include "gtknotebook.h"
33

34 35 36 37
#include "gtkmain.h"
#include "gtkmenu.h"
#include "gtkmenuitem.h"
#include "gtklabel.h"
38
#include "gtkintl.h"
39
#include "gtkmarshalers.h"
40
#include "gtkbindings.h"
41
#include "gtkprivate.h"
42
#include "gtkdnd.h"
43
#include "gtkbuildable.h"
44
#include "gtktypebuiltins.h"
45
#include "gtkwidgetpath.h"
Benjamin Otte's avatar
Benjamin Otte committed
46
#include "gtkboxgadgetprivate.h"
47
#include "gtkbuiltiniconprivate.h"
48
#include "gtkcsscustomgadgetprivate.h"
49
#include "gtkcssstylepropertyprivate.h"
50
#include "gtksizerequest.h"
51
#include "gtkstylecontextprivate.h"
52
#include "gtkwidgetprivate.h"
53
#include "a11y/gtknotebookaccessible.h"
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

/**
 * 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())
 *
73
 * # GtkNotebook as GtkBuildable
74
 * 
75
 * The GtkNotebook implementation of the #GtkBuildable interface
76
 * supports placing children into tabs by specifying “tab” as the
77
 * “type” attribute of a <child> element. Note that the content
78
 * of the tab must be created before the tab can be filled.
79
 * A tab child can be specified without specifying a <child>
80
 * type attribute.
81
 *
82
 * To add a child widget in the notebooks action area, specify
83 84
 * "action-start" or “action-end” as the “type” attribute of the
 * <child> element.
85 86
 *
 * An example of a UI definition fragment with GtkNotebook:
87
 * |[
88 89 90 91 92 93 94 95 96 97 98 99
 * <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>
100
 * ]|
101 102 103
 *
 * # CSS nodes
 *
104 105 106
 * |[<!-- language="plain" -->
 * notebook
 * ├── header.top
107
 * │   ├── [<action widget>]
108
 * │   ├── tabs
109
 * │   │   ├── [arrow]
110
 * │   │   ├── tab
111 112
 * │   │   │   ╰── <tab label>
 * ┊   ┊   ┊
113
 * │   │   ├── tab[.reorderable-page]
114
 * │   │   │   ╰── <tab label>
115
 * │   │   ╰── [arrow]
116
 * │   ╰── [<action widget>]
117
 * │
118 119 120 121
 * ╰── stack
 *     ├── <child>
 *     ┊
 *     ╰── <child>
122 123
 * ]|
 *
124
 * GtkNotebook has a main CSS node with name notebook, a subnode
125 126 127 128
 * with name header and below that a subnode with name tabs which
 * contains one subnode per tab with name tab.
 *
 * If action widgets are present, their CSS nodes are placed next
129 130
 * to the tabs node. If the notebook is scrollable, CSS nodes with
 * name arrow are placed as first and last child of the tabs node.
131
 *
132
 * The main node gets the .frame style class when the notebook
133
 * has a border (see gtk_notebook_set_show_border()).
134
 *
135
 * The header node gets one of the style class .top, .bottom,
136
 * .left or .right, depending on where the tabs are placed. For
137
 * reorderable pages, the tab node gets the .reorderable-page class.
138 139
 *
 * A tab node gets the .dnd style class while it is moved with drag-and-drop.
140 141
 *
 * The nodes are always arranged from left-to-right, regarldess of text direction.
142 143 144
 */


145
#define SCROLL_DELAY_FACTOR   5
146 147
#define SCROLL_THRESHOLD      12
#define DND_THRESHOLD_MULTIPLIER 4
Elliot Lee's avatar
Elliot Lee committed
148

149 150 151 152
#define TIMEOUT_INITIAL  500
#define TIMEOUT_REPEAT    50
#define TIMEOUT_EXPAND   500

153
typedef struct _GtkNotebookPage GtkNotebookPage;
154 155 156 157 158 159 160 161 162 163 164 165 166 167

typedef enum
{
  DRAG_OPERATION_NONE,
  DRAG_OPERATION_REORDER,
  DRAG_OPERATION_DETACH
} GtkNotebookDragOperation;

enum {
  ACTION_WIDGET_START,
  ACTION_WIDGET_END,
  N_ACTION_WIDGETS
};

168
struct _GtkNotebookPrivate
169 170 171 172
{
  GtkNotebookDragOperation   operation;
  GtkNotebookPage           *cur_page;
  GtkNotebookPage           *detached_tab;
Paolo Borelli's avatar
Paolo Borelli committed
173
  GtkNotebookPage           *prelight_tab;
174 175 176 177 178 179 180 181
  GtkTargetList             *source_targets;
  GtkWidget                 *action_widget[N_ACTION_WIDGETS];
  GtkWidget                 *dnd_window;
  GtkWidget                 *menu;

  GdkWindow               *drag_window;
  GdkWindow               *event_window;

182
  GtkCssGadget              *gadget;
183
  GtkCssGadget              *stack_gadget;
184
  GtkCssGadget              *header_gadget;
185
  GtkCssGadget              *tabs_gadget;
186
  GtkCssGadget              *arrow_gadget[4];
187

188 189 190 191 192 193 194 195 196 197 198 199 200 201
  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;

202
  GQuark         group;
203 204 205

  guint          dnd_timer;
  guint          switch_tab_timer;
206
  GList         *switch_tab;
207 208 209 210 211

  guint32        timer;

  guint          child_has_focus    : 1;
  guint          click_child        : 3;
212
  guint          remove_in_detach   : 1;
213 214 215 216 217 218 219 220
  guint          focus_out          : 1; /* Flag used by ::move-focus-out implementation */
  guint          has_scrolled       : 1;
  guint          in_child           : 3;
  guint          need_timer         : 1;
  guint          show_border        : 1;
  guint          show_tabs          : 1;
  guint          scrollable         : 1;
  guint          tab_pos            : 2;
221
  guint          tabs_reversed      : 1;
222
  guint          rootwindow_drop    : 1;
223 224
};

225 226
enum {
  SWITCH_PAGE,
227 228
  FOCUS_TAB,
  SELECT_PAGE,
229
  CHANGE_CURRENT_PAGE,
230
  MOVE_FOCUS_OUT,
231
  REORDER_TAB,
232 233 234
  PAGE_REORDERED,
  PAGE_REMOVED,
  PAGE_ADDED,
235
  CREATE_WINDOW,
236 237 238
  LAST_SIGNAL
};

239 240 241 242 243
enum {
  STEP_PREV,
  STEP_NEXT
};

244 245 246 247 248
typedef enum
{
  ARROW_LEFT_BEFORE,
  ARROW_RIGHT_BEFORE,
  ARROW_LEFT_AFTER,
249 250
  ARROW_RIGHT_AFTER,
  ARROW_NONE
251 252
} GtkNotebookArrow;

253 254 255 256 257 258 259
typedef enum
{
  POINTER_BEFORE,
  POINTER_AFTER,
  POINTER_BETWEEN
} GtkNotebookPointerPosition;

260 261 262
#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)

263
enum {
264 265 266 267 268 269 270
  PROP_0,
  PROP_TAB_POS,
  PROP_SHOW_TABS,
  PROP_SHOW_BORDER,
  PROP_SCROLLABLE,
  PROP_PAGE,
  PROP_ENABLE_POPUP,
271 272
  PROP_GROUP_NAME,
  LAST_PROP
273 274
};

275 276
static GParamSpec *properties[LAST_PROP];

277
enum {
Tim Janik's avatar
Tim Janik committed
278 279 280 281 282 283
  CHILD_PROP_0,
  CHILD_PROP_TAB_LABEL,
  CHILD_PROP_MENU_LABEL,
  CHILD_PROP_POSITION,
  CHILD_PROP_TAB_EXPAND,
  CHILD_PROP_TAB_FILL,
284 285
  CHILD_PROP_REORDERABLE,
  CHILD_PROP_DETACHABLE
286 287
};

288
#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)(_glist_)->data)
289

290
/* some useful defines for calculating coords */
291
#define NOTEBOOK_IS_TAB_LABEL_PARENT(_notebook_,_page_) (gtk_widget_get_parent ((_page_)->tab_label) == (GTK_WIDGET (_notebook_)))
292

293 294 295 296 297
struct _GtkNotebookPage
{
  GtkWidget *child;
  GtkWidget *tab_label;
  GtkWidget *menu_label;
298
  GtkWidget *last_focus_child;  /* Last descendant of the page that had focus */
299

300
  GtkCssGadget *gadget;         /* gadget used for the tab itself */
301

302 303
  guint default_menu : 1;       /* If true, we create the menu label ourself */
  guint default_tab  : 1;       /* If true, we create the tab label ourself */
304 305
  guint expand       : 1;
  guint fill         : 1;
306 307
  guint reorderable  : 1;
  guint detachable   : 1;
308 309

  GtkRequisition requisition;
310

311 312
  gulong mnemonic_activate_signal;
  gulong notify_visible_handler;
313 314
};

315
static const GtkTargetEntry src_notebook_targets [] = {
316
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
317
  { "application/x-rootwindow-drop", 0, 0 },
318 319
};

320 321 322
static const GtkTargetEntry dst_notebook_targets [] = {
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
};
323

324
/*** GtkNotebook Methods ***/
325
static gboolean gtk_notebook_select_page         (GtkNotebook      *notebook,
326
                                                  gboolean          move_focus);
327
static gboolean gtk_notebook_focus_tab           (GtkNotebook      *notebook,
328
                                                  GtkNotebookTab    type);
329
static gboolean gtk_notebook_change_current_page (GtkNotebook      *notebook,
330
                                                  gint              offset);
331
static void     gtk_notebook_move_focus_out      (GtkNotebook      *notebook,
332
                                                  GtkDirectionType  direction_type);
333
static gboolean gtk_notebook_reorder_tab         (GtkNotebook      *notebook,
334 335
                                                  GtkDirectionType  direction_type,
                                                  gboolean          move_to_last);
336
static void     gtk_notebook_remove_tab_label    (GtkNotebook      *notebook,
337
                                                  GtkNotebookPage  *page);
338 339 340
static void     gtk_notebook_set_tab_label_packing   (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean      expand,
341
                                                      gboolean      fill);
342 343 344
static void     gtk_notebook_query_tab_label_packing (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean     *expand,
345
                                                      gboolean     *fill);
346

347
/*** GObject Methods ***/
348 349 350 351 352 353 354 355
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);
356
static void gtk_notebook_finalize            (GObject         *object);
357

358
/*** GtkWidget Methods ***/
359
static void gtk_notebook_destroy             (GtkWidget        *widget);
360 361 362
static void gtk_notebook_map                 (GtkWidget        *widget);
static void gtk_notebook_unmap               (GtkWidget        *widget);
static void gtk_notebook_realize             (GtkWidget        *widget);
363
static void gtk_notebook_unrealize           (GtkWidget        *widget);
364
static void gtk_notebook_get_preferred_width (GtkWidget        *widget,
365 366
                                              gint             *minimum,
                                              gint             *natural);
367
static void gtk_notebook_get_preferred_height(GtkWidget        *widget,
368 369
                                              gint             *minimum,
                                              gint             *natural);
370 371 372 373 374 375 376 377 378 379
static void gtk_notebook_get_preferred_width_for_height
                                             (GtkWidget        *widget,
                                              gint              height,
                                              gint             *minimum,
                                              gint             *natural);
static void gtk_notebook_get_preferred_height_for_width
                                             (GtkWidget        *widget,
                                              gint              width,
                                              gint             *minimum,
                                              gint             *natural);
380
static void gtk_notebook_size_allocate       (GtkWidget        *widget,
381
                                              GtkAllocation    *allocation);
382
static gboolean gtk_notebook_draw            (GtkWidget        *widget,
383
                                              cairo_t          *cr);
384
static gboolean gtk_notebook_button_press    (GtkWidget        *widget,
385
                                              GdkEventButton   *event);
386
static gboolean gtk_notebook_button_release  (GtkWidget        *widget,
387
                                              GdkEventButton   *event);
388
static gboolean gtk_notebook_popup_menu      (GtkWidget        *widget);
Paolo Borelli's avatar
Paolo Borelli committed
389 390
static gboolean gtk_notebook_enter_notify    (GtkWidget        *widget,
                                              GdkEventCrossing *event);
391
static gboolean gtk_notebook_leave_notify    (GtkWidget        *widget,
392
                                              GdkEventCrossing *event);
393
static gboolean gtk_notebook_motion_notify   (GtkWidget        *widget,
394
                                              GdkEventMotion   *event);
395
static gboolean gtk_notebook_focus_in        (GtkWidget        *widget,
396
                                              GdkEventFocus    *event);
397
static gboolean gtk_notebook_focus_out       (GtkWidget        *widget,
398
                                              GdkEventFocus    *event);
Matthias Clasen's avatar
Matthias Clasen committed
399
static void gtk_notebook_grab_notify         (GtkWidget          *widget,
400
                                              gboolean            was_grabbed);
401
static void gtk_notebook_state_flags_changed (GtkWidget          *widget,
402
                                              GtkStateFlags       previous_state);
403
static gboolean gtk_notebook_focus           (GtkWidget        *widget,
404
                                              GtkDirectionType  direction);
405
static void gtk_notebook_style_updated       (GtkWidget        *widget);
406

407 408
/*** Drag and drop Methods ***/
static void gtk_notebook_drag_begin          (GtkWidget        *widget,
409
                                              GdkDragContext   *context);
410
static void gtk_notebook_drag_end            (GtkWidget        *widget,
411
                                              GdkDragContext   *context);
412
static gboolean gtk_notebook_drag_failed     (GtkWidget        *widget,
413 414
                                              GdkDragContext   *context,
                                              GtkDragResult     result);
415
static gboolean gtk_notebook_drag_motion     (GtkWidget        *widget,
416 417 418 419
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              guint             time);
420
static void gtk_notebook_drag_leave          (GtkWidget        *widget,
421 422
                                              GdkDragContext   *context,
                                              guint             time);
423
static gboolean gtk_notebook_drag_drop       (GtkWidget        *widget,
424 425 426 427
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              guint             time);
428
static void gtk_notebook_drag_data_get       (GtkWidget        *widget,
429 430 431 432
                                              GdkDragContext   *context,
                                              GtkSelectionData *data,
                                              guint             info,
                                              guint             time);
433
static void gtk_notebook_drag_data_received  (GtkWidget        *widget,
434 435 436 437 438 439
                                              GdkDragContext   *context,
                                              gint              x,
                                              gint              y,
                                              GtkSelectionData *data,
                                              guint             info,
                                              guint             time);
440 441
static void gtk_notebook_direction_changed   (GtkWidget        *widget,
                                              GtkTextDirection  previous_direction);
442

443
/*** GtkContainer Methods ***/
Tim Janik's avatar
Tim Janik committed
444
static void gtk_notebook_set_child_property  (GtkContainer     *container,
445 446 447 448
                                              GtkWidget        *child,
                                              guint             property_id,
                                              const GValue     *value,
                                              GParamSpec       *pspec);
Tim Janik's avatar
Tim Janik committed
449
static void gtk_notebook_get_child_property  (GtkContainer     *container,
450 451 452 453
                                              GtkWidget        *child,
                                              guint             property_id,
                                              GValue           *value,
                                              GParamSpec       *pspec);
454
static void gtk_notebook_add                 (GtkContainer     *container,
455
                                              GtkWidget        *widget);
456
static void gtk_notebook_remove              (GtkContainer     *container,
457
                                              GtkWidget        *widget);
458
static void gtk_notebook_set_focus_child     (GtkContainer     *container,
459
                                              GtkWidget        *child);
Manish Singh's avatar
Manish Singh committed
460
static GType gtk_notebook_child_type       (GtkContainer     *container);
461
static void gtk_notebook_forall              (GtkContainer     *container,
462 463 464
                                              gboolean          include_internals,
                                              GtkCallback       callback,
                                              gpointer          callback_data);
465

466 467
/*** GtkNotebook Methods ***/
static gint gtk_notebook_real_insert_page    (GtkNotebook      *notebook,
468 469 470 471
                                              GtkWidget        *child,
                                              GtkWidget        *tab_label,
                                              GtkWidget        *menu_label,
                                              gint              position);
472

473 474 475 476 477
static GtkNotebook *gtk_notebook_create_window (GtkNotebook    *notebook,
                                                GtkWidget      *page,
                                                gint            x,
                                                gint            y);

478
/*** Gadget Functions ***/
479
static void gtk_notebook_measure_tabs        (GtkCssGadget     *gadget,
480 481 482 483 484 485 486
                                              GtkOrientation    orientation,
                                              gint              for_size,
                                              gint             *minimum,
                                              gint             *natural,
                                              gint             *minimum_baseline,
                                              gint             *natural_baseline,
                                              gpointer          data);
487
static void gtk_notebook_allocate_tabs       (GtkCssGadget     *gadget,
488 489 490 491
                                              const GtkAllocation *allocation,
                                              int               baseline,
                                              GtkAllocation    *out_clip,
                                              gpointer          data);
492
static gboolean gtk_notebook_draw_tabs       (GtkCssGadget     *gadget,
493 494 495 496 497 498
                                              cairo_t          *cr,
                                              int               x,
                                              int               y,
                                              int               width,
                                              int               height,
                                              gpointer          data);
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
static void gtk_notebook_measure_stack       (GtkCssGadget     *gadget,
                                              GtkOrientation    orientation,
                                              gint              for_size,
                                              gint             *minimum,
                                              gint             *natural,
                                              gint             *minimum_baseline,
                                              gint             *natural_baseline,
                                              gpointer          data);
static void gtk_notebook_allocate_stack      (GtkCssGadget     *gadget,
                                              const GtkAllocation *allocation,
                                              int               baseline,
                                              GtkAllocation    *out_clip,
                                              gpointer          data);
static gboolean gtk_notebook_draw_stack      (GtkCssGadget     *gadget,
                                              cairo_t          *cr,
                                              int               x,
                                              int               y,
                                              int               width,
                                              int               height,
                                              gpointer          data);
519

520
/*** GtkNotebook Private Functions ***/
521
static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
522
static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
523
                                              GList            *list);
524 525
static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
static gint gtk_notebook_timer               (GtkNotebook      *notebook);
526
static void gtk_notebook_set_scroll_timer    (GtkNotebook *notebook);
527
static gint gtk_notebook_page_compare        (gconstpointer     a,
528
                                              gconstpointer     b);
529
static GList* gtk_notebook_find_child        (GtkNotebook      *notebook,
530
                                              GtkWidget        *child);
531
static GList * gtk_notebook_search_page      (GtkNotebook      *notebook,
532 533 534
                                              GList            *list,
                                              gint              direction,
                                              gboolean          find_visible);
535
static void  gtk_notebook_child_reordered    (GtkNotebook      *notebook,
536
                                              GtkNotebookPage  *page);
537

538
/*** GtkNotebook Size Allocate Functions ***/
539 540
static void gtk_notebook_pages_allocate      (GtkNotebook      *notebook,
                                              const GtkAllocation *allocation);
541
static void gtk_notebook_calc_tabs           (GtkNotebook      *notebook,
542 543 544 545
                                              GList            *start,
                                              GList           **end,
                                              gint             *tab_space,
                                              guint             direction);
546

547
/*** GtkNotebook Page Switch Methods ***/
548
static void gtk_notebook_real_switch_page    (GtkNotebook      *notebook,
549 550
                                              GtkWidget        *child,
                                              guint             page_num);
551

552
/*** GtkNotebook Page Switch Functions ***/
553
static void gtk_notebook_switch_page         (GtkNotebook      *notebook,
554
                                              GtkNotebookPage  *page);
555
static gint gtk_notebook_page_select         (GtkNotebook      *notebook,
556
                                              gboolean          move_focus);
557 558
static void gtk_notebook_switch_focus_tab    (GtkNotebook      *notebook,
                                              GList            *new_child);
559
static void gtk_notebook_menu_switch_page    (GtkWidget        *widget,
560
                                              GtkNotebookPage  *page);
561

562
/*** GtkNotebook Menu Functions ***/
563
static void gtk_notebook_menu_item_create    (GtkNotebook      *notebook,
564
                                              GList            *list);
565
static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
566
                                              gpointer          data);
567
static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
568
                                              GtkMenu          *menu);
569

Benjamin Otte's avatar
Benjamin Otte committed
570 571
static void gtk_notebook_update_tab_pos      (GtkNotebook      *notebook);

572
/*** GtkNotebook Private Setters ***/
573
static gboolean gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
574 575
                                                            gboolean overload,
                                                            gpointer data);
576

577 578
static gboolean focus_tabs_in  (GtkNotebook      *notebook);
static gboolean focus_child_in (GtkNotebook      *notebook,
579
                                GtkDirectionType  direction);
Elliot Lee's avatar
Elliot Lee committed
580

581
static void stop_scrolling (GtkNotebook *notebook);
582
static void do_detach_tab  (GtkNotebook *from,
583 584 585 586
                            GtkNotebook *to,
                            GtkWidget   *child,
                            gint         x,
                            gint         y);
587

588 589
/* GtkBuildable */
static void gtk_notebook_buildable_init           (GtkBuildableIface *iface);
590
static void gtk_notebook_buildable_add_child      (GtkBuildable *buildable,
591 592 593
                                                   GtkBuilder   *builder,
                                                   GObject      *child,
                                                   const gchar  *type);
594

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

597
G_DEFINE_TYPE_WITH_CODE (GtkNotebook, gtk_notebook, GTK_TYPE_CONTAINER,
598
                         G_ADD_PRIVATE (GtkNotebook)
599 600
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                gtk_notebook_buildable_init))
Elliot Lee's avatar
Elliot Lee committed
601

602 603
static void
add_tab_bindings (GtkBindingSet    *binding_set,
604 605
                  GdkModifierType   modifiers,
                  GtkDirectionType  direction)
606
{
607
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
608 609
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
610
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
611 612 613 614 615 616
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

static void
add_arrow_bindings (GtkBindingSet    *binding_set,
617 618
                    guint             keysym,
                    GtkDirectionType  direction)
619
{
620
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
621

622 623 624 625 626 627 628 629
  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);
}

630 631
static void
add_reorder_bindings (GtkBindingSet    *binding_set,
632 633 634
                      guint             keysym,
                      GtkDirectionType  direction,
                      gboolean          move_to_last)
635
{
636
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
637 638

  gtk_binding_entry_add_signal (binding_set, keysym, GDK_MOD1_MASK,
639 640 641
                                "reorder_tab", 2,
                                GTK_TYPE_DIRECTION_TYPE, direction,
                                G_TYPE_BOOLEAN, move_to_last);
642
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_MOD1_MASK,
643 644 645
                                "reorder_tab", 2,
                                GTK_TYPE_DIRECTION_TYPE, direction,
                                G_TYPE_BOOLEAN, move_to_last);
646 647
}

648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
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;
}

664
static void
665 666 667
gtk_notebook_compute_expand (GtkWidget *widget,
                             gboolean  *hexpand_p,
                             gboolean  *vexpand_p)
668
{
669
  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696
  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
697 698 699
static void
gtk_notebook_class_init (GtkNotebookClass *class)
{
Tim Janik's avatar
Tim Janik committed
700 701 702
  GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
703
  GtkBindingSet *binding_set;
704

705 706
  gobject_class->set_property = gtk_notebook_set_property;
  gobject_class->get_property = gtk_notebook_get_property;
707
  gobject_class->finalize = gtk_notebook_finalize;
708

709
  widget_class->destroy = gtk_notebook_destroy;
Elliot Lee's avatar
Elliot Lee committed
710 711 712
  widget_class->map = gtk_notebook_map;
  widget_class->unmap = gtk_notebook_unmap;
  widget_class->realize = gtk_notebook_realize;
713
  widget_class->unrealize = gtk_notebook_unrealize;
714 715
  widget_class->get_preferred_width = gtk_notebook_get_preferred_width;
  widget_class->get_preferred_height = gtk_notebook_get_preferred_height;
716 717
  widget_class->get_preferred_width_for_height = gtk_notebook_get_preferred_width_for_height;
  widget_class->get_preferred_height_for_width = gtk_notebook_get_preferred_height_for_width;
Elliot Lee's avatar
Elliot Lee committed
718
  widget_class->size_allocate = gtk_notebook_size_allocate;
719
  widget_class->draw = gtk_notebook_draw;
Elliot Lee's avatar
Elliot Lee committed
720
  widget_class->button_press_event = gtk_notebook_button_press;
721
  widget_class->button_release_event = gtk_notebook_button_release;
722
  widget_class->popup_menu = gtk_notebook_popup_menu;
Paolo Borelli's avatar
Paolo Borelli committed
723
  widget_class->enter_notify_event = gtk_notebook_enter_notify;
724 725
  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
726
  widget_class->grab_notify = gtk_notebook_grab_notify;
727
  widget_class->state_flags_changed = gtk_notebook_state_flags_changed;
728
  widget_class->focus_in_event = gtk_notebook_focus_in;
729
  widget_class->focus_out_event = gtk_notebook_focus_out;
730
  widget_class->focus = gtk_notebook_focus;
731
  widget_class->style_updated = gtk_notebook_style_updated;
732
  widget_class->drag_begin = gtk_notebook_drag_begin;
733
  widget_class->drag_end = gtk_notebook_drag_end;
734
  widget_class->drag_motion = gtk_notebook_drag_motion;
735
  widget_class->drag_leave = gtk_notebook_drag_leave;
736 737 738
  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;
739
  widget_class->drag_failed = gtk_notebook_drag_failed;
740
  widget_class->compute_expand = gtk_notebook_compute_expand;
741
  widget_class->direction_changed = gtk_notebook_direction_changed;
742

Elliot Lee's avatar
Elliot Lee committed
743 744
  container_class->add = gtk_notebook_add;
  container_class->remove = gtk_notebook_remove;
745
  container_class->forall = gtk_notebook_forall;
746
  container_class->set_focus_child = gtk_notebook_set_focus_child;
Tim Janik's avatar
Tim Janik committed
747 748
  container_class->get_child_property = gtk_notebook_get_child_property;
  container_class->set_child_property = gtk_notebook_set_child_property;
749
  container_class->child_type = gtk_notebook_child_type;
750

751
  class->switch_page = gtk_notebook_real_switch_page;
752
  class->insert_page = gtk_notebook_real_insert_page;
753

754 755
  class->focus_tab = gtk_notebook_focus_tab;
  class->select_page = gtk_notebook_select_page;
756
  class->change_current_page = gtk_notebook_change_current_page;
757
  class->move_focus_out = gtk_notebook_move_focus_out;
758
  class->reorder_tab = gtk_notebook_reorder_tab;
759
  class->create_window = gtk_notebook_create_window;
760

761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
  properties[PROP_PAGE] =
      g_param_spec_int ("page",
                        P_("Page"),
                        P_("The index of the current page"),
                        -1, G_MAXINT,
                        -1,
                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  properties[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|G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_SHOW_TABS] =
      g_param_spec_boolean ("show-tabs",
                            P_("Show Tabs"),
                            P_("Whether tabs should be shown"),
                            TRUE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_SHOW_BORDER] =
      g_param_spec_boolean ("show-border",
                            P_("Show Border"),
                            P_("Whether the border should be shown"),
                            TRUE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  properties[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|G_PARAM_EXPLICIT_NOTIFY);

  properties[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|G_PARAM_EXPLICIT_NOTIFY);
Matthias Clasen's avatar
Matthias Clasen committed
804 805

  /**
806
   * GtkNotebook:group-name:
Matthias Clasen's avatar
Matthias Clasen committed
807
   *
808
   * Group name for tab drag and drop.
Matthias Clasen's avatar
Matthias Clasen committed
809 810
   *
   * Since: 2.24
811
   */
812 813 814 815 816 817 818 819
  properties[PROP_GROUP_NAME] =
      g_param_spec_string ("group-name",
                           P_("Group Name"),
                           P_("Group name for tab drag and drop"),
                           NULL,
                           GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  g_object_class_install_properties (gobject_class, LAST_PROP, properties);
Tim Janik's avatar
Tim Janik committed
820 821

  gtk_container_class_install_child_property (container_class,
822 823 824 825 826 827
                                              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
828
  gtk_container_class_install_child_property (container_class,
829 830 831 832 833 834
                                              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
835
  gtk_container_class_install_child_property (container_class,
836 837 838 839 840 841
                                              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
842
  gtk_container_class_install_child_property (container_class,
843 844 845 846 847 848
                                              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
849
  gtk_container_class_install_child_property (container_class,
850 851 852 853 854 855
                                              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));
856

857
  gtk_container_class_install_child_property (container_class,
858 859 860 861 862 863
                                              CHILD_PROP_REORDERABLE,
                                              g_param_spec_boolean ("reorderable",
                                                                    P_("Tab reorderable"),
                                                                    P_("Whether the tab is reorderable by user action"),
                                                                    FALSE,
                                                                    GTK_PARAM_READWRITE));
864
  gtk_container_class_install_child_property (container_class,
865 866 867 868 869 870
                                              CHILD_PROP_DETACHABLE,
                                              g_param_spec_boolean ("detachable",
                                                                    P_("Tab detachable"),
                                                                    P_("Whether the tab is detachable"),
                                                                    FALSE,
                                                                    GTK_PARAM_READWRITE));
871 872 873 874

/**
 * GtkNotebook:has-secondary-backward-stepper:
 *
875
 * The “has-secondary-backward-stepper” property determines whether
876
 * a second backward arrow button is displayed on the opposite end
877 878 879
 * of the tab area.
 *
 * Since: 2.4
880
 */
881
  gtk_widget_class_install_style_property (widget_class,
882 883 884 885 886
                                           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));
887

888 889 890
/**
 * GtkNotebook:has-secondary-forward-stepper:
 *
891
 * The “has-secondary-forward-stepper” property determines whether
892
 * a second forward arrow button is displayed on the opposite end
893 894 895
 * of the tab area.
 *
 * Since: 2.4
896
 */
897
  gtk_widget_class_install_style_property (widget_class,
898 899 900 901 902
                                           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));
903

904 905 906
/**
 * GtkNotebook:has-backward-stepper:
 *
907
 * The “has-backward-stepper” property determines whether
908 909 910
 * the standard backward arrow button is displayed.
 *
 * Since: 2.4
911
 */
912
  gtk_widget_class_install_style_property (widget_class,
913 914 915 916 917
                                           g_param_spec_boolean ("has-backward-stepper",
                                                                 P_("Backward stepper"),
                                                                 P_("Display the standard backward arrow button"),
                                                                 TRUE,
                                                                 GTK_PARAM_READABLE));
918

919 920 921
/**
 * GtkNotebook:has-forward-stepper:
 *
922
 * The “has-forward-stepper” property determines whether
923 924 925
 * the standard forward arrow button is displayed.
 *
 * Since: 2.4
926
 */
927
  gtk_widget_class_install_style_property (widget_class,
928 929 930 931 932 933
                                           g_param_spec_boolean ("has-forward-stepper",
                                                                 P_("Forward stepper"),
                                                                 P_("Display the standard forward arrow button"),
                                                                 TRUE,
                                                                 GTK_PARAM_READABLE));

934 935 936
/**
 * GtkNotebook:tab-overlap:
 *
937
 * The “tab-overlap” property defines size of tab overlap
938 939 940
 * area.
 *
 * Since: 2.10
941 942 943
 *
 * Deprecated: 3.20: This property is ignored. Use margins on tab nodes
 *     to achieve the same effect.
944
 */
945
  gtk_widget_class_install_style_property (widget_class,
946 947 948 949 950 951
                                           g_param_spec_int ("tab-overlap",
                                                             P_("Tab overlap"),
                                                             P_("Size of tab overlap area"),
                                                             G_MININT,
                                                             G_MAXINT,
                                                             2,
952
                                                             GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
953 954 955 956

/**
 * GtkNotebook:tab-curvature:
 *
957
 * The “tab-curvature” property defines size of tab curvature.
958 959
 *
 * Since: 2.10
960 961 962
 *
 * Deprecated: 3.20: This property is ignored. Use margins on tab nodes
 *     to achieve the same effect.
963
 */
964
  gtk_widget_class_install_style_property (widget_class,
965 966 967 968 969 970
                                           g_param_spec_int ("tab-curvature",
                                                             P_("Tab curvature"),
                                                             P_("Size of tab curvature"),
                                                             0,
                                                             G_MAXINT,
                                                             1,
971
                                                             GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
972

973 974 975
  /**
   * GtkNotebook:arrow-spacing:
   *
976
   * The "arrow-spacing" property defines the spacing between the scroll
977 978 979
   * arrows and the tabs.
   *
   * Since: 2.10
980 981 982
   *
   * Deprecated: 3.20: This property is ignored. Use margins on arrows or
   *     the "tabs" node to achieve the same effect.
983 984 985
   */
  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("arrow-spacing",
986 987
                                                             P_("Arrow spacing"),
                                                             P_("Scroll arrow spacing"),
988 989 990
                                                             0,
                                                             G_MAXINT,
                                                             0,
991
                                                             GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
992

993 994 995 996 997 998 999
  /**
   * GtkNotebook:initial-gap:
   *
   * The "initial-gap" property defines the minimum size for the initial
   * gap between the first tab.
   *
   * Since: 3.2
1000 1001 1002
   *
   * Deprecated: 3.20: The intial gap is ignored. Use margins on the header node
   *     to achieve the same effect.
1003 1004 1005 1006 1007 1008 1009 1010
   */
  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,
1011
                                                             GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
1012

1013 1014 1015 1016 1017 1018 1019 1020 1021
  /**
   * GtkNotebook:has-tab-gap:
   *
   * The "has-tab-gap" property defines whether the active tab is draw
   * with a gap at the bottom. When %TRUE the theme engine uses
   * gtk_render_extension to draw the active tab. When %FALSE
   * gtk_render_background and gtk_render_frame are used.
   *
   * Since: 3.12
1022 1023
   *
   * Deprecated: 3.20: This function always behaves as if it was set to %FALSE.
1024 1025 1026 1027 1028 1029
   */
  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_boolean ("has-tab-gap",
                                                                 P_("Tab gap"),
                                                                 P_("Active tab is drawn with a gap at the bottom"),
                                                                 TRUE,
1030
                                                                 GTK_PARAM_READABLE | G_PARAM_DEPRECATED));
1031

1032 1033 1034 1035 1036 1037 1038 1039
  /**
   * 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.
   */
1040
  notebook_signals[SWITCH_PAGE] =
1041
    g_signal_new (I_("switch-page"),
1042 1043 1044 1045 1046 1047 1048 1049 1050
                  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] =
1051
    g_signal_new (I_("focus-tab"),
Manish Singh's avatar
Manish Singh committed
1052
                  G_TYPE_FROM_CLASS (gobject_class),
1053 1054 1055
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                  NULL, NULL,
1056
                  _gtk_marshal_BOOLEAN__ENUM,
1057
                  G_TYPE_BOOLEAN, 1,
1058
                  GTK_TYPE_NOTEBOOK_TAB);
1059
  notebook_signals[SELECT_PAGE] =
1060
    g_signal_new (I_("select-page"),
Manish Singh's avatar
Manish Singh committed
1061
                  G_TYPE_FROM_CLASS (gobject_class),
1062 1063 1064
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                  NULL, NULL,
1065 1066
                  _gtk_marshal_BOOLEAN__BOOLEAN,
                  G_TYPE_BOOLEAN, 1,
1067
                  G_TYPE_BOOLEAN);
1068
  notebook_signals[CHANGE_CURRENT_PAGE] =
1069
    g_signal_new (I_("change-current-page"),
Manish Singh's avatar
Manish Singh committed
1070
                  G_TYPE_FROM_CLASS (gobject_class),
1071 1072 1073
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                  NULL, NULL,
1074 1075
                  _gtk_marshal_BOOLEAN__INT,
                  G_TYPE_BOOLEAN, 1,
1076
                  G_TYPE_INT);
1077
  notebook_signals[MOVE_FOCUS_OUT] =
1078
    g_signal_new (I_("move-focus-out"),
Manish Singh's avatar
Manish Singh committed
1079
                  G_TYPE_FROM_CLASS (gobject_class),
1080 1081 1082
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, move_focus_out),
                  NULL, NULL,
1083
                  NULL,
1084 1085
                  G_TYPE_NONE, 1,
                  GTK_TYPE_DIRECTION_TYPE);
1086
  notebook_signals[REORDER_TAB] =
1087
    g_signal_new (I_("reorder-tab"),
1088 1089 1090 1091
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, reorder_tab),
                  NULL, NULL,
1092 1093
                  _gtk_marshal_BOOLEAN__ENUM_BOOLEAN,
                  G_TYPE_BOOLEAN, 2,
1094
                  GTK_TYPE_DIRECTION_TYPE,
1095
                  G_TYPE_BOOLEAN);
1096
  /**
1097
   * GtkNotebook::page-reordered:
1098 1099 1100 1101
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
1102 1103
   * the ::page-reordered signal is emitted in the notebook
   * right after a page has been reordered.
1104 1105
   *
   * Since: 2.10
1106
   */
1107
  notebook_signals[PAGE_REORDERED] =
1108
    g_signal_new (I_("page-reordered"),
1109
                  G_TYPE_FROM_CLASS (gobject_class),
1110
                  G_SIGNAL_RUN_LAST,
1111 1112 1113
                  G_STRUCT_OFFSET (GtkNotebookClass, page_reordered),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1114
                  G_TYPE_NONE, 2,
1115 1116
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1117
  /**
1118
   * GtkNotebook::page-removed:
1119 1120 1121 1122
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the @child page number
   *
1123
   * the ::page-removed signal is emitted in the notebook
1124
   * right after a page is removed from the notebook.
1125 1126
   *
   * Since: 2.10
1127
   */
1128
  notebook_signals[PAGE_REMOVED] =
1129
    g_signal_new (I_("page-removed"),
1130
                  G_TYPE_FROM_CLASS (gobject_class),
1131
                  G_SIGNAL_RUN_LAST,
1132 1133 1134
                  G_STRUCT_OFFSET (GtkNotebookClass, page_removed),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1135
                  G_TYPE_NONE, 2,
1136 1137
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1138
  /**
1139
   * GtkNotebook::page-added:
1140 1141 1142 1143
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
1144 1145
   * the ::page-added signal is emitted in the notebook
   * right after a page is added to the notebook.
1146 1147
   *
   * Since: 2.10
1148
   */
1149
  notebook_signals[PAGE_ADDED] =
1150
    g_signal_new (I_("page-added"),
1151
                  G_TYPE_FROM_CLASS (gobject_class),
1152
                  G_SIGNAL_RUN_LAST,
1153 1154 1155
                  G_STRUCT_OFFSET (GtkNotebookClass, page_added),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1156
                  G_TYPE_NONE, 2,
1157 1158
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1159

1160 1161 1162 1163 1164 1165 1166 1167
  /**
   * 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