diff options
Diffstat (limited to 'subprojects/libhandy/src/hdy-window.c')
-rw-r--r-- | subprojects/libhandy/src/hdy-window.c | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/subprojects/libhandy/src/hdy-window.c b/subprojects/libhandy/src/hdy-window.c new file mode 100644 index 0000000..1a868d7 --- /dev/null +++ b/subprojects/libhandy/src/hdy-window.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 Alexander Mikhaylenko <alexm@gnome.org> + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include "hdy-window.h" +#include "hdy-window-mixin-private.h" + +/** + * SECTION:hdy-window + * @short_description: A freeform window. + * @title: HdyWindow + * @See_also: #HdyApplicationWindow, #HdyHeaderBar, #HdyWindowHandle + * + * The HdyWindow widget is a subclass of #GtkWindow which has no titlebar area + * and provides rounded corners on all sides, ensuring they can never be + * overlapped by the content. This makes it safe to use headerbars in the + * content area as follows: + * + * |[ + * <object class="HdyWindow"/> + * <child> + * <object class="GtkBox"> + * <property name="visible">True</property> + * <property name="orientation">vertical</property> + * <child> + * <object class="HdyHeaderBar"> + * <property name="visible">True</property> + * <property name="show-close-button">True</property> + * </object> + * </child> + * <child> + * ... + * </child> + * </object> + * </child> + * </object> + * ]| + * + * It's recommended to use #HdyHeaderBar with #HdyWindow, as unlike + * #GtkHeaderBar it remains draggable inside the window. Otherwise, + * #HdyWindowHandle can be used. + * + * #HdyWindow allows to easily implement titlebar autohiding by putting the + * headerbar inside a #GtkRevealer, and to show titlebar above content by + * putting it into a #GtkOverlay instead of #GtkBox. + * + * if the window has a #GtkGLArea, it may bring a slight performance regression + * when the window is not fullscreen, tiled or maximized. + * + * Using gtk_window_get_titlebar() and gtk_window_set_titlebar() is not + * supported and will result in a crash. + * + * # CSS nodes + * + * #HdyWindow has a main CSS node with the name window and style classes + * .background, .csd and .unified. + * + * The .solid-csd style class on the main node is used for client-side + * decorations without invisible borders. + * + * #HdyWindow also represents window states with the following + * style classes on the main node: .tiled, .maximized, .fullscreen. + * + * It contains the subnodes decoration for window shadow and/or border, + * decoration-overlay for the sheen on top of the window, widget.titlebar, and + * deck, which contains the child inside the window. + * + * Since: 1.0 + */ + +typedef struct +{ + HdyWindowMixin *mixin; +} HdyWindowPrivate; + +static void hdy_window_buildable_init (GtkBuildableIface *iface); + +G_DEFINE_TYPE_WITH_CODE (HdyWindow, hdy_window, GTK_TYPE_WINDOW, + G_ADD_PRIVATE (HdyWindow) + G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, hdy_window_buildable_init)) + +#define HDY_GET_WINDOW_MIXIN(obj) (((HdyWindowPrivate *) hdy_window_get_instance_private (HDY_WINDOW (obj)))->mixin) + +static void +hdy_window_add (GtkContainer *container, + GtkWidget *widget) +{ + hdy_window_mixin_add (HDY_GET_WINDOW_MIXIN (container), widget); +} + +static void +hdy_window_remove (GtkContainer *container, + GtkWidget *widget) +{ + hdy_window_mixin_remove (HDY_GET_WINDOW_MIXIN (container), widget); +} + +static void +hdy_window_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + hdy_window_mixin_forall (HDY_GET_WINDOW_MIXIN (container), + include_internals, + callback, + callback_data); +} + +static gboolean +hdy_window_draw (GtkWidget *widget, + cairo_t *cr) +{ + return hdy_window_mixin_draw (HDY_GET_WINDOW_MIXIN (widget), cr); +} + +static void +hdy_window_destroy (GtkWidget *widget) +{ + hdy_window_mixin_destroy (HDY_GET_WINDOW_MIXIN (widget)); +} + +static void +hdy_window_finalize (GObject *object) +{ + HdyWindow *self = (HdyWindow *)object; + HdyWindowPrivate *priv = hdy_window_get_instance_private (self); + + g_clear_object (&priv->mixin); + + G_OBJECT_CLASS (hdy_window_parent_class)->finalize (object); +} + +static void +hdy_window_class_init (HdyWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + + object_class->finalize = hdy_window_finalize; + widget_class->draw = hdy_window_draw; + widget_class->destroy = hdy_window_destroy; + container_class->add = hdy_window_add; + container_class->remove = hdy_window_remove; + container_class->forall = hdy_window_forall; +} + +static void +hdy_window_init (HdyWindow *self) +{ + HdyWindowPrivate *priv = hdy_window_get_instance_private (self); + + priv->mixin = hdy_window_mixin_new (GTK_WINDOW (self), + GTK_WINDOW_CLASS (hdy_window_parent_class)); +} + +static void +hdy_window_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type) +{ + hdy_window_mixin_buildable_add_child (HDY_GET_WINDOW_MIXIN (buildable), + builder, + child, + type); +} + +static void +hdy_window_buildable_init (GtkBuildableIface *iface) +{ + iface->add_child = hdy_window_buildable_add_child; +} + +/** + * hdy_window_new: + * + * Creates a new #HdyWindow. + * + * Returns: (transfer full): a newly created #HdyWindow + * + * Since: 1.0 + */ +GtkWidget * +hdy_window_new (void) +{ + return g_object_new (HDY_TYPE_WINDOW, + "type", GTK_WINDOW_TOPLEVEL, + NULL); +} |