diff --git a/examples/sunny.c b/examples/sunny.c index fdb15b8912..62f51a9866 100644 --- a/examples/sunny.c +++ b/examples/sunny.c @@ -18,7 +18,6 @@ new_window (GApplication *app, gtk_widget_show (header); gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Sunny"); gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header), TRUE); - gtk_header_bar_set_show_fallback_app_menu (GTK_HEADER_BAR (header), TRUE); gtk_window_set_titlebar (GTK_WINDOW (window), header); overlay = gtk_overlay_new (); diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c index 333e69c25b..5a58e893c6 100644 --- a/gtk/gtkheaderbar.c +++ b/gtk/gtkheaderbar.c @@ -26,6 +26,7 @@ #include "gtktypebuiltins.h" #include "gtkwidgetprivate.h" #include "gtkcontainerprivate.h" +#include "gtkwindowprivate.h" #include "a11y/gtkcontaineraccessible.h" #include @@ -55,15 +56,21 @@ struct _GtkHeaderBarPrivate GtkWidget *label_sizing_box; GtkWidget *subtitle_sizing_label; GtkWidget *custom_title; - GtkWidget *close_button; - GtkWidget *separator; gint spacing; - gboolean show_fallback_app_menu; - GtkWidget *menu_button; - GtkWidget *menu_separator; gboolean has_subtitle; GList *children; + + gboolean shows_wm_decorations; + + GtkWidget *titlebar_start_box; + GtkWidget *titlebar_end_box; + + GtkWidget *titlebar_icon; + GtkWidget *titlebar_menu_button; + GtkWidget *titlebar_min_button; + GtkWidget *titlebar_max_button; + GtkWidget *titlebar_close_button; }; typedef struct _Child Child; @@ -81,7 +88,6 @@ enum { PROP_CUSTOM_TITLE, PROP_SPACING, PROP_SHOW_CLOSE_BUTTON, - PROP_SHOW_FALLBACK_APP_MENU }; enum { @@ -194,175 +200,277 @@ create_title_box (const char *title, return label_box; } -static void -close_button_clicked (GtkButton *button, gpointer data) -{ - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button)); - gtk_window_close (GTK_WINDOW (toplevel)); -} - -static void -add_close_button (GtkHeaderBar *bar) -{ - GtkHeaderBarPrivate *priv; - GtkWidget *button; - GIcon *icon; - GtkWidget *image; - GtkWidget *separator; - GtkStyleContext *context; - AtkObject *accessible; - - priv = gtk_header_bar_get_instance_private (bar); - - button = gtk_button_new (); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - context = gtk_widget_get_style_context (button); - gtk_style_context_add_class (context, "image-button"); - gtk_style_context_add_class (context, "titlebutton"); - icon = g_themed_icon_new ("window-close-symbolic"); - image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_MENU); - g_object_unref (icon); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - g_signal_connect (button, "clicked", - G_CALLBACK (close_button_clicked), NULL); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, _("Close")); - gtk_widget_show_all (button); - gtk_widget_set_parent (button, GTK_WIDGET (bar)); - - separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); - gtk_widget_show (separator); - gtk_widget_set_parent (separator, GTK_WIDGET (bar)); - - priv->separator = separator; - priv->close_button = button; -} - -static void -remove_close_button (GtkHeaderBar *bar) +void +_gtk_header_bar_update_window_icon (GtkHeaderBar *bar, + GList *list) { GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar); - gtk_widget_unparent (priv->separator); - gtk_widget_unparent (priv->close_button); + if (priv->titlebar_icon && list != NULL) + { + GdkPixbuf *pixbuf, *best; + GList *l; + gint size; - priv->separator = NULL; - priv->close_button = NULL; + if (GTK_IS_BUTTON (gtk_widget_get_parent (priv->titlebar_icon))) + size = 16; + else + size = 20; + + best = NULL; + for (l = list; l; l = l->next) + { + pixbuf = list->data; + if (gdk_pixbuf_get_width (pixbuf) <= size) + { + best = g_object_ref (pixbuf); + break; + } + } + + if (best == NULL) + best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR); + + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best); + g_object_unref (best); + + gtk_widget_show (priv->titlebar_icon); + } } -static void -add_menu_button (GtkHeaderBar *bar, - GMenuModel *menu) +void +_gtk_header_bar_update_window_buttons (GtkHeaderBar *bar) { GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar); - GtkWidget *window; - GtkWidget *button; - GtkWidget *image; - GtkWidget *separator; - GtkStyleContext *context; - AtkObject *accessible; + GtkWindow *window; + GtkTextDirection direction; + gchar *layout_desc; + gchar **tokens, **t; + gint i, j; + GdkPixbuf *icon = NULL; + GMenuModel *menu; + gboolean shown_by_shell; - if (priv->menu_button) + if (!gtk_widget_get_realized (GTK_WIDGET (bar))) return; - button = gtk_menu_button_new (); - gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu); - gtk_widget_set_valign (button, GTK_ALIGN_CENTER); - context = gtk_widget_get_style_context (button); - gtk_style_context_add_class (context, "image-button"); - gtk_style_context_add_class (context, "titlebutton"); - image = NULL; - window = gtk_widget_get_toplevel (GTK_WIDGET (bar)); - if (GTK_IS_WINDOW (window)) + window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (bar))); + + direction = gtk_widget_get_direction (GTK_WIDGET (window)); + + if (priv->titlebar_icon) { - const gchar *icon_name; - GdkPixbuf *icon; - icon_name = gtk_window_get_icon_name (GTK_WINDOW (window)); - icon = gtk_window_get_icon (GTK_WINDOW (window)); - if (icon_name != NULL) + icon = gtk_image_get_pixbuf (GTK_IMAGE (priv->titlebar_icon)); + if (icon) + g_object_ref (icon); + gtk_widget_destroy (priv->titlebar_icon); + priv->titlebar_icon = NULL; + } + if (priv->titlebar_menu_button) + { + gtk_widget_destroy (priv->titlebar_menu_button); + priv->titlebar_menu_button = NULL; + } + if (priv->titlebar_min_button) + { + gtk_widget_destroy (priv->titlebar_min_button); + priv->titlebar_min_button = NULL; + } + if (priv->titlebar_max_button) + { + gtk_widget_destroy (priv->titlebar_max_button); + priv->titlebar_max_button = NULL; + } + if (priv->titlebar_close_button) + { + gtk_widget_destroy (priv->titlebar_close_button); + priv->titlebar_close_button = NULL; + } + if (priv->titlebar_start_box) + { + gtk_widget_destroy (priv->titlebar_start_box); + priv->titlebar_start_box = NULL; + } + if (priv->titlebar_end_box) + { + gtk_widget_destroy (priv->titlebar_end_box); + priv->titlebar_end_box = NULL; + } + + gtk_widget_style_get (GTK_WIDGET (window), + "decoration-button-layout", &layout_desc, + NULL); + + g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)), + "gtk-shell-shows-app-menu", &shown_by_shell, NULL); + + if (!shown_by_shell && gtk_window_get_application (window)) + menu = gtk_application_get_app_menu (gtk_window_get_application (window)); + else + menu = NULL; + + tokens = g_strsplit (layout_desc, ":", 2); + if (tokens) + { + for (i = 0; i < 2; i++) { - image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); - } - else if (icon != NULL) - { - if (gdk_pixbuf_get_width (icon) > 16) + GtkWidget *box; + GtkWidget *separator; + int n_children = 0; + + if (tokens[i] == NULL) + continue; + + t = g_strsplit (tokens[i], ",", -1); + + separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); + gtk_widget_show (separator); + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, priv->spacing); + + for (j = 0; t[j]; j++) { - GdkPixbuf *pixbuf; - pixbuf = gdk_pixbuf_scale_simple (icon, 16, 16, GDK_INTERP_BILINEAR); - image = gtk_image_new_from_pixbuf (pixbuf); - g_object_unref (pixbuf); + GtkWidget *button = NULL; + GtkWidget *image = NULL; + AtkObject *accessible; + + if (strcmp (t[j], "icon") == 0) + { + button = gtk_image_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); + gtk_widget_set_size_request (button, 20, 20); + gtk_widget_show (button); + if (icon != NULL) + gtk_image_set_from_pixbuf (GTK_IMAGE (button), icon); + else + gtk_widget_hide (button); + + priv->titlebar_icon = button; + } + else if (strcmp (t[j], "menu") == 0 && menu != NULL) + { + button = gtk_menu_button_new (); + gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); + if (icon != NULL) + image = gtk_image_new_from_pixbuf (icon); + else + image = gtk_image_new_from_icon_name ("process-stop-symbolic", GTK_ICON_SIZE_MENU); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_widget_set_can_focus (button, FALSE); + gtk_widget_show_all (button); + accessible = gtk_widget_get_accessible (button); + if (GTK_IS_ACCESSIBLE (accessible)) + atk_object_set_name (accessible, _("Application menu")); + priv->titlebar_icon = image; + priv->titlebar_menu_button = button; + } + else if (strcmp (t[j], "minimize") == 0 && + gtk_window_get_type_hint (window) == GDK_WINDOW_TYPE_HINT_NORMAL) + { + button = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); + image = gtk_image_new_from_icon_name ("window-minimize-symbolic", GTK_ICON_SIZE_MENU); + g_object_set (image, "use-fallback", TRUE, NULL); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_widget_set_can_focus (button, FALSE); + gtk_widget_show_all (button); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (gtk_window_iconify), window); + accessible = gtk_widget_get_accessible (button); + if (GTK_IS_ACCESSIBLE (accessible)) + atk_object_set_name (accessible, _("Minimize")); + priv->titlebar_min_button = button; + } + else if (strcmp (t[j], "maximize") == 0 && + gtk_window_get_resizable (window) && + gtk_window_get_type_hint (window) == GDK_WINDOW_TYPE_HINT_NORMAL) + { + const gchar *icon_name; + gboolean maximized = _gtk_window_get_maximized (window); + + icon_name = maximized ? "window-restore-symbolic" : "window-maximize-symbolic"; + button = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); + image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + g_object_set (image, "use-fallback", TRUE, NULL); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_widget_set_can_focus (button, FALSE); + gtk_widget_show_all (button); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (_gtk_window_toggle_maximized), window); + accessible = gtk_widget_get_accessible (button); + if (GTK_IS_ACCESSIBLE (accessible)) + atk_object_set_name (accessible, maximized ? _("Restore") : _("Maximize")); + priv->titlebar_max_button = button; + } + else if (strcmp (t[j], "close") == 0 && + gtk_window_get_deletable (window) && + gtk_window_get_type_hint (window) == GDK_WINDOW_TYPE_HINT_NORMAL) + { + button = gtk_button_new (); + image = gtk_image_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); + g_object_set (image, "use-fallback", TRUE, NULL); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_widget_set_can_focus (button, FALSE); + gtk_widget_show_all (button); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (gtk_window_close), window); + accessible = gtk_widget_get_accessible (button); + if (GTK_IS_ACCESSIBLE (accessible)) + atk_object_set_name (accessible, _("Close")); + priv->titlebar_close_button = button; + } + + if (button) + { + gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); + n_children ++; + } + } + g_strfreev (t); + + if (n_children == 0) + { + gtk_widget_destroy (box); + continue; + } + + gtk_widget_show (box); + gtk_widget_set_parent (box, GTK_WIDGET (bar)); + + if ((direction == GTK_TEXT_DIR_LTR && i == 0) || + (direction == GTK_TEXT_DIR_RTL && i == 1)) + { + gtk_style_context_add_class (gtk_widget_get_style_context (box), "left"); + gtk_box_pack_end (GTK_BOX (box), separator, FALSE, FALSE, 0); } else - image = gtk_image_new_from_pixbuf (icon); + { + gtk_style_context_add_class (gtk_widget_get_style_context (box), "right"); + gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (box), separator, 0); + } + + if (i == 0) + priv->titlebar_start_box = box; + else + priv->titlebar_end_box = box; } + g_strfreev (tokens); } - if (image == NULL) - image = gtk_image_new_from_icon_name ("process-stop-symbolic", GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, _("Application menu")); - gtk_widget_show_all (button); - gtk_widget_set_parent (button, GTK_WIDGET (bar)); - - separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); - gtk_widget_show (separator); - gtk_widget_set_parent (separator, GTK_WIDGET (bar)); - - priv->menu_separator = separator; - priv->menu_button = button; + g_free (layout_desc); + if (icon) + g_object_unref (icon); } -static void -remove_menu_button (GtkHeaderBar *bar) +gboolean +_gtk_header_bar_get_shows_app_menu (GtkHeaderBar *bar) { GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar); - if (!priv->menu_button) - return; - - gtk_widget_unparent (priv->menu_separator); - gtk_widget_unparent (priv->menu_button); - - priv->menu_separator = NULL; - priv->menu_button = NULL; -} - -static void -update_fallback_app_menu (GtkHeaderBar *bar) -{ - GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar); - GtkSettings *settings; - gboolean shown_by_shell; - GtkWidget *toplevel; - GtkApplication *application; - GMenuModel *menu; - - menu = NULL; - - settings = gtk_widget_get_settings (GTK_WIDGET (bar)); - g_object_get (settings, "gtk-shell-shows-app-menu", &shown_by_shell, NULL); - - if (!shown_by_shell && priv->show_fallback_app_menu) - { - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bar)); - if (GTK_IS_WINDOW (toplevel)) - { - application = gtk_window_get_application (GTK_WINDOW (toplevel)); - if (GTK_IS_APPLICATION (application)) - menu = gtk_application_get_app_menu (application); - } - } - - if (menu) - add_menu_button (bar, menu); - else - remove_menu_button (bar); + return (priv->titlebar_menu_button != NULL); } static void @@ -393,8 +501,6 @@ gtk_header_bar_init (GtkHeaderBar *bar) priv->title = NULL; priv->subtitle = NULL; priv->custom_title = NULL; - priv->close_button = NULL; - priv->separator = NULL; priv->children = NULL; priv->spacing = DEFAULT_SPACING; priv->has_subtitle = TRUE; @@ -492,21 +598,15 @@ gtk_header_bar_get_size (GtkWidget *widget, nvis_children += 1; } - if (priv->close_button != NULL) + if (priv->titlebar_start_box != NULL) { - if (add_child_size (priv->close_button, orientation, &minimum, &natural)) - nvis_children += 1; - - if (add_child_size (priv->separator, orientation, &minimum, &natural)) + if (add_child_size (priv->titlebar_start_box, orientation, &minimum, &natural)) nvis_children += 1; } - if (priv->menu_button != NULL) + if (priv->titlebar_end_box != NULL) { - if (add_child_size (priv->menu_button, orientation, &minimum, &natural)) - nvis_children += 1; - - if (add_child_size (priv->menu_separator, orientation, &minimum, &natural)) + if (add_child_size (priv->titlebar_end_box, orientation, &minimum, &natural)) nvis_children += 1; } @@ -588,30 +688,22 @@ gtk_header_bar_compute_size_for_orientation (GtkWidget *widget, required_natural += child_natural; } - if (priv->close_button != NULL) + if (priv->titlebar_start_box != NULL) { - gtk_widget_get_preferred_width (priv->close_button, - &child_size, &child_natural); - required_size += child_size; - required_natural += child_natural; - - gtk_widget_get_preferred_width (priv->separator, + gtk_widget_get_preferred_width (priv->titlebar_start_box, &child_size, &child_natural); required_size += child_size; required_natural += child_natural; + nvis_children += 1; } - if (priv->menu_button != NULL) + if (priv->titlebar_end_box != NULL) { - gtk_widget_get_preferred_width (priv->menu_button, - &child_size, &child_natural); - required_size += child_size; - required_natural += child_natural; - - gtk_widget_get_preferred_width (priv->menu_separator, + gtk_widget_get_preferred_width (priv->titlebar_end_box, &child_size, &child_natural); required_size += child_size; required_natural += child_natural; + nvis_children += 1; } if (nvis_children > 0) @@ -731,27 +823,17 @@ gtk_header_bar_compute_size_for_opposing_orientation (GtkWidget *widget, computed_natural = MAX (computed_natural, child_natural); } - if (priv->close_button != NULL) + if (priv->titlebar_start_box != NULL) { - gtk_widget_get_preferred_height (priv->close_button, - &child_minimum, &child_natural); - computed_minimum = MAX (computed_minimum, child_minimum); - computed_natural = MAX (computed_natural, child_natural); - - gtk_widget_get_preferred_height (priv->separator, + gtk_widget_get_preferred_height (priv->titlebar_start_box, &child_minimum, &child_natural); computed_minimum = MAX (computed_minimum, child_minimum); computed_natural = MAX (computed_natural, child_natural); } - if (priv->menu_button != NULL) + if (priv->titlebar_end_box != NULL) { - gtk_widget_get_preferred_height (priv->menu_button, - &child_minimum, &child_natural); - computed_minimum = MAX (computed_minimum, child_minimum); - computed_natural = MAX (computed_natural, child_natural); - - gtk_widget_get_preferred_height (priv->menu_separator, + gtk_widget_get_preferred_height (priv->titlebar_end_box, &child_minimum, &child_natural); computed_minimum = MAX (computed_minimum, child_minimum); computed_natural = MAX (computed_natural, child_natural); @@ -803,30 +885,6 @@ gtk_header_bar_get_preferred_height_for_width (GtkWidget *widget, gtk_header_bar_compute_size_for_opposing_orientation (widget, width, minimum_height, natural_height); } -static gboolean -close_button_at_end (GtkWidget *widget) -{ - GtkWidget *toplevel; - gchar *layout_desc; - gboolean at_end; - gchar *p; - - toplevel = gtk_widget_get_toplevel (widget); - if (!GTK_IS_WINDOW (toplevel)) - return TRUE; - gtk_widget_style_get (toplevel, "decoration-button-layout", &layout_desc, NULL); - - p = strchr (layout_desc, ':'); - if (p && strstr (p, "close")) - at_end = TRUE; - else - at_end = FALSE; - - g_free (layout_desc); - - return at_end; -} - static void gtk_header_bar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) @@ -838,12 +896,7 @@ gtk_header_bar_size_allocate (GtkWidget *widget, gint nvis_children; gint title_minimum_size; gint title_natural_size; - gint close_button_width; - gint separator_width; - gint close_width; - gint menu_button_width; - gint menu_width; - gint menu_separator_width; + gint start_width, end_width; gint side[2]; GList *l; gint i; @@ -854,9 +907,6 @@ gtk_header_bar_size_allocate (GtkWidget *widget, gint child_size; GtkTextDirection direction; GtkBorder css_borders; - gboolean at_end; - - at_end = close_button_at_end (widget); gtk_widget_set_allocation (widget, allocation); @@ -899,39 +949,27 @@ gtk_header_bar_size_allocate (GtkWidget *widget, } width -= title_natural_size; - close_button_width = separator_width = close_width = 0; - if (priv->close_button != NULL) + start_width = 0; + if (priv->titlebar_start_box != NULL) { gint min, nat; - gtk_widget_get_preferred_width_for_height (priv->close_button, + gtk_widget_get_preferred_width_for_height (priv->titlebar_start_box, height, &min, &nat); - close_button_width = nat; - - gtk_widget_get_preferred_width_for_height (priv->separator, - height, - &min, &nat); - separator_width = nat; - close_width = close_button_width + separator_width + 2 * priv->spacing; + start_width = nat + priv->spacing; } - width -= close_width; + width -= start_width; - menu_button_width = menu_separator_width = menu_width = 0; - if (priv->menu_button != NULL) + end_width = 0; + if (priv->titlebar_end_box != NULL) { gint min, nat; - gtk_widget_get_preferred_width_for_height (priv->menu_button, + gtk_widget_get_preferred_width_for_height (priv->titlebar_end_box, height, &min, &nat); - menu_button_width = nat; - - gtk_widget_get_preferred_width_for_height (priv->menu_separator, - height, - &min, &nat); - menu_separator_width = nat; - menu_width = menu_button_width + menu_separator_width + 2 * priv->spacing; + end_width = nat + priv->spacing; } - width -= menu_width; + width -= end_width; width = gtk_distribute_natural_allocation (MAX (0, width), nvis_children, sizes); @@ -941,9 +979,9 @@ gtk_header_bar_size_allocate (GtkWidget *widget, child_allocation.y = allocation->y + css_borders.top; child_allocation.height = height; if (packing == GTK_PACK_START) - x = allocation->x + css_borders.left + (at_end ? 0 : close_width) + (at_end ? menu_width : 0); + x = allocation->x + css_borders.left + start_width; else - x = allocation->x + allocation->width - (at_end ? close_width : 0) - (at_end ? 0 : menu_width) - css_borders.right; + x = allocation->x + allocation->width - end_width - css_borders.right; if (packing == GTK_PACK_START) { @@ -997,16 +1035,8 @@ gtk_header_bar_size_allocate (GtkWidget *widget, } } - if (at_end) - { - side[GTK_PACK_START] += menu_width; - side[GTK_PACK_END] += close_width; - } - else - { - side[GTK_PACK_START] += close_width; - side[GTK_PACK_END] += menu_width; - } + side[GTK_PACK_START] += start_width; + side[GTK_PACK_END] += end_width; child_allocation.y = allocation->y + css_borders.top; child_allocation.height = height; @@ -1036,52 +1066,26 @@ gtk_header_bar_size_allocate (GtkWidget *widget, else gtk_widget_size_allocate (priv->label_box, &child_allocation); - if (priv->close_button) + if (priv->titlebar_start_box) { - gboolean left; - - if (direction == GTK_TEXT_DIR_RTL) - left = at_end; - else - left = !at_end; - + gboolean left = (direction == GTK_TEXT_DIR_LTR); if (left) child_allocation.x = allocation->x + css_borders.left; else - child_allocation.x = allocation->x + allocation->width - css_borders.right - close_button_width; - child_allocation.width = close_button_width; - gtk_widget_size_allocate (priv->close_button, &child_allocation); - - if (left) - child_allocation.x = allocation->x + css_borders.left + close_button_width + priv->spacing; - else - child_allocation.x = allocation->x + allocation->width - css_borders.right - close_button_width - priv->spacing - separator_width; - child_allocation.width = separator_width; - gtk_widget_size_allocate (priv->separator, &child_allocation); + child_allocation.x = allocation->x + allocation->width - css_borders.right - start_width; + child_allocation.width = start_width; + gtk_widget_size_allocate (priv->titlebar_start_box, &child_allocation); } - if (priv->menu_button) + if (priv->titlebar_end_box) { - gboolean left; - - if (direction == GTK_TEXT_DIR_RTL) - left = !at_end; - else - left = at_end; - + gboolean left = (direction != GTK_TEXT_DIR_LTR); if (left) child_allocation.x = allocation->x + css_borders.left; else - child_allocation.x = allocation->x + allocation->width - css_borders.right - close_button_width; - child_allocation.width = menu_button_width; - gtk_widget_size_allocate (priv->menu_button, &child_allocation); - - if (left) - child_allocation.x = allocation->x + css_borders.left + menu_button_width + priv->spacing; - else - child_allocation.x = allocation->x + allocation->width - css_borders.right - menu_button_width - priv->spacing - menu_separator_width; - child_allocation.width = menu_separator_width; - gtk_widget_size_allocate (priv->menu_separator, &child_allocation); + child_allocation.x = allocation->x + allocation->width - css_borders.right - end_width; + child_allocation.width = end_width; + gtk_widget_size_allocate (priv->titlebar_end_box, &child_allocation); } } @@ -1335,10 +1339,6 @@ gtk_header_bar_get_property (GObject *object, g_value_set_boolean (value, gtk_header_bar_get_show_close_button (bar)); break; - case PROP_SHOW_FALLBACK_APP_MENU: - g_value_set_boolean (value, priv->show_fallback_app_menu); - break; - case PROP_HAS_SUBTITLE: g_value_set_boolean (value, gtk_header_bar_get_has_subtitle (bar)); break; @@ -1381,10 +1381,6 @@ gtk_header_bar_set_property (GObject *object, gtk_header_bar_set_show_close_button (bar, g_value_get_boolean (value)); break; - case PROP_SHOW_FALLBACK_APP_MENU: - gtk_header_bar_set_show_fallback_app_menu (bar, g_value_get_boolean (value)); - break; - case PROP_HAS_SUBTITLE: gtk_header_bar_set_has_subtitle (bar, g_value_get_boolean (value)); break; @@ -1489,17 +1485,11 @@ gtk_header_bar_forall (GtkContainer *container, if (include_internals && priv->label_box != NULL) (* callback) (priv->label_box, callback_data); - if (include_internals && priv->close_button != NULL) - (* callback) (priv->close_button, callback_data); + if (include_internals && priv->titlebar_start_box != NULL) + (* callback) (priv->titlebar_start_box, callback_data); - if (include_internals && priv->separator != NULL) - (* callback) (priv->separator, callback_data); - - if (include_internals && priv->menu_button != NULL) - (* callback) (priv->menu_button, callback_data); - - if (include_internals && priv->menu_separator != NULL) - (* callback) (priv->menu_separator, callback_data); + if (include_internals && priv->titlebar_end_box != NULL) + (* callback) (priv->titlebar_end_box, callback_data); children = priv->children; while (children) @@ -1653,13 +1643,12 @@ gtk_header_bar_realize (GtkWidget *widget) { GtkSettings *settings; + GTK_WIDGET_CLASS (gtk_header_bar_parent_class)->realize (widget); + settings = gtk_widget_get_settings (widget); g_signal_connect_swapped (settings, "notify::gtk-shell-shows-app-menu", - G_CALLBACK (update_fallback_app_menu), widget); - - update_fallback_app_menu (GTK_HEADER_BAR (widget)); - - GTK_WIDGET_CLASS (gtk_header_bar_parent_class)->realize (widget); + G_CALLBACK (_gtk_header_bar_update_window_buttons), widget); + _gtk_header_bar_update_window_buttons (GTK_HEADER_BAR (widget)); } static void @@ -1669,7 +1658,7 @@ gtk_header_bar_unrealize (GtkWidget *widget) settings = gtk_widget_get_settings (widget); - g_signal_handlers_disconnect_by_func (settings, update_fallback_app_menu, widget); + g_signal_handlers_disconnect_by_func (settings, _gtk_header_bar_update_window_buttons, widget); GTK_WIDGET_CLASS (gtk_header_bar_parent_class)->unrealize (widget); } @@ -1756,8 +1745,8 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class) g_object_class_install_property (object_class, PROP_SHOW_CLOSE_BUTTON, g_param_spec_boolean ("show-close-button", - P_("Show Close button"), - P_("Whether to show a window close button"), + P_("Show decorations"), + P_("Whether to show window decorations"), FALSE, GTK_PARAM_READWRITE)); @@ -1777,32 +1766,6 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class) TRUE, GTK_PARAM_READWRITE)); - /** - * GtkHeaderBar:show-fallback-app-menu: - * - * If %TRUE, the header bar will show a menu button for the - * application menu when needed, ie when the application menu - * is not shown by the desktop shell. - * - * If %FALSE, the header bar will not whow a menu button, - * regardless whether the desktop shell shows the application - * menu or not. - * - * GtkApplicationWindow will not add a the application menu - * to the fallback menubar that it creates if the window - * has a header bar with ::show-fallback-app-menu set to %TRUE - * as its titlebar widget. - * - * Since: 3.12 - */ - g_object_class_install_property (object_class, - PROP_SHOW_FALLBACK_APP_MENU, - g_param_spec_boolean ("show-fallback-app-menu", - P_("Show Fallback application menu"), - P_("Whether to show a fallback application menu"), - FALSE, - GTK_PARAM_READWRITE)); - gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_PANEL); } @@ -1879,10 +1842,10 @@ gtk_header_bar_new (void) * gtk_header_bar_get_show_close_button: * @bar: a #GtkHeaderBar * - * Returns whether this header bar shows a window close - * button. + * Returns whether this header bar shows the standard window + * decorations. * - * Returns: %TRUE if a window close button is shown + * Returns: %TRUE if the decorations are shown * * Since: 3.10 */ @@ -1895,16 +1858,16 @@ gtk_header_bar_get_show_close_button (GtkHeaderBar *bar) priv = gtk_header_bar_get_instance_private (bar); - return priv->close_button != NULL; + return priv->shows_wm_decorations; } /** * gtk_header_bar_set_show_close_button: * @bar: a #GtkHeaderBar - * @setting: %TRUE to show a window close button + * @setting: %TRUE to show standard widow decorations * - * Sets whether this header bar shows a window close - * button. + * Sets whether this header bar shows the standard window decorations, + * including close, maximize, and minimize. * * Since: 3.10 */ @@ -1920,74 +1883,14 @@ gtk_header_bar_set_show_close_button (GtkHeaderBar *bar, setting = setting != FALSE; - if ((priv->close_button != NULL) == setting) + if (priv->shows_wm_decorations == setting) return; - if (setting) - add_close_button (bar); - else - remove_close_button (bar); - - gtk_widget_queue_resize (GTK_WIDGET (bar)); - + priv->shows_wm_decorations = setting; + _gtk_header_bar_update_window_buttons (bar); g_object_notify (G_OBJECT (bar), "show-close-button"); } -/** - * gtk_header_bar_get_show_fallback_app_menu: - * @bar: a #GtkHeaderBar - * - * Returns whether this header bar shows a menu - * button for the application menu when needed. - * - * Returns: %TRUE if an application menu button may be shown - * - * Since: 3.12 - */ -gboolean -gtk_header_bar_get_show_fallback_app_menu (GtkHeaderBar *bar) -{ - GtkHeaderBarPrivate *priv; - - g_return_val_if_fail (GTK_IS_HEADER_BAR (bar), FALSE); - - priv = gtk_header_bar_get_instance_private (bar); - - return priv->show_fallback_app_menu; -} - -/** - * gtk_header_bar_set_show_fallback_app_menu: - * @bar: a #GtkHeaderBar - * @setting: %TRUE to enable the fallback application menu - * - * Sets whether this header bar may show a menu button - * for the application menu when it is not shown by the - * desktop environment. - * - * Since: 3.12 - */ -void -gtk_header_bar_set_show_fallback_app_menu (GtkHeaderBar *bar, - gboolean setting) -{ - GtkHeaderBarPrivate *priv; - - g_return_if_fail (GTK_IS_HEADER_BAR (bar)); - - priv = gtk_header_bar_get_instance_private (bar); - - setting = setting != FALSE; - - if (priv->show_fallback_app_menu == setting) - return; - - priv->show_fallback_app_menu = setting; - update_fallback_app_menu (bar); - - g_object_notify (G_OBJECT (bar), "show-fallback-app-menu"); -} - /** * gtk_header_bar_set_has_subtitle: * @bar: a #GtkHeaderBar diff --git a/gtk/gtkheaderbar.h b/gtk/gtkheaderbar.h index 701dbac5f3..1df62b7773 100644 --- a/gtk/gtkheaderbar.h +++ b/gtk/gtkheaderbar.h @@ -90,13 +90,6 @@ GDK_AVAILABLE_IN_3_10 void gtk_header_bar_set_show_close_button (GtkHeaderBar *bar, gboolean setting); -GDK_AVAILABLE_IN_3_12 -gboolean gtk_header_bar_get_show_fallback_app_menu (GtkHeaderBar *bar); - -GDK_AVAILABLE_IN_3_12 -void gtk_header_bar_set_show_fallback_app_menu (GtkHeaderBar *bar, - gboolean setting); - GDK_AVAILABLE_IN_3_12 void gtk_header_bar_set_has_subtitle (GtkHeaderBar *bar, gboolean setting); diff --git a/gtk/gtkheaderbarprivate.h b/gtk/gtkheaderbarprivate.h index a895db9732..c4c04ba8f9 100644 --- a/gtk/gtkheaderbarprivate.h +++ b/gtk/gtkheaderbarprivate.h @@ -20,4 +20,9 @@ #ifndef __GTK_HEADER_BAR_PRIVATE_H__ #define __GTK_HEADER_BAR_PRIVATE_H__ +gboolean _gtk_header_bar_get_shows_app_menu (GtkHeaderBar *bar); +void _gtk_header_bar_update_window_buttons (GtkHeaderBar *bar); +void _gtk_header_bar_update_window_icon (GtkHeaderBar *bar, + GList *list); + #endif /* __GTK_HEADER_BAR_PRIVATE_H__ */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index f7cb65e7ff..90306ca5a2 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -54,6 +54,7 @@ #include "gtkbox.h" #include "gtkbutton.h" #include "gtkheaderbar.h" +#include "gtkheaderbarprivate.h" #include "a11y/gtkwindowaccessible.h" #include "gtkapplicationprivate.h" @@ -160,11 +161,6 @@ struct _GtkWindowPrivate gint title_height; GtkWidget *title_box; GtkWidget *titlebar; - GtkWidget *titlebar_icon; - GtkWidget *titlebar_menu_button; - GtkWidget *titlebar_min_button; - GtkWidget *titlebar_max_button; - GtkWidget *titlebar_close_button; GtkWidget *popup_menu; GdkWindow *border_window[8]; @@ -1218,8 +1214,16 @@ gtk_window_class_init (GtkWindowClass *klass) gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE); } -static void -gtk_window_toggle_maximized (GtkWindow *window) +gboolean +_gtk_window_get_maximized (GtkWindow *window) +{ + GtkWindowPrivate *priv = window->priv; + + return priv->maximized; +} + +void +_gtk_window_toggle_maximized (GtkWindow *window) { GtkWindowPrivate *priv = window->priv; @@ -3485,11 +3489,6 @@ unset_titlebar (GtkWindow *window) gtk_widget_unparent (priv->title_box); priv->title_box = NULL; priv->titlebar = NULL; - priv->titlebar_icon = NULL; - priv->titlebar_menu_button = NULL; - priv->titlebar_min_button = NULL; - priv->titlebar_max_button = NULL; - priv->titlebar_close_button = NULL; } } @@ -3619,11 +3618,8 @@ _gtk_window_titlebar_shows_app_menu (GtkWindow *window) { GtkWindowPrivate *priv = window->priv; - if (priv->titlebar_menu_button) - return TRUE; - if (GTK_IS_HEADER_BAR (priv->title_box)) - return gtk_header_bar_get_show_fallback_app_menu (GTK_HEADER_BAR (priv->title_box)); + return _gtk_header_bar_get_shows_app_menu (GTK_HEADER_BAR (priv->title_box)); return FALSE; } @@ -3845,43 +3841,6 @@ icon_list_from_theme (GtkWidget *widget, return list; } -static void -set_titlebar_icon (GtkWindow *window, GList *list) -{ - GtkWindowPrivate *priv = window->priv; - - if (priv->titlebar_icon && list != NULL) - { - GdkPixbuf *pixbuf, *best; - GList *l; - gint size; - - if (GTK_IS_BUTTON (gtk_widget_get_parent (priv->titlebar_icon))) - size = 16; - else - size = 20; - - best = NULL; - for (l = list; l; l = l->next) - { - pixbuf = list->data; - if (gdk_pixbuf_get_width (pixbuf) <= size) - { - best = g_object_ref (pixbuf); - break; - } - } - - if (best == NULL) - best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR); - - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best); - g_object_unref (best); - - gtk_widget_show (priv->titlebar_icon); - } -} - static void gtk_window_realize_icon (GtkWindow *window) { @@ -3948,7 +3907,8 @@ gtk_window_realize_icon (GtkWindow *window) info->realized = TRUE; gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list); - set_titlebar_icon (window, icon_list); + if (GTK_IS_HEADER_BAR (priv->title_box)) + _gtk_header_bar_update_window_icon (GTK_HEADER_BAR (priv->title_box), icon_list); if (info->using_themed_icon) { @@ -5167,205 +5127,30 @@ get_default_title (void) return title; } +static gboolean +update_csd_visibility (GtkWindow *window) +{ + GtkWindowPrivate *priv = window->priv; + gboolean visible; + + if (priv->title_box == NULL) + return FALSE; + + visible = !priv->fullscreen && !(priv->maximized && priv->hide_titlebar_when_maximized); + gtk_widget_set_child_visible (priv->title_box, visible); + return visible; +} + static void update_window_buttons (GtkWindow *window) { GtkWindowPrivate *priv = window->priv; - GtkTextDirection direction; - gchar *layout_desc; - gchar **tokens, **t; - gint i, j; - GdkPixbuf *icon = NULL; - GMenuModel *menu; - gboolean shown_by_shell; - if (priv->title_box == NULL) + if (!update_csd_visibility (window)) return; - direction = gtk_widget_get_direction (GTK_WIDGET (window)); - - if (priv->fullscreen || - (priv->maximized && priv->hide_titlebar_when_maximized)) - { - gtk_widget_set_child_visible (priv->title_box, FALSE); - return; - } - else - { - gtk_widget_set_child_visible (priv->title_box, TRUE); - } - - if (priv->titlebar == NULL) - return; - - if (priv->titlebar_icon) - { - icon = gtk_image_get_pixbuf (GTK_IMAGE (priv->titlebar_icon)); - if (icon) - g_object_ref (icon); - gtk_widget_destroy (priv->titlebar_icon); - priv->titlebar_icon = NULL; - } - if (priv->titlebar_menu_button) - { - gtk_widget_destroy (priv->titlebar_menu_button); - priv->titlebar_menu_button = NULL; - } - if (priv->titlebar_min_button) - { - gtk_widget_destroy (priv->titlebar_min_button); - priv->titlebar_min_button = NULL; - } - if (priv->titlebar_max_button) - { - gtk_widget_destroy (priv->titlebar_max_button); - priv->titlebar_max_button = NULL; - } - if (priv->titlebar_close_button) - { - gtk_widget_destroy (priv->titlebar_close_button); - priv->titlebar_close_button = NULL; - } - - gtk_widget_style_get (GTK_WIDGET (window), - "decoration-button-layout", &layout_desc, - NULL); - - g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)), - "gtk-shell-shows-app-menu", &shown_by_shell, NULL); - - if (!shown_by_shell && priv->application) - menu = gtk_application_get_app_menu (priv->application); - else - menu = NULL; - - tokens = g_strsplit (layout_desc, ":", 2); - if (tokens) - { - for (i = 0; i < 2; i++) - { - GtkWidget *box; - - if (tokens[i] == NULL) - continue; - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_show (box); - if ((direction == GTK_TEXT_DIR_LTR && i == 0) || - (direction == GTK_TEXT_DIR_RTL && i == 1)) - gtk_style_context_add_class (gtk_widget_get_style_context (box), "left"); - else - gtk_style_context_add_class (gtk_widget_get_style_context (box), "right"); - if (i == 0) - gtk_header_bar_pack_start (GTK_HEADER_BAR (priv->title_box), box); - else - gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->title_box), box); - - t = g_strsplit (tokens[i], ",", -1); - for (j = 0; t[j]; j++) - { - GtkWidget *button = NULL; - GtkWidget *image = NULL; - AtkObject *accessible; - - if (strcmp (t[j], "icon") == 0) - { - button = gtk_image_new (); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); - gtk_widget_set_size_request (button, 20, 20); - gtk_widget_show (button); - if (icon != NULL) - gtk_image_set_from_pixbuf (GTK_IMAGE (button), icon); - else - gtk_widget_hide (button); - - priv->titlebar_icon = button; - } - else if (strcmp (t[j], "menu") == 0 && menu != NULL) - { - button = gtk_menu_button_new (); - gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), menu); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); - if (icon != NULL) - image = gtk_image_new_from_pixbuf (icon); - else - image = gtk_image_new_from_icon_name ("process-stop-symbolic", GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_widget_set_can_focus (button, FALSE); - gtk_widget_show_all (button); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, _("Application menu")); - priv->titlebar_icon = image; - priv->titlebar_menu_button = button; - } - else if (strcmp (t[j], "minimize") == 0 && - priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL) - { - button = gtk_button_new (); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); - image = gtk_image_new_from_icon_name ("window-minimize-symbolic", GTK_ICON_SIZE_MENU); - g_object_set (image, "use-fallback", TRUE, NULL); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_widget_set_can_focus (button, FALSE); - gtk_widget_show_all (button); - g_signal_connect_swapped (button, "clicked", - G_CALLBACK (gtk_window_iconify), window); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, _("Minimize")); - priv->titlebar_min_button = button; - } - else if (strcmp (t[j], "maximize") == 0 && - priv->resizable && - priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL) - { - const gchar *icon_name; - - icon_name = priv->maximized ? "window-restore-symbolic" : "window-maximize-symbolic"; - button = gtk_button_new (); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); - image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); - g_object_set (image, "use-fallback", TRUE, NULL); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_widget_set_can_focus (button, FALSE); - gtk_widget_show_all (button); - g_signal_connect_swapped (button, "clicked", - G_CALLBACK (gtk_window_toggle_maximized), window); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, priv->maximized ? _("Restore") : _("Maximize")); - priv->titlebar_max_button = button; - } - else if (strcmp (t[j], "close") == 0 && - priv->deletable && - priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL) - { - button = gtk_button_new (); - image = gtk_image_new_from_icon_name ("window-close-symbolic", GTK_ICON_SIZE_MENU); - gtk_style_context_add_class (gtk_widget_get_style_context (button), "titlebutton"); - g_object_set (image, "use-fallback", TRUE, NULL); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_widget_set_can_focus (button, FALSE); - gtk_widget_show_all (button); - g_signal_connect_swapped (button, "clicked", - G_CALLBACK (gtk_window_close), window); - accessible = gtk_widget_get_accessible (button); - if (GTK_IS_ACCESSIBLE (accessible)) - atk_object_set_name (accessible, _("Close")); - priv->titlebar_close_button = button; - } - - if (button) - gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 0); - } - g_strfreev (t); - } - g_strfreev (tokens); - } - g_free (layout_desc); - if (icon) - g_object_unref (icon); + if (GTK_IS_HEADER_BAR (priv->title_box)) + _gtk_header_bar_update_window_buttons (GTK_HEADER_BAR (priv->title_box)); } static GtkWidget * @@ -5435,7 +5220,7 @@ create_decoration (GtkWidget *widget) priv->title_box = priv->titlebar; } - update_window_buttons (window); + update_csd_visibility (window); } static void @@ -6971,7 +6756,7 @@ gtk_window_state_event (GtkWidget *widget, if (event->changed_mask & (GDK_WINDOW_STATE_FULLSCREEN | GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_TILED)) { update_window_style_classes (window); - update_window_buttons (window); + update_csd_visibility (window); gtk_widget_queue_resize (widget); } @@ -7531,7 +7316,7 @@ gtk_window_button_press_event (GtkWidget *widget, { if (region == GTK_WINDOW_REGION_TITLE) { - gtk_window_toggle_maximized (window); + _gtk_window_toggle_maximized (window); return TRUE; } } @@ -8254,7 +8039,7 @@ gtk_window_do_popup (GtkWindow *window, priv->gdk_type_hint != GDK_WINDOW_TYPE_HINT_NORMAL) gtk_widget_set_sensitive (menuitem, FALSE); g_signal_connect_swapped (G_OBJECT (menuitem), "activate", - G_CALLBACK (gtk_window_toggle_maximized), window); + G_CALLBACK (_gtk_window_toggle_maximized), window); gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem); menuitem = gtk_check_menu_item_new_with_label (_("Always on Top")); @@ -11750,7 +11535,7 @@ _gtk_window_handle_button_press_for_widget (GtkWidget *widget, return TRUE; case GDK_2BUTTON_PRESS: - gtk_window_toggle_maximized (window); + _gtk_window_toggle_maximized (window); return TRUE; default: diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h index a9f431d432..a1b1f8ee42 100644 --- a/gtk/gtkwindowprivate.h +++ b/gtk/gtkwindowprivate.h @@ -92,6 +92,9 @@ gboolean _gtk_window_titlebar_shows_app_menu (GtkWindow *window); void _gtk_window_get_decoration_size (GtkWindow *window, GtkBorder *border); +gboolean _gtk_window_get_maximized (GtkWindow *window); +void _gtk_window_toggle_maximized (GtkWindow *window); + G_END_DECLS #endif /* __GTK_WINDOW_PRIVATE_H__ */