forked from AuroraMiddleware/gtk
window: Allow theme control over window buttons
Add a style property to control the presence and order of window buttons. We allow buttons at the left and right side, they can be specified like this: icon,close:minimize,maximize. Also, change the default button layout back to have just a close button on the right, use icons in buttons, and set style classes on the buttons, to allow better theming.
This commit is contained in:
parent
7d71f8888d
commit
037b1435ae
209
gtk/gtkwindow.c
209
gtk/gtkwindow.c
@ -1025,6 +1025,13 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
|
||||
/* Style properties.
|
||||
*/
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_string ("decoration-button-layout",
|
||||
P_("Decorated button layout"),
|
||||
P_("Decorated button layout"),
|
||||
":close",
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("resize-grip-width",
|
||||
P_("Width of resize grip"),
|
||||
@ -3582,6 +3589,36 @@ icon_list_from_theme (GtkWidget *widget,
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
set_title_icon (GtkWindow *window, GList *list)
|
||||
{
|
||||
GtkWindowPrivate *priv = window->priv;
|
||||
|
||||
if (priv->title_icon && list != NULL)
|
||||
{
|
||||
GdkPixbuf *pixbuf, *best;
|
||||
GList *l;
|
||||
|
||||
best = NULL;
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
pixbuf = list->data;
|
||||
if (gdk_pixbuf_get_width (pixbuf) <= 20)
|
||||
{
|
||||
best = g_object_ref (pixbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (best == NULL)
|
||||
best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), 20, 20, GDK_INTERP_BILINEAR);
|
||||
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (priv->title_icon), best);
|
||||
g_object_unref (best);
|
||||
|
||||
gtk_widget_show (priv->title_icon);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_realize_icon (GtkWindow *window)
|
||||
@ -3643,13 +3680,14 @@ gtk_window_realize_icon (GtkWindow *window)
|
||||
{
|
||||
icon_list = icon_list_from_theme (widget, default_icon_name);
|
||||
info->using_default_icon = TRUE;
|
||||
info->using_themed_icon = TRUE;
|
||||
info->using_themed_icon = TRUE;
|
||||
}
|
||||
|
||||
info->realized = TRUE;
|
||||
|
||||
gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list);
|
||||
|
||||
set_title_icon (window, icon_list);
|
||||
|
||||
if (info->using_themed_icon)
|
||||
{
|
||||
GtkIconTheme *icon_theme;
|
||||
@ -4867,39 +4905,138 @@ update_window_buttons (GtkWindow *window)
|
||||
{
|
||||
GtkWindowPrivate *priv = window->priv;
|
||||
|
||||
if (priv->client_decorated)
|
||||
if (priv->decorated &&
|
||||
priv->client_decorated &&
|
||||
priv->title_box != NULL)
|
||||
{
|
||||
if (priv->title_box != NULL)
|
||||
gtk_widget_show (priv->title_box);
|
||||
gchar *layout_desc;
|
||||
gchar **tokens, **t;
|
||||
gint i, j;
|
||||
GdkPixbuf *icon = NULL;
|
||||
|
||||
if (priv->title_min_button != NULL)
|
||||
if (priv->title_icon)
|
||||
{
|
||||
if (priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
|
||||
gtk_widget_show (priv->title_min_button);
|
||||
else
|
||||
gtk_widget_hide (priv->title_min_button);
|
||||
icon = gtk_image_get_pixbuf (GTK_IMAGE (priv->title_icon));
|
||||
if (icon)
|
||||
g_object_ref (icon);
|
||||
gtk_widget_destroy (priv->title_icon);
|
||||
priv->title_icon = NULL;
|
||||
}
|
||||
if (priv->title_min_button)
|
||||
{
|
||||
gtk_widget_destroy (priv->title_min_button);
|
||||
priv->title_min_button = NULL;
|
||||
}
|
||||
if (priv->title_max_button)
|
||||
{
|
||||
gtk_widget_destroy (priv->title_max_button);
|
||||
priv->title_max_button = NULL;
|
||||
}
|
||||
if (priv->title_close_button)
|
||||
{
|
||||
gtk_widget_destroy (priv->title_close_button);
|
||||
priv->title_close_button = NULL;
|
||||
}
|
||||
|
||||
if (priv->title_max_button != NULL)
|
||||
{
|
||||
if (priv->resizable &&
|
||||
priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
|
||||
gtk_widget_show (priv->title_max_button);
|
||||
else
|
||||
gtk_widget_hide (priv->title_max_button);
|
||||
}
|
||||
gtk_widget_style_get (GTK_WIDGET (window),
|
||||
"decoration-button-layout", &layout_desc,
|
||||
NULL);
|
||||
|
||||
if (priv->title_close_button != NULL)
|
||||
tokens = g_strsplit (layout_desc, ":", 2);
|
||||
if (tokens)
|
||||
{
|
||||
if (priv->deletable &&
|
||||
priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
|
||||
gtk_widget_show_all (priv->title_close_button);
|
||||
else
|
||||
gtk_widget_hide (priv->title_close_button);
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (tokens[i] == NULL)
|
||||
continue;
|
||||
|
||||
if (priv->title_label != NULL)
|
||||
gtk_widget_show (priv->title_label);
|
||||
t = g_strsplit (tokens[i], ",", -1);
|
||||
for (j = 0; t[j]; j++)
|
||||
{
|
||||
GtkWidget *button = NULL;
|
||||
|
||||
if (strcmp (t[j], "icon") == 0)
|
||||
{
|
||||
button = gtk_image_new ();
|
||||
gtk_widget_set_size_request (button, 20, 20);
|
||||
gtk_widget_show (button);
|
||||
if (icon != NULL)
|
||||
{
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (button), icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
else
|
||||
gtk_widget_hide (button);
|
||||
|
||||
priv->title_icon = button;
|
||||
}
|
||||
else if (strcmp (t[j], "minimize") == 0 &&
|
||||
priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
|
||||
{
|
||||
button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (button),
|
||||
gtk_image_new_from_icon_name ("window-minimize", GTK_ICON_SIZE_MENU));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "window-minimize-button");
|
||||
gtk_widget_set_can_focus (button, FALSE);
|
||||
gtk_widget_show_all (button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_min_clicked), window);
|
||||
priv->title_min_button = button;
|
||||
}
|
||||
else if (strcmp (t[j], "maximize") == 0 &&
|
||||
priv->resizable &&
|
||||
priv->gdk_type_hint == GDK_WINDOW_TYPE_HINT_NORMAL)
|
||||
{
|
||||
GdkWindow *win;
|
||||
gboolean maximized;
|
||||
const gchar *icon_name;
|
||||
|
||||
win = gtk_widget_get_window (GTK_WIDGET (window));
|
||||
if (win != NULL)
|
||||
maximized = gdk_window_get_state (win) & GDK_WINDOW_STATE_MAXIMIZED;
|
||||
else
|
||||
maximized = FALSE;
|
||||
icon_name = maximized ? "window-restore" : "window-maximize";
|
||||
button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (button),
|
||||
gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "window-maximize-button");
|
||||
gtk_widget_set_can_focus (button, FALSE);
|
||||
gtk_widget_show_all (button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_max_clicked), window);
|
||||
priv->title_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 ();
|
||||
gtk_container_add (GTK_CONTAINER (button),
|
||||
gtk_image_new_from_icon_name ("window-delete", GTK_ICON_SIZE_MENU));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (button), "window-close-button");
|
||||
gtk_widget_set_can_focus (button, FALSE);
|
||||
gtk_widget_show_all (button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_close_clicked), window);
|
||||
priv->title_close_button = button;
|
||||
}
|
||||
|
||||
if (button)
|
||||
{
|
||||
if (i == 0)
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (priv->title_box), button);
|
||||
else
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->title_box), button);
|
||||
}
|
||||
}
|
||||
g_strfreev (t);
|
||||
}
|
||||
g_strfreev (tokens);
|
||||
}
|
||||
g_free (layout_desc);
|
||||
|
||||
gtk_widget_show (priv->title_box);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4961,24 +5098,6 @@ create_decoration (GtkWidget *widget)
|
||||
title = get_default_title ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (priv->title_box), title);
|
||||
|
||||
priv->title_min_button = gtk_button_new_with_label ("_");
|
||||
gtk_widget_set_can_focus (priv->title_min_button, FALSE);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->title_box), priv->title_min_button);
|
||||
g_signal_connect (priv->title_min_button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_min_clicked), window);
|
||||
|
||||
priv->title_max_button = gtk_button_new_with_label ("\342\226\253");
|
||||
gtk_widget_set_can_focus (priv->title_max_button, FALSE);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->title_box), priv->title_max_button);
|
||||
g_signal_connect (priv->title_max_button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_max_clicked), window);
|
||||
|
||||
priv->title_close_button = gtk_button_new_with_label ("×");
|
||||
gtk_widget_set_can_focus (priv->title_close_button, FALSE);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->title_box), priv->title_close_button);
|
||||
g_signal_connect (priv->title_close_button, "clicked",
|
||||
G_CALLBACK (gtk_window_title_close_clicked), window);
|
||||
|
||||
gtk_widget_show_all (priv->title_box);
|
||||
|
||||
update_window_buttons (window);
|
||||
|
Loading…
Reference in New Issue
Block a user