Merge branch 'wip/exalm/headerbar-title' into 'master'

Headerbar title/subtitle cleanups

See merge request GNOME/gtk!1807
This commit is contained in:
Benjamin Otte 2020-05-01 19:39:27 +00:00
commit fa90747815
35 changed files with 290 additions and 527 deletions

View File

@ -9,7 +9,6 @@
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="title" translatable="yes">GTK Constraint Editor</property>
<property name="show-title-buttons">1</property>
<child type="start">
<object class="GtkButton">

View File

@ -257,9 +257,9 @@ do_constraints (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",

View File

@ -213,9 +213,9 @@ do_constraints2 (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",

View File

@ -133,9 +133,9 @@ do_constraints3 (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_signal_connect (window, "destroy",

View File

@ -194,7 +194,7 @@ static void
set_widget_type (GtkFishbowl *fishbowl,
int widget_type_index)
{
GtkWidget *window, *headerbar;
GtkWidget *window;
if (widget_type_index == selected_widget_type)
return;
@ -205,9 +205,8 @@ set_widget_type (GtkFishbowl *fishbowl,
widget_types[selected_widget_type].create_func);
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (fishbowl)));
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window));
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
widget_types[selected_widget_type].name);
gtk_window_set_title (GTK_WINDOW (window),
widget_types[selected_widget_type].name);
}
void

View File

@ -4,10 +4,10 @@
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<property name="title">Font Explorer</property>
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>

View File

@ -2,9 +2,8 @@
*
* GtkHeaderBar is a container that is suitable for implementing
* window titlebars. One of its features is that it can position
* a title (and optional subtitle) centered with regard to the
* full width, regardless of variable-width content at the left
* or right.
* a title centered with regard to the full width, regardless of
* variable-width content at the left or right.
*
* It is commonly used with gtk_window_set_titlebar()
*/
@ -25,14 +24,13 @@ do_headerbar (GtkWidget *do_widget)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Welcome to Facebook - Log in, sign up or learn more");
gtk_header_bar_set_has_subtitle (GTK_HEADER_BAR (header), FALSE);
button = gtk_button_new ();
icon = g_themed_icon_new ("mail-send-receive-symbolic");

View File

@ -17,7 +17,7 @@ static gchar *current_file = NULL;
static GtkWidget *notebook;
static GtkWidget *treeview;
static GtkWidget *headerbar;
static GtkWidget *toplevel;
enum {
NAME_COLUMN,
@ -915,7 +915,7 @@ selection_cb (GtkTreeSelection *selection,
if (filename)
load_file (name, filename);
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), title);
gtk_window_set_title (GTK_WINDOW (toplevel), title);
g_free (name);
g_free (title);
@ -1030,9 +1030,9 @@ activate (GApplication *app)
info_view = (GtkWidget *)gtk_builder_get_object (builder, "info-textview");
source_view = (GtkWidget *)gtk_builder_get_object (builder, "source-textview");
headerbar = (GtkWidget *)gtk_builder_get_object (builder, "headerbar");
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
toplevel = GTK_WIDGET (window);
load_file (gtk_demos[0].name, gtk_demos[0].filename);

View File

@ -31,7 +31,6 @@
</style>
<property name="default-width">800</property>
<property name="default-height">600</property>
<property name="title">GTK Demo</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="show-title-buttons">1</property>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="title" translatable="yes">Model Button</property>
<property name="resizable">0</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<property name="title" translatable="yes">Model Button</property>
</object>
</child>
<child>

View File

@ -392,7 +392,6 @@ do_paint (GtkWidget *toplevel)
gtk_container_add (GTK_CONTAINER (window), draw_area);
headerbar = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), "Paint");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
colorbutton = gtk_color_button_new ();
@ -405,6 +404,7 @@ do_paint (GtkWidget *toplevel)
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_title (GTK_WINDOW (window), "Paint");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);

View File

