[libadwaita/wip/exalm/tab-overview] a
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/tab-overview] a
- Date: Sun, 28 Aug 2022 17:02:43 +0000 (UTC)
commit fb0f143522c05fbf1b69d2e6733f2811cee8262e
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sun Aug 28 21:02:17 2022 +0400
a
src/adw-tab-grid.c | 3 +
src/adw-tab-overview.c | 5 +
src/adw-tab-view-private.h | 3 +
src/adw-tab-view.c | 471 +++++++++++++++++++++++++++-------
src/adw-tab-view.h | 12 +
src/stylesheet/widgets/_tab-view.scss | 9 +-
6 files changed, 407 insertions(+), 96 deletions(-)
---
diff --git a/src/adw-tab-grid.c b/src/adw-tab-grid.c
index 82609844..f7f9d610 100644
--- a/src/adw-tab-grid.c
+++ b/src/adw-tab-grid.c
@@ -442,6 +442,9 @@ get_max_n_columns (AdwTabGrid *self)
other_max_columns += info->appear_progress;
}
+ max_columns = MAX (1, max_columns);
+ other_max_columns = MAX (1, other_max_columns);
+
return MAX (max_columns, other_max_columns);
}
diff --git a/src/adw-tab-overview.c b/src/adw-tab-overview.c
index 9217e64b..bbc29b71 100644
--- a/src/adw-tab-overview.c
+++ b/src/adw-tab-overview.c
@@ -18,6 +18,7 @@
#include "adw-style-manager.h"
#include "adw-tab-grid-private.h"
#include "adw-tab-thumbnail-private.h"
+#include "adw-tab-view-private.h"
#include "adw-timed-animation.h"
#include "adw-widget-utils-private.h"
#include "adw-window-title.h"
@@ -894,6 +895,8 @@ open_animation_done_cb (AdwTabOverview *self)
gtk_widget_set_can_target (self->child_bin, TRUE);
gtk_widget_set_can_focus (self->child_bin, TRUE);
+ adw_tab_view_close_overview (self->view);
+
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (self->search_bar), FALSE);
if (self->last_focus) {
@@ -1896,6 +1899,8 @@ adw_tab_overview_set_open (AdwTabOverview *self,
(gpointer *) &self->last_focus);
}
+ adw_tab_view_open_overview (self->view);
+
gtk_widget_set_child_visible (self->overview, TRUE);
gtk_widget_set_can_target (self->overview, TRUE);
gtk_widget_set_can_focus (self->overview, TRUE);
diff --git a/src/adw-tab-view-private.h b/src/adw-tab-view-private.h
index 9a250bf8..e26b4f2b 100644
--- a/src/adw-tab-view-private.h
+++ b/src/adw-tab-view-private.h
@@ -29,4 +29,7 @@ void adw_tab_view_attach_page (AdwTabView *self,
AdwTabView *adw_tab_view_create_window (AdwTabView *self) G_GNUC_WARN_UNUSED_RESULT;
+void adw_tab_view_open_overview (AdwTabView *self);
+void adw_tab_view_close_overview (AdwTabView *self);
+
G_END_DECLS
diff --git a/src/adw-tab-view.c b/src/adw-tab-view.c
index f2de2ff7..12b1d1a2 100644
--- a/src/adw-tab-view.c
+++ b/src/adw-tab-view.c
@@ -10,6 +10,7 @@
#include "adw-tab-view-private.h"
+#include "adw-bin.h"
#include "adw-gizmo-private.h"
#include "adw-macros-private.h"
#include "adw-widget-utils-private.h"
@@ -118,6 +119,7 @@ struct _AdwTabPage
{
GObject parent_instance;
+ GtkWidget *bin;
GtkWidget *child;
AdwTabPage *parent;
gboolean selected;
@@ -135,9 +137,13 @@ struct _AdwTabPage
float thumbnail_yalign;
GtkWidget *last_focus;
+ GBinding *transfer_binding;
gboolean closing;
GdkPaintable *paintable;
+
+ gboolean live_thumbnail;
+ gboolean refresh_queued;
};
G_DEFINE_FINAL_TYPE (AdwTabPage, adw_tab_page, G_TYPE_OBJECT)
@@ -159,6 +165,7 @@ enum {
PAGE_PROP_KEYWORD,
PAGE_PROP_THUMBNAIL_XALIGN,
PAGE_PROP_THUMBNAIL_YALIGN,
+ PAGE_PROP_LIVE_THUMBNAIL,
LAST_PAGE_PROP
};
@@ -178,6 +185,8 @@ struct _AdwTabView
AdwTabViewShortcuts shortcuts;
int transfer_count;
+ int overview_count;
+ gulong unmap_extra_pages_cb;
GtkSelectionModel *pages;
};
@@ -217,6 +226,16 @@ enum {
static guint signals[SIGNAL_LAST_SIGNAL];
+static gboolean
+page_should_be_visible (AdwTabView *view,
+ AdwTabPage *page)
+{
+ if (!view->overview_count)
+ return FALSE;
+
+ return page->live_thumbnail || page->refresh_queued;
+}
+
static void
set_page_selected (AdwTabPage *self,
gboolean selected)
@@ -290,6 +309,33 @@ set_page_parent (AdwTabPage *self,
g_object_notify_by_pspec (G_OBJECT (self), props[PAGE_PROP_PARENT]);
}
+static void
+map_or_unmap_page (AdwTabPage *self)
+{
+ GtkWidget *parent;
+ AdwTabView *view;
+ gboolean should_be_visible;
+
+ parent = gtk_widget_get_parent (self->bin);
+
+ if (!ADW_IS_TAB_VIEW (parent))
+ return;
+
+ view = ADW_TAB_VIEW (parent);
+
+ if (!view->overview_count)
+ return;
+
+ should_be_visible = self == view->selected_page ||
+ page_should_be_visible (view, self);
+
+ if (gtk_widget_get_child_visible (self->bin) == should_be_visible)
+ return;
+
+ gtk_widget_set_child_visible (self->bin, should_be_visible);
+ gtk_widget_queue_allocate (parent);
+}
+
static void
adw_tab_page_dispose (GObject *object)
{
@@ -297,6 +343,7 @@ adw_tab_page_dispose (GObject *object)
set_page_parent (self, NULL);
+ g_clear_object (&self->bin);
g_clear_object (&self->paintable);
G_OBJECT_CLASS (adw_tab_page_parent_class)->dispose (object);
@@ -391,6 +438,10 @@ adw_tab_page_get_property (GObject *object,
g_value_set_float (value, adw_tab_page_get_thumbnail_yalign (self));
break;
+ case PAGE_PROP_LIVE_THUMBNAIL:
+ g_value_set_boolean (value, adw_tab_page_get_live_thumbnail (self));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -407,6 +458,7 @@ adw_tab_page_set_property (GObject *object,
switch (prop_id) {
case PAGE_PROP_CHILD:
g_set_object (&self->child, g_value_get_object (value));
+ adw_bin_set_child (ADW_BIN (self->bin), g_value_get_object (value));
break;
case PAGE_PROP_PARENT:
@@ -457,6 +509,10 @@ adw_tab_page_set_property (GObject *object,
adw_tab_page_set_thumbnail_yalign (self, g_value_get_float (value));
break;
+ case PAGE_PROP_LIVE_THUMBNAIL:
+ adw_tab_page_set_live_thumbnail (self, g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -703,6 +759,18 @@ adw_tab_page_class_init (AdwTabPageClass *klass)
0.0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+ /**
+ * AdwTabPage:live-thumbnail: (attributes org.gtk.Property.get=adw_tab_page_get_live_thumbnail
org.gtk.Property.set=adw_tab_page_set_live_thumbnail)
+ *
+ * TODO
+ *
+ * Since: 1.3
+ */
+ page_props[PAGE_PROP_LIVE_THUMBNAIL] =
+ g_param_spec_boolean ("live-thumbnail", NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
g_object_class_install_properties (object_class, LAST_PAGE_PROP, page_props);
}
@@ -714,6 +782,7 @@ adw_tab_page_init (AdwTabPage *self)
self->indicator_tooltip = g_strdup ("");
self->thumbnail_xalign = 0;
self->thumbnail_yalign = 0;
+ self->bin = g_object_ref_sink (adw_bin_new ());
}
#define ADW_TYPE_TAB_PAINTABLE (adw_tab_paintable_get_type ())
@@ -728,12 +797,16 @@ struct _AdwTabPaintable
AdwTabPage *page;
GdkPaintable *view_paintable;
+ GdkPaintable *child_paintable;
GdkPaintable *cached_paintable;
- GdkRGBA cached_bg;
+ double cached_aspect_ratio;
- gboolean schedule_clear_cache;
gboolean frozen;
+
+ double last_xalign;
+ double last_yalign;
+ GdkRGBA last_bg_color;
};
static void
@@ -743,7 +816,7 @@ get_background_color (AdwTabPaintable *self,
GtkWidget *child = adw_tab_page_get_child (self->page);
GtkStyleContext *context = gtk_widget_get_style_context (child);
- if (gtk_style_context_lookup_color (context, "window_bg_color", rgba))
+ if (gtk_style_context_lookup_color (context, "thumbnail_bg_color", rgba))
return;
rgba->red = 1;
@@ -757,48 +830,41 @@ invalidate_contents_and_clear_cache (AdwTabPaintable *self)
{
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
- if (self->schedule_clear_cache) {
+ if (!self->frozen &&
+ self->page->bin &&
+ gtk_widget_get_mapped (self->page->bin))
g_clear_object (&self->cached_paintable);
- self->schedule_clear_cache = FALSE;
- }
}
-static void
-child_map_cb (AdwTabPaintable *self)
+static double
+get_unclamped_aspect_ratio (AdwTabPaintable *self)
{
- if (self->frozen)
- return;
+ if (self->frozen || !self->view_paintable)
+ return self->cached_aspect_ratio;
- gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
-
- self->schedule_clear_cache = TRUE;
+ return gdk_paintable_get_intrinsic_aspect_ratio (self->view_paintable);
}
static void
child_unmap_cb (AdwTabPaintable *self)
{
- if (self->frozen || self->cached_paintable || !self->view)
+ if (self->frozen)
return;
g_clear_object (&self->cached_paintable);
- self->cached_paintable = gdk_paintable_get_current_image (self->view_paintable);
-
- get_background_color (self, &self->cached_bg);
+ self->cached_paintable = gdk_paintable_get_current_image (self->child_paintable);
+ self->cached_aspect_ratio = get_unclamped_aspect_ratio (self);
}
static void
connect_to_view (AdwTabPaintable *self)
{
- GtkWidget *child = adw_tab_page_get_child (self->page);
-
- if (self->view || !gtk_widget_get_parent (child))
+ if (self->view || !gtk_widget_get_parent (self->page->bin))
return;
- self->view = gtk_widget_get_ancestor (child, ADW_TYPE_TAB_VIEW);
+ self->view = gtk_widget_get_parent (self->page->bin);
self->view_paintable = gtk_widget_paintable_new (self->view);
- g_signal_connect_swapped (self->view_paintable, "invalidate-contents",
- G_CALLBACK (invalidate_contents_and_clear_cache), self);
g_signal_connect_swapped (self->view_paintable, "invalidate-size",
G_CALLBACK (gdk_paintable_invalidate_size), self);
}
@@ -807,7 +873,6 @@ static void
disconnect_from_view (AdwTabPaintable *self)
{
g_clear_object (&self->view_paintable);
-
self->view = NULL;
}
@@ -822,28 +887,21 @@ static double
adw_tab_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
{
AdwTabPaintable *self = ADW_TAB_PAINTABLE (paintable);
- double ratio;
-
- if (self->view_paintable)
- ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->view_paintable);
- else if (self->cached_paintable)
- ratio = gdk_paintable_get_intrinsic_aspect_ratio (self->cached_paintable);
- else
- ratio = 0;
+ double ratio = get_unclamped_aspect_ratio (self);
return CLAMP (ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
}
static void
-snapshot_paintable (GtkSnapshot *snapshot,
- double width,
- double height,
- GdkPaintable *paintable,
- double xalign,
- double yalign)
+snapshot_paintable (GtkSnapshot *snapshot,
+ double width,
+ double height,
+ GdkPaintable *paintable,
+ double paintable_ratio,
+ double xalign,
+ double yalign)
{
double snapshot_ratio = width / height;
- double paintable_ratio = gdk_paintable_get_intrinsic_aspect_ratio (paintable);
if (paintable_ratio > snapshot_ratio) {
double new_width = height * paintable_ratio;
@@ -894,35 +952,42 @@ adw_tab_paintable_snapshot (GdkPaintable *paintable,
GdkRGBA bg;
double xalign, yalign;
- if (!self->view)
- return;
-
- child = adw_tab_page_get_child (self->page);
- xalign = adw_tab_page_get_thumbnail_xalign (self->page);
- yalign = adw_tab_page_get_thumbnail_yalign (self->page);
+ if (self->frozen) {
+ xalign = self->last_xalign;
+ yalign = self->last_yalign;
+ child = NULL;
+ } else {
+ xalign = adw_tab_page_get_thumbnail_xalign (self->page);
+ yalign = adw_tab_page_get_thumbnail_yalign (self->page);
+ child = self->page->bin;
- if (gtk_widget_get_direction (child) == GTK_TEXT_DIR_RTL)
- xalign = 1 - xalign;
+ if (gtk_widget_get_direction (child) == GTK_TEXT_DIR_RTL)
+ xalign = 1 - xalign;
+ }
if (self->cached_paintable) {
- gtk_snapshot_append_color (GTK_SNAPSHOT (snapshot), &self->cached_bg,
- &GRAPHENE_RECT_INIT (0, 0, width, height));
-
snapshot_paintable (GTK_SNAPSHOT (snapshot), width, height,
- self->cached_paintable, xalign, yalign);
-
+ self->cached_paintable, self->cached_aspect_ratio,
+ xalign, yalign);
return;
}
- if (!gtk_widget_get_mapped (child) || self->schedule_clear_cache)
+ if (child && gtk_widget_get_mapped (child)) {
+ double aspect_ratio = get_unclamped_aspect_ratio (self);
+
+ snapshot_paintable (GTK_SNAPSHOT (snapshot), width, height,
+ self->child_paintable, aspect_ratio,
+ xalign, yalign);
return;
+ }
+
+ if (self->frozen)
+ bg = self->last_bg_color;
+ else
+ get_background_color (self, &bg);
- get_background_color (self, &bg);
gtk_snapshot_append_color (GTK_SNAPSHOT (snapshot), &bg,
&GRAPHENE_RECT_INIT (0, 0, width, height));
-
- snapshot_paintable (GTK_SNAPSHOT (snapshot), width, height,
- self->view_paintable, xalign, yalign);
}
static void
@@ -943,6 +1008,7 @@ adw_tab_paintable_dispose (GObject *object)
disconnect_from_view (self);
+ g_clear_object (&self->child_paintable);
g_clear_object (&self->cached_paintable);
G_OBJECT_CLASS (adw_tab_paintable_parent_class)->dispose (object);
@@ -965,14 +1031,16 @@ static GdkPaintable *
adw_tab_paintable_new (AdwTabPage *page)
{
AdwTabPaintable *self = g_object_new (ADW_TYPE_TAB_PAINTABLE, NULL);
- GtkWidget *child;
self->page = page;
- child = adw_tab_page_get_child (page);
-
connect_to_view (self);
+ self->child_paintable = gtk_widget_paintable_new (page->bin);
+
+ g_signal_connect_swapped (self->child_paintable, "invalidate-contents",
+ G_CALLBACK (invalidate_contents_and_clear_cache), self);
+
g_signal_connect_object (self->page, "notify::thumbnail-xalign",
G_CALLBACK (gdk_paintable_invalidate_contents), self,
G_CONNECT_SWAPPED);
@@ -980,13 +1048,10 @@ adw_tab_paintable_new (AdwTabPage *page)
G_CALLBACK (gdk_paintable_invalidate_contents), self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (child, "notify::parent",
+ g_signal_connect_object (page->bin, "notify::parent",
G_CALLBACK (child_parent_changed), self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (child, "map",
- G_CALLBACK (child_map_cb), self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (child, "unmap",
+ g_signal_connect_object (page->bin, "unmap",
G_CALLBACK (child_unmap_cb), self,
G_CONNECT_SWAPPED);
@@ -997,8 +1062,16 @@ static void
adw_tab_paintable_freeze (AdwTabPaintable *self)
{
child_unmap_cb (self);
- self->schedule_clear_cache = FALSE;
+ self->last_xalign = adw_tab_page_get_thumbnail_xalign (self->page);
+ self->last_yalign = adw_tab_page_get_thumbnail_yalign (self->page);
+ get_background_color (self, &self->last_bg_color);
+
+ if (gtk_widget_get_direction (self->page->bin) == GTK_TEXT_DIR_RTL)
+ self->last_xalign = 1 - self->last_xalign;
+
self->frozen = TRUE;
+
+ g_clear_object (&self->child_paintable);
}
#define ADW_TYPE_TAB_PAGES (adw_tab_pages_get_type ())
@@ -1180,7 +1253,7 @@ page_belongs_to_this_view (AdwTabView *self,
if (!page)
return FALSE;
- return gtk_widget_get_parent (page->child) == GTK_WIDGET (self);
+ return gtk_widget_get_parent (page->bin) == GTK_WIDGET (self);
}
static inline gboolean
@@ -1198,13 +1271,18 @@ attach_page (AdwTabView *self,
AdwTabPage *page,
int position)
{
- GtkWidget *child = adw_tab_page_get_child (page);
AdwTabPage *parent;
g_list_store_insert (self->children, position, page);
- gtk_widget_set_child_visible (child, FALSE);
- gtk_widget_set_parent (child, GTK_WIDGET (self));
+ gtk_widget_set_child_visible (page->bin,
+ page_should_be_visible (self, page));
+ gtk_widget_set_parent (page->bin, GTK_WIDGET (self));
+ page->transfer_binding =
+ g_object_bind_property (self, "is-transferring-page",
+ page->bin, "can-target",
+ G_BINDING_SYNC_CREATE |
+ G_BINDING_INVERT_BOOLEAN);
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_freeze_notify (G_OBJECT (self));
@@ -1246,8 +1324,8 @@ set_selected_page (AdwTabView *self,
if (!gtk_widget_in_destruction (GTK_WIDGET (self)) &&
focus &&
self->selected_page &&
- self->selected_page->child &&
- gtk_widget_is_ancestor (focus, self->selected_page->child)) {
+ self->selected_page->bin &&
+ gtk_widget_is_ancestor (focus, self->selected_page->bin)) {
contains_focus = TRUE;
if (self->selected_page->last_focus)
@@ -1258,8 +1336,9 @@ set_selected_page (AdwTabView *self,
(gpointer *) &self->selected_page->last_focus);
}
- if (self->selected_page->child)
- gtk_widget_set_child_visible (self->selected_page->child, FALSE);
+ if (self->selected_page->bin)
+ gtk_widget_set_child_visible (self->selected_page->bin,
+ page_should_be_visible (self, self->selected_page));
set_page_selected (self->selected_page, FALSE);
}
@@ -1271,13 +1350,13 @@ set_selected_page (AdwTabView *self,
new_position = adw_tab_view_get_page_position (self, self->selected_page);
if (!gtk_widget_in_destruction (GTK_WIDGET (self))) {
- gtk_widget_set_child_visible (selected_page->child, TRUE);
+ gtk_widget_set_child_visible (selected_page->bin, TRUE);
if (contains_focus) {
if (selected_page->last_focus)
gtk_widget_grab_focus (selected_page->last_focus);
else
- gtk_widget_child_focus (selected_page->child, GTK_DIR_TAB_FORWARD);
+ gtk_widget_child_focus (selected_page->bin, GTK_DIR_TAB_FORWARD);
}
gtk_widget_queue_allocate (GTK_WIDGET (self));
@@ -1351,14 +1430,11 @@ detach_page (AdwTabView *self,
gboolean in_dispose)
{
int pos = adw_tab_view_get_page_position (self, page);
- GtkWidget *child;
select_previous_page (self, page);
- child = adw_tab_page_get_child (page);
-
g_object_ref (page);
- g_object_ref (child);
+ g_object_ref (page->bin);
if (self->n_pages == 1)
set_selected_page (self, NULL, !in_dispose);
@@ -1374,7 +1450,8 @@ detach_page (AdwTabView *self,
g_object_thaw_notify (G_OBJECT (self));
- gtk_widget_unparent (child);
+ g_clear_pointer (&page->transfer_binding, g_binding_unbind);
+ gtk_widget_unparent (page->bin);
if (!in_dispose)
gtk_widget_queue_resize (GTK_WIDGET (self));
@@ -1384,7 +1461,7 @@ detach_page (AdwTabView *self,
if (!in_dispose && self->pages)
g_list_model_items_changed (G_LIST_MODEL (self->pages), pos, 1, 0);
- g_object_unref (child);
+ g_object_unref (page->bin);
g_object_unref (page);
}
@@ -1703,16 +1780,13 @@ adw_tab_view_measure (GtkWidget *widget,
for (i = 0; i < self->n_pages; i++) {
AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+ int child_min, child_nat;
- if (gtk_widget_get_visible (page->child)) {
- int child_min, child_nat;
+ gtk_widget_measure (page->bin, orientation, for_size,
+ &child_min, &child_nat, NULL, NULL);
- gtk_widget_measure (page->child, orientation, for_size,
- &child_min, &child_nat, NULL, NULL);
-
- *minimum = MAX (*minimum, child_min);
- *natural = MAX (*natural, child_nat);
- }
+ *minimum = MAX (*minimum, child_min);
+ *natural = MAX (*natural, child_nat);
}
}
@@ -1723,11 +1797,80 @@ adw_tab_view_size_allocate (GtkWidget *widget,
int baseline)
{
AdwTabView *self = ADW_TAB_VIEW (widget);
+ int i;
- if (!self->selected_page)
- return;
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ if (gtk_widget_get_child_visible (page->bin))
+ gtk_widget_allocate (page->bin, width, height, baseline, NULL);
+ }
+}
+
+static gboolean
+unmap_extra_pages (AdwTabView *self)
+{
+ int i;
+
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ if (page == self->selected_page)
+ continue;
+
+ if (!gtk_widget_get_child_visible (page->bin))
+ continue;
+
+ if (page_should_be_visible (self, page))
+ continue;
+
+ gtk_widget_set_child_visible (page->bin, FALSE);
+ }
+
+ self->unmap_extra_pages_cb = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+adw_tab_view_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ AdwTabView *self = ADW_TAB_VIEW (widget);
+ int i;
- gtk_widget_allocate (self->selected_page->child, width, height, baseline, NULL);
+ if (self->selected_page)
+ gtk_widget_snapshot_child (widget, self->selected_page->bin, snapshot);
+
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ if (page == self->selected_page) {
+ page->refresh_queued = FALSE;
+ continue;
+ }
+
+ if (!gtk_widget_get_child_visible (page->bin))
+ continue;
+
+ if (page->paintable) {
+ /* We don't want to actually draw the child, but we do need it
+ * to redraw so that it can be displayed by its paintable */
+ GtkSnapshot *child_snapshot = gtk_snapshot_new ();
+
+ gtk_widget_snapshot_child (widget, page->bin, child_snapshot);
+
+ child_unmap_cb (ADW_TAB_PAINTABLE (page->paintable));
+
+ g_object_unref (child_snapshot);
+ }
+
+ page->refresh_queued = FALSE;
+
+ if (!self->unmap_extra_pages_cb)
+ self->unmap_extra_pages_cb =
+ g_idle_add ((GSourceFunc) unmap_extra_pages, self);
+ }
}
static void
@@ -1735,6 +1878,11 @@ adw_tab_view_dispose (GObject *object)
{
AdwTabView *self = ADW_TAB_VIEW (object);
+ if (self->unmap_extra_pages_cb) {
+ g_source_remove (self->unmap_extra_pages_cb);
+ self->unmap_extra_pages_cb = 0;
+ }
+
if (self->pages)
g_list_model_items_changed (G_LIST_MODEL (self->pages), 0, self->n_pages, 0);
@@ -1855,6 +2003,7 @@ adw_tab_view_class_init (AdwTabViewClass *klass)
widget_class->measure = adw_tab_view_measure;
widget_class->size_allocate = adw_tab_view_size_allocate;
+ widget_class->snapshot = adw_tab_view_snapshot;
widget_class->get_request_mode = adw_widget_get_request_mode;
widget_class->compute_expand = adw_widget_compute_expand;
@@ -2819,6 +2968,70 @@ adw_tab_page_set_thumbnail_yalign (AdwTabPage *self,
g_object_notify_by_pspec (G_OBJECT (self), page_props[PAGE_PROP_THUMBNAIL_YALIGN]);
}
+/**
+ * adw_tab_page_get_live_thumbnail: (attributes org.gtk.Method.get_property=live-thumbnail)
+ * @self: a tab overview
+ *
+ * Gets TODO
+ *
+ * Returns: TODO
+ *
+ * Since: 1.3
+ */
+gboolean
+adw_tab_page_get_live_thumbnail (AdwTabPage *self)
+{
+ g_return_val_if_fail (ADW_IS_TAB_PAGE (self), FALSE);
+
+ return self->live_thumbnail;
+}
+
+/**
+ * adw_tab_page_set_live_thumbnail: (attributes org.gtk.Method.set_property=live-thumbnail)
+ * @self: a tab page
+ * @live_thumbnail: TODO
+ *
+ * Sets TODO
+ *
+ * Since: 1.3
+ */
+void
+adw_tab_page_set_live_thumbnail (AdwTabPage *self,
+ gboolean live_thumbnail)
+{
+ g_return_if_fail (ADW_IS_TAB_PAGE (self));
+
+ live_thumbnail = !!live_thumbnail;
+
+ if (self->live_thumbnail == live_thumbnail)
+ return;
+
+ self->live_thumbnail = live_thumbnail;
+
+ map_or_unmap_page (self);
+
+ g_object_notify_by_pspec (G_OBJECT (self), page_props[PAGE_PROP_LIVE_THUMBNAIL]);
+}
+
+
+/**
+ * adw_tab_page_queue_refresh_thumbnail:
+ * @self: a tab page
+ *
+ * TODO
+ *
+ * Since: 1.3
+ */
+void
+adw_tab_page_queue_refresh_thumbnail (AdwTabPage *self)
+{
+ g_return_if_fail (ADW_IS_TAB_PAGE (self));
+
+ self->refresh_queued = TRUE;
+
+ map_or_unmap_page (self);
+}
+
GdkPaintable *
adw_tab_page_get_paintable (AdwTabPage *self)
{
@@ -3356,11 +3569,15 @@ AdwTabPage *
adw_tab_view_get_page (AdwTabView *self,
GtkWidget *child)
{
+ GtkWidget *parent;
int i;
g_return_val_if_fail (ADW_IS_TAB_VIEW (self), NULL);
g_return_val_if_fail (GTK_IS_WIDGET (child), NULL);
- g_return_val_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (self), NULL);
+
+ parent = gtk_widget_get_parent (child);
+
+ g_return_val_if_fail (parent && gtk_widget_get_parent (parent) == GTK_WIDGET (self), NULL);
for (i = 0; i < self->n_pages; i++) {
AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
@@ -4080,6 +4297,27 @@ adw_tab_view_get_pages (AdwTabView *self)
return self->pages;
}
+/**
+ * adw_tab_view_queue_refresh_thumbnails:
+ * @self: a tab view
+ *
+ * TODO
+ *
+ * Since: 1.3
+ */
+void
+adw_tab_view_queue_refresh_thumbnails (AdwTabView *self)
+{
+ int i;
+ g_return_if_fail (ADW_IS_TAB_VIEW (self));
+
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ adw_tab_page_queue_refresh_thumbnail (page);
+ }
+}
+
AdwTabView *
adw_tab_view_create_window (AdwTabView *self)
{
@@ -4097,3 +4335,48 @@ adw_tab_view_create_window (AdwTabView *self)
return new_view;
}
+
+void
+adw_tab_view_open_overview (AdwTabView *self)
+{
+ g_return_if_fail (ADW_IS_TAB_VIEW (self));
+
+ if (self->overview_count == 0) {
+ int i;
+
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ if (page->live_thumbnail || page->refresh_queued)
+ gtk_widget_set_child_visible (page->bin, TRUE);
+ }
+
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+ }
+
+ self->overview_count++;
+}
+
+void
+adw_tab_view_close_overview (AdwTabView *self)
+{
+ g_return_if_fail (ADW_IS_TAB_VIEW (self));
+
+ self->overview_count--;
+
+ if (self->overview_count == 0) {
+ int i;
+
+ for (i = 0; i < self->n_pages; i++) {
+ AdwTabPage *page = adw_tab_view_get_nth_page (self, i);
+
+ if (page->live_thumbnail || page->refresh_queued)
+ gtk_widget_set_child_visible (page->bin,
+ page == self->selected_page);
+ }
+
+ gtk_widget_queue_allocate (GTK_WIDGET (self));
+ }
+
+ g_assert (self->overview_count >= 0);
+}
diff --git a/src/adw-tab-view.h b/src/adw-tab-view.h
index ad4fdf11..51e01900 100644
--- a/src/adw-tab-view.h
+++ b/src/adw-tab-view.h
@@ -119,6 +119,15 @@ ADW_AVAILABLE_IN_1_2
void adw_tab_page_set_thumbnail_yalign (AdwTabPage *self,
float yalign);
+ADW_AVAILABLE_IN_1_2
+gboolean adw_tab_page_get_live_thumbnail (AdwTabPage *self);
+ADW_AVAILABLE_IN_1_2
+void adw_tab_page_set_live_thumbnail (AdwTabPage *self,
+ gboolean live_thumbnail);
+
+ADW_AVAILABLE_IN_1_2
+void adw_tab_page_queue_refresh_thumbnail (AdwTabPage *self);
+
#define ADW_TYPE_TAB_VIEW (adw_tab_view_get_type())
ADW_AVAILABLE_IN_ALL
@@ -258,4 +267,7 @@ void adw_tab_view_transfer_page (AdwTabView *self,
ADW_AVAILABLE_IN_ALL
GtkSelectionModel *adw_tab_view_get_pages (AdwTabView *self) G_GNUC_WARN_UNUSED_RESULT;
+ADW_AVAILABLE_IN_1_2
+void adw_tab_view_queue_refresh_thumbnails (AdwTabView *self);
+
G_END_DECLS
diff --git a/src/stylesheet/widgets/_tab-view.scss b/src/stylesheet/widgets/_tab-view.scss
index 31ed8cfd..9dc8cadc 100644
--- a/src/stylesheet/widgets/_tab-view.scss
+++ b/src/stylesheet/widgets/_tab-view.scss
@@ -178,8 +178,8 @@ tabthumbnail {
border-radius: $card_radius;
}
- background-color: $thumbnail_bg_color;
- color: $thumbnail_fg_color;
+ background: none;
+ color: inherit;
@if $contrast == 'high' {
box-shadow: 0 0 0 1px transparentize(black, 0.5),
@@ -188,6 +188,11 @@ tabthumbnail {
}
}
+ &.pinned .card {
+ background-color: $thumbnail_bg_color;
+ color: $thumbnail_fg_color;
+ }
+
.pinned-box {
margin-left: 10px;
margin-right: 10px;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]