[libdazzle] application-window: start on DzlApplicationWindow
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] application-window: start on DzlApplicationWindow
- Date: Sat, 8 Jul 2017 08:16:39 +0000 (UTC)
commit 42cebbb4195daf817dcaf9e460df91639c367d99
Author: Christian Hergert <chergert redhat com>
Date: Sat Jul 8 01:08:18 2017 -0700
application-window: start on DzlApplicationWindow
This is a base-window for applications to use that currently has
a single helper, a basic (un)fullscreen implementation. This
makes it easier on applications so they don't have to duplicate
this rather tricky logic.
One possible way to improve this would be to use a GdkWindow
that is input only with 5x high at the top of the screen. When
the revealer is expanded, increase the input-only window to
match the size. Then just watch for enter/leave notify.
As you can imagine, that is even more complex, so we'll avoid
doing that for now.
src/app/dzl-application-window.c | 615 ++++++++++++++++++++++++++++++++++++++
src/app/dzl-application-window.h | 57 ++++
src/dazzle.h | 1 +
src/meson.build | 2 +
4 files changed, 675 insertions(+), 0 deletions(-)
---
diff --git a/src/app/dzl-application-window.c b/src/app/dzl-application-window.c
new file mode 100644
index 0000000..7b647d1
--- /dev/null
+++ b/src/app/dzl-application-window.c
@@ -0,0 +1,615 @@
+/* dzl-application-window.c
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "dzl-application-window"
+
+#include "app/dzl-application-window.h"
+
+#define DEFAULT_DISMISSAL_SECONDS 3
+#define SHOW_HEADER_WITHIN_DISTANCE 5
+
+typedef struct
+{
+ GtkStack *titlebar_container;
+ GtkRevealer *titlebar_revealer;
+ GtkEventBox *event_box;
+ GtkOverlay *overlay;
+
+ gulong motion_notify_handler;
+
+ guint fullscreen_source;
+ guint fullscreen_reveal_source;
+ guint fullscreen : 1;
+} DzlApplicationWindowPrivate;
+
+enum {
+ PROP_0,
+ PROP_FULLSCREEN,
+ N_PROPS
+};
+
+static void buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (DzlApplicationWindow, dzl_application_window, GTK_TYPE_APPLICATION_WINDOW,
+ G_ADD_PRIVATE (DzlApplicationWindow)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
+
+static GParamSpec *properties [N_PROPS];
+static GtkBuildableIface *parent_buildable;
+
+static gboolean
+dzl_application_window_dismissal (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ priv->fullscreen_reveal_source = 0;
+
+ if (dzl_application_window_get_fullscreen (self))
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, FALSE);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+dzl_application_window_queue_dismissal (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ if (priv->fullscreen_reveal_source != 0)
+ g_source_remove (priv->fullscreen_reveal_source);
+
+ priv->fullscreen_reveal_source =
+ gdk_threads_add_timeout_seconds_full (G_PRIORITY_LOW,
+ DEFAULT_DISMISSAL_SECONDS,
+ (GSourceFunc) dzl_application_window_dismissal,
+ self, NULL);
+}
+
+static gboolean
+dzl_application_window_real_get_fullscreen (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ return priv->fullscreen;
+}
+
+static void
+revealer_set_reveal_child_now (GtkRevealer *revealer,
+ gboolean reveal_child)
+{
+
+ g_assert (GTK_IS_REVEALER (revealer));
+
+ gtk_revealer_set_transition_type (revealer, GTK_REVEALER_TRANSITION_TYPE_NONE);
+ gtk_revealer_set_reveal_child (revealer, reveal_child);
+ gtk_revealer_set_transition_type (revealer, GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN);
+}
+
+static gboolean
+dzl_application_window_event_box_motion (DzlApplicationWindow *self,
+ GdkEventMotion *motion,
+ GtkEventBox *event_box)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ GtkWidget *widget = NULL;
+ GtkWidget *focus;
+ gint x = 0;
+ gint y = 0;
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (motion != NULL);
+ g_assert (GTK_IS_EVENT_BOX (event_box));
+
+ /*
+ * If we are focused in the revealer, ignore this. We will have already
+ * killed the GSource in set_focus().
+ */
+ focus = gtk_window_get_focus (GTK_WINDOW (self));
+ if (focus && gtk_widget_is_ancestor (focus, GTK_WIDGET (priv->titlebar_revealer)))
+ return GDK_EVENT_PROPAGATE;
+
+ /* The widget is stored in GdkWindow user_data */
+ gdk_window_get_user_data (motion->window, (gpointer *)&widget);
+ if (widget == NULL)
+ return GDK_EVENT_PROPAGATE;
+
+ /* If the headerbar is underneath the pointer or we are within a
+ * small distance of the edge of the window (and monitor), ensure
+ * that the titlebar is displayed and queue our next dismissal.
+ */
+ if (gtk_widget_is_ancestor (widget, GTK_WIDGET (priv->titlebar_revealer)) ||
+ gtk_widget_translate_coordinates (widget, GTK_WIDGET (self), motion->x, motion->y, &x, &y))
+ {
+ if (y < SHOW_HEADER_WITHIN_DISTANCE)
+ {
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
+ dzl_application_window_queue_dismissal (self);
+ }
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ GtkWidget *titlebar;
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ priv->fullscreen_source = 0;
+
+ titlebar = dzl_application_window_get_titlebar (self);
+
+ if (titlebar == NULL)
+ {
+ g_warning ("Attempt to alter fullscreen state without a titlebar set!");
+ return G_SOURCE_REMOVE;
+ }
+
+ /*
+ * This is where we apply the fullscreen widget transitions.
+ *
+ * If we were toggled really fast, we could have skipped oure previous
+ * operation. So make sure that the revealer is in the state we expect
+ * it before performing further (destructive) work.
+ */
+
+ g_object_ref (priv->titlebar_revealer);
+
+ if (priv->fullscreen)
+ {
+ /* Only listen for motion notify events while in fullscreen mode. */
+ g_signal_handler_unblock (priv->event_box, priv->motion_notify_handler);
+
+ if (titlebar && gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_container)))
+ {
+ revealer_set_reveal_child_now (priv->titlebar_revealer, FALSE);
+ gtk_container_remove (GTK_CONTAINER (priv->titlebar_container), titlebar);
+ gtk_container_add (GTK_CONTAINER (priv->titlebar_revealer), titlebar);
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, TRUE);
+ dzl_application_window_queue_dismissal (self);
+ }
+ }
+ else
+ {
+ /* Motion events are no longer needed */
+ g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
+
+ if (gtk_widget_is_ancestor (titlebar, GTK_WIDGET (priv->titlebar_revealer)))
+ {
+ gtk_container_remove (GTK_CONTAINER (priv->titlebar_revealer), titlebar);
+ gtk_container_add (GTK_CONTAINER (priv->titlebar_container), titlebar);
+ revealer_set_reveal_child_now (priv->titlebar_revealer, FALSE);
+ }
+ }
+
+ g_object_unref (priv->titlebar_revealer);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+dzl_application_window_real_set_fullscreen (DzlApplicationWindow *self,
+ gboolean fullscreen)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (priv->fullscreen != fullscreen);
+
+ priv->fullscreen = fullscreen;
+
+ if (priv->fullscreen_source != 0)
+ {
+ g_source_remove (priv->fullscreen_source);
+ priv->fullscreen_source = 0;
+ }
+
+ if (priv->fullscreen)
+ {
+ /*
+ * Once we go fullscreen, the headerbar will no longer be visible.
+ * So we will delay for a short bit until we've likely entered the
+ * fullscreen state, and then remove the titlebar and place it into
+ * the hover state.
+ */
+ priv->fullscreen_source =
+ gdk_threads_add_timeout_full (G_PRIORITY_LOW,
+ 300,
+ (GSourceFunc) dzl_application_window_complete_fullscreen,
+ self, NULL);
+ gtk_window_fullscreen (GTK_WINDOW (self));
+ }
+ else
+ {
+ /*
+ * We must apply our unfullscreen state transition immediately
+ * so that we have a titlebar as soon as the window changes.
+ */
+ dzl_application_window_complete_fullscreen (self);
+ gtk_window_unfullscreen (GTK_WINDOW (self));
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FULLSCREEN]);
+}
+
+static void
+dzl_application_window_set_focus (GtkWindow *window,
+ GtkWidget *widget)
+{
+ DzlApplicationWindow *self = (DzlApplicationWindow *)window;
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ GtkWidget *old_focus;
+ gboolean titlebar_had_focus = FALSE;
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (!widget || GTK_IS_WIDGET (widget));
+
+ /* Check if we have titlebar focus already */
+ old_focus = gtk_window_get_focus (window);
+ if (old_focus && gtk_widget_is_ancestor (old_focus, GTK_WIDGET (priv->titlebar_revealer)))
+ titlebar_had_focus = TRUE;
+
+ /* Chain-up first */
+ GTK_WINDOW_CLASS (dzl_application_window_parent_class)->set_focus (window, widget);
+
+ /* Now see what is selected */
+ widget = gtk_window_get_focus (window);
+
+ if (widget != NULL)
+ {
+ if (gtk_widget_is_ancestor (widget, GTK_WIDGET (priv->titlebar_revealer)))
+ {
+ /* Disable transition while the revealer is focused */
+ if (priv->fullscreen_reveal_source != 0)
+ {
+ g_source_remove (priv->fullscreen_reveal_source);
+ priv->fullscreen_reveal_source = 0;
+ }
+ }
+ else if (titlebar_had_focus)
+ {
+ /* We are going from titlebar to non-titlebar focus. Dismiss
+ * the titlebar immediately to get out of the users way.
+ */
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, FALSE);
+ if (priv->fullscreen_reveal_source != 0)
+ {
+ g_source_remove (priv->fullscreen_reveal_source);
+ priv->fullscreen_reveal_source = 0;
+ }
+ }
+ }
+}
+
+static void
+dzl_application_window_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ DzlApplicationWindow *self = (DzlApplicationWindow *)container;
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (GTK_IS_WIDGET (widget));
+
+ gtk_container_add (GTK_CONTAINER (priv->event_box), widget);
+}
+
+static void
+dzl_application_window_destroy (GtkWidget *widget)
+{
+ DzlApplicationWindow *self = (DzlApplicationWindow *)widget;
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ if (priv->event_box != NULL)
+ {
+ g_signal_handler_disconnect (priv->event_box, priv->motion_notify_handler);
+ priv->motion_notify_handler = 0;
+ }
+
+ g_clear_pointer (&priv->titlebar_container, gtk_widget_destroy);
+ g_clear_pointer (&priv->titlebar_revealer, gtk_widget_destroy);
+ g_clear_pointer (&priv->event_box, gtk_widget_destroy);
+ g_clear_pointer (&priv->overlay, gtk_widget_destroy);
+
+ if (priv->fullscreen_source)
+ {
+ g_source_remove (priv->fullscreen_source);
+ priv->fullscreen_source = 0;
+ }
+
+ if (priv->fullscreen_reveal_source)
+ {
+ g_source_remove (priv->fullscreen_reveal_source);
+ priv->fullscreen_reveal_source = 0;
+ }
+
+ GTK_WIDGET_CLASS (dzl_application_window_parent_class)->destroy (widget);
+}
+
+static void
+dzl_application_window_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ DzlApplicationWindow *self = DZL_APPLICATION_WINDOW (object);
+
+ switch (prop_id)
+ {
+ case PROP_FULLSCREEN:
+ g_value_set_boolean (value, dzl_application_window_get_fullscreen (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+dzl_application_window_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ DzlApplicationWindow *self = DZL_APPLICATION_WINDOW (object);
+
+ switch (prop_id)
+ {
+ case PROP_FULLSCREEN:
+ dzl_application_window_set_fullscreen (self, g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+dzl_application_window_class_init (DzlApplicationWindowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+ GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
+
+ object_class->get_property = dzl_application_window_get_property;
+ object_class->set_property = dzl_application_window_set_property;
+
+ widget_class->destroy = dzl_application_window_destroy;
+
+ container_class->add = dzl_application_window_add;
+
+ window_class->set_focus = dzl_application_window_set_focus;
+
+ klass->get_fullscreen = dzl_application_window_real_get_fullscreen;
+ klass->set_fullscreen = dzl_application_window_real_set_fullscreen;
+
+ /**
+ * DzlApplicationWindow:fullscreen:
+ *
+ * The "fullscreen" property denotes if the window is in the fullscreen
+ * state. The titlebar of the #DzlApplicationWindow contains a revealer
+ * which will be repurposed into a floating bar while the window is in
+ * the fullscreen mode.
+ *
+ * Set this property to %FALSE to unfullscreen.
+ */
+ properties [PROP_FULLSCREEN] =
+ g_param_spec_boolean ("fullscreen",
+ "Fullscreen",
+ "If the window is fullscreen",
+ FALSE,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+dzl_application_window_init (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ g_autoptr(GPropertyAction) fullscreen = NULL;
+
+ priv->titlebar_container = g_object_new (GTK_TYPE_STACK,
+ "name", "titlebar_container",
+ "visible", TRUE,
+ NULL);
+ g_signal_connect (priv->titlebar_container,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &priv->titlebar_container);
+ gtk_window_set_titlebar (GTK_WINDOW (self), GTK_WIDGET (priv->titlebar_container));
+
+ priv->overlay = g_object_new (GTK_TYPE_OVERLAY,
+ "visible", TRUE,
+ NULL);
+ g_signal_connect (priv->overlay,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &priv->overlay);
+ GTK_CONTAINER_CLASS (dzl_application_window_parent_class)->add (GTK_CONTAINER (self),
+ GTK_WIDGET (priv->overlay));
+
+ priv->event_box = g_object_new (GTK_TYPE_EVENT_BOX,
+ "above-child", FALSE,
+ "visible", TRUE,
+ "visible-window", TRUE,
+ NULL);
+ gtk_widget_set_events (GTK_WIDGET (priv->event_box), GDK_POINTER_MOTION_MASK);
+ g_signal_connect (priv->event_box,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &priv->event_box);
+ priv->motion_notify_handler =
+ g_signal_connect_swapped (priv->event_box,
+ "motion-notify-event",
+ G_CALLBACK (dzl_application_window_event_box_motion),
+ self);
+ g_signal_handler_block (priv->event_box, priv->motion_notify_handler);
+ gtk_container_add (GTK_CONTAINER (priv->overlay), GTK_WIDGET (priv->event_box));
+
+ priv->titlebar_revealer = g_object_new (GTK_TYPE_REVEALER,
+ "valign", GTK_ALIGN_START,
+ "hexpand", TRUE,
+ "transition-duration", 500,
+ "transition-type", GTK_REVEALER_TRANSITION_TYPE_SLIDE_DOWN,
+ "reveal-child", TRUE,
+ "visible", TRUE,
+ NULL);
+ g_signal_connect (priv->titlebar_revealer,
+ "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &priv->titlebar_revealer);
+ gtk_overlay_add_overlay (priv->overlay, GTK_WIDGET (priv->titlebar_revealer));
+
+ fullscreen = g_property_action_new ("fullscreen", self, "fullscreen");
+ g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (fullscreen));
+}
+
+/**
+ * dzl_application_window_get_fullscreen:
+ * @self: a #DzlApplicationWindow
+ *
+ * Gets if the window is in the fullscreen state.
+ *
+ * Returns: %TRUE if @self is fullscreen, otherwise %FALSE.
+ *
+ * Since: 3.26
+ */
+gboolean
+dzl_application_window_get_fullscreen (DzlApplicationWindow *self)
+{
+ g_return_val_if_fail (DZL_IS_APPLICATION_WINDOW (self), FALSE);
+
+ return DZL_APPLICATION_WINDOW_GET_CLASS (self)->get_fullscreen (self);
+}
+
+/**
+ * dzl_application_window_set_fullscreen:
+ * @self: a #DzlApplicationWindow
+ * @fullscreen: if the window should be in the fullscreen state
+ *
+ * Sets the #DzlApplicationWindow into either the fullscreen or unfullscreen
+ * state based on @fullscreen.
+ *
+ * The titlebar for the window is contained within a #GtkRevealer which is
+ * repurposed as a floating bar when the application is in fullscreen mode.
+ *
+ * See dzl_application_window_get_fullscreen() to get the current fullscreen
+ * state.
+ *
+ * Since: 3.26
+ */
+void
+dzl_application_window_set_fullscreen (DzlApplicationWindow *self,
+ gboolean fullscreen)
+{
+ g_return_if_fail (DZL_IS_APPLICATION_WINDOW (self));
+
+ fullscreen = !!fullscreen;
+
+ if (fullscreen != dzl_application_window_get_fullscreen (self))
+ DZL_APPLICATION_WINDOW_GET_CLASS (self)->set_fullscreen (self, fullscreen);
+}
+
+static void
+dzl_application_window_add_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *type)
+{
+ DzlApplicationWindow *self = (DzlApplicationWindow *)buildable;
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (GTK_IS_BUILDER (builder));
+ g_assert (G_IS_OBJECT (child));
+
+ if (g_strcmp0 (type, "titlebar") == 0)
+ gtk_container_add (GTK_CONTAINER (priv->titlebar_container), GTK_WIDGET (child));
+ else
+ parent_buildable->add_child (buildable, builder, child, type);
+}
+
+static void
+buildable_iface_init (GtkBuildableIface *iface)
+{
+ parent_buildable = g_type_interface_peek_parent (iface);
+
+ iface->add_child = dzl_application_window_add_child;
+}
+
+/**
+ * dzl_application_window_get_titlebar:
+ * @self: a #DzlApplicationWindow
+ *
+ * Gets the titlebar for the window, if there is one.
+ *
+ * Returns: (transfer none): A #GtkWidget or %NULL
+ *
+ * Since: 3.26
+ */
+GtkWidget *
+dzl_application_window_get_titlebar (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ GtkWidget *child;
+
+ g_return_val_if_fail (DZL_IS_APPLICATION_WINDOW (self), NULL);
+
+ child = gtk_stack_get_visible_child (priv->titlebar_container);
+ if (child == NULL)
+ child = gtk_bin_get_child (GTK_BIN (priv->titlebar_revealer));
+
+ return child;
+}
+
+/**
+ * dzl_application_window_set_titlebar:
+ * @self: a #DzlApplicationWindow
+ *
+ * Sets the titlebar for the window.
+ *
+ * Generally, you want to do this from your GTK ui template by setting
+ * the <child type="titlebar">
+ *
+ * Since: 3.26
+ */
+void
+dzl_application_window_set_titlebar (DzlApplicationWindow *self,
+ GtkWidget *titlebar)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_return_if_fail (DZL_IS_APPLICATION_WINDOW (self));
+ g_return_if_fail (GTK_IS_WIDGET (titlebar));
+
+ if (titlebar != NULL)
+ gtk_container_add (GTK_CONTAINER (priv->titlebar_container), titlebar);
+}
diff --git a/src/app/dzl-application-window.h b/src/app/dzl-application-window.h
new file mode 100644
index 0000000..05ddbfb
--- /dev/null
+++ b/src/app/dzl-application-window.h
@@ -0,0 +1,57 @@
+/* dzl-application-window.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DZL_APPLICATION_WINDOW_H
+#define DZL_APPLICATION_WINDOW_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define DZL_TYPE_APPLICATION_WINDOW (dzl_application_window_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (DzlApplicationWindow, dzl_application_window, DZL, APPLICATION_WINDOW,
GtkApplicationWindow)
+
+struct _DzlApplicationWindowClass
+{
+ GtkApplicationWindowClass parent_class;
+
+ gboolean (*get_fullscreen) (DzlApplicationWindow *self);
+ void (*set_fullscreen) (DzlApplicationWindow *self,
+ gboolean fullscreen);
+
+ gpointer _reserved1;
+ gpointer _reserved2;
+ gpointer _reserved3;
+ gpointer _reserved4;
+ gpointer _reserved5;
+ gpointer _reserved6;
+ gpointer _reserved7;
+ gpointer _reserved8;
+};
+
+gboolean dzl_application_window_get_fullscreen (DzlApplicationWindow *self);
+void dzl_application_window_set_fullscreen (DzlApplicationWindow *self,
+ gboolean fullscreen);
+GtkWidget *dzl_application_window_get_titlebar (DzlApplicationWindow *self);
+void dzl_application_window_set_titlebar (DzlApplicationWindow *self,
+ GtkWidget *titlebar);
+
+G_END_DECLS
+
+#endif /* DZL_APPLICATION_WINDOW_H */
diff --git a/src/dazzle.h b/src/dazzle.h
index dce57c5..5020e7a 100644
--- a/src/dazzle.h
+++ b/src/dazzle.h
@@ -40,6 +40,7 @@ G_BEGIN_DECLS
#include "animation/dzl-animation.h"
#include "animation/dzl-box-theatric.h"
#include "app/dzl-application.h"
+#include "app/dzl-application-window.h"
#include "bindings/dzl-binding-group.h"
#include "bindings/dzl-signal-group.h"
#include "cache/dzl-task-cache.h"
diff --git a/src/meson.build b/src/meson.build
index 2fdb228..de3279f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -51,6 +51,7 @@ libdazzle_public_headers = [
'animation/dzl-box-theatric.h',
'app/dzl-application.h',
+ 'app/dzl-application-window.h',
'bindings/dzl-binding-group.h',
'bindings/dzl-signal-group.h',
@@ -197,6 +198,7 @@ libdazzle_public_sources = [
'animation/dzl-box-theatric.c',
'app/dzl-application.c',
+ 'app/dzl-application-window.c',
'bindings/dzl-binding-group.c',
'bindings/dzl-signal-group.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]