@ -40,9 +40,9 @@ do_password_entry (GtkWidget *do_widget)
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Choose a Password");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_title (GTK_WINDOW (window), "Choose a Password");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_deletable (GTK_WINDOW (window), FALSE);
g_signal_connect (window, "destroy",

View File

@ -276,13 +276,12 @@ do_peg_solitaire (GtkWidget *do_widget)
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Peg Solitaire");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Sliding Puzzle");
gtk_window_set_title (GTK_WINDOW (window), "Peg Solitaire");
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
g_signal_connect (window, "destroy",

View File

@ -67,9 +67,9 @@ do_tagged_entry (GtkWidget *do_widget)
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
header = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "A tagged entry");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_title (GTK_WINDOW (window), "A tagged entry");
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_deletable (GTK_WINDOW (window), FALSE);
g_signal_connect (window, "destroy",

View File

@ -97,7 +97,6 @@ change_theme (GtkWidget *widget,
gpointer data)
{
GtkBuilder *builder = data;
GtkWidget *header;
GtkWidget *label;
Theme next = themes[theme++ % G_N_ELEMENTS (themes)];
char *name;
@ -107,9 +106,8 @@ change_theme (GtkWidget *widget,
"gtk-application-prefer-dark-theme", next.dark,
NULL);
header = GTK_WIDGET (gtk_builder_get_object (builder, "header"));
name = g_strconcat (next.name, next.dark ? " (dark)" : NULL, NULL);
gtk_header_bar_set_title (GTK_HEADER_BAR (header), name);
gtk_window_set_title (GTK_WINDOW (widget), name);
g_free (name);
label = GTK_WIDGET (gtk_builder_get_object (builder, "fps"));

View File

@ -75,7 +75,6 @@ do_video_player (GtkWidget *do_widget)
title = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (title), TRUE);
gtk_header_bar_set_title (GTK_HEADER_BAR (title), "Video Player");
gtk_window_set_titlebar (GTK_WINDOW (window), title);
open_button = gtk_button_new_with_mnemonic ("_Open");

View File

@ -25,7 +25,6 @@
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="title" translatable="yes">Icon Browser</property>
<property name="show-title-buttons">1</property>
<child type="title">
<object class="GtkBox">

View File

@ -86,7 +86,6 @@
<property name="focus-widget">text_view</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="title" translatable="yes">GTK Node Editor</property>
<property name="show-title-buttons">1</property>
<child type="start">
<object class="GtkButton">
@ -120,11 +119,6 @@
<property name="popover">testcase_popover</property>
</object>
</child>
<child type="title">
<object class="GtkLabel">
<property name="label" translatable="yes">GTK Node Editor</property>
</object>
</child>
</object>
</child>
<child>

View File

@ -5579,14 +5579,8 @@ gtk_action_bar_get_type
<TITLE>GtkHeaderBar</TITLE>
GtkHeaderBar
gtk_header_bar_new
gtk_header_bar_set_title
gtk_header_bar_get_title
gtk_header_bar_set_subtitle
gtk_header_bar_get_subtitle
gtk_header_bar_set_has_subtitle
gtk_header_bar_get_has_subtitle
gtk_header_bar_set_custom_title
gtk_header_bar_get_custom_title
gtk_header_bar_set_title_widget
gtk_header_bar_get_title_widget
gtk_header_bar_pack_start
gtk_header_bar_pack_end
gtk_header_bar_set_show_title_buttons

View File

@ -1122,13 +1122,12 @@ create_headerbar (void)
GtkWidget *button;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (bar), "Header Bar");
view = gtk_text_view_new ();
gtk_widget_show (view);
gtk_widget_set_size_request (window, 220, 150);
gtk_container_add (GTK_CONTAINER (window), view);
bar = gtk_header_bar_new ();
gtk_header_bar_set_title (GTK_HEADER_BAR (bar), "Header Bar");
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (bar), "(subtitle)");
gtk_window_set_titlebar (GTK_WINDOW (window), bar);
button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (button), gtk_image_new_from_icon_name ("bookmark-new-symbolic"));

View File

@ -15,8 +15,6 @@ new_window (GApplication *app,
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
header = gtk_header_bar_new ();
gtk_widget_show (header);
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Sunny");
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);

View File

@ -48,6 +48,7 @@
#include "gtkmessagedialog.h"
#include "gtksettings.h"
#include "gtklabel.h"
#include "gtkbox.h"
#include "gtkbutton.h"
#include "gtkentry.h"
#include "gtktogglebutton.h"
@ -55,6 +56,7 @@
#include "gtkdialogprivate.h"
#include "gtksearchbar.h"
#include "gtksizegroup.h"
#include "gtkstylecontext.h"
#include <string.h>
#include <glib/gi18n-lib.h>
@ -222,9 +224,29 @@ set_dialog_properties (GtkAppChooserDialog *self)
g_object_get (self, "use-header-bar", &use_header, NULL);
if (use_header)
{
GtkWidget *box, *label;
header = gtk_dialog_get_header_bar (GTK_DIALOG (self));
gtk_header_bar_set_title (GTK_HEADER_BAR (header), title);
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (header), subtitle);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
label = gtk_label_new (title);
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 5);
gtk_widget_add_css_class (label, GTK_STYLE_CLASS_TITLE);
gtk_widget_set_parent (label, box);
label = gtk_label_new (subtitle);
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_widget_add_css_class (label, GTK_STYLE_CLASS_SUBTITLE);
gtk_widget_set_parent (label, box);
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), box);
}
else
{

View File

@ -37,6 +37,7 @@
#include "gtkdialogprivate.h"
#include "gtklabel.h"
#include "gtkfilechooserentry.h"
#include "gtkbox.h"
#include <stdarg.h>
@ -430,6 +431,19 @@ add_button (GtkWidget *button, gpointer data)
gtk_size_group_add_widget (priv->buttons, button);
}
static gboolean
translate_subtitle_to_visible (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data)
{
const char *subtitle = g_value_get_string (from_value);
g_value_set_boolean (to_value, subtitle != NULL);
return TRUE;
}
static void
setup_search (GtkFileChooserDialog *dialog)
{
@ -446,6 +460,8 @@ setup_search (GtkFileChooserDialog *dialog)
{
GtkWidget *button;
GtkWidget *header;
GtkWidget *box;
GtkWidget *label;
button = gtk_toggle_button_new ();
gtk_widget_set_focus_on_click (button, FALSE);
@ -459,10 +475,40 @@ setup_search (GtkFileChooserDialog *dialog)
g_object_bind_property (button, "active",
priv->widget, "search-mode",
G_BINDING_BIDIRECTIONAL);
g_object_bind_property (priv->widget, "subtitle",
header, "subtitle",
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_valign (box, GTK_ALIGN_CENTER);
label = gtk_label_new (NULL);
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 5);
gtk_widget_add_css_class (label, GTK_STYLE_CLASS_TITLE);
gtk_widget_set_parent (label, box);
g_object_bind_property (dialog, "title",
label, "label",
G_BINDING_SYNC_CREATE);
label = gtk_label_new (NULL);
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_widget_add_css_class (label, GTK_STYLE_CLASS_SUBTITLE);
gtk_widget_set_parent (label, box);
g_object_bind_property (priv->widget, "subtitle",
label, "label",
G_BINDING_SYNC_CREATE);
g_object_bind_property_full (priv->widget, "subtitle",
label, "visible",
G_BINDING_SYNC_CREATE,
translate_subtitle_to_visible,
NULL, NULL, NULL);
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), box);
gtk_container_forall (GTK_CONTAINER (header), add_button, dialog);
}
}
@ -503,12 +549,12 @@ setup_save_entry (GtkFileChooserDialog *dialog)
gtk_container_add (GTK_CONTAINER (box), label);
gtk_container_add (GTK_CONTAINER (box), entry);
gtk_header_bar_set_custom_title (GTK_HEADER_BAR (header), box);
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), box);
gtk_file_chooser_widget_set_save_entry (GTK_FILE_CHOOSER_WIDGET (priv->widget), entry);
}
else if (!need_entry && priv->has_entry)
{
gtk_header_bar_set_custom_title (GTK_HEADER_BAR (header), NULL);
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), NULL);
gtk_file_chooser_widget_set_save_entry (GTK_FILE_CHOOSER_WIDGET (priv->widget), NULL);
}

