[libdazzle] app: add DzlApplicationWindow:titlebar-animation property
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] app: add DzlApplicationWindow:titlebar-animation property
- Date: Fri, 1 May 2020 22:05:16 +0000 (UTC)
commit ce56a559c06a4336f6c1b27ab3746bd3858cbbf2
Author: Christian Hergert <chergert redhat com>
Date: Fri May 1 15:04:14 2020 -0700
app: add DzlApplicationWindow:titlebar-animation property
This property can be used to track the changes of the titlebar as they
animate in and out. Some effort is made to ensure that changes are only
emitted once and in order, however immediate changes to fullscreen may
result in going from SHOWN to HIDDEN immediately.
Related #38
src/app/dzl-application-window.c | 134 +++++++++++++++++++++++++++++++++++++--
src/app/dzl-application-window.h | 22 +++++--
src/app/meson.build | 4 ++
src/dzl-enums.c.in | 1 +
4 files changed, 151 insertions(+), 10 deletions(-)
---
diff --git a/src/app/dzl-application-window.c b/src/app/dzl-application-window.c
index b23ec4d..6eccd74 100644
--- a/src/app/dzl-application-window.c
+++ b/src/app/dzl-application-window.c
@@ -26,6 +26,8 @@
# include "backports/gtkeventcontrollermotion.c"
#endif
+#include "dzl-enums.h"
+
#include "app/dzl-application-window.h"
#include "shortcuts/dzl-shortcut-manager.h"
#include "util/dzl-gtk.h"
@@ -59,8 +61,12 @@ typedef struct
GtkEventController *motion_controller;
gulong motion_controller_handler;
+ DzlTitlebarAnimation last_titlebar_animation;
+
guint fullscreen_source;
guint fullscreen_reveal_source;
+ guint titlebar_hiding;
+
guint fullscreen : 1;
guint in_key_press : 1;
} DzlApplicationWindowPrivate;
@@ -68,6 +74,7 @@ typedef struct
enum {
PROP_0,
PROP_FULLSCREEN,
+ PROP_TITLEBAR_ANIMATION,
N_PROPS
};
@@ -80,17 +87,58 @@ G_DEFINE_TYPE_WITH_CODE (DzlApplicationWindow, dzl_application_window, GTK_TYPE_
static GParamSpec *properties [N_PROPS];
static GtkBuildableIface *parent_buildable;
+static void
+update_titlebar_animation_property (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ DzlTitlebarAnimation current;
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+
+ current = dzl_application_window_get_titlebar_animation (self);
+
+ if (current != priv->last_titlebar_animation)
+ {
+ priv->last_titlebar_animation = current;
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_TITLEBAR_ANIMATION]);
+ }
+}
+
static gboolean
-dzl_application_window_dismissal (DzlApplicationWindow *self)
+dzl_application_window_titlebar_hidden_cb (gpointer data)
{
+ DzlApplicationWindow *self = data;
DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
g_assert (DZL_IS_APPLICATION_WINDOW (self));
- priv->fullscreen_reveal_source = 0;
+ priv->titlebar_hiding--;
+ update_titlebar_animation_property (self);
+
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+dzl_application_window_dismissal (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
if (dzl_application_window_get_fullscreen (self))
- gtk_revealer_set_reveal_child (priv->titlebar_revealer, FALSE);
+ {
+ priv->titlebar_hiding++;
+ gtk_revealer_set_reveal_child (priv->titlebar_revealer, FALSE);
+ g_timeout_add_full (G_PRIORITY_DEFAULT,
+ gtk_revealer_get_transition_duration (priv->titlebar_revealer),
+ dzl_application_window_titlebar_hidden_cb,
+ g_object_ref (self),
+ g_object_unref);
+ }
+
+ update_titlebar_animation_property (self);
+
+ priv->fullscreen_reveal_source = 0;
return G_SOURCE_REMOVE;
}
@@ -223,6 +271,8 @@ dzl_application_window_complete_fullscreen (DzlApplicationWindow *self)
g_object_unref (titlebar);
+ update_titlebar_animation_property (self);
+
return G_SOURCE_REMOVE;
}
@@ -370,6 +420,17 @@ dzl_application_window_window_state_event (GtkWidget *widget,
return ret;
}
+static void
+dzl_application_window_revealer_notify_child_state (DzlApplicationWindow *self,
+ GParamSpec *pspec,
+ GtkRevealer *revealer)
+{
+ g_assert (DZL_IS_APPLICATION_WINDOW (self));
+ g_assert (GTK_IS_REVEALER (revealer));
+
+ update_titlebar_animation_property (self);
+}
+
static void
dzl_application_window_destroy (GtkWidget *widget)
{
@@ -404,6 +465,10 @@ dzl_application_window_get_property (GObject *object,
g_value_set_boolean (value, dzl_application_window_get_fullscreen (self));
break;
+ case PROP_TITLEBAR_ANIMATION:
+ g_value_set_enum (value, dzl_application_window_get_titlebar_animation (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -467,6 +532,14 @@ dzl_application_window_class_init (DzlApplicationWindowClass *klass)
FALSE,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ properties [PROP_TITLEBAR_ANIMATION] =
+ g_param_spec_enum ("titlebar-animation",
+ "Titlebar Animation",
+ "The state of the titlebar animation",
+ DZL_TYPE_TITLEBAR_ANIMATION,
+ DZL_TITLEBAR_ANIMATION_SHOWN,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -476,6 +549,8 @@ dzl_application_window_init (DzlApplicationWindow *self)
DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
g_autoptr(GPropertyAction) fullscreen = NULL;
+ priv->last_titlebar_animation = DZL_TITLEBAR_ANIMATION_SHOWN;
+
priv->titlebar_container = g_object_new (GTK_TYPE_STACK,
"name", "titlebar_container",
"visible", TRUE,
@@ -513,6 +588,16 @@ dzl_application_window_init (DzlApplicationWindow *self)
"reveal-child", TRUE,
"visible", TRUE,
NULL);
+ g_signal_connect_object (priv->titlebar_revealer,
+ "notify::child-revealed",
+ G_CALLBACK (dzl_application_window_revealer_notify_child_state),
+ self,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (priv->titlebar_revealer,
+ "notify::reveal-child",
+ G_CALLBACK (dzl_application_window_revealer_notify_child_state),
+ self,
+ G_CONNECT_SWAPPED);
g_signal_connect (priv->titlebar_revealer,
"destroy",
G_CALLBACK (gtk_widget_destroyed),
@@ -566,7 +651,10 @@ dzl_application_window_set_fullscreen (DzlApplicationWindow *self,
fullscreen = !!fullscreen;
if (fullscreen != dzl_application_window_get_fullscreen (self))
- DZL_APPLICATION_WINDOW_GET_CLASS (self)->set_fullscreen (self, fullscreen);
+ {
+ DZL_APPLICATION_WINDOW_GET_CLASS (self)->set_fullscreen (self, fullscreen);
+ update_titlebar_animation_property (self);
+ }
}
static void
@@ -644,3 +732,41 @@ dzl_application_window_set_titlebar (DzlApplicationWindow *self,
if (titlebar != NULL)
gtk_container_add (GTK_CONTAINER (priv->titlebar_container), titlebar);
}
+
+DzlTitlebarAnimation
+dzl_application_window_get_titlebar_animation (DzlApplicationWindow *self)
+{
+ DzlApplicationWindowPrivate *priv = dzl_application_window_get_instance_private (self);
+ GtkWidget *titlebar;
+
+ g_return_val_if_fail (DZL_IS_APPLICATION_WINDOW (self), 0);
+
+ titlebar = dzl_application_window_get_titlebar (self);
+ if (titlebar == NULL)
+ return DZL_TITLEBAR_ANIMATION_HIDDEN;
+
+ if (!dzl_application_window_get_fullscreen (self))
+ {
+ if (gtk_widget_get_visible (titlebar))
+ return DZL_TITLEBAR_ANIMATION_SHOWN;
+ else
+ return DZL_TITLEBAR_ANIMATION_HIDDEN;
+ }
+
+ /* If the source from queue_dismissal is 0, then we already
+ * fired and we are hiding the titlebar.
+ */
+ if (priv->titlebar_hiding)
+ return DZL_TITLEBAR_ANIMATION_HIDING;
+
+ /* Titlebar currently visible */
+ if (gtk_revealer_get_reveal_child (priv->titlebar_revealer) &&
+ gtk_revealer_get_child_revealed (priv->titlebar_revealer))
+ return DZL_TITLEBAR_ANIMATION_SHOWN;
+
+ /* Working towards becoming visible */
+ if (gtk_revealer_get_reveal_child (priv->titlebar_revealer))
+ return DZL_TITLEBAR_ANIMATION_SHOWING;
+
+ return DZL_TITLEBAR_ANIMATION_HIDDEN;
+}
diff --git a/src/app/dzl-application-window.h b/src/app/dzl-application-window.h
index d9bfe87..752dfd4 100644
--- a/src/app/dzl-application-window.h
+++ b/src/app/dzl-application-window.h
@@ -30,6 +30,14 @@ G_BEGIN_DECLS
DZL_AVAILABLE_IN_ALL
G_DECLARE_DERIVABLE_TYPE (DzlApplicationWindow, dzl_application_window, DZL, APPLICATION_WINDOW,
GtkApplicationWindow)
+typedef enum
+{
+ DZL_TITLEBAR_ANIMATION_HIDDEN = 0,
+ DZL_TITLEBAR_ANIMATION_SHOWING = 1,
+ DZL_TITLEBAR_ANIMATION_SHOWN = 2,
+ DZL_TITLEBAR_ANIMATION_HIDING = 3,
+} DzlTitlebarAnimation;
+
struct _DzlApplicationWindowClass
{
GtkApplicationWindowClass parent_class;
@@ -49,15 +57,17 @@ struct _DzlApplicationWindowClass
};
DZL_AVAILABLE_IN_ALL
-gboolean dzl_application_window_get_fullscreen (DzlApplicationWindow *self);
+gboolean dzl_application_window_get_fullscreen (DzlApplicationWindow *self);
DZL_AVAILABLE_IN_ALL
-void dzl_application_window_set_fullscreen (DzlApplicationWindow *self,
- gboolean fullscreen);
+void dzl_application_window_set_fullscreen (DzlApplicationWindow *self,
+ gboolean fullscreen);
DZL_AVAILABLE_IN_ALL
-GtkWidget *dzl_application_window_get_titlebar (DzlApplicationWindow *self);
+GtkWidget *dzl_application_window_get_titlebar (DzlApplicationWindow *self);
DZL_AVAILABLE_IN_ALL
-void dzl_application_window_set_titlebar (DzlApplicationWindow *self,
- GtkWidget *titlebar);
+void dzl_application_window_set_titlebar (DzlApplicationWindow *self,
+ GtkWidget *titlebar);
+DZL_AVAILABLE_IN_3_38
+DzlTitlebarAnimation dzl_application_window_get_titlebar_animation (DzlApplicationWindow *self);
G_END_DECLS
diff --git a/src/app/meson.build b/src/app/meson.build
index 363569c..a1471a8 100644
--- a/src/app/meson.build
+++ b/src/app/meson.build
@@ -8,6 +8,10 @@ app_sources = [
'dzl-application-window.c',
]
+dzl_enum_headers += files([
+ 'dzl-application-window.h',
+])
+
libdazzle_public_headers += files(app_headers)
libdazzle_public_sources += files(app_sources)
diff --git a/src/dzl-enums.c.in b/src/dzl-enums.c.in
index d132b52..0b362ca 100644
--- a/src/dzl-enums.c.in
+++ b/src/dzl-enums.c.in
@@ -4,6 +4,7 @@
#include "dzl-enums.h"
+#include "app/dzl-application-window.h"
#include "files/dzl-file-transfer.h"
#include "tree/dzl-tree-types.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]