[libadwaita/wip/exalm/recoloring-fixes: 32/32] tab-box: Support recolorability better
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/recoloring-fixes: 32/32] tab-box: Support recolorability better
- Date: Tue, 14 Sep 2021 12:11:39 +0000 (UTC)
commit 271ebd8e25952c84fbbd6285b3910f3e3e014001
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Mon Sep 13 18:02:15 2021 +0500
tab-box: Support recolorability better
Move background to a separate widget instead of tab box itself.
Make tabs clip other tabs and the new background. This means that we can
have half-transparent background and borders on both, and let the
background of the tab bar be seen through.
This doesn't adjust colors yet, that will be done later when refreshing
colors in general. However, we can already get rid of the mix()ed border.
src/adw-tab-box.c | 110 +++++++++++++++++++++++++++++++++-
src/stylesheet/widgets/_tab-view.scss | 15 +++--
2 files changed, 120 insertions(+), 5 deletions(-)
---
diff --git a/src/adw-tab-box.c b/src/adw-tab-box.c
index 37f6bdeb..607a1127 100644
--- a/src/adw-tab-box.c
+++ b/src/adw-tab-box.c
@@ -11,6 +11,7 @@
#include "adw-tab-box-private.h"
#include "adw-animation-util-private.h"
#include "adw-animation-private.h"
+#include "adw-gizmo-private.h"
#include "adw-tab-private.h"
#include "adw-tab-bar-private.h"
#include "adw-tab-view-private.h"
@@ -93,6 +94,7 @@ struct _AdwTabBox
int n_tabs;
GtkPopover *context_menu;
+ GtkWidget *background;
int allocated_width;
int last_width;
@@ -2904,6 +2906,10 @@ adw_tab_box_size_allocate (GtkWidget *widget,
int pos;
double value;
+ gtk_widget_measure (self->background, GTK_ORIENTATION_HORIZONTAL, -1,
+ NULL, NULL, NULL, NULL);
+ gtk_widget_allocate (self->background, width, height, baseline, NULL);
+
adw_tab_box_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
&self->allocated_width, NULL, NULL, NULL);
self->allocated_width = MAX (self->allocated_width, width);
@@ -2983,7 +2989,7 @@ adw_tab_box_size_allocate (GtkWidget *widget,
if (is_rtl)
info->pos -= info->width;
- child_allocation.x = ((info == self->reordered_tab) ? self->reorder_window_x : info->pos) - value;
+ child_allocation.x = ((info == self->reordered_tab) ? self->reorder_window_x : info->pos) - (int) floor
(value);
child_allocation.y = 0;
child_allocation.width = info->width;
child_allocation.height = height;
@@ -3018,6 +3024,100 @@ adw_tab_box_size_allocate (GtkWidget *widget,
update_visible (self);
}
+static void
+snapshot_tab (AdwTabBox *self,
+ GtkSnapshot *snapshot,
+ TabInfo *info,
+ cairo_region_t *clip_region)
+{
+ cairo_rectangle_int_t rect = { 0, 0, 0, 0 };
+ gboolean clip = FALSE;
+ int pos, width, scroll_pos;
+ int i, n;
+
+ if (gtk_widget_get_opacity (GTK_WIDGET (info->tab)) <= 0)
+ return;
+
+ rect.height = gtk_widget_get_height (GTK_WIDGET (self));
+ scroll_pos = (int) floor (gtk_adjustment_get_value (self->adjustment));
+
+ pos = get_tab_position (self, info);
+ width = info->width;
+
+ n = cairo_region_num_rectangles (clip_region);
+ for (i = 0; i < n; i++) {
+ cairo_rectangle_int_t clip_rect;
+ int x1, x2;
+
+ cairo_region_get_rectangle (clip_region, i, &clip_rect);
+ x1 = clip_rect.x + scroll_pos;
+ x2 = x1 + clip_rect.width;
+
+ if (x1 < pos && x2 > pos + width) {
+ clip = FALSE;
+ break;
+ }
+
+ if (x2 < pos || x1 > pos + width)
+ continue;
+
+ gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (clip_rect.x, clip_rect.y, clip_rect.width,
clip_rect.height));
+ gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (info->tab), snapshot);
+ gtk_snapshot_pop (snapshot);
+ clip = TRUE;
+ }
+
+ if (!clip)
+ gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (info->tab), snapshot);
+
+ rect.x = pos - scroll_pos;
+ rect.width = width;
+ cairo_region_subtract_rectangle (clip_region, &rect);
+}
+
+static void
+adw_tab_box_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ AdwTabBox *self = ADW_TAB_BOX (widget);
+ int w = gtk_widget_get_width (widget);
+ int h = gtk_widget_get_height (widget);
+ cairo_rectangle_int_t rect = { 0, 0, 0, 0 };
+ cairo_region_t *region;
+ int i, n;
+ GList *l;
+
+ rect.width = w;
+ rect.height = h;
+ region = cairo_region_create_rectangle (&rect);
+
+ if (self->reordered_tab)
+ snapshot_tab (self, snapshot, self->reordered_tab, region);
+
+ if (self->selected_tab)
+ snapshot_tab (self, snapshot, self->selected_tab, region);
+
+ for (l = self->tabs; l; l = l->next) {
+ TabInfo *info = l->data;
+
+ if (info == self->reordered_tab || info == self->selected_tab)
+ continue;
+
+ snapshot_tab (self, snapshot, info, region);
+ }
+
+ n = cairo_region_num_rectangles (region);
+ for (i = 0; i < n; i++) {
+ cairo_region_get_rectangle (region, i, &rect);
+
+ gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (rect.x, rect.y, rect.width, rect.height));
+ gtk_widget_snapshot_child (widget, self->background, snapshot);
+ gtk_snapshot_pop (snapshot);
+ }
+
+ cairo_region_destroy (region);
+}
+
static gboolean
adw_tab_box_focus (GtkWidget *widget,
GtkDirectionType direction)
@@ -3092,6 +3192,8 @@ adw_tab_box_dispose (GObject *object)
g_clear_handle_id (&self->drop_switch_timeout_id, g_source_remove);
+ g_clear_pointer (&self->background, gtk_widget_unparent);
+
self->drag_gesture = NULL;
self->tab_bar = NULL;
adw_tab_box_set_view (self, NULL);
@@ -3205,6 +3307,7 @@ adw_tab_box_class_init (AdwTabBoxClass *klass)
widget_class->measure = adw_tab_box_measure;
widget_class->size_allocate = adw_tab_box_size_allocate;
+ widget_class->snapshot = adw_tab_box_snapshot;
widget_class->focus = adw_tab_box_focus;
widget_class->unrealize = adw_tab_box_unrealize;
widget_class->unmap = adw_tab_box_unmap;
@@ -3309,6 +3412,11 @@ adw_tab_box_init (AdwTabBox *self)
gtk_widget_set_overflow (GTK_WIDGET (self), GTK_OVERFLOW_HIDDEN);
+ self->background = adw_gizmo_new ("background", NULL, NULL, NULL, NULL, NULL, NULL);
+ gtk_widget_set_can_target (self->background, FALSE);
+ gtk_widget_set_can_focus (self->background, FALSE);
+ gtk_widget_set_parent (self->background, GTK_WIDGET (self));
+
controller = gtk_event_controller_motion_new ();
g_signal_connect_swapped (controller, "motion", G_CALLBACK (motion_cb), self);
g_signal_connect_swapped (controller, "leave", G_CALLBACK (leave_cb), self);
diff --git a/src/stylesheet/widgets/_tab-view.scss b/src/stylesheet/widgets/_tab-view.scss
index e8c03590..e7fb32a4 100644
--- a/src/stylesheet/widgets/_tab-view.scss
+++ b/src/stylesheet/widgets/_tab-view.scss
@@ -1,5 +1,5 @@
$tab_bg: $headerbar_bg_color;
-$tab_border: gtkmix($headerbar_border_color, $headerbar_bg_color, 100% * $headerbar_border_opacity);
+$tab_border: gtkalpha($headerbar_border_color, $headerbar_border_opacity);
@mixin undershoot-gradient($dir) {
@if $variant == 'dark' {
@@ -24,7 +24,7 @@ $tab_border: gtkmix($headerbar_border_color, $headerbar_bg_color, 100% * $header
tabbar {
.box {
min-height: 38px;
- background: gtkshade($tab_bg, .97);
+ background: $headerbar_bg_color;
color: $headerbar_fg_color;
border-bottom: 1px solid $tab_border;
}
@@ -42,7 +42,7 @@ tabbar {
border-right-width: 1px;
}
- tabbox {
+ tabbox > background {
&:dir(ltr) {
box-shadow: inset -1px 0 $tab_border;
}
@@ -73,12 +73,17 @@ tabbar {
@include need-attention-gradient("left");
}
+ tabbox > background {
+ background: gtkshade($tab_bg, .97);
+ }
+
tab {
border-style: solid;
border-color: $tab_border;
border-width: 0 1px 0 1px;
transition: background 150ms ease-in-out, $focus_transition;
background-color: $tab_bg;
+ background-clip: padding-box;
@include focus-ring();
@@ -97,7 +102,8 @@ tabbar {
.start-action,
.end-action {
- background: $tab_bg;
+ background-color: $tab_bg;
+ background-clip: padding-box;
border-color: $tab_border;
border-style: solid;
transition: background 150ms ease-in-out;
@@ -122,6 +128,7 @@ tabbar {
dnd tab {
min-height: 26px;
background-color: gtkshade($tab_bg, 1.09);
+ color: $headerbar_fg_color;
$_wm_border: if($variant=='light', transparentize(black, 0.77), transparentize(black, 0.25));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]