View File

@ -45,13 +45,10 @@
* @See_also: #GtkBox, #GtkActionBar
*
* GtkHeaderBar is similar to a horizontal #GtkBox. It allows children to
* be placed at the start or the end. In addition, it allows a title and
* subtitle to be displayed. The title will be centered with respect to
* the width of the box, even if the children at either side take up
* different amounts of space. The height of the titlebar will be
* set to provide sufficient space for the subtitle, even if none is
* currently set. If a subtitle is not needed, the space reservation
* can be turned off with gtk_header_bar_set_has_subtitle().
* be placed at the start or the end. In addition, it allows the window
* title to be displayed. The title will be centered with respect to the
* width of the box, even if the children at either side take up different
* amounts of space.
*
* GtkHeaderBar can add typical window frame controls, such as minimize,
* maximize and close buttons, or the window icon.
@ -60,6 +57,31 @@
* titlebar widget of a #GtkWindow (see gtk_window_set_titlebar()), as it gives
* features typical of titlebars while allowing the addition of child widgets.
*
* The GtkHeaderBar implementation of the #GtkBuildable interface supports
* adding children at the start or end sides by specifying start or end as
* the type attribute of a <child> element, or setting the title widget by
* specifying title value.
*
* By default the GtkHeaderBar uses a #GtkLabel displaying the title of the
* window it is contained in as the title widget, equivalent to the following
* UI definition:
*
* |[
* <object class="GtkHeaderBar">
* <property name="title-widget">
* <object class="GtkLabel">
* <property name="label" translatable="yes">Label</property>
* <property name="single-line-mode">True</property>
* <property name="ellipsize">end</property>
* <property name="width-chars">5</property>
* <style>
* <class name="title"/>
* </style>
* </object>
* </property>
* </object>
* ]|
*
* # CSS nodes
*
* |[<!-- language="plain" -->
@ -67,7 +89,7 @@
* box.start
* windowcontrols.start
* [other children]
* [Custom Title]
* [Title Widget]
* box.end
* [other children]
* windowcontrols.end
@ -101,15 +123,8 @@ struct _GtkHeaderBarPrivate
GtkWidget *start_box;
GtkWidget *end_box;
gchar *title;
gchar *subtitle;
GtkWidget *title_label;
GtkWidget *subtitle_label;
GtkWidget *label_box;
GtkWidget *label_sizing_box;
GtkWidget *subtitle_sizing_label;
GtkWidget *custom_title;
gboolean has_subtitle;
GtkWidget *title_widget;
gboolean show_title_buttons;
gchar *decoration_layout;
@ -123,10 +138,7 @@ struct _GtkHeaderBarPrivate
enum {
PROP_0,
PROP_TITLE,
PROP_SUBTITLE,
PROP_HAS_SUBTITLE,
PROP_CUSTOM_TITLE,
PROP_TITLE_WIDGET,
PROP_SHOW_TITLE_BUTTONS,
PROP_DECORATION_LAYOUT,
LAST_PROP
@ -141,75 +153,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkHeaderBar, gtk_header_bar, GTK_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_header_bar_buildable_init));
static void
init_sizing_box (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
GtkWidget *w;
/* We use this box to always request size for the two labels (title
* and subtitle) as if they were always visible, but then allocate
* the real label box with its actual size, to keep it center-aligned
* in case we have only the title.
*/
w = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
priv->label_sizing_box = g_object_ref_sink (w);
w = gtk_label_new (NULL);
gtk_widget_add_css_class (w, GTK_STYLE_CLASS_TITLE);
gtk_container_add (GTK_CONTAINER (priv->label_sizing_box), w);
gtk_label_set_wrap (GTK_LABEL (w), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (w), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (w), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (w), MIN_TITLE_CHARS);
w = gtk_label_new (NULL);
gtk_widget_add_css_class (w, GTK_STYLE_CLASS_SUBTITLE);
gtk_container_add (GTK_CONTAINER (priv->label_sizing_box), w);
gtk_label_set_wrap (GTK_LABEL (w), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (w), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (w), PANGO_ELLIPSIZE_END);
gtk_widget_set_visible (w, priv->has_subtitle || (priv->subtitle && priv->subtitle[0]));
priv->subtitle_sizing_label = w;
}
static GtkWidget *
create_title_box (const char *title,
const char *subtitle,
GtkWidget **ret_title_label,
GtkWidget **ret_subtitle_label)
{
GtkWidget *label_box;
GtkWidget *title_label;
GtkWidget *subtitle_label;
label_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_valign (label_box, GTK_ALIGN_CENTER);
title_label = gtk_label_new (title);
gtk_widget_add_css_class (title_label, GTK_STYLE_CLASS_TITLE);
gtk_label_set_wrap (GTK_LABEL (title_label), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (title_label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (title_label), PANGO_ELLIPSIZE_END);
gtk_container_add (GTK_CONTAINER (label_box), title_label);
gtk_label_set_width_chars (GTK_LABEL (title_label), MIN_TITLE_CHARS);
subtitle_label = gtk_label_new (subtitle);
gtk_widget_add_css_class (subtitle_label, GTK_STYLE_CLASS_SUBTITLE);
gtk_label_set_wrap (GTK_LABEL (subtitle_label), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (subtitle_label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (subtitle_label), PANGO_ELLIPSIZE_END);
gtk_container_add (GTK_CONTAINER (label_box), subtitle_label);
gtk_widget_set_visible (subtitle_label, subtitle && subtitle[0]);
if (ret_title_label)
*ret_title_label = title_label;
if (ret_subtitle_label)
*ret_subtitle_label = subtitle_label;
return label_box;
}
static void
create_window_controls (GtkHeaderBar *bar)
{
@ -277,7 +220,7 @@ update_default_decoration (GtkHeaderBar *bar)
}
}
if (have_children || priv->custom_title != NULL)
if (have_children || priv->title_widget != NULL)
gtk_widget_remove_css_class (GTK_WIDGET (bar), "default-decoration");
else
gtk_widget_add_css_class (GTK_WIDGET (bar), "default-decoration");
@ -294,147 +237,72 @@ _gtk_header_bar_track_default_decoration (GtkHeaderBar *bar)
}
static void
construct_label_box (GtkHeaderBar *bar)
update_title (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
GtkRoot *root;
const gchar *title = NULL;
if (!priv->title_label)
return;
root = gtk_widget_get_root (GTK_WIDGET (bar));
if (GTK_IS_WINDOW (root))
title = gtk_window_get_title (GTK_WINDOW (root));
if (!title)
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
gtk_label_set_text (GTK_LABEL (priv->title_label), title);
}
static void
construct_title_label (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (bar));
GtkWidget *label;
g_assert (priv->label_box == NULL);
g_assert (priv->title_label == NULL);
priv->label_box = create_title_box (priv->title,
priv->subtitle,
&priv->title_label,
&priv->subtitle_label);
gtk_widget_insert_after (priv->label_box, GTK_WIDGET (bar), priv->start_box);
gtk_center_layout_set_center_widget (GTK_CENTER_LAYOUT (layout), priv->label_box);
label = gtk_label_new (NULL);
gtk_widget_add_css_class (label, GTK_STYLE_CLASS_TITLE);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
gtk_label_set_wrap (GTK_LABEL (label), FALSE);
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), MIN_TITLE_CHARS);
gtk_widget_insert_after (label, GTK_WIDGET (bar), priv->start_box);
gtk_center_layout_set_center_widget (GTK_CENTER_LAYOUT (layout), label);
priv->title_label = label;
update_title (bar);
}
/**
* gtk_header_bar_set_title:
* gtk_header_bar_set_title_widget:
* @bar: a #GtkHeaderBar
* @title: (allow-none): a title, or %NULL
* @title_widget: (allow-none): a widget to use for a title
*
* Sets the title of the #GtkHeaderBar. The title should help a user
* identify the current view. A good title should not include the
* application name.
* Sets the title for the #GtkHeaderBar.
*
* When set to %NULL, the headerbar will display the title of the window it is
* contained in.
*
* The title should help a user identify the current view. To achieve the same
* style as the builtin title, use the title style class.
*
* You should set the title widget to %NULL, for the window title label to be
* visible again.
*/
void
gtk_header_bar_set_title (GtkHeaderBar *bar,
const gchar *title)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
gchar *new_title;
g_return_if_fail (GTK_IS_HEADER_BAR (bar));
new_title = g_strdup (title);
g_free (priv->title);
priv->title = new_title;
if (priv->title_label != NULL)
{
gtk_label_set_label (GTK_LABEL (priv->title_label), priv->title);
gtk_widget_queue_resize (GTK_WIDGET (bar));
}
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_TITLE]);
}
/**
* gtk_header_bar_get_title:
* @bar: a #GtkHeaderBar
*
* Retrieves the title of the header. See gtk_header_bar_set_title().
*
* Returns: (nullable): the title of the header, or %NULL if none has
* been set explicitly. The returned string is owned by the widget
* and must not be modified or freed.
*/
const gchar *
gtk_header_bar_get_title (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
g_return_val_if_fail (GTK_IS_HEADER_BAR (bar), NULL);
return priv->title;
}
/**
* gtk_header_bar_set_subtitle:
* @bar: a #GtkHeaderBar
* @subtitle: (allow-none): a subtitle, or %NULL
*
* Sets the subtitle of the #GtkHeaderBar. The title should give a user
* an additional detail to help him identify the current view.
*
* Note that GtkHeaderBar by default reserves room for the subtitle,
* even if none is currently set. If this is not desired, set the
* #GtkHeaderBar:has-subtitle property to %FALSE.
*/
void
gtk_header_bar_set_subtitle (GtkHeaderBar *bar,
const gchar *subtitle)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
gchar *new_subtitle;
g_return_if_fail (GTK_IS_HEADER_BAR (bar));
new_subtitle = g_strdup (subtitle);
g_free (priv->subtitle);
priv->subtitle = new_subtitle;
if (priv->subtitle_label != NULL)
{
gtk_label_set_label (GTK_LABEL (priv->subtitle_label), priv->subtitle);
gtk_widget_set_visible (priv->subtitle_label, priv->subtitle && priv->subtitle[0]);
gtk_widget_queue_resize (GTK_WIDGET (bar));
}
gtk_widget_set_visible (priv->subtitle_sizing_label, priv->has_subtitle || (priv->subtitle && priv->subtitle[0]));
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_SUBTITLE]);
}
/**
* gtk_header_bar_get_subtitle:
* @bar: a #GtkHeaderBar
*
* Retrieves the subtitle of the header. See gtk_header_bar_set_subtitle().
*
* Returns: (nullable): the subtitle of the header, or %NULL if none has
* been set explicitly. The returned string is owned by the widget
* and must not be modified or freed.
*/
const gchar *
gtk_header_bar_get_subtitle (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
g_return_val_if_fail (GTK_IS_HEADER_BAR (bar), NULL);
return priv->subtitle;
}
/**
* gtk_header_bar_set_custom_title:
* @bar: a #GtkHeaderBar
* @title_widget: (allow-none): a custom widget to use for a title
*
* Sets a custom title for the #GtkHeaderBar.
*
* The title should help a user identify the current view. This
* supersedes any title set by gtk_header_bar_set_title() or
* gtk_header_bar_set_subtitle(). To achieve the same style as
* the builtin title and subtitle, use the title and subtitle
* style classes.
*
* You should set the custom title to %NULL, for the header title
* label to be visible again.
*/
void
gtk_header_bar_set_custom_title (GtkHeaderBar *bar,
gtk_header_bar_set_title_widget (GtkHeaderBar *bar,
GtkWidget *title_widget)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
@ -443,64 +311,74 @@ gtk_header_bar_set_custom_title (GtkHeaderBar *bar,
if (title_widget)
g_return_if_fail (GTK_IS_WIDGET (title_widget));
/* No need to do anything if the custom widget stays the same */
if (priv->custom_title == title_widget)
/* No need to do anything if the title widget stays the same */
if (priv->title_widget == title_widget)
return;
if (priv->custom_title)
{
GtkWidget *custom = priv->custom_title;
priv->custom_title = NULL;
gtk_widget_unparent (custom);
}
g_clear_pointer (&priv->title_widget, gtk_widget_unparent);
if (title_widget != NULL)
{
GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (bar));
priv->custom_title = title_widget;
priv->title_widget = title_widget;
gtk_widget_insert_after (priv->custom_title, GTK_WIDGET (bar), priv->start_box);
gtk_widget_insert_after (priv->title_widget, GTK_WIDGET (bar), priv->start_box);
gtk_center_layout_set_center_widget (GTK_CENTER_LAYOUT (layout), title_widget);
if (priv->label_box != NULL)
{
GtkWidget *label_box = priv->label_box;
priv->label_box = NULL;
priv->title_label = NULL;
priv->subtitle_label = NULL;
gtk_widget_unparent (label_box);
}
g_clear_pointer (&priv->title_label, gtk_widget_unparent);
}
else
{
if (priv->label_box == NULL)
construct_label_box (bar);
if (priv->title_label == NULL)
construct_title_label (bar);
}
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_CUSTOM_TITLE]);
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_TITLE_WIDGET]);
}
/**
* gtk_header_bar_get_custom_title:
* gtk_header_bar_get_title_widget:
* @bar: a #GtkHeaderBar
*
* Retrieves the custom title widget of the header. See
* gtk_header_bar_set_custom_title().
* Retrieves the title widget of the header. See
* gtk_header_bar_set_title_widget().
*
* Returns: (nullable) (transfer none): the custom title widget
* Returns: (nullable) (transfer none): the title widget
* of the header, or %NULL if none has been set explicitly.
*/
GtkWidget *
gtk_header_bar_get_custom_title (GtkHeaderBar *bar)
gtk_header_bar_get_title_widget (GtkHeaderBar *bar)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
g_return_val_if_fail (GTK_IS_HEADER_BAR (bar), NULL);
return priv->custom_title;
return priv->title_widget;
}
static void
gtk_header_bar_root (GtkWidget *widget)
{
GtkWidget *root;
GTK_WIDGET_CLASS (gtk_header_bar_parent_class)->root (widget);
root = GTK_WIDGET (gtk_widget_get_root (widget));
if (GTK_IS_WINDOW (root))
g_signal_connect_swapped (root, "notify::title",
G_CALLBACK (update_title), widget);
update_title (GTK_HEADER_BAR (widget));
}
static void
gtk_header_bar_unroot (GtkWidget *widget)
{
g_signal_handlers_disconnect_by_func (gtk_widget_get_root (widget),
update_title, widget);
GTK_WIDGET_CLASS (gtk_header_bar_parent_class)->unroot (widget);
}
static void
@ -508,14 +386,8 @@ gtk_header_bar_dispose (GObject *object)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (object));
if (priv->label_sizing_box)
{
g_object_ref_sink (priv->label_sizing_box);
g_clear_object (&priv->label_sizing_box);
}
g_clear_pointer (&priv->custom_title, gtk_widget_unparent);
g_clear_pointer (&priv->label_box, gtk_widget_unparent);
g_clear_pointer (&priv->title_widget, gtk_widget_unparent);
g_clear_pointer (&priv->title_label, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_header_bar_parent_class)->dispose (object);
@ -528,8 +400,6 @@ gtk_header_bar_finalize (GObject *object)
{
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (object));
g_free (priv->title);
g_free (priv->subtitle);
g_free (priv->decoration_layout);
G_OBJECT_CLASS (gtk_header_bar_parent_class)->finalize (object);
@ -546,26 +416,14 @@ gtk_header_bar_get_property (GObject *object,
switch (prop_id)
{
case PROP_TITLE:
g_value_set_string (value, priv->title);
break;
case PROP_SUBTITLE:
g_value_set_string (value, priv->subtitle);
break;
case PROP_CUSTOM_TITLE:
g_value_set_object (value, priv->custom_title);
case PROP_TITLE_WIDGET:
g_value_set_object (value, priv->title_widget);
break;
case PROP_SHOW_TITLE_BUTTONS:
g_value_set_boolean (value, gtk_header_bar_get_show_title_buttons (bar));
break;
case PROP_HAS_SUBTITLE:
g_value_set_boolean (value, gtk_header_bar_get_has_subtitle (bar));
break;
case PROP_DECORATION_LAYOUT:
g_value_set_string (value, gtk_header_bar_get_decoration_layout (bar));
break;
@ -586,26 +444,14 @@ gtk_header_bar_set_property (GObject *object,
switch (prop_id)
{
case PROP_TITLE:
gtk_header_bar_set_title (bar, g_value_get_string (value));
break;
case PROP_SUBTITLE:
gtk_header_bar_set_subtitle (bar, g_value_get_string (value));
break;
case PROP_CUSTOM_TITLE:
gtk_header_bar_set_custom_title (bar, g_value_get_object (value));
case PROP_TITLE_WIDGET:
gtk_header_bar_set_title_widget (bar, g_value_get_object (value));
break;
case PROP_SHOW_TITLE_BUTTONS:
gtk_header_bar_set_show_title_buttons (bar, g_value_get_boolean (value));
break;
case PROP_HAS_SUBTITLE:
gtk_header_bar_set_has_subtitle (bar, g_value_get_boolean (value));
break;
case PROP_DECORATION_LAYOUT:
gtk_header_bar_set_decoration_layout (bar, g_value_get_string (value));
break;
@ -702,8 +548,8 @@ gtk_header_bar_forall (GtkContainer *container,
}
}
if (priv->custom_title != NULL)
(* callback) (priv->custom_title, callback_data);
if (priv->title_widget != NULL)
(* callback) (priv->title_widget, callback_data);
if (priv->end_box)
{
@ -738,29 +584,18 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class)
object_class->get_property = gtk_header_bar_get_property;
object_class->set_property = gtk_header_bar_set_property;
widget_class->root = gtk_header_bar_root;
widget_class->unroot = gtk_header_bar_unroot;
container_class->add = gtk_header_bar_add;
container_class->remove = gtk_header_bar_remove;
container_class->forall = gtk_header_bar_forall;
container_class->child_type = gtk_header_bar_child_type;
header_bar_props[PROP_TITLE] =
g_param_spec_string ("title",
P_("Title"),
P_("The title to display"),
NULL,
G_PARAM_READWRITE);
header_bar_props[PROP_SUBTITLE] =
g_param_spec_string ("subtitle",
P_("Subtitle"),
P_("The subtitle to display"),
NULL,
G_PARAM_READWRITE);
header_bar_props[PROP_CUSTOM_TITLE] =
g_param_spec_object ("custom-title",
P_("Custom Title"),
P_("Custom title widget to display"),
header_bar_props[PROP_TITLE_WIDGET] =
g_param_spec_object ("title-widget",
P_("Title Widget"),
P_("Title widget to display"),
GTK_TYPE_WIDGET,
G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS);
@ -798,19 +633,6 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class)
NULL,
GTK_PARAM_READWRITE);
/**
* GtkHeaderBar:has-subtitle:
*
* If %TRUE, reserve space for a subtitle, even if none
* is currently set.
*/
header_bar_props[PROP_HAS_SUBTITLE] =
g_param_spec_boolean ("has-subtitle",
P_("Has Subtitle"),
P_("Whether to reserve space for a subtitle"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, LAST_PROP, header_bar_props);
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_PANEL);
@ -824,10 +646,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar);
GtkLayoutManager *layout;
priv->title = NULL;
priv->subtitle = NULL;
priv->custom_title = NULL;
priv->has_subtitle = TRUE;
priv->title_widget = NULL;
priv->decoration_layout = NULL;
priv->state = GDK_SURFACE_STATE_WITHDRAWN;
@ -841,8 +660,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
gtk_widget_set_parent (priv->end_box, GTK_WIDGET (bar));
gtk_center_layout_set_end_widget (GTK_CENTER_LAYOUT (layout), priv->end_box);
init_sizing_box (bar);
construct_label_box (bar);
construct_title_label (bar);
}
static GtkBuildableIface *parent_buildable_iface;
@ -854,7 +672,7 @@ gtk_header_bar_buildable_add_child (GtkBuildable *buildable,
const gchar *type)
{
if (g_strcmp0 (type, "title") == 0)
gtk_header_bar_set_custom_title (GTK_HEADER_BAR (buildable), GTK_WIDGET (child));
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (buildable), GTK_WIDGET (child));
else if (g_strcmp0 (type, "start") == 0)
gtk_header_bar_pack_start (GTK_HEADER_BAR (buildable), GTK_WIDGET (child));
else if (g_strcmp0 (type, "end") == 0)
@ -971,59 +789,6 @@ gtk_header_bar_set_show_title_buttons (GtkHeaderBar *bar,
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_SHOW_TITLE_BUTTONS]);
}
/**
* gtk_header_bar_set_has_subtitle:
* @bar: a #GtkHeaderBar
* @setting: %TRUE to reserve space for a subtitle
*
* Sets whether the header bar should reserve space
* for a subtitle, even if none is currently set.
*/
void
gtk_header_bar_set_has_subtitle (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->has_subtitle == setting)
return;
priv->has_subtitle = setting;
gtk_widget_set_visible (priv->subtitle_sizing_label, setting || (priv->subtitle && priv->subtitle[0]));
gtk_widget_queue_resize (GTK_WIDGET (bar));
g_object_notify_by_pspec (G_OBJECT (bar), header_bar_props[PROP_HAS_SUBTITLE]);
}
/**
* gtk_header_bar_get_has_subtitle:
* @bar: a #GtkHeaderBar
*
* Retrieves whether the header bar reserves space for
* a subtitle, regardless if one is currently set or not.
*
* Returns: %TRUE if the header bar reserves space
* for a subtitle
*/
gboolean
gtk_header_bar_get_has_subtitle (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->has_subtitle;
}
/**
* gtk_header_bar_set_decoration_layout:
* @bar: a #GtkHeaderBar

View File

@ -38,23 +38,12 @@ GDK_AVAILABLE_IN_ALL
GType gtk_header_bar_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_header_bar_new (void);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_title (GtkHeaderBar *bar,
const gchar *title);
GDK_AVAILABLE_IN_ALL
const gchar *gtk_header_bar_get_title (GtkHeaderBar *bar);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_subtitle (GtkHeaderBar *bar,
const gchar *subtitle);
GDK_AVAILABLE_IN_ALL
const gchar *gtk_header_bar_get_subtitle (GtkHeaderBar *bar);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_custom_title (GtkHeaderBar *bar,
void gtk_header_bar_set_title_widget (GtkHeaderBar *bar,
GtkWidget *title_widget);
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_header_bar_get_custom_title (GtkHeaderBar *bar);
GtkWidget *gtk_header_bar_get_title_widget (GtkHeaderBar *bar);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_pack_start (GtkHeaderBar *bar,
GtkWidget *child);
@ -69,12 +58,6 @@ GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_show_title_buttons (GtkHeaderBar *bar,
gboolean setting);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_has_subtitle (GtkHeaderBar *bar,
gboolean setting);
GDK_AVAILABLE_IN_ALL
gboolean gtk_header_bar_get_has_subtitle (GtkHeaderBar *bar);
GDK_AVAILABLE_IN_ALL
void gtk_header_bar_set_decoration_layout (GtkHeaderBar *bar,
const gchar *layout);

View File

@ -921,7 +921,7 @@ gtk_shortcuts_window_init (GtkShortcutsWindow *self)
priv->title_stack = g_object_new (GTK_TYPE_STACK,
NULL);
gtk_header_bar_set_custom_title (priv->header_bar, GTK_WIDGET (priv->title_stack));
gtk_header_bar_set_title_widget (priv->header_bar, GTK_WIDGET (priv->title_stack));
/* Translators: This is the window title for the shortcuts window in normal mode */
label = gtk_label_new (_("Shortcuts"));

