[libhandy/wip/haecker-felix/flap-widget] Have separate windows for content and flap
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libhandy/wip/haecker-felix/flap-widget] Have separate windows for content and flap
- Date: Thu, 19 Nov 2020 10:41:36 +0000 (UTC)
commit 54de28d0a2b99ad618ef4ebaa8edae8ddf4aa42d
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Thu Nov 19 13:16:59 2020 +0500
Have separate windows for content and flap
I love GTK 3.
src/hdy-flap.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 143 insertions(+), 25 deletions(-)
---
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index 1f579306..70050e9f 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -44,6 +44,12 @@ struct _HdyFlap
GtkWidget *content;
GtkWidget *flap;
+ GdkWindow *content_window;
+ GdkWindow *flap_window;
+
+ GtkAllocation flap_allocation;
+ GtkAllocation content_allocation;
+
HdyFlapFoldPolicy fold_policy;
GtkPackType flap_position;
gboolean reveal_flap;
@@ -180,6 +186,9 @@ static void
reveal_animation_done_cb (HdyFlap *self)
{
g_clear_pointer (&self->reveal_animation, hdy_animation_unref);
+
+ if (self->reveal_progress <= 0)
+ hdy_shadow_helper_clear_cache (self->shadow_helper);
}
static void
@@ -290,6 +299,59 @@ end_swipe_cb (HdySwipeTracker *tracker,
set_reveal_flap (self, to > 0, duration, FALSE);
}
+static void
+register_window (HdyFlap *self,
+ GtkWidget *widget,
+ GtkAllocation *allocation,
+ GdkWindow **window)
+{
+ GdkWindowAttr attributes = { 0 };
+ GdkWindowAttributesType attributes_mask;
+
+ attributes.x = allocation->x;
+ attributes.y = allocation->y;
+ attributes.width = allocation->width;
+ attributes.height = allocation->height;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.event_mask = gtk_widget_get_events (widget);
+ attributes_mask = (GDK_WA_X | GDK_WA_Y) | GDK_WA_VISUAL;
+
+ attributes.event_mask = gtk_widget_get_events (GTK_WIDGET (self)) |
+ gtk_widget_get_events (widget);
+
+ *window = gdk_window_new (gtk_widget_get_window (GTK_WIDGET (self)),
+ &attributes, attributes_mask);
+ gtk_widget_register_window (GTK_WIDGET (self), *window);
+
+ gtk_widget_set_parent_window (widget, *window);
+
+ gdk_window_show (*window);
+}
+
+static void
+unregister_window (HdyFlap *self,
+ GdkWindow **window)
+{
+ if (!*window)
+ return;
+
+ gtk_widget_unregister_window (GTK_WIDGET (self), *window);
+ gdk_window_destroy (*window);
+ *window = NULL;
+}
+
+static void
+restack_windows (HdyFlap *self)
+{
+ if (self->content_window)
+ gdk_window_raise (self->content_window);
+
+ if (self->flap_window)
+ gdk_window_raise (self->flap_window);
+}
+
static inline GtkPackType
get_start_or_end (HdyFlap *self)
{
@@ -523,7 +585,7 @@ hdy_flap_size_allocate (GtkWidget *widget,
GtkAllocation *alloc)
{
HdyFlap *self = HDY_FLAP (widget);
- GtkAllocation flap_alloc, content_alloc;
+ GtkAllocation child_alloc;
gtk_widget_set_allocation (widget, alloc);
@@ -543,16 +605,41 @@ hdy_flap_size_allocate (GtkWidget *widget,
set_folded (self, alloc->height < content_min.height + flap_min.height);
}
- compute_allocation (self, alloc, &flap_alloc, &content_alloc);
+ compute_allocation (self, alloc, &self->flap_allocation, &self->content_allocation);
- if (self->content)
- gtk_widget_size_allocate (self->content, &content_alloc);
+ child_alloc.x = 0;
+ child_alloc.y = 0;
+
+ if (self->content) {
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (self->content_window,
+ self->content_allocation.x,
+ self->content_allocation.y,
+ self->content_allocation.width,
+ self->content_allocation.height);
+
+ child_alloc.width = self->content_allocation.width;
+ child_alloc.height = self->content_allocation.height;
+
+ gtk_widget_size_allocate (self->content, &child_alloc);
+ }
if (self->flap) {
gtk_widget_set_child_visible (self->flap, self->reveal_progress > 0);
- if (self->reveal_progress > 0)
- gtk_widget_size_allocate (self->flap, &flap_alloc);
+ if (self->reveal_progress > 0) {
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (self->flap_window,
+ self->flap_allocation.x,
+ self->flap_allocation.y,
+ self->flap_allocation.width,
+ self->flap_allocation.height);
+
+ child_alloc.width = self->flap_allocation.width;
+ child_alloc.height = self->flap_allocation.height;
+
+ gtk_widget_size_allocate (self->flap, &child_alloc);
+ }
}
gtk_widget_set_clip (widget, alloc);
@@ -662,24 +749,20 @@ hdy_flap_draw (GtkWidget *widget,
height = gtk_widget_get_allocated_height (widget);
if (self->orientation == GTK_ORIENTATION_VERTICAL) {
- gint flap_height = gtk_widget_get_allocated_height (self->flap);
-
if (self->flap_position == GTK_PACK_START) {
shadow_direction = GTK_PAN_DIRECTION_UP;
- shadow_y = (gint) round (flap_height * self->reveal_progress);
+ shadow_y = self->flap_allocation.y + self->flap_allocation.height;
} else {
shadow_direction = GTK_PAN_DIRECTION_DOWN;
- shadow_y = (gint) -round (flap_height * self->reveal_progress);
+ shadow_y = self->flap_allocation.y - height;
}
} else {
- gint flap_width = gtk_widget_get_allocated_width (self->flap);
-
if (self->flap_position == get_start_or_end (self)) {
shadow_direction = GTK_PAN_DIRECTION_LEFT;
- shadow_x = (gint) round (flap_width * self->reveal_progress);
+ shadow_x = self->flap_allocation.x + self->flap_allocation.width;
} else {
shadow_direction = GTK_PAN_DIRECTION_RIGHT;
- shadow_x = (gint) -round (flap_width * self->reveal_progress);
+ shadow_x = self->flap_allocation.x - width;
}
}
@@ -733,10 +816,23 @@ hdy_flap_realize (GtkWidget *widget)
gtk_widget_register_window (widget, window);
if (self->content)
- gtk_widget_set_parent_window (self->content, window);
+ register_window (self, self->content, &self->content_allocation, &self->content_window);
if (self->flap)
- gtk_widget_set_parent_window (self->flap, window);
+ register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
+
+ restack_windows (self);
+}
+
+static void
+hdy_flap_unrealize (GtkWidget *widget)
+{
+ HdyFlap *self = HDY_FLAP (widget);
+
+ unregister_window (self, &self->content_window);
+ unregister_window (self, &self->flap_window);
+
+ GTK_WIDGET_CLASS (hdy_flap_parent_class)->unrealize (widget);
}
static void
@@ -784,11 +880,13 @@ hdy_flap_add (GtkContainer *container,
return;
}
+ if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+ register_window (self, widget, &self->content_allocation, &self->content_window);
+ restack_windows (self);
+ }
+
gtk_widget_set_parent (widget, GTK_WIDGET (self));
self->content = widget;
-
- if (gtk_widget_get_realized (GTK_WIDGET (self)))
- gtk_widget_set_parent_window (self->content, gtk_widget_get_window (GTK_WIDGET (self)));
}
static void
@@ -797,12 +895,22 @@ hdy_flap_remove (GtkContainer *container,
{
HdyFlap *self = HDY_FLAP (container);
- if (widget == self->flap)
+ if (widget == self->flap) {
hdy_flap_set_flap (self, NULL);
- else if (widget == self->content)
+
+ return;
+ }
+
+ if (widget == self->content) {
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ unregister_window (self, &self->content_window);
+
g_clear_pointer (&self->content, gtk_widget_unparent);
- else
- g_return_if_reached ();
+
+ return;
+ }
+
+ g_return_if_reached ();
}
static void
@@ -913,6 +1021,7 @@ hdy_flap_class_init (HdyFlapClass *klass)
widget_class->size_allocate = hdy_flap_size_allocate;
widget_class->draw = hdy_flap_draw;
widget_class->realize = hdy_flap_realize;
+ widget_class->unrealize = hdy_flap_unrealize;
widget_class->direction_changed = hdy_flap_direction_changed;
container_class->remove = hdy_flap_remove;
@@ -1158,7 +1267,7 @@ hdy_flap_get_swipe_area (HdySwipeable *swipeable,
width = gtk_widget_get_allocated_width (GTK_WIDGET (self));
height = gtk_widget_get_allocated_height (GTK_WIDGET (self));
- gtk_widget_get_allocation (self->flap, &alloc);
+ alloc = self->flap_allocation;
if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
if (self->flap_position == get_start_or_end (self)) {
@@ -1245,12 +1354,21 @@ hdy_flap_set_flap (HdyFlap *self,
if (self->flap == flap)
return;
- if (self->flap)
+ if (self->flap) {
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ unregister_window (self, &self->flap_window);
+
gtk_widget_unparent (self->flap);
+ }
self->flap = flap;
if (self->flap) {
+ if (gtk_widget_get_realized (GTK_WIDGET (self))) {
+ register_window (self, self->flap, &self->flap_allocation, &self->flap_window);
+ restack_windows (self);
+ }
+
gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
if (gtk_widget_get_realized (GTK_WIDGET (self)))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]