]> Pileus Git - ~andy/gtk/blob - gtk/gtkapplicationwindow.c
GtkApplicationWindow: Add a GtkAccelGroup
[~andy/gtk] / gtk / gtkapplicationwindow.c
1 /*
2  * Copyright © 2011 Canonical Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the licence, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include "config.h"
23
24 #include "gtkapplicationwindow.h"
25
26 #include "gtkmodelmenu.h"
27 #include "gactionmuxer.h"
28 #include "gtkaccelgroup.h"
29 #include "gtkintl.h"
30
31 /**
32  * SECTION:gtkapplicationwindow
33  * @title: GtkApplicationWindow
34  * @short_description: GtkWindow subclass with GtkApplication support
35  *
36  * GtkApplicationWindow is a #GtkWindow subclass that offers some
37  * extra functionality for better integration with #GtkApplication
38  * features.  Notably, it can handle both the application menu as well
39  * as the menubar.  See g_application_set_app_menu() and
40  * g_application_set_menubar().
41  *
42  * This class implements the #GActionGroup and #GActionMap interfaces,
43  * to let you add window-specific actions that will be exported by the
44  * associated #GtkApplication, together with its application-wide
45  * actions.  Window-specific actions are prefixed with the "win."
46  * prefix and application-wide actions are prefixed with the "app."
47  * prefix.  Actions must be addressed with the prefixed name when
48  * referring to them from a #GMenuModel.
49  *
50  * If the desktop environment does not display the application menu
51  * as part of the desktop shell, then #GApplicationWindow will
52  * automatically show the menu as part of a menubar. This behaviour
53  * can be overridden with the #GtkApplicationWindow:show-menubar
54  * property.
55  *
56  * <example><title>A GtkApplicationWindow with a menubar</title>
57  * <programlisting><![CDATA[
58  * app = gtk_application_new ();
59  *
60  * builder = gtk_builder_new ();
61  * gtk_builder_add_from_string (builder,
62  *     "<interface>"
63  *     "  <menu id='menubar'>"
64  *     "    <submenu label='_Edit'>"
65  *     "      <item label='_Copy' action='win.copy'/>"
66  *     "      <item label='_Paste' action='win.paste'/>"
67  *     "    </submenu>"
68  *     "  </menu>"
69  *     "</interface>");
70  * g_application_set_menubar (G_APPLICATION (app),
71  *                            G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
72  * g_object_unref (builder);
73  *
74  * ...
75  *
76  * window = gtk_application_window_new (app);
77  * ]]>
78  * </programlisting>
79  * </example>
80  */
81 struct _GtkApplicationWindowPrivate
82 {
83   GSimpleActionGroup *actions;
84   GtkWidget *menubar;
85   GtkAccelGroup *accels;
86
87   GMenu *app_menu_section;
88   GMenu *menubar_section;
89   gboolean show_menubar;
90 };
91
92 static void
93 gtk_application_window_update_menubar (GtkApplicationWindow *window)
94 {
95   gboolean should_have_menubar;
96   gboolean have_menubar;
97
98   have_menubar = window->priv->menubar != NULL;
99
100   should_have_menubar = window->priv->show_menubar &&
101                         (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) ||
102                          g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)));
103
104   if (have_menubar && !should_have_menubar)
105     {
106       gtk_widget_unparent (window->priv->menubar);
107       window->priv->menubar = NULL;
108
109       gtk_widget_queue_resize (GTK_WIDGET (window));
110     }
111
112   if (!have_menubar && should_have_menubar)
113     {
114       GActionMuxer *muxer;
115       GMenu *combined;
116
117       muxer = g_action_muxer_new ();
118       g_action_muxer_insert (muxer, "app", G_ACTION_GROUP (gtk_window_get_application (GTK_WINDOW (window))));
119       g_action_muxer_insert (muxer, "win", G_ACTION_GROUP (window));
120
121       combined = g_menu_new ();
122       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->app_menu_section));
123       g_menu_append_section (combined, NULL, G_MENU_MODEL (window->priv->menubar_section));
124
125       window->priv->menubar = gtk_model_menu_create_menu_bar (G_MENU_MODEL (combined), G_ACTION_OBSERVABLE (muxer));
126       gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
127       gtk_widget_show_all (window->priv->menubar);
128       g_object_unref (combined);
129       g_object_unref (muxer);
130
131       gtk_widget_queue_resize (GTK_WIDGET (window));
132     }
133 }
134
135 static void
136 gtk_application_window_update_shell_shows_app_menu (GtkApplicationWindow *window,
137                                                     GtkSettings          *settings)
138 {
139   gboolean shown_by_shell;
140
141   g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL);
142
143   if (shown_by_shell)
144     {
145       /* the shell shows it, so don't show it locally */
146       if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) != 0)
147         g_menu_remove (window->priv->app_menu_section, 0);
148     }
149   else
150     {
151       /* the shell does not show it, so make sure we show it */
152       if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->app_menu_section)) == 0)
153         {
154           GMenuModel *app_menu;
155
156           app_menu = g_application_get_app_menu (G_APPLICATION (gtk_window_get_application (GTK_WINDOW (window))));
157
158           if (app_menu != NULL)
159             g_menu_append_submenu (window->priv->app_menu_section, _("Application"), app_menu);
160         }
161     }
162 }
163
164 static void
165 gtk_application_window_update_shell_shows_menubar (GtkApplicationWindow *window,
166                                                    GtkSettings          *settings)
167 {
168   gboolean shown_by_shell;
169
170   g_object_get (settings, "gtk-shell-shows-menubar", &shown_by_shell, NULL);
171
172   if (shown_by_shell)
173     {
174       /* the shell shows it, so don't show it locally */
175       if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) != 0)
176         g_menu_remove (window->priv->menubar_section, 0);
177     }
178   else
179     {
180       /* the shell does not show it, so make sure we show it */
181       if (g_menu_model_get_n_items (G_MENU_MODEL (window->priv->menubar_section)) == 0)
182         {
183           GMenuModel *menubar;
184
185           menubar = g_application_get_menubar (G_APPLICATION (gtk_window_get_application (GTK_WINDOW (window))));
186
187           if (menubar != NULL)
188             g_menu_append_section (window->priv->menubar_section, NULL, menubar);
189         }
190     }
191 }
192
193 static void
194 gtk_application_window_shell_shows_app_menu_changed (GObject    *object,
195                                                      GParamSpec *pspec,
196                                                      gpointer    user_data)
197 {
198   GtkApplicationWindow *window = user_data;
199
200   gtk_application_window_update_shell_shows_app_menu (window, GTK_SETTINGS (object));
201   gtk_application_window_update_menubar (window);
202 }
203
204 static void
205 gtk_application_window_shell_shows_menubar_changed (GObject    *object,
206                                                     GParamSpec *pspec,
207                                                     gpointer    user_data)
208 {
209   GtkApplicationWindow *window = user_data;
210
211   gtk_application_window_update_shell_shows_menubar (window, GTK_SETTINGS (object));
212   gtk_application_window_update_menubar (window);
213 }
214
215 static gchar **
216 gtk_application_window_list_actions (GActionGroup *group)
217 {
218   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (group);
219
220   return g_action_group_list_actions (G_ACTION_GROUP (window->priv->actions));
221 }
222
223 static gboolean
224 gtk_application_window_query_action (GActionGroup        *group,
225                                      const gchar         *action_name,
226                                      gboolean            *enabled,
227                                      const GVariantType **parameter_type,
228                                      const GVariantType **state_type,
229                                      GVariant           **state_hint,
230                                      GVariant           **state)
231 {
232   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (group);
233
234   return g_action_group_query_action (G_ACTION_GROUP (window->priv->actions),
235                                       action_name, enabled, parameter_type, state_type, state_hint, state);
236 }
237
238 static void
239 gtk_application_window_activate_action (GActionGroup *group,
240                                         const gchar  *action_name,
241                                         GVariant     *parameter)
242 {
243   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (group);
244
245   return g_action_group_activate_action (G_ACTION_GROUP (window->priv->actions), action_name, parameter);
246 }
247
248 static void
249 gtk_application_window_change_action_state (GActionGroup *group,
250                                             const gchar  *action_name,
251                                             GVariant     *state)
252 {
253   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (group);
254
255   return g_action_group_change_action_state (G_ACTION_GROUP (window->priv->actions), action_name, state);
256 }
257
258 static GAction *
259 gtk_application_window_lookup_action (GActionMap  *action_map,
260                                       const gchar *action_name)
261 {
262   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (action_map);
263
264   return g_action_map_lookup_action (G_ACTION_MAP (window->priv->actions), action_name);
265 }
266
267 static void
268 gtk_application_window_add_action (GActionMap *action_map,
269                                    GAction    *action)
270 {
271   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (action_map);
272
273   g_action_map_add_action (G_ACTION_MAP (window->priv->actions), action);
274 }
275
276 static void
277 gtk_application_window_remove_action (GActionMap  *action_map,
278                                       const gchar *action_name)
279 {
280   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (action_map);
281
282   g_action_map_remove_action (G_ACTION_MAP (window->priv->actions), action_name);
283 }
284
285 static void
286 gtk_application_window_group_iface_init (GActionGroupInterface *iface)
287 {
288   iface->list_actions = gtk_application_window_list_actions;
289   iface->query_action = gtk_application_window_query_action;
290   iface->activate_action = gtk_application_window_activate_action;
291   iface->change_action_state = gtk_application_window_change_action_state;
292 }
293
294 static void
295 gtk_application_window_map_iface_init (GActionMapInterface *iface)
296 {
297   iface->lookup_action = gtk_application_window_lookup_action;
298   iface->add_action = gtk_application_window_add_action;
299   iface->remove_action = gtk_application_window_remove_action;
300 }
301
302 G_DEFINE_TYPE_WITH_CODE (GtkApplicationWindow, gtk_application_window, GTK_TYPE_WINDOW,
303                          G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, gtk_application_window_group_iface_init)
304                          G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_MAP, gtk_application_window_map_iface_init))
305
306 enum {
307   PROP_0,
308   PROP_SHOW_MENUBAR,
309   N_PROPS
310 };
311 static GParamSpec *gtk_application_window_properties[N_PROPS];
312
313 static void
314 gtk_application_window_real_get_preferred_height (GtkWidget *widget,
315                                                   gint      *minimum_height,
316                                                   gint      *natural_height)
317 {
318   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
319
320   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
321     ->get_preferred_height (widget, minimum_height, natural_height);
322
323   if (window->priv->menubar != NULL)
324     {
325       gint menubar_min_height, menubar_nat_height;
326
327       gtk_widget_get_preferred_height (window->priv->menubar, &menubar_min_height, &menubar_nat_height);
328       *minimum_height += menubar_min_height;
329       *natural_height += menubar_nat_height;
330     }
331 }
332
333 static void
334 gtk_application_window_real_get_preferred_height_for_width (GtkWidget *widget,
335                                                             gint       width,
336                                                             gint      *minimum_height,
337                                                             gint      *natural_height)
338 {
339   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
340
341   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
342     ->get_preferred_height_for_width (widget, width, minimum_height, natural_height);
343
344   if (window->priv->menubar != NULL)
345     {
346       gint menubar_min_height, menubar_nat_height;
347
348       gtk_widget_get_preferred_height_for_width (window->priv->menubar, width, &menubar_min_height, &menubar_nat_height);
349       *minimum_height += menubar_min_height;
350       *natural_height += menubar_nat_height;
351     }
352 }
353
354 static void
355 gtk_application_window_real_get_preferred_width (GtkWidget *widget,
356                                                  gint      *minimum_width,
357                                                  gint      *natural_width)
358 {
359   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
360
361   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
362     ->get_preferred_width (widget, minimum_width, natural_width);
363
364   if (window->priv->menubar != NULL)
365     {
366       gint menubar_min_width, menubar_nat_width;
367
368       gtk_widget_get_preferred_width (window->priv->menubar, &menubar_min_width, &menubar_nat_width);
369       *minimum_width = MAX (*minimum_width, menubar_min_width);
370       *natural_width = MAX (*natural_width, menubar_nat_width);
371     }
372 }
373
374 static void
375 gtk_application_window_real_get_preferred_width_for_height (GtkWidget *widget,
376                                                             gint       height,
377                                                             gint      *minimum_width,
378                                                             gint      *natural_width)
379 {
380   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
381
382   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
383     ->get_preferred_width_for_height (widget, height, minimum_width, natural_width);
384
385   if (window->priv->menubar != NULL)
386     {
387       gint menubar_min_width, menubar_nat_width;
388
389       gtk_widget_get_preferred_width_for_height (window->priv->menubar, height, &menubar_min_width, &menubar_nat_width);
390       *minimum_width = MAX (*minimum_width, menubar_min_width);
391       *natural_width = MAX (*natural_width, menubar_nat_width);
392     }
393 }
394
395 static void
396 gtk_application_window_real_size_allocate (GtkWidget     *widget,
397                                            GtkAllocation *allocation)
398 {
399   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
400
401   if (window->priv->menubar != NULL)
402     {
403       GtkAllocation menubar_allocation = *allocation;
404       gint menubar_min_height, menubar_nat_height;
405       GtkWidget *child;
406
407       gtk_widget_get_preferred_height_for_width (window->priv->menubar, allocation->width, &menubar_min_height, &menubar_nat_height);
408
409       menubar_allocation.height = menubar_min_height;
410       gtk_widget_size_allocate (window->priv->menubar, &menubar_allocation);
411
412       child = gtk_bin_get_child (GTK_BIN (window));
413       if (child != NULL && gtk_widget_get_visible (child))
414         {
415           GtkAllocation child_allocation = *allocation;
416           gint border_width;
417
418           child_allocation.height = MAX (1, child_allocation.height - menubar_min_height);
419
420           border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
421           child_allocation.x += border_width;
422           child_allocation.y += border_width + menubar_min_height;
423           child_allocation.width -= border_width * 2;
424           child_allocation.height -= border_width * 2 - menubar_min_height;
425           gtk_widget_size_allocate (child, &child_allocation);
426         }
427
428       gtk_widget_set_allocation (widget, allocation);
429     }
430   else
431     GTK_WIDGET_CLASS (gtk_application_window_parent_class)
432       ->size_allocate (widget, allocation);
433 }
434
435 static void
436 gtk_application_window_real_realize (GtkWidget *widget)
437 {
438   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
439   GtkSettings *settings;
440
441   settings = gtk_widget_get_settings (widget);
442
443   g_signal_connect (settings, "notify::gtk-shell-shows-app-menu",
444                     G_CALLBACK (gtk_application_window_shell_shows_app_menu_changed), window);
445   g_signal_connect (settings, "notify::gtk-shell-shows-menubar",
446                     G_CALLBACK (gtk_application_window_shell_shows_menubar_changed), window);
447
448   gtk_application_window_update_shell_shows_app_menu (window, settings);
449   gtk_application_window_update_shell_shows_menubar (window, settings);
450   gtk_application_window_update_menubar (window);
451
452   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
453     ->realize (widget);
454 }
455
456 static void
457 gtk_application_window_real_unrealize (GtkWidget *widget)
458 {
459   GtkSettings *settings;
460
461   settings = gtk_widget_get_settings (widget);
462
463   g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_app_menu_changed, widget);
464   g_signal_handlers_disconnect_by_func (settings, gtk_application_window_shell_shows_menubar_changed, widget);
465
466   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
467     ->unrealize (widget);
468 }
469
470 static void
471 gtk_application_window_real_map (GtkWidget *widget)
472 {
473   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
474
475   /* XXX could eliminate this by tweaking gtk_window_map */
476   if (window->priv->menubar)
477     gtk_widget_map (window->priv->menubar);
478
479   GTK_WIDGET_CLASS (gtk_application_window_parent_class)
480     ->map (widget);
481 }
482
483 static void
484 gtk_application_window_real_forall_internal (GtkContainer *container,
485                                              gboolean      include_internal,
486                                              GtkCallback   callback,
487                                              gpointer      user_data)
488 {
489   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (container);
490
491   if (window->priv->menubar)
492     callback (window->priv->menubar, user_data);
493
494   GTK_CONTAINER_CLASS (gtk_application_window_parent_class)
495     ->forall (container, include_internal, callback, user_data);
496 }
497
498
499 static void
500 gtk_application_window_get_property (GObject    *object,
501                                      guint       prop_id,
502                                      GValue     *value,
503                                      GParamSpec *pspec)
504 {
505   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (object);
506
507   switch (prop_id)
508     {
509     case PROP_SHOW_MENUBAR:
510       g_value_set_boolean (value, window->priv->show_menubar);
511       break;
512
513     default:
514       g_assert_not_reached ();
515     }
516 }
517
518 static void
519 gtk_application_window_set_property (GObject      *object,
520                                      guint         prop_id,
521                                      const GValue *value,
522                                      GParamSpec   *pspec)
523 {
524   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (object);
525
526   switch (prop_id)
527     {
528     case PROP_SHOW_MENUBAR:
529       gtk_application_window_set_show_menubar (window, g_value_get_boolean (value));
530       break;
531
532     default:
533       g_assert_not_reached ();
534     }
535 }
536
537 static void
538 gtk_application_window_dispose (GObject *object)
539 {
540   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (object);
541
542   if (window->priv->menubar)
543     {
544       gtk_widget_unparent (window->priv->menubar);
545       window->priv->menubar = NULL;
546     }
547
548   g_clear_object (&window->priv->app_menu_section);
549   g_clear_object (&window->priv->menubar_section);
550   g_clear_object (&window->priv->actions);
551   g_clear_object (&window->priv->accels);
552
553   G_OBJECT_CLASS (gtk_application_window_parent_class)
554     ->dispose (object);
555 }
556
557 static void
558 gtk_application_window_init (GtkApplicationWindow *window)
559 {
560   window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window, GTK_TYPE_APPLICATION_WINDOW, GtkApplicationWindowPrivate);
561
562   window->priv->actions = g_simple_action_group_new ();
563   window->priv->app_menu_section = g_menu_new ();
564   window->priv->menubar_section = g_menu_new ();
565   window->priv->accels = gtk_accel_group_new ();
566   gtk_window_add_accel_group (GTK_WINDOW (window), window->priv->accels);
567
568   /* window->priv->actions is the one and only ref on the group, so when
569    * we dispose, the action group will die, disconnecting all signals.
570    */
571   g_signal_connect_swapped (window->priv->actions, "action-added",
572                             G_CALLBACK (g_action_group_action_added), window);
573   g_signal_connect_swapped (window->priv->actions, "action-enabled-changed",
574                             G_CALLBACK (g_action_group_action_enabled_changed), window);
575   g_signal_connect_swapped (window->priv->actions, "action-state-changed",
576                             G_CALLBACK (g_action_group_action_state_changed), window);
577   g_signal_connect_swapped (window->priv->actions, "action-removed",
578                             G_CALLBACK (g_action_group_action_removed), window);
579 }
580
581 static void
582 gtk_application_window_class_init (GtkApplicationWindowClass *class)
583 {
584   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
585   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
586   GObjectClass *object_class = G_OBJECT_CLASS (class);
587
588   container_class->forall = gtk_application_window_real_forall_internal;
589   widget_class->get_preferred_height = gtk_application_window_real_get_preferred_height;
590   widget_class->get_preferred_height_for_width = gtk_application_window_real_get_preferred_height_for_width;
591   widget_class->get_preferred_width = gtk_application_window_real_get_preferred_width;
592   widget_class->get_preferred_width_for_height = gtk_application_window_real_get_preferred_width_for_height;
593   widget_class->size_allocate = gtk_application_window_real_size_allocate;
594   widget_class->realize = gtk_application_window_real_realize;
595   widget_class->unrealize = gtk_application_window_real_unrealize;
596   widget_class->map = gtk_application_window_real_map;
597   object_class->get_property = gtk_application_window_get_property;
598   object_class->set_property = gtk_application_window_set_property;
599   object_class->dispose = gtk_application_window_dispose;
600
601   /**
602    * GtkApplicationWindow:show-menubar:
603    *
604    * If this property is %TRUE, the window will display a menubar
605    * that includes the app menu and menubar, unless these are
606    * shown by the desktop shell. See g_application_set_app_menu()
607    * and g_application_set_menubar().
608    *
609    * If %FALSE, the window will not display a menubar, regardless
610    * of whether the desktop shell is showing the menus or not.
611    */
612   gtk_application_window_properties[PROP_SHOW_MENUBAR] =
613     g_param_spec_boolean ("show-menubar",
614                           P_("Show a menubar"),
615                           P_("TRUE if the window should show a "
616                              "menubar at the top of the window"),
617                           TRUE, G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
618   g_object_class_install_properties (object_class, N_PROPS, gtk_application_window_properties);
619   g_type_class_add_private (class, sizeof (GtkApplicationWindowPrivate));
620 }
621
622 /**
623  * gtk_application_window_new:
624  * @application: a #GtkApplication
625  *
626  * Creates a new #GtkApplicationWindow.
627  *
628  * Returns: a newly created #GtkApplicationWindow
629  *
630  * Since: 3.4
631  */
632 GtkWidget *
633 gtk_application_window_new (GtkApplication *application)
634 {
635   g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
636
637   return g_object_new (GTK_TYPE_APPLICATION_WINDOW,
638                        "application", application,
639                        NULL);
640 }
641
642 /**
643  * gtk_application_window_get_show_menubar:
644  * @window: a #GtkApplicationWindow
645  *
646  * Returns whether the window will display a menubar for the app menu
647  * and menubar as needed.
648  *
649  * Returns: %TRUE if @window will display a menubar when needed
650  *
651  * Since: 3.4
652  */
653 gboolean
654 gtk_application_window_get_show_menubar (GtkApplicationWindow *window)
655 {
656   return window->priv->show_menubar;
657 }
658
659 /**
660  * gtk_application_window_set_show_menubar:
661  * @window: a #GtkApplicationWindow
662  * @show_menubar: whether to show a menubar when needed
663  *
664  * Sets whether the window will display a menubar for the app menu
665  * and menubar as needed.
666  *
667  * Since: 3.4
668  */
669 void
670 gtk_application_window_set_show_menubar (GtkApplicationWindow *window,
671                                          gboolean              show_menubar)
672 {
673   g_return_if_fail (GTK_IS_APPLICATION_WINDOW (window));
674
675   show_menubar = !!show_menubar;
676
677   if (window->priv->show_menubar != show_menubar)
678     {
679       window->priv->show_menubar = show_menubar;
680
681       gtk_application_window_update_menubar (window);
682
683       g_object_notify_by_pspec (G_OBJECT (window), gtk_application_window_properties[PROP_SHOW_MENUBAR]);
684     }
685 }