View File

@ -2214,29 +2214,6 @@ gtk_window_new (void)
return g_object_new (GTK_TYPE_WINDOW, NULL);
}
static void
gtk_window_set_title_internal (GtkWindow *window,
const gchar *title,
gboolean update_titlebar)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
char *new_title;
g_return_if_fail (GTK_IS_WINDOW (window));
new_title = g_strdup (title);
g_free (priv->title);
priv->title = new_title;
if (_gtk_widget_get_realized (GTK_WIDGET (window)))
gdk_toplevel_set_title (GDK_TOPLEVEL (priv->surface), new_title != NULL ? new_title : "");
if (update_titlebar && GTK_IS_HEADER_BAR (priv->title_box))
gtk_header_bar_set_title (GTK_HEADER_BAR (priv->title_box), new_title != NULL ? new_title : "");
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_TITLE]);
}
/**
* gtk_window_set_title:
* @window: a #GtkWindow
@ -2254,11 +2231,21 @@ gtk_window_set_title_internal (GtkWindow *window,
**/
void
gtk_window_set_title (GtkWindow *window,
const gchar *title)
const gchar *title)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
char *new_title;
g_return_if_fail (GTK_IS_WINDOW (window));
gtk_window_set_title_internal (window, title, TRUE);
new_title = g_strdup (title);
g_free (priv->title);
priv->title = new_title;
if (_gtk_widget_get_realized (GTK_WIDGET (window)))
gdk_toplevel_set_title (GDK_TOPLEVEL (priv->surface), new_title != NULL ? new_title : "");
g_object_notify_by_pspec (G_OBJECT (window), window_props[PROP_TITLE]);
}
/**
@ -4100,21 +4087,6 @@ gtk_window_finalize (GObject *object)
G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
}
/* copied from gdksurface-x11.c */
static const gchar *
get_default_title (void)
{
const gchar *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
if (!title)
title = "";
return title;
}
static gboolean
update_csd_visibility (GtkWindow *window)
{
@ -4151,15 +4123,8 @@ update_window_actions (GtkWindow *window)
static GtkWidget *
create_titlebar (GtkWindow *window)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
GtkWidget *titlebar;
titlebar = gtk_header_bar_new ();
g_object_set (titlebar,
"title", priv->title ? priv->title : get_default_title (),
"has-subtitle", FALSE,
"show-title-buttons", TRUE,
NULL);
GtkWidget *titlebar = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (titlebar), TRUE);
gtk_widget_add_css_class (titlebar, GTK_STYLE_CLASS_TITLEBAR);
gtk_widget_add_css_class (titlebar, "default-decoration");

