[gnome-todo] window: Add fullscreen button and plumbing
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo] window: Add fullscreen button and plumbing
- Date: Tue, 28 Apr 2020 21:28:22 +0000 (UTC)
commit 480e329b9715711f3473ba85fd103fa02966da64
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Apr 28 18:14:43 2020 -0300
window: Add fullscreen button and plumbing
It's not super useful right now, but it'll be in the future,
specially with 2+ monitors.
https://gitlab.gnome.org/GNOME/gnome-todo/-/issues/325
src/gtd-window.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gtd-window.ui | 27 +++++++++++++++-
2 files changed, 123 insertions(+), 1 deletion(-)
---
diff --git a/src/gtd-window.c b/src/gtd-window.c
index 94f410d..d9864a8 100644
--- a/src/gtd-window.c
+++ b/src/gtd-window.c
@@ -59,18 +59,24 @@ struct _GtdWindow
GtkApplicationWindow application;
GtkHeaderBar *headerbar;
+ GtkWidget *headerbar_box;
+ GtkRevealer *headerbar_overlay_revealer;
GtkStack *stack;
GtkWidget *workspace_box_end;
GtkWidget *workspace_box_start;
GtkListBox *workspaces_listbox;
GtdMenuButton *workspaces_menu_button;
+ GtkEventController *overlay_motion_controller;
+
GtdNotificationWidget *notification_widget;
GPtrArray *workspace_header_widgets;
GtdWorkspace *current_workspace;
GListStore *workspaces;
+
+ guint toggle_headerbar_revealer_id;
};
typedef struct
@@ -230,6 +236,18 @@ remove_all_workspace_header_widgets (GtdWindow *self)
* Callbacks
*/
+static gboolean
+toggle_headerbar_overlay_cb (gpointer user_data)
+{
+ GtdWindow *self = GTD_WINDOW (user_data);
+
+ gtk_revealer_set_reveal_child (self->headerbar_overlay_revealer,
+ !gtk_revealer_get_reveal_child (self->headerbar_overlay_revealer));
+
+ self->toggle_headerbar_revealer_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
static void
on_action_activate_workspace_activated_cb (GSimpleAction *simple,
@@ -245,6 +263,79 @@ on_action_activate_workspace_activated_cb (GSimpleAction *simple,
gtk_stack_set_visible_child_name (self->stack, workspace_id);
}
+static void
+on_action_toggle_fullscreen_state_changed_cb (GSimpleAction *simple,
+ GVariant *state,
+ gpointer user_data)
+{
+ GtkContainer *parent;
+ GtdWindow *self;
+ gboolean fullscreen;
+
+ self = GTD_WINDOW (user_data);
+ fullscreen = g_variant_get_boolean (state);
+ parent = GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (self->headerbar)));
+
+ g_clear_handle_id (&self->toggle_headerbar_revealer_id, g_source_remove);
+
+ gtk_header_bar_set_show_title_buttons (self->headerbar, !fullscreen);
+
+ g_object_ref (self->headerbar);
+ gtk_container_remove (parent, GTK_WIDGET (self->headerbar));
+
+ if (fullscreen)
+ {
+ gtk_event_controller_set_propagation_phase (self->overlay_motion_controller, GTK_PHASE_BUBBLE);
+ gtk_container_add (GTK_CONTAINER (self->headerbar_overlay_revealer), GTK_WIDGET (self->headerbar));
+ gtk_revealer_set_reveal_child (self->headerbar_overlay_revealer, TRUE);
+ gtk_window_fullscreen (GTK_WINDOW (self));
+
+ self->toggle_headerbar_revealer_id = g_timeout_add_seconds (2, toggle_headerbar_overlay_cb, self);
+ }
+ else
+ {
+ gtk_event_controller_set_propagation_phase (self->overlay_motion_controller, GTK_PHASE_NONE);
+ gtk_revealer_set_reveal_child (self->headerbar_overlay_revealer, FALSE);
+ gtk_container_add (GTK_CONTAINER (self->headerbar_box), GTK_WIDGET (self->headerbar));
+ gtk_window_unfullscreen (GTK_WINDOW (self));
+ }
+ g_object_unref (self->headerbar);
+
+ g_simple_action_set_state (simple, state);
+}
+
+static void
+on_overlay_motion_controller_motion_cb (GtkEventControllerMotion *controller,
+ gdouble x,
+ gdouble y,
+ GtdWindow *self)
+{
+ const gint y_threashold = 5;
+ GtkWidget *hovered_widget;
+
+ hovered_widget = gtk_widget_pick (GTK_WIDGET (self), x, y, GTK_PICK_DEFAULT);
+
+ /* Show headerbar when hovering it */
+ if (hovered_widget &&
+ gtk_widget_is_ancestor (hovered_widget, GTK_WIDGET (self->headerbar_overlay_revealer)))
+ {
+ gtk_revealer_set_reveal_child (self->headerbar_overlay_revealer, TRUE);
+ g_clear_handle_id (&self->toggle_headerbar_revealer_id, g_source_remove);
+ return;
+ }
+
+ if (y <= y_threashold)
+ {
+ gtk_revealer_set_reveal_child (self->headerbar_overlay_revealer, TRUE);
+ g_clear_handle_id (&self->toggle_headerbar_revealer_id, g_source_remove);
+ }
+ else if (self->toggle_headerbar_revealer_id == 0 &&
+ gtk_revealer_get_reveal_child (self->headerbar_overlay_revealer))
+ {
+ self->toggle_headerbar_revealer_id = g_timeout_add (500, toggle_headerbar_overlay_cb, self);
+ }
+}
+
static gint
compare_workspaced_func (gconstpointer a,
gconstpointer b,
@@ -438,6 +529,7 @@ gtd_window_dispose (GObject *object)
{
GtdWindow *self = GTD_WINDOW (object);
+ g_clear_handle_id (&self->toggle_headerbar_revealer_id, g_source_remove);
g_clear_object (&self->workspaces);
G_OBJECT_CLASS (gtd_window_parent_class)->dispose (object);
@@ -489,13 +581,17 @@ gtd_window_class_init (GtdWindowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/gtd-window.ui");
gtk_widget_class_bind_template_child (widget_class, GtdWindow, headerbar);
+ gtk_widget_class_bind_template_child (widget_class, GtdWindow, headerbar_box);
+ gtk_widget_class_bind_template_child (widget_class, GtdWindow, headerbar_overlay_revealer);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, notification_widget);
+ gtk_widget_class_bind_template_child (widget_class, GtdWindow, overlay_motion_controller);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, stack);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspace_box_end);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspace_box_start);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspaces_menu_button);
gtk_widget_class_bind_template_child (widget_class, GtdWindow, workspaces_listbox);
+ gtk_widget_class_bind_template_callback (widget_class, on_overlay_motion_controller_motion_cb);
gtk_widget_class_bind_template_callback (widget_class, on_stack_visible_child_cb);
gtk_widget_class_bind_template_callback (widget_class, on_workspaces_listbox_row_activated_cb);
}
@@ -505,6 +601,7 @@ gtd_window_init (GtdWindow *self)
{
static const GActionEntry entries[] = {
{ "activate-workspace", on_action_activate_workspace_activated_cb, "s" },
+ { "toggle-fullscreen", NULL, NULL, "false", on_action_toggle_fullscreen_state_changed_cb },
};
g_action_map_add_action_entries (G_ACTION_MAP (self),
diff --git a/src/gtd-window.ui b/src/gtd-window.ui
index 493926f..9be2aa3 100644
--- a/src/gtd-window.ui
+++ b/src/gtd-window.ui
@@ -17,6 +17,22 @@
</object>
</child>
+ <child type="overlay">
+ <object class="GtkRevealer" id="headerbar_overlay_revealer">
+ <property name="transition-type">slide-down</property>
+ <property name="transition-duration">750</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkEventControllerMotion" id="overlay_motion_controller">
+ <property name="propagation-phase">none</property>
+ <signal name="motion" handler="on_overlay_motion_controller_motion_cb" object="GtdWindow"
swapped="no" />
+ </object>
+ </child>
+
<!-- Main Stack -->
<child>
<object class="GtkStack" id="stack">
@@ -35,7 +51,7 @@
</object>
</child>
<child type="titlebar">
- <object class="GtkBox">
+ <object class="GtkBox" id="headerbar_box">
<child>
<object class="GtkHeaderBar" id="headerbar">
<property name="hexpand">1</property>
@@ -60,6 +76,15 @@
<property name="direction">none</property>
</object>
</child>
+
+ <!-- Fullscreen Button -->
+ <child type="end">
+ <object class="GtkToggleButton">
+ <property name="action-name">win.toggle-fullscreen</property>
+ <property name="icon-name">view-fullscreen-symbolic</property>
+ </object>
+ </child>
+
<child type="end">
<object class="GtkBox" id="workspace_box_end">
<property name="spacing">6</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]