[libadwaita/wip/exalm/recoloring-fixes: 35/35] tab-box: Support recolorability better
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libadwaita/wip/exalm/recoloring-fixes: 35/35] tab-box: Support recolorability better
- Date: Mon, 13 Sep 2021 13:51:22 +0000 (UTC)
commit fcc99b494994a6094e37cfbf6c7543fc79ffc208
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 | 103 +++++++++++++++++++++++++++++++++-
src/stylesheet/widgets/_tab-view.scss | 15 +++--
2 files changed, 113 insertions(+), 5 deletions(-)
---
diff --git a/src/adw-tab-box.c b/src/adw-tab-box.c
index 37f6bdeb..37a01e13 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,93 @@ adw_tab_box_size_allocate (GtkWidget *widget,
update_visible (self);
}
+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 scroll_pos;
+ int i, n;
+ GList *l;
+
+ rect.width = w;
+ rect.height = h;
+ region = cairo_region_create_rectangle (&rect);
+ scroll_pos = (int) floor (gtk_adjustment_get_value (self->adjustment));
+
+ if (self->reordered_tab) {
+ TabInfo *info = self->reordered_tab;
+
+ if (gtk_widget_get_opacity (GTK_WIDGET (info->tab)) > 0) {
+ gtk_widget_snapshot_child (widget, GTK_WIDGET (info->tab), snapshot);
+
+ rect.x = get_tab_position (self, info) - scroll_pos;
+ rect.width = info->width;
+ cairo_region_subtract_rectangle (region, &rect);
+ }
+ }
+
+ for (l = self->tabs; l; l = l->next) {
+ TabInfo *info = l->data;
+ gboolean clip = FALSE;
+ int pos, width;
+
+ if (info == self->reordered_tab)
+ continue;
+
+ if (gtk_widget_get_opacity (GTK_WIDGET (info->tab)) <= 0)
+ continue;
+
+ pos = get_tab_position (self, info);
+ width = info->width;
+
+ n = cairo_region_num_rectangles (region);
+ for (i = 0; i < n; i++) {
+ cairo_rectangle_int_t clip_rect;
+ int x1, x2;
+
+ cairo_region_get_rectangle (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, 0, clip_rect.width, h));
+ gtk_widget_snapshot_child (widget, GTK_WIDGET (info->tab), snapshot);
+ gtk_snapshot_pop (snapshot);
+ clip = TRUE;
+ }
+
+ if (!clip)
+ gtk_widget_snapshot_child (widget, GTK_WIDGET (info->tab), snapshot);
+
+ rect.x = pos - scroll_pos;
+ rect.width = width;
+ cairo_region_subtract_rectangle (region, &rect);
+ }
+
+ 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 +3185,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 +3300,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 +3405,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]