View File

@ -733,6 +733,7 @@ maybe_rename_property (Element *element, MyParserData *data)
{ "GtkWidget", "margin-left", GTK_TYPE_WIDGET, PROP_KIND_OBJECT, "margin-start", { NULL, NULL, NULL } },
{ "GtkWidget", "margin-right", GTK_TYPE_WIDGET, PROP_KIND_OBJECT, "margin-end", { NULL, NULL, NULL } },
{ "GtkHeaderBar", "show-close-button", GTK_TYPE_HEADER_BAR, PROP_KIND_OBJECT, "show-title-buttons", { NULL, NULL, NULL } },
{ "GtkHeaderBar", "custom-title", GTK_TYPE_HEADER_BAR, PROP_KIND_OBJECT, "title-widget", { NULL, NULL, NULL } },
{ "GtkStack", "homogeneous", GTK_TYPE_STACK, PROP_KIND_OBJECT, "hhomogeneous", { "vhomogeneous", NULL, NULL } }
};
int i, k, l;

View File

@ -4,7 +4,6 @@
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="show-title-buttons">1</property>
<property name="has-subtitle">0</property>
</object>
</child>
<child>

View File

@ -16,9 +16,9 @@
<property name="type_hint">dialog</property>
<property name="default_width">500</property>
<property name="use_header_bar">1</property>
<property name="title" translatable="yes">Join Chat Room</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="titlebar">
<property name="title" translatable="yes">Join Chat Room</property>
<child>
<object class="GtkButton" id="back_button">
<property name="visible">0</property>

