Add gtk_window_set_titlebar

A new function that sets a custom titlebar on a GtkWindow.
With client-side decorations, the custom titlebar simply
replaces the one that GtkWindow would otherwise create itself.
With traditional decorations, we tell the window manager
to just decorate the window with a border. This works ok
at least with metacity and mutter.
This commit is contained in:
Matthias Clasen 2013-03-18 08:38:02 -04:00
parent 105c808d0a
commit 4afbaf699f
2 changed files with 94 additions and 48 deletions

View File

@ -200,6 +200,7 @@ struct _GtkWindowPrivate
*/
guint gravity : 5; /* GdkGravity */
guint client_decorated : 1; /* Decorations drawn client-side */
guint custom_title : 1; /* app-provided titlebar */
guint fullscreen : 1;
};
@ -3414,6 +3415,35 @@ gtk_window_set_geometry_hints (GtkWindow *window,
gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
}
void
gtk_window_set_titlebar (GtkWindow *window,
GtkWidget *titlebar)
{
GtkWidget *widget = GTK_WIDGET (window);
GtkWindowPrivate *priv = window->priv;
GdkVisual *visual;
g_return_if_fail (GTK_IS_WINDOW (window));
if (priv->title_box != NULL)
{
gtk_widget_unparent (priv->title_box);
priv->title_box = NULL;
priv->title_icon = NULL;
priv->title_min_button = NULL;
priv->title_max_button = NULL;
priv->title_close_button = NULL;
}
priv->custom_title = TRUE;
priv->title_box = titlebar;
gtk_widget_set_parent (priv->title_box, widget);
visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget));
if (visual)
gtk_widget_set_visual (widget, visual);
}
/**
* gtk_window_set_decorated:
* @window: a #GtkWindow
@ -3453,12 +3483,17 @@ gtk_window_set_decorated (GtkWindow *window,
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
if (gdk_window)
{
if (priv->decorated && !priv->client_decorated)
gdk_window_set_decorations (gdk_window,
GDK_DECOR_ALL);
if (priv->decorated)
{
if (priv->client_decorated)
gdk_window_set_decorations (gdk_window, 0);
else if (priv->custom_title)
gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
else
gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL);
}
else
gdk_window_set_decorations (gdk_window,
0);
gdk_window_set_decorations (gdk_window, 0);
}
update_window_buttons (window);
@ -4942,6 +4977,9 @@ update_window_buttons (GtkWindow *window)
{
GtkWindowPrivate *priv = window->priv;
if (priv->custom_title)
return;
if (priv->decorated &&
priv->client_decorated &&
priv->title_box != NULL)
@ -5122,23 +5160,26 @@ create_decoration (GtkWidget *widget)
if (!priv->client_decorated)
return;
priv->title_box = gtk_header_bar_new ();
g_object_set (priv->title_box,
"spacing", 0,
"hpadding", 0,
"vpadding", 0,
NULL);
context = gtk_widget_get_style_context (priv->title_box);
gtk_style_context_add_class (context, "titlebar");
gtk_widget_set_parent (priv->title_box, GTK_WIDGET (window));
if (priv->title_box == NULL)
{
priv->title_box = gtk_header_bar_new ();
g_object_set (priv->title_box,
"spacing", 0,
"hpadding", 0,
"vpadding", 0,
NULL);
context = gtk_widget_get_style_context (priv->title_box);
gtk_style_context_add_class (context, "titlebar");
gtk_widget_set_parent (priv->title_box, GTK_WIDGET (window));
if (priv->title)
title = priv->title;
else
title = get_default_title ();
gtk_header_bar_set_title (GTK_HEADER_BAR (priv->title_box), title);
if (priv->title)
title = priv->title;
else
title = get_default_title ();
gtk_header_bar_set_title (GTK_HEADER_BAR (priv->title_box), title);
gtk_widget_show_all (priv->title_box);
gtk_widget_show_all (priv->title_box);
}
update_window_buttons (window);
}
@ -5630,7 +5671,8 @@ gtk_window_realize (GtkWidget *widget)
GDK_FOCUS_CHANGE_MASK |
GDK_STRUCTURE_MASK);
if (priv->decorated && priv->client_decorated)
if (priv->decorated &&
(priv->client_decorated || priv->custom_title))
attributes.event_mask |= GDK_POINTER_MOTION_MASK;
attributes.type_hint = priv->type_hint;
@ -5663,6 +5705,8 @@ gtk_window_realize (GtkWidget *widget)
if (!priv->decorated || priv->client_decorated)
gdk_window_set_decorations (gdk_window, 0);
else if (priv->custom_title)
gdk_window_set_decorations (gdk_window, GDK_DECOR_BORDER);
if (!priv->deletable)
gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
@ -6028,10 +6072,12 @@ _gtk_window_set_allocation (GtkWindow *window,
gtk_widget_set_allocation (widget, allocation);
if (priv->title_box != NULL)
if (priv->title_box != NULL && priv->client_decorated)
get_decoration_borders (widget, &title_border, &window_border, NULL);
else
else if (priv->client_decorated)
get_decoration_borders (widget, NULL, &window_border, NULL);
else if (priv->title_box != NULL)
get_decoration_borders (widget, &title_border, NULL, NULL);
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
@ -6043,7 +6089,6 @@ _gtk_window_set_allocation (GtkWindow *window,
child_allocation.height = MAX (1, child_allocation.height - border_width * 2);
if (priv->title_box != NULL &&
priv->client_decorated &&
priv->decorated &&
!priv->fullscreen)
{
@ -6066,8 +6111,7 @@ _gtk_window_set_allocation (GtkWindow *window,
gtk_widget_size_allocate (priv->title_box, &title_allocation);
}
if (priv->client_decorated &&
priv->decorated &&
if (priv->decorated &&
!priv->fullscreen)
{
child_allocation.x += window_border.left;
@ -6650,10 +6694,13 @@ get_region_type (GtkWindow *window, gint x, gint y)
if (priv->title_box)
title_height = gtk_widget_get_allocated_height (priv->title_box);
get_decoration_borders (widget, NULL, &window_border, NULL);
gtk_widget_style_get (widget,
"decoration-resize-handle", &resize_handle,
NULL);
if (priv->client_decorated)
{
get_decoration_borders (widget, NULL, &window_border, NULL);
gtk_widget_style_get (widget,
"decoration-resize-handle", &resize_handle,
NULL);
}
if (x < window_border.left)
{
@ -6708,10 +6755,11 @@ get_active_region_type (GtkWindow *window, gint x, gint y)
GtkWindowRegion region;
gboolean resize_h, resize_v;
gint state;
GtkBorder window_border;
GtkBorder window_border = { 0 };
region = get_region_type (window, x, y);
get_decoration_borders (widget, NULL, &window_border, NULL);
if (priv->client_decorated)
get_decoration_borders (widget, NULL, &window_border, NULL);
state = gdk_window_get_state (gtk_widget_get_window (widget));
if (!priv->resizable || (state & GDK_WINDOW_STATE_MAXIMIZED))
@ -6822,8 +6870,7 @@ gtk_window_button_press_event (GtkWidget *widget,
return TRUE;
}
else if (priv->client_decorated &&
priv->decorated &&
else if (priv->decorated &&
priv->title_box != NULL &&
!priv->fullscreen)
{
@ -7093,8 +7140,8 @@ gtk_window_forall (GtkContainer *container,
if (child != NULL)
(* callback) (child, callback_data);
if (include_internals &&
priv->title_box != NULL)
if (priv->title_box != NULL &&
(priv->custom_title || include_internals))
(* callback) (priv->title_box, callback_data);
}
@ -7387,8 +7434,7 @@ gtk_window_get_preferred_width (GtkWidget *widget,
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
if (priv->client_decorated &&
priv->decorated &&
if (priv->decorated &&
!priv->fullscreen)
{
if (priv->title_box != NULL)
@ -7397,7 +7443,7 @@ gtk_window_get_preferred_width (GtkWidget *widget,
&title_min, &title_nat);
get_decoration_borders (widget, &title_border, &window_border, NULL);
}
else
else if (priv->client_decorated)
{
get_decoration_borders (widget, NULL, &window_border, NULL);
}
@ -7445,8 +7491,7 @@ gtk_window_get_preferred_width_for_height (GtkWidget *widget,
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
if (priv->client_decorated &&
priv->decorated &&
if (priv->decorated &&
!priv->fullscreen)
{
if (priv->title_box != NULL)
@ -7456,7 +7501,7 @@ gtk_window_get_preferred_width_for_height (GtkWidget *widget,
&title_min, &title_nat);
get_decoration_borders (widget, &title_border, &window_border, NULL);
}
else
else if (priv->client_decorated)
{
get_decoration_borders (widget, NULL, &window_border, NULL);
}
@ -7507,8 +7552,7 @@ gtk_window_get_preferred_height (GtkWidget *widget,
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
if (priv->client_decorated &&
priv->decorated &&
if (priv->decorated &&
!priv->fullscreen)
{
if (priv->title_box != NULL)
@ -7518,7 +7562,7 @@ gtk_window_get_preferred_height (GtkWidget *widget,
&title_height);
get_decoration_borders (widget, &title_border, &window_border, NULL);
}
else
else if (priv->client_decorated)
{
get_decoration_borders (widget, NULL, &window_border, NULL);
}
@ -7567,8 +7611,7 @@ gtk_window_get_preferred_height_for_width (GtkWidget *widget,
border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
if (priv->client_decorated &&
priv->decorated &&
if (priv->decorated &&
!priv->fullscreen)
{
if (priv->title_box != NULL)
@ -7579,7 +7622,7 @@ gtk_window_get_preferred_height_for_width (GtkWidget *widget,
&title_height);
get_decoration_borders (widget, &title_border, &window_border, NULL);
}
else
else if (priv->client_decorated)
{
get_decoration_borders (widget, NULL, &window_border, NULL);
}

View File

@ -348,6 +348,9 @@ gboolean gtk_window_resize_grip_is_visible (GtkWindow *window);
gboolean gtk_window_get_resize_grip_area (GtkWindow *window,
GdkRectangle *rect);
void gtk_window_set_titlebar (GtkWindow *window,
GtkWidget *titlebar);
G_END_DECLS
#endif /* __GTK_WINDOW_H__ */