View File

@ -130,7 +130,8 @@ main (int argc, char *argv[])
gtk_init ();
window = gtk_window_new ();
gtk_window_set_titlebar (GTK_WINDOW (window), g_object_new (GTK_TYPE_HEADER_BAR, "visible", TRUE, "title", "GdkGears", NULL));
gtk_window_set_titlebar (GTK_WINDOW (window), gtk_header_bar_new ());
gtk_window_set_title (GTK_WINDOW (window), "GdkGears");
gtk_window_set_default_size (GTK_WINDOW (window), 640, 640);
g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);

View File

@ -36,22 +36,6 @@ on_bookmark_clicked (GtkButton *button, gpointer data)
static GtkWidget *header;
static void
change_subtitle (GtkButton *button, gpointer data)
{
if (!GTK_IS_HEADER_BAR (header))
return;
if (gtk_header_bar_get_subtitle (GTK_HEADER_BAR (header)) == NULL)
{
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (header), "(subtle subtitle)");
}
else
{
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (header), NULL);
}
}
static void
toggle_fullscreen (GtkButton *button, gpointer data)
{
@ -111,7 +95,6 @@ change_header (GtkButton *button, gpointer data)
{
header = gtk_header_bar_new ();
gtk_widget_add_css_class (header, "titlebar");
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Example header");
widget = gtk_button_new_with_label ("_Close");
gtk_button_set_use_underline (GTK_BUTTON (widget), TRUE);
@ -168,9 +151,6 @@ main (int argc, char *argv[])
button = gtk_toggle_button_new_with_label ("Custom");
g_signal_connect (button, "clicked", G_CALLBACK (change_header), window);
gtk_action_bar_pack_start (GTK_ACTION_BAR (footer), button);
button = gtk_button_new_with_label ("Subtitle");
g_signal_connect (button, "clicked", G_CALLBACK (change_subtitle), NULL);
gtk_action_bar_pack_end (GTK_ACTION_BAR (footer), button);
button = gtk_button_new_with_label ("Fullscreen");
gtk_action_bar_pack_end (GTK_ACTION_BAR (footer), button);
g_signal_connect (button, "clicked", G_CALLBACK (toggle_fullscreen), window);

View File

@ -2,8 +2,6 @@
<object class="GtkWindow" id="window1">
<child>
<object class="GtkHeaderBar" id="headerbar1">
<property name="title">Title</property>
<property name="subtitle">Subtitle</property>
<child type="start">
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Yes</property>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar1">
<property name="show-title-buttons">1</property>
<property name="title-widget">box1</property>
</object>
</child>
</object>
<object class="GtkBox" id="box1"/>
</interface>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkWindow" id="window1">
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar1">
<property name="visible">True</property>
<property name="show-close-button">True</property>
<property name="custom-title">box1</property>
</object>
</child>
</object>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
</object>
</interface>