From feecfbca6fa5cff2bcfbdf2a0bf79785da951108 Mon Sep 17 00:00:00 2001 From: Alice Mikhaylenko Date: Wed, 20 Mar 2024 21:23:00 +0400 Subject: [PATCH] tmp: Add libadwaita styles --- gtk/meson.build | 2 + gtk/theme/libadwaita/README.md | 42 ++ gtk/theme/libadwaita/_colors.scss | 131 ++++ gtk/theme/libadwaita/_common.scss | 107 +++ gtk/theme/libadwaita/_compat-colors.scss | 0 gtk/theme/libadwaita/_defaults.scss | 83 +++ gtk/theme/libadwaita/_drawing.scss | 138 ++++ gtk/theme/libadwaita/_functions.scss | 16 + gtk/theme/libadwaita/_palette.scss | 94 +++ gtk/theme/libadwaita/_widgets.scss | 42 ++ .../adwaita-stylesheet.gresources.xml | 32 + .../libadwaita/assets/bullet-symbolic.svg | 1 + .../assets/bullet-symbolic.symbolic.png | Bin 0 -> 165 bytes .../assets/bullet@2-symbolic.symbolic.png | Bin 0 -> 268 bytes .../libadwaita/assets/check-symbolic.svg | 1 + .../assets/check-symbolic.symbolic.png | Bin 0 -> 244 bytes .../assets/check@2-symbolic.symbolic.png | Bin 0 -> 369 bytes gtk/theme/libadwaita/assets/dash-symbolic.svg | 1 + .../assets/dash-symbolic.symbolic.png | Bin 0 -> 130 bytes .../assets/dash@2-symbolic.symbolic.png | Bin 0 -> 183 bytes .../libadwaita/assets/devel-symbolic.svg | 1 + gtk/theme/libadwaita/base-hc.scss | 8 + gtk/theme/libadwaita/base.scss | 8 + gtk/theme/libadwaita/defaults-dark.scss | 3 + gtk/theme/libadwaita/defaults-light.scss | 3 + gtk/theme/libadwaita/empty.css | 0 gtk/theme/libadwaita/gtk-dark.css | 2 + gtk/theme/libadwaita/gtk-hc-dark.css | 2 + gtk/theme/libadwaita/gtk-hc.css | 2 + gtk/theme/libadwaita/gtk.css | 2 + gtk/theme/libadwaita/meson.build | 100 +++ gtk/theme/libadwaita/widgets/_avatar.scss | 38 ++ .../libadwaita/widgets/_bottom-sheet.scss | 45 ++ gtk/theme/libadwaita/widgets/_buttons.scss | 628 ++++++++++++++++++ gtk/theme/libadwaita/widgets/_calendar.scss | 54 ++ gtk/theme/libadwaita/widgets/_checks.scss | 104 +++ .../libadwaita/widgets/_color-chooser.scss | 109 +++ .../libadwaita/widgets/_column-view.scss | 115 ++++ gtk/theme/libadwaita/widgets/_deprecated.scss | 343 ++++++++++ gtk/theme/libadwaita/widgets/_dialogs.scss | 125 ++++ gtk/theme/libadwaita/widgets/_dropdowns.scss | 38 ++ .../libadwaita/widgets/_emoji-chooser.scss | 91 +++ gtk/theme/libadwaita/widgets/_entries.scss | 107 +++ gtk/theme/libadwaita/widgets/_expanders.scss | 27 + .../libadwaita/widgets/_file-chooser.scss | 230 +++++++ gtk/theme/libadwaita/widgets/_header-bar.scss | 230 +++++++ gtk/theme/libadwaita/widgets/_labels.scss | 92 +++ gtk/theme/libadwaita/widgets/_level-bar.scss | 100 +++ gtk/theme/libadwaita/widgets/_linked.scss | 46 ++ gtk/theme/libadwaita/widgets/_links.scss | 53 ++ gtk/theme/libadwaita/widgets/_lists.scss | 547 +++++++++++++++ gtk/theme/libadwaita/widgets/_menus.scss | 275 ++++++++ .../libadwaita/widgets/_message-dialog.scss | 170 +++++ gtk/theme/libadwaita/widgets/_misc.scss | 228 +++++++ gtk/theme/libadwaita/widgets/_notebook.scss | 216 ++++++ gtk/theme/libadwaita/widgets/_paned.scss | 46 ++ gtk/theme/libadwaita/widgets/_popovers.scss | 83 +++ .../libadwaita/widgets/_preferences.scss | 18 + .../libadwaita/widgets/_progress-bar.scss | 93 +++ gtk/theme/libadwaita/widgets/_scale.scss | 232 +++++++ gtk/theme/libadwaita/widgets/_scrolling.scss | 184 +++++ .../libadwaita/widgets/_shortcuts-window.scss | 55 ++ gtk/theme/libadwaita/widgets/_sidebars.scss | 215 ++++++ .../libadwaita/widgets/_spin-button.scss | 72 ++ gtk/theme/libadwaita/widgets/_spinner.scss | 16 + gtk/theme/libadwaita/widgets/_switch.scss | 60 ++ gtk/theme/libadwaita/widgets/_tab-view.scss | 268 ++++++++ .../libadwaita/widgets/_text-selection.scss | 30 + gtk/theme/libadwaita/widgets/_toolbars.scss | 310 +++++++++ gtk/theme/libadwaita/widgets/_tooltip.scss | 20 + .../libadwaita/widgets/_view-switcher.scss | 123 ++++ gtk/theme/libadwaita/widgets/_views.scss | 75 +++ gtk/theme/libadwaita/widgets/_window.scss | 81 +++ 73 files changed, 6813 insertions(+) create mode 100644 gtk/theme/libadwaita/README.md create mode 100644 gtk/theme/libadwaita/_colors.scss create mode 100644 gtk/theme/libadwaita/_common.scss create mode 100644 gtk/theme/libadwaita/_compat-colors.scss create mode 100644 gtk/theme/libadwaita/_defaults.scss create mode 100644 gtk/theme/libadwaita/_drawing.scss create mode 100644 gtk/theme/libadwaita/_functions.scss create mode 100644 gtk/theme/libadwaita/_palette.scss create mode 100644 gtk/theme/libadwaita/_widgets.scss create mode 100644 gtk/theme/libadwaita/adwaita-stylesheet.gresources.xml create mode 100644 gtk/theme/libadwaita/assets/bullet-symbolic.svg create mode 100644 gtk/theme/libadwaita/assets/bullet-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/bullet@2-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/check-symbolic.svg create mode 100644 gtk/theme/libadwaita/assets/check-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/check@2-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/dash-symbolic.svg create mode 100644 gtk/theme/libadwaita/assets/dash-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/dash@2-symbolic.symbolic.png create mode 100644 gtk/theme/libadwaita/assets/devel-symbolic.svg create mode 100644 gtk/theme/libadwaita/base-hc.scss create mode 100644 gtk/theme/libadwaita/base.scss create mode 100644 gtk/theme/libadwaita/defaults-dark.scss create mode 100644 gtk/theme/libadwaita/defaults-light.scss create mode 100644 gtk/theme/libadwaita/empty.css create mode 100644 gtk/theme/libadwaita/gtk-dark.css create mode 100644 gtk/theme/libadwaita/gtk-hc-dark.css create mode 100644 gtk/theme/libadwaita/gtk-hc.css create mode 100644 gtk/theme/libadwaita/gtk.css create mode 100644 gtk/theme/libadwaita/meson.build create mode 100644 gtk/theme/libadwaita/widgets/_avatar.scss create mode 100644 gtk/theme/libadwaita/widgets/_bottom-sheet.scss create mode 100644 gtk/theme/libadwaita/widgets/_buttons.scss create mode 100644 gtk/theme/libadwaita/widgets/_calendar.scss create mode 100644 gtk/theme/libadwaita/widgets/_checks.scss create mode 100644 gtk/theme/libadwaita/widgets/_color-chooser.scss create mode 100644 gtk/theme/libadwaita/widgets/_column-view.scss create mode 100644 gtk/theme/libadwaita/widgets/_deprecated.scss create mode 100644 gtk/theme/libadwaita/widgets/_dialogs.scss create mode 100644 gtk/theme/libadwaita/widgets/_dropdowns.scss create mode 100644 gtk/theme/libadwaita/widgets/_emoji-chooser.scss create mode 100644 gtk/theme/libadwaita/widgets/_entries.scss create mode 100644 gtk/theme/libadwaita/widgets/_expanders.scss create mode 100644 gtk/theme/libadwaita/widgets/_file-chooser.scss create mode 100644 gtk/theme/libadwaita/widgets/_header-bar.scss create mode 100644 gtk/theme/libadwaita/widgets/_labels.scss create mode 100644 gtk/theme/libadwaita/widgets/_level-bar.scss create mode 100644 gtk/theme/libadwaita/widgets/_linked.scss create mode 100644 gtk/theme/libadwaita/widgets/_links.scss create mode 100644 gtk/theme/libadwaita/widgets/_lists.scss create mode 100644 gtk/theme/libadwaita/widgets/_menus.scss create mode 100644 gtk/theme/libadwaita/widgets/_message-dialog.scss create mode 100644 gtk/theme/libadwaita/widgets/_misc.scss create mode 100644 gtk/theme/libadwaita/widgets/_notebook.scss create mode 100644 gtk/theme/libadwaita/widgets/_paned.scss create mode 100644 gtk/theme/libadwaita/widgets/_popovers.scss create mode 100644 gtk/theme/libadwaita/widgets/_preferences.scss create mode 100644 gtk/theme/libadwaita/widgets/_progress-bar.scss create mode 100644 gtk/theme/libadwaita/widgets/_scale.scss create mode 100644 gtk/theme/libadwaita/widgets/_scrolling.scss create mode 100644 gtk/theme/libadwaita/widgets/_shortcuts-window.scss create mode 100644 gtk/theme/libadwaita/widgets/_sidebars.scss create mode 100644 gtk/theme/libadwaita/widgets/_spin-button.scss create mode 100644 gtk/theme/libadwaita/widgets/_spinner.scss create mode 100644 gtk/theme/libadwaita/widgets/_switch.scss create mode 100644 gtk/theme/libadwaita/widgets/_tab-view.scss create mode 100644 gtk/theme/libadwaita/widgets/_text-selection.scss create mode 100644 gtk/theme/libadwaita/widgets/_toolbars.scss create mode 100644 gtk/theme/libadwaita/widgets/_tooltip.scss create mode 100644 gtk/theme/libadwaita/widgets/_view-switcher.scss create mode 100644 gtk/theme/libadwaita/widgets/_views.scss create mode 100644 gtk/theme/libadwaita/widgets/_window.scss diff --git a/gtk/meson.build b/gtk/meson.build index bd59f38c72..38c32b8d63 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -721,6 +721,7 @@ if not fs.exists('theme/Default/Default-light.css') sassc_opts = [ '-a', '-M', '-t', 'compact' ] subdir('theme/Default') + subdir('theme/libadwaita') theme_deps += [ default_theme_deps, @@ -988,6 +989,7 @@ gtk_sources += [ gtkprivatetypebuiltins, gtktypebuiltins, font_script_language_sources, + libadwaita_stylesheet_resources, ] gtk_deps = [ diff --git a/gtk/theme/libadwaita/README.md b/gtk/theme/libadwaita/README.md new file mode 100644 index 0000000000..5616843987 --- /dev/null +++ b/gtk/theme/libadwaita/README.md @@ -0,0 +1,42 @@ +## Summary + +* To be able to use the latest/adequate version of sass, install sassc +* meson will regenerate the CSS every time you modify the SCSS files. +* Note that meson always builds out-of-tree, so the modified css files will + appear in your builddir. + +## Theme Variants + +The Adwaita theme comes in 4 variants: light, dark, hc (highcontrast) and +hc-dark (highcontrast inverse). The generated CSS files for the variants +are called Adwaita-$variant.css. For technical reasons, GTK adds one level +of include wrappers around these, which are called gtk-$variant.css. + +## How to Tweak the Theme + +Adwaita is a complex theme, so to keep it maintainable it's written and +processed in SASS. The generated CSS is then transformed into a gresource file +during gtk build and used at runtime in a non-legible or editable form. + +It is very likely your change will happen in the _common.scss file. That's where +all the widget selectors are defined. Here's a rundown of the "supporting" +stylesheets, that are unlikely to be the right place for a drive by stylesheet +fix: + +_colors.scss - global color definitions. We keep the number of defined + colors to a necessary minimum, most colors are derived + from a handful of basics. It covers both the light variant + and the dark variant. + +_colors-public.scss - SCSS colors exported through gtk to allow for 3rd party + apps color mixing. + +_drawing.scss - drawing helper mixings/functions to allow easier + definition of widget drawing under specific context. This + is why Adwaita isn't 15000 LOC. + +_common.scss - actual definitions of style for each widget. This is + where you are likely to add/remove your changes. + +You can read about SASS at http://sass-lang.com/documentation/. Once you make +your changes to the _common.scss file, libadwaita will rebuild the CSS files. diff --git a/gtk/theme/libadwaita/_colors.scss b/gtk/theme/libadwaita/_colors.scss new file mode 100644 index 0000000000..614055c575 --- /dev/null +++ b/gtk/theme/libadwaita/_colors.scss @@ -0,0 +1,131 @@ +$border_opacity: if($contrast == 'high', .5, .15); +$thin_border_opacity: if($contrast == 'high', .25, .05); +$focus_border_opacity: if($contrast == 'high', 0.8, 0.5); + +// Colors from _defaults.scss + +$accent_bg_color: gtkcolor(accent_bg_color); +$accent_fg_color: gtkcolor(accent_fg_color); +$accent_color: gtkcolor(accent_color); + +$destructive_bg_color: gtkcolor(destructive_bg_color); +$destructive_fg_color: gtkcolor(destructive_fg_color); +$destructive_color: gtkcolor(destructive_color); + +$success_bg_color: gtkcolor(success_bg_color); +$success_fg_color: gtkcolor(success_fg_color); +$success_color: gtkcolor(success_color); + +$warning_bg_color: gtkcolor(warning_bg_color); +$warning_fg_color: gtkcolor(warning_fg_color); +$warning_color: gtkcolor(warning_color); + +$error_bg_color: gtkcolor(error_bg_color); +$error_fg_color: gtkcolor(error_fg_color); +$error_color: gtkcolor(error_color); + +$window_bg_color: gtkcolor(window_bg_color); +$window_fg_color: gtkcolor(window_fg_color); + +$view_bg_color: gtkcolor(view_bg_color); +$view_fg_color: gtkcolor(view_fg_color); + +$headerbar_bg_color: gtkcolor(headerbar_bg_color); +$headerbar_fg_color: gtkcolor(headerbar_fg_color); +$headerbar_border_color: gtkalpha(gtkcolor(headerbar_border_color), $border_opacity); +$headerbar_backdrop_color: gtkcolor(headerbar_backdrop_color); +$headerbar_shade_color: gtkcolor(headerbar_shade_color); +$headerbar_darker_shade_color: gtkcolor(headerbar_darker_shade_color); + +$sidebar_bg_color: gtkcolor(sidebar_bg_color); +$sidebar_fg_color: gtkcolor(sidebar_fg_color); +$sidebar_backdrop_color: gtkcolor(sidebar_backdrop_color); +$sidebar_border_color: gtkcolor(sidebar_border_color); +$sidebar_shade_color: gtkcolor(sidebar_shade_color); + +$secondary_sidebar_bg_color: gtkcolor(secondary_sidebar_bg_color); +$secondary_sidebar_fg_color: gtkcolor(secondary_sidebar_fg_color); +$secondary_sidebar_backdrop_color: gtkcolor(secondary_sidebar_backdrop_color); +$secondary_sidebar_border_color: gtkcolor(secondary_sidebar_border_color); +$secondary_sidebar_shade_color: gtkcolor(secondary_sidebar_shade_color); + +$card_bg_color: gtkcolor(card_bg_color); +$card_fg_color: gtkcolor(card_fg_color); +$card_shade_color: gtkcolor(card_shade_color); + +$dialog_bg_color: gtkcolor(dialog_bg_color); +$dialog_fg_color: gtkcolor(dialog_fg_color); + +$popover_bg_color: gtkcolor(popover_bg_color); +$popover_fg_color: gtkcolor(popover_fg_color); +$popover_shade_color: gtkcolor(popover_shade_color); + +$thumbnail_bg_color: gtkcolor(thumbnail_bg_color); +$thumbnail_fg_color: gtkcolor(thumbnail_fg_color); + +$shade_color: gtkcolor(shade_color); +$scrollbar_outline_color: gtkcolor(scrollbar_outline_color); + +// Other colors + +$border_color: gtkalpha(currentColor, $border_opacity); +$thin_border_color: gtkalpha(currentColor, $thin_border_opacity); +$link_color: $accent_color; +$link_visited_color: gtkmix($accent_color, $view_fg_color, 80%); + +$hover_color: gtkalpha(currentColor, .07); +$active_color: gtkalpha(currentColor, .16); +$selected_color: gtkalpha(currentColor, .1); +$selected_hover_color: gtkalpha(currentColor, .13); +$selected_active_color: gtkalpha(currentColor, .19); + +$view_hover_color: gtkalpha(currentColor, .04); +$view_active_color: gtkalpha(currentColor, .08); +$view_selected_color: gtkalpha($accent_bg_color, .25); +$view_selected_hover_color: gtkalpha($accent_bg_color, .32); +$view_selected_active_color: gtkalpha($accent_bg_color, .39); + +$trough_color: gtkalpha(currentColor, .15); +$trough_hover_color: gtkalpha(currentColor, .2); +$trough_active_color: gtkalpha(currentColor, .25); + +$fill_color: $accent_bg_color; +$fill_text_color: $accent_fg_color; + +$slider_color: gtkmix(white, $view_bg_color, 80%); +$slider_hover_color: white; + +$osd_fg_color: transparentize(white, .1); +$osd_text_color: white; +$osd_bg_color: transparentize(black, 0.3); +$osd_fill_bg_color: transparentize(white, .25); +$osd_fill_fg_color: transparentize(black, .25); +$osd_focus_color: transparentize(white, .5); +$osd_link_color: gtkmix($accent_bg_color, $osd_text_color, 50%); +$osd_link_visited_color: gtkmix($accent_bg_color, $osd_text_color, 75%); + +$tooltip_border_color: transparentize(white, 0.9); +$shadow_color: transparentize(black, 0.9); + +$drop_target_color: $accent_bg_color; + +$window_outline_color: transparentize(white, .93); + +//special cased widget colors +$focus_border_color: gtkalpha($accent_color, $focus_border_opacity); +$dim_label_opacity: 0.55; +$dimmer_opacity: 0.3; +$disabled_opacity: 0.5; +$strong_disabled_opacity: 0.3; + +// High Contrast color overrides +@if $contrast == 'high' { + $dim_label_opacity: 0.9; + $dimmer_opacity: 0.8; + $disabled_opacity: 0.4; + + $trough_color: gtkalpha(currentColor, .3); + $trough_hover_color: gtkalpha(currentColor, .4); + $trough_active_color: gtkalpha(currentColor, .5); + $window_outline_color: transparentize(white, .7); +} diff --git a/gtk/theme/libadwaita/_common.scss b/gtk/theme/libadwaita/_common.scss new file mode 100644 index 0000000000..961be739d2 --- /dev/null +++ b/gtk/theme/libadwaita/_common.scss @@ -0,0 +1,107 @@ +$ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); +$backdrop_transition: 200ms ease-out; +$focus_transition: outline-color 200ms $ease-out-quad, + outline-width 200ms $ease-out-quad, + outline-offset 200ms $ease-out-quad; +$button_transition: background 200ms $ease-out-quad, + box-shadow 200ms $ease-out-quad; +$button_radius: 6px; +$card_radius: $button_radius + 6; +$menu_radius: 6px; +$menu_margin: 6px; //margin around menuitems & sidebar items +$menu_padding: 12px; //inner menuitem padding +$window_radius: $button_radius + 6; +$popover_radius: $window_radius; + +.background { + color: $window_fg_color; + background-color: $window_bg_color; +} + +dnd { + color: $window_fg_color; +} + +.normal-icons { + -gtk-icon-size: 16px; +} + +.large-icons { + -gtk-icon-size: 32px; +} + +%osd, +.osd { + color: $osd_fg_color; + border: none; + background-color: $osd_bg_color; + background-clip: padding-box; +} + +/* Text selection */ + +selection { + background-color: gtkalpha($view_fg_color, 0.1); + color: transparent; + + &:focus-within { + background-color: gtkalpha($accent_bg_color, 0.3); + } +} + +:not(window):drop(active):focus, +:not(window):drop(active) { // FIXME needs to be done widget by widget, this wildcard should really die + border-color: $drop_target_color; + box-shadow: inset 0 0 0 1px $drop_target_color; + caret-color: $drop_target_color; +} + +.navigation-sidebar, +placessidebar, +stackswitcher, +expander-widget { + :not(window):drop(active):focus, + :not(window):drop(active) { + box-shadow: none; + } +} + +/* Outline for low res icons */ +.lowres-icon { + -gtk-icon-shadow: 0 -1px rgba(0,0,0,0.05), + 1px 0 rgba(0,0,0,0.1), + 0 1px rgba(0,0,0,0.3), + -1px 0 rgba(0,0,0,0.1); +} + +/* Drop shadow for large icons */ +.icon-dropshadow { + -gtk-icon-shadow: 0 1px 12px rgba(0,0,0,0.05), + 0 -1px rgba(0,0,0,0.05), + 1px 0 rgba(0,0,0,0.1), + 0 1px rgba(0,0,0,0.3), + -1px 0 rgba(0,0,0,0.1); +} + +@keyframes needs_attention { + from { background-image: radial-gradient(farthest-side, $accent_color 0%, transparent 0%); } + to { background-image: radial-gradient(farthest-side, $accent_color 95%, transparent); } +} + +%needs_attention { + // the dot is drawn by using two radial gradient, the first one is the actual dot, the other + // simulates the shadow labels and icons normally have in buttons. + animation: needs_attention 150ms ease-in; + + background-image: radial-gradient(farthest-side, $accent_color 96%, transparent); + background-size: 6px 6px; + background-repeat: no-repeat; + + background-position: right 3px; + + &:dir(rtl) { + background-position: left 3px; + } +} + +@import 'widgets'; diff --git a/gtk/theme/libadwaita/_compat-colors.scss b/gtk/theme/libadwaita/_compat-colors.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gtk/theme/libadwaita/_defaults.scss b/gtk/theme/libadwaita/_defaults.scss new file mode 100644 index 0000000000..a262a9897a --- /dev/null +++ b/gtk/theme/libadwaita/_defaults.scss @@ -0,0 +1,83 @@ +/* GTK NAMED COLORS + ---------------- + use responsibly! */ + +// Sass thinks we're using the colors in the variables as strings and may shoot +// warning, it's innocuous and can be defeated by using #{$var}. + +// These are the colors apps are can override. We define the defaults here and +// define variables for them in _colors.scss + +// The main accent color and the matching text value +@define-color accent_bg_color @blue_3; +@define-color accent_fg_color white; +@define-color accent_color #{if($variant == 'dark', #78aeed, "@blue_4")}; + +// destructive-action buttons +@define-color destructive_bg_color #{if($variant == 'dark', "@red_4", "@red_3")}; +@define-color destructive_fg_color white; +@define-color destructive_color #{if($variant == 'dark', #ff7b63, "@red_4")}; + +// Levelbars, entries, labels and infobars. These don't need text colors +@define-color success_bg_color #{if($variant == 'dark', "@green_5", "@green_4")}; +@define-color success_fg_color white; +@define-color success_color #{if($variant == 'dark', "@green_1", "#1b8553")}; + +@define-color warning_bg_color #{if($variant == 'dark', #cd9309, "@yellow_5")}; +@define-color warning_fg_color #{transparentize(black, .2)}; +@define-color warning_color #{if($variant == 'dark', "@yellow_2", #9c6e03)}; + +@define-color error_bg_color #{if($variant == 'dark', "@red_4", "@red_3")}; +@define-color error_fg_color white; +@define-color error_color #{if($variant == 'dark', #ff7b63, "@red_4")}; + +// Window +@define-color window_bg_color #{if($variant == 'light', #fafafa, #242424)}; +@define-color window_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; + +// Views - e.g. text view or tree view +@define-color view_bg_color #{if($variant == 'light', #ffffff, #1e1e1e)}; +@define-color view_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; + +// Header bar, search bar, tab bar +@define-color headerbar_bg_color #{if($variant == 'light', #ffffff, #303030)}; +@define-color headerbar_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color headerbar_border_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color headerbar_backdrop_color @window_bg_color; +@define-color headerbar_shade_color #{if($variant == 'light', transparentize(black, .88), transparentize(black, .64))}; +@define-color headerbar_darker_shade_color #{if($variant == 'light', transparentize(black, .88), transparentize(black, .1))}; + +// Split pane views +@define-color sidebar_bg_color #{if($variant == 'light', #ebebeb, #303030)}; +@define-color sidebar_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color sidebar_backdrop_color #{if($variant == 'light', #f2f2f2, #2a2a2a)}; +@define-color sidebar_shade_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .75))}; +@define-color sidebar_border_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .64))}; + +@define-color secondary_sidebar_bg_color #{if($variant == 'light', #f3f3f3, #2a2a2a)}; +@define-color secondary_sidebar_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color secondary_sidebar_backdrop_color #{if($variant == 'light', #f6f6f6, #272727)}; +@define-color secondary_sidebar_shade_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .75))}; +@define-color secondary_sidebar_border_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .64))}; + +// Cards, boxed lists +@define-color card_bg_color #{if($variant == 'light', #ffffff, transparentize(white, .92))}; +@define-color card_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color card_shade_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .64))}; + +// Dialogs +@define-color dialog_bg_color #{if($variant == 'light', #fafafa, #383838)}; +@define-color dialog_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; + +// Popovers +@define-color popover_bg_color #{if($variant == 'light', #ffffff, #383838)}; +@define-color popover_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; +@define-color popover_shade_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .75))}; + +// Thumbnails +@define-color thumbnail_bg_color #{if($variant == 'light', #ffffff, #383838)}; +@define-color thumbnail_fg_color #{if($variant == 'light', transparentize(black, .2), white)}; + +// Miscellaneous +@define-color shade_color #{if($variant == 'light', transparentize(black, .93), transparentize(black, .75))}; +@define-color scrollbar_outline_color #{if($variant == 'light', white, transparentize(black, .5))}; diff --git a/gtk/theme/libadwaita/_drawing.scss b/gtk/theme/libadwaita/_drawing.scss new file mode 100644 index 0000000000..ad64e5d909 --- /dev/null +++ b/gtk/theme/libadwaita/_drawing.scss @@ -0,0 +1,138 @@ +// Drawing mixins + +// generic drawing of more complex things + +// +// Helper mixin for drawing visible focus rings +// +// If $target is specified, the focus ring is applied to the specified child element. +// If $outer is true, the focus ring extends outward. Otherwise, it extends inward. +// If $within is true, use focus-within instead of focus:focus-visible +// +@mixin focus-ring($target: null, $width: 2px, $offset: -$width, $outer: false, $focus-state: ':focus:focus-visible', $fc: $focus_border_color, $transition: null) { + & #{$target} { + outline: 0 solid transparent; + outline-offset: if($outer, $offset + 4px, $offset + $width + 4px); + transition: $focus_transition, $transition; + } + + &#{$focus-state} #{$target} { + outline-color: $fc; + outline-width: $width; + outline-offset: $offset; + } +} + +@mixin undershoot($p, $c: $shade_color, $neighbor: false) { +// +// undershoot +// +// $p: position +// $c: shade color +// $neighbor: use ~ instead of > +// +// possible $p values: +// top, bottom, right, left +// + + $_border_pos: ''; + $_direction: ''; + $_selector: if($neighbor, '~', '>'); + + @if $p==top { + $_direction: bottom; + $_border_pos: 0 1px; + } @else if $p==bottom { + $_direction: top; + $_border_pos: 0 -1px; + } @else if $p==left { + $_direction: right; + $_border_pos: 1px 0; + } @else if $p==right { + $_direction: left; + $_border_pos: -1px 0; + } @else { + @error "Unknown position #{$p}" + } + + #{$_selector} undershoot.#{$p} { + box-shadow: inset $_border_pos if($contrast == 'high', $border_color, gtkalpha($c, .75)); + background: linear-gradient(to $_direction, gtkalpha($c, .75), transparent 4px); + } +} + +@mixin overshoot($p) { +// +// overshoot +// +// $p: position +// +// possible $p values: +// top, bottom, right, left +// + + $_small_gradient_length: 3%; + $_big_gradient_length: 50%; + + $_small_gradient_size: 100% $_small_gradient_length; + $_big_gradient_size: 100% $_big_gradient_length; + + @if $p==right or $p==left { + $_small_gradient_size: $_small_gradient_length 100%; + $_big_gradient_size: $_big_gradient_length 100%; + } + + $_small_gradient: radial-gradient(farthest-side at $p, + gtkalpha(currentColor, 0.12) 85%, + gtkalpha(currentColor, 0)); + + $_big_gradient: radial-gradient(farthest-side at $p, + gtkalpha(currentColor, 0.05), + gtkalpha(currentColor, 0)); + + background-image: $_small_gradient, $_big_gradient; + background-size: $_small_gradient_size, $_big_gradient_size; + + background-repeat: no-repeat; + background-position: $p; + + background-color: transparent; // reset some properties to be sure to not inherit them somehow + border: none; // + box-shadow: none; // +} + +@mixin background-shadow($direction, $color) { + background-image: + linear-gradient($direction, + gtkalpha($color, 0.7), + gtkalpha($color, 0.14) 40px, + gtkalpha($color, 0) 56px), + linear-gradient($direction, + gtkalpha($color, 0.4), + gtkalpha($color, 0.14) 7px, + gtkalpha($color, 0) 24px); +} + +@mixin transition-shadows($color) { + > dimming { + background: $color; + } + + @if $contrast == 'high' { + > border { + min-width: 1px; + min-height: 1px; + background: $border_color; + } + } + + > shadow { + min-width: 56px; + min-height: 56px; + + &.left { @include background-shadow(to right, $color); } + &.right { @include background-shadow(to left, $color); } + &.up { @include background-shadow(to bottom, $color); } + &.down { @include background-shadow(to top, $color); } + } +} diff --git a/gtk/theme/libadwaita/_functions.scss b/gtk/theme/libadwaita/_functions.scss new file mode 100644 index 0000000000..c4af658b6c --- /dev/null +++ b/gtk/theme/libadwaita/_functions.scss @@ -0,0 +1,16 @@ +@function gtkalpha($c,$a) { + @return unquote("alpha(#{$c},#{$a})"); +} + +@function gtkmix($c1,$c2,$r) { + $ratio: 1 - $r / 100%; // match SCSS mix() + @return unquote("mix(#{$c1},#{$c2},#{$ratio})"); +} + +@function gtkshade($c,$s) { + @return unquote("shade(#{$c},#{$s})"); +} + +@function gtkcolor($c) { + @return unquote("@#{$c}"); +} diff --git a/gtk/theme/libadwaita/_palette.scss b/gtk/theme/libadwaita/_palette.scss new file mode 100644 index 0000000000..dd59a7109e --- /dev/null +++ b/gtk/theme/libadwaita/_palette.scss @@ -0,0 +1,94 @@ +$blue_1: #99c1f1; +$blue_2: #62a0ea; +$blue_3: #3584e4; +$blue_4: #1c71d8; +$blue_5: #1a5fb4; +$green_1: #8ff0a4; +$green_2: #57e389; +$green_3: #33d17a; +$green_4: #2ec27e; +$green_5: #26a269; +$yellow_1: #f9f06b; +$yellow_2: #f8e45c; +$yellow_3: #f6d32d; +$yellow_4: #f5c211; +$yellow_5: #e5a50a; +$orange_1: #ffbe6f; +$orange_2: #ffa348; +$orange_3: #ff7800; +$orange_4: #e66100; +$orange_5: #c64600; +$red_1: #f66151; +$red_2: #ed333b; +$red_3: #e01b24; +$red_4: #c01c28; +$red_5: #a51d2d; +$purple_1: #dc8add; +$purple_2: #c061cb; +$purple_3: #9141ac; +$purple_4: #813d9c; +$purple_5: #613583; +$brown_1: #cdab8f; +$brown_2: #b5835a; +$brown_3: #986a44; +$brown_4: #865e3c; +$brown_5: #63452c; +$light_1: #ffffff; +$light_2: #f6f5f4; +$light_3: #deddda; +$light_4: #c0bfbc; +$light_5: #9a9996; +$dark_1: #77767b; +$dark_2: #5e5c64; +$dark_3: #3d3846; +$dark_4: #241f31; +$dark_5: #000000; + +// Sass thinks we're using the colors in the variables as strings and may shoot +// warning, it's innocuous and can be defeated by using #{$var}. + +@define-color blue_1 #{$blue_1}; +@define-color blue_2 #{$blue_2}; +@define-color blue_3 #{$blue_3}; +@define-color blue_4 #{$blue_4}; +@define-color blue_5 #{$blue_5}; +@define-color green_1 #{$green_1}; +@define-color green_2 #{$green_2}; +@define-color green_3 #{$green_3}; +@define-color green_4 #{$green_4}; +@define-color green_5 #{$green_5}; +@define-color yellow_1 #{$yellow_1}; +@define-color yellow_2 #{$yellow_2}; +@define-color yellow_3 #{$yellow_3}; +@define-color yellow_4 #{$yellow_4}; +@define-color yellow_5 #{$yellow_5}; +@define-color orange_1 #{$orange_1}; +@define-color orange_2 #{$orange_2}; +@define-color orange_3 #{$orange_3}; +@define-color orange_4 #{$orange_4}; +@define-color orange_5 #{$orange_5}; +@define-color red_1 #{$red_1}; +@define-color red_2 #{$red_2}; +@define-color red_3 #{$red_3}; +@define-color red_4 #{$red_4}; +@define-color red_5 #{$red_5}; +@define-color purple_1 #{$purple_1}; +@define-color purple_2 #{$purple_2}; +@define-color purple_3 #{$purple_3}; +@define-color purple_4 #{$purple_4}; +@define-color purple_5 #{$purple_5}; +@define-color brown_1 #{$brown_1}; +@define-color brown_2 #{$brown_2}; +@define-color brown_3 #{$brown_3}; +@define-color brown_4 #{$brown_4}; +@define-color brown_5 #{$brown_5}; +@define-color light_1 #{$light_1}; +@define-color light_2 #{$light_2}; +@define-color light_3 #{$light_3}; +@define-color light_4 #{$light_4}; +@define-color light_5 #{$light_5}; +@define-color dark_1 #{$dark_1}; +@define-color dark_2 #{$dark_2}; +@define-color dark_3 #{$dark_3}; +@define-color dark_4 #{$dark_4}; +@define-color dark_5 #{$dark_5}; diff --git a/gtk/theme/libadwaita/_widgets.scss b/gtk/theme/libadwaita/_widgets.scss new file mode 100644 index 0000000000..471d0a9045 --- /dev/null +++ b/gtk/theme/libadwaita/_widgets.scss @@ -0,0 +1,42 @@ +@import 'widgets/avatar'; +@import 'widgets/bottom-sheet'; +@import 'widgets/buttons'; +@import 'widgets/calendar'; +@import 'widgets/checks'; +@import 'widgets/color-chooser'; +@import 'widgets/column-view'; +@import 'widgets/dialogs'; +@import 'widgets/deprecated'; +@import 'widgets/dropdowns'; +@import 'widgets/emoji-chooser'; +@import 'widgets/entries'; +@import 'widgets/expanders'; +@import 'widgets/file-chooser'; +@import 'widgets/header-bar'; +@import 'widgets/labels'; +@import 'widgets/level-bar'; +@import 'widgets/linked'; +@import 'widgets/links'; +@import 'widgets/lists'; +@import 'widgets/menus'; +@import 'widgets/message-dialog'; +@import 'widgets/misc'; +@import 'widgets/notebook'; +@import 'widgets/paned'; +@import 'widgets/popovers'; +@import 'widgets/preferences'; +@import 'widgets/progress-bar'; +@import 'widgets/scale'; +@import 'widgets/scrolling'; +@import 'widgets/shortcuts-window'; +@import 'widgets/sidebars'; +@import 'widgets/spinner'; +@import 'widgets/spin-button'; +@import 'widgets/switch'; +@import 'widgets/tab-view'; +@import 'widgets/text-selection'; +@import 'widgets/toolbars'; +@import 'widgets/tooltip'; +@import 'widgets/views'; +@import 'widgets/view-switcher'; +@import 'widgets/window'; diff --git a/gtk/theme/libadwaita/adwaita-stylesheet.gresources.xml b/gtk/theme/libadwaita/adwaita-stylesheet.gresources.xml new file mode 100644 index 0000000000..c09dbe0db2 --- /dev/null +++ b/gtk/theme/libadwaita/adwaita-stylesheet.gresources.xml @@ -0,0 +1,32 @@ + + + + base.css + base-hc.css + defaults-light.css + defaults-dark.css + + assets/bullet-symbolic.symbolic.png + assets/bullet@2-symbolic.symbolic.png + assets/check-symbolic.symbolic.png + assets/check@2-symbolic.symbolic.png + assets/dash-symbolic.symbolic.png + assets/dash@2-symbolic.symbolic.png + + assets/bullet-symbolic.svg + assets/check-symbolic.svg + assets/dash-symbolic.svg + + assets/devel-symbolic.svg + + + + gtk.css + gtk-dark.css + + + + gtk-hc.css + gtk-hc-dark.css + + diff --git a/gtk/theme/libadwaita/assets/bullet-symbolic.svg b/gtk/theme/libadwaita/assets/bullet-symbolic.svg new file mode 100644 index 0000000000..f359a7012e --- /dev/null +++ b/gtk/theme/libadwaita/assets/bullet-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gtk/theme/libadwaita/assets/bullet-symbolic.symbolic.png b/gtk/theme/libadwaita/assets/bullet-symbolic.symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..8e6925a5f851df0f65b8ec5ce0add05b88683463 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@?$(*978lF zUY+2`)u15aB0u-=w1;;eU*_C3iFL9 zm?QMox$4H$87&g8k1xHt*DLIirc3GJ&-Ul8t$MPfy@U1jM7DFRx7Mg!-M>fV63`w7 MPgg&ebxsLQ0M~Ln!2kdN literal 0 HcmV?d00001 diff --git a/gtk/theme/libadwaita/assets/bullet@2-symbolic.symbolic.png b/gtk/theme/libadwaita/assets/bullet@2-symbolic.symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..e9df4256c0fda41a3ef6e43ba0150a926b32c4c7 GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zEX7WqAsj$Z!;#VfuOGz z^vPedf%yV6fB4?&uo~egM$->0$7UKiJiQm1{G8!S+*+}<$_DXEMYK1#i*idT%#SV+ zWZ3SYCSk&C)?}x5cV2xhmTEf%w4(h`jZ24)hpS \ No newline at end of file diff --git a/gtk/theme/libadwaita/assets/check-symbolic.symbolic.png b/gtk/theme/libadwaita/assets/check-symbolic.symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..9144bcd1baf3d5de08611969d5eb875c208587fc GIT binary patch literal 244 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@>hGhIEH9U zJbTeFiz!f`{p0<0jzOKSJ^>pxofKSS(8gV;$^C+}PDDhP#0JqfD(NSp-b71q z=IlnB;6mKsQKgtuI_@E`wYVSMI%-`}wYYsoqz2eR@TTbz?yMR}WVeX_w pe`YR`zj}YGTKL`kd#+h$Wd$B+8r+P0mjQG(gQu&X%Q~loCIAouUJC#K literal 0 HcmV?d00001 diff --git a/gtk/theme/libadwaita/assets/check@2-symbolic.symbolic.png b/gtk/theme/libadwaita/assets/check@2-symbolic.symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..c0baa3c10e2c675565a4a9e371adc76cdb729683 GIT binary patch literal 369 zcmV-%0gnEOP)`iVpFFN347UTf|F%RR!N| zvtwctJ3U|vs0Y{$N>SlSmx3m?bFewo0_+auyq)d_g-yxnJ5z2i+O4M6-b`*raS<%= zj*ZORlB8YT=GG-`?kVHA%sJ_nmi6-zUL>tMk*aTgkrU!$)~`1T0%v~%`@i`FvK^{#DUTU_ P00000NkvXXu0mjfL#3Ld literal 0 HcmV?d00001 diff --git a/gtk/theme/libadwaita/assets/dash-symbolic.svg b/gtk/theme/libadwaita/assets/dash-symbolic.svg new file mode 100644 index 0000000000..de3638dd2b --- /dev/null +++ b/gtk/theme/libadwaita/assets/dash-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gtk/theme/libadwaita/assets/dash-symbolic.symbolic.png b/gtk/theme/libadwaita/assets/dash-symbolic.symbolic.png new file mode 100644 index 0000000000000000000000000000000000000000..3afcfd6fa2b65e4fcdae11d780afd7115b140d23 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xamSQK*5Dp-y;YjHK@-01G978lF zzCGv2#UQ}IdU5*ghyTP6*hXktpYmIl_H*|6bZ~=6_VDk=HUh!!rjnc8wv3du|Gc*?l-$Iiq*Onff!{@;b`D2Q zL-tXp_6yZcy03VXDyIc)I4+f4{PaYCmbAyx2Z<7QyxaL^`xi4Mzg6Rls4Tnp`0leX dAD1J?cw0nT<}+*j)d$+l;OXk;vd$@?2>_u&KVkp? literal 0 HcmV?d00001 diff --git a/gtk/theme/libadwaita/assets/devel-symbolic.svg b/gtk/theme/libadwaita/assets/devel-symbolic.svg new file mode 100644 index 0000000000..14843f0965 --- /dev/null +++ b/gtk/theme/libadwaita/assets/devel-symbolic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/gtk/theme/libadwaita/base-hc.scss b/gtk/theme/libadwaita/base-hc.scss new file mode 100644 index 0000000000..278e537909 --- /dev/null +++ b/gtk/theme/libadwaita/base-hc.scss @@ -0,0 +1,8 @@ +$contrast: 'high'; + +@import 'palette'; +@import 'functions'; +@import 'colors'; +@import 'drawing'; +@import 'common'; +@import 'compat-colors'; diff --git a/gtk/theme/libadwaita/base.scss b/gtk/theme/libadwaita/base.scss new file mode 100644 index 0000000000..ffba5eacdc --- /dev/null +++ b/gtk/theme/libadwaita/base.scss @@ -0,0 +1,8 @@ +$contrast: 'normal'; + +@import 'palette'; +@import 'functions'; +@import 'colors'; +@import 'drawing'; +@import 'common'; +@import 'compat-colors'; diff --git a/gtk/theme/libadwaita/defaults-dark.scss b/gtk/theme/libadwaita/defaults-dark.scss new file mode 100644 index 0000000000..7c56516cf1 --- /dev/null +++ b/gtk/theme/libadwaita/defaults-dark.scss @@ -0,0 +1,3 @@ +$variant: 'dark'; + +@import 'defaults'; diff --git a/gtk/theme/libadwaita/defaults-light.scss b/gtk/theme/libadwaita/defaults-light.scss new file mode 100644 index 0000000000..97159a234f --- /dev/null +++ b/gtk/theme/libadwaita/defaults-light.scss @@ -0,0 +1,3 @@ +$variant: 'light'; + +@import 'defaults'; diff --git a/gtk/theme/libadwaita/empty.css b/gtk/theme/libadwaita/empty.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gtk/theme/libadwaita/gtk-dark.css b/gtk/theme/libadwaita/gtk-dark.css new file mode 100644 index 0000000000..18a6b5fc10 --- /dev/null +++ b/gtk/theme/libadwaita/gtk-dark.css @@ -0,0 +1,2 @@ +@import url("resource:///org/gnome/Adwaita/styles/base.css"); +@import url("resource:///org/gnome/Adwaita/styles/defaults-dark.css"); diff --git a/gtk/theme/libadwaita/gtk-hc-dark.css b/gtk/theme/libadwaita/gtk-hc-dark.css new file mode 100644 index 0000000000..a0290659cc --- /dev/null +++ b/gtk/theme/libadwaita/gtk-hc-dark.css @@ -0,0 +1,2 @@ +@import url("resource:///org/gnome/Adwaita/styles/base-hc.css"); +@import url("resource:///org/gnome/Adwaita/styles/defaults-dark.css"); diff --git a/gtk/theme/libadwaita/gtk-hc.css b/gtk/theme/libadwaita/gtk-hc.css new file mode 100644 index 0000000000..793b67384d --- /dev/null +++ b/gtk/theme/libadwaita/gtk-hc.css @@ -0,0 +1,2 @@ +@import url("resource:///org/gnome/Adwaita/styles/base-hc.css"); +@import url("resource:///org/gnome/Adwaita/styles/defaults-light.css"); diff --git a/gtk/theme/libadwaita/gtk.css b/gtk/theme/libadwaita/gtk.css new file mode 100644 index 0000000000..d6216bb9cf --- /dev/null +++ b/gtk/theme/libadwaita/gtk.css @@ -0,0 +1,2 @@ +@import url("resource:///org/gnome/Adwaita/styles/base.css"); +@import url("resource:///org/gnome/Adwaita/styles/defaults-light.css"); diff --git a/gtk/theme/libadwaita/meson.build b/gtk/theme/libadwaita/meson.build new file mode 100644 index 0000000000..563cafcc4c --- /dev/null +++ b/gtk/theme/libadwaita/meson.build @@ -0,0 +1,100 @@ +fs = import('fs') + +stylesheet_deps = [] + +# For git checkouts, but not for tarballs... +if not fs.exists('base.css') + sassc = find_program('sassc', required: false) + if not sassc.found() + subproject('sassc', default_options: ['warning_level=0', 'werror=false']) + sassc = find_program('sassc') + endif + + if sassc.found() + sassc_opts = [ '-a', '-M', '-t', 'compact' ] + + scss_deps = files([ + '_colors.scss', + '_common.scss', + '_compat-colors.scss', + '_defaults.scss', + '_drawing.scss', + '_functions.scss', + '_widgets.scss', + + 'widgets/_avatar.scss', + 'widgets/_bottom-sheet.scss', + 'widgets/_buttons.scss', + 'widgets/_calendar.scss', + 'widgets/_checks.scss', + 'widgets/_color-chooser.scss', + 'widgets/_column-view.scss', + 'widgets/_deprecated.scss', + 'widgets/_dialogs.scss', + 'widgets/_dropdowns.scss', + 'widgets/_emoji-chooser.scss', + 'widgets/_entries.scss', + 'widgets/_expanders.scss', + 'widgets/_file-chooser.scss', + 'widgets/_header-bar.scss', + 'widgets/_labels.scss', + 'widgets/_level-bar.scss', + 'widgets/_linked.scss', + 'widgets/_links.scss', + 'widgets/_lists.scss', + 'widgets/_menus.scss', + 'widgets/_message-dialog.scss', + 'widgets/_misc.scss', + 'widgets/_notebook.scss', + 'widgets/_paned.scss', + 'widgets/_popovers.scss', + 'widgets/_preferences.scss', + 'widgets/_progress-bar.scss', + 'widgets/_scale.scss', + 'widgets/_scrolling.scss', + 'widgets/_shortcuts-window.scss', + 'widgets/_sidebars.scss', + 'widgets/_spinner.scss', + 'widgets/_spin-button.scss', + 'widgets/_switch.scss', + 'widgets/_tab-view.scss', + 'widgets/_text-selection.scss', + 'widgets/_toolbars.scss', + 'widgets/_tooltip.scss', + 'widgets/_views.scss', + 'widgets/_view-switcher.scss', + 'widgets/_window.scss', + ]) + + scss_files = [ + 'base', + 'base-hc', + 'defaults-light', + 'defaults-dark', + ] + + foreach scss: scss_files + stylesheet_deps += custom_target('@0@.scss'.format(scss), + input: '@0@.scss'.format(scss), + output: '@0@.css'.format(scss), + command: [ + sassc, sassc_opts, '@INPUT@', '@OUTPUT@', + ], + depend_files: scss_deps, + ) + endforeach + endif +endif + +libadwaita_stylesheet_resources = gnome.compile_resources( + 'adwaita-stylesheet-resources', + 'adwaita-stylesheet.gresources.xml', + + source_dir: [ + # List in order of preference + meson.current_build_dir(), + meson.current_source_dir(), + ], + dependencies: stylesheet_deps, + c_name: 'adw_stylesheet', +) diff --git a/gtk/theme/libadwaita/widgets/_avatar.scss b/gtk/theme/libadwaita/widgets/_avatar.scss new file mode 100644 index 0000000000..9eaea476e1 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_avatar.scss @@ -0,0 +1,38 @@ +avatar { + border-radius: 9999px; + font-weight: bold; + + // The list of colors to generate avatars. + // Each avatar color is represented by a font color, a gradient start color and a gradient stop color. + // There are 8 different colors for avtars in the list if you change the number of them you + // need to update the NUMBER_OF_COLORS in src/adw-avatar.c. + // The 2D list has this form: ((font-color, gradient-top-color, gradient-bottom-color)). + $avatarcolorlist: ( + (#cfe1f5, #83b6ec, #337fdc), // blue + (#caeaf2, #7ad9f1, #0f9ac8), // cyan + (#cef8d8, #8de6b1, #29ae74), // green + (#e6f9d7, #b5e98a, #6ab85b), // lime + (#f9f4e1, #f8e359, #d29d09), // yellow + (#ffead1, #ffcb62, #d68400), // gold + (#ffe5c5, #ffa95a, #ed5b00), // orange + (#f8d2ce, #f78773, #e62d42), // raspberry + (#fac7de, #e973ab, #e33b6a), // magenta + (#e7c2e8, #cb78d4, #9945b5), // purple + (#d5d2f5, #9e91e8, #7a59ca), // violet + (#f2eade, #e3cf9c, #b08952), // beige + (#e5d6ca, #be916d, #785336), // brown + (#d8d7d3, #c0bfbc, #6e6d71), // gray + ); + + @for $i from 1 through length($avatarcolorlist) { + &.color#{$i} { + $avatarcolor: nth($avatarcolorlist, $i); + background-image: linear-gradient(nth($avatarcolor, 2), nth($avatarcolor, 3)); + color: nth($avatarcolor, 1); + } + } + + &.contrasted { color: white; } + + &.image { background: none; } +} diff --git a/gtk/theme/libadwaita/widgets/_bottom-sheet.scss b/gtk/theme/libadwaita/widgets/_bottom-sheet.scss new file mode 100644 index 0000000000..8d280c12e8 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_bottom-sheet.scss @@ -0,0 +1,45 @@ + +bottom-sheet { + > dimming { + background-color: gtkalpha($shade_color, 2); + } + + > sheet { + border-top-left-radius: $window_radius; + border-top-right-radius: $window_radius; + box-shadow: 0 2px 8px 2px transparentize(black, 0.93), + 0 3px 20px 10px transparentize(black, 0.95), + 0 6px 32px 16px transparentize(black, 0.98), + 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .95)); + + > drag-handle { + background-color: gtkalpha(currentColor, .25); + min-width: 60px; + min-height: 4px; + margin: 6px; + border-radius: 99px; + } + + > outline { + border-top-left-radius: $window_radius; + border-top-right-radius: $window_radius; + box-shadow: inset 1px 0 $window_outline_color, + inset -1px 0 $window_outline_color, + inset 0 1px $window_outline_color; + + &.flush-left { + box-shadow: inset -1px 0 $window_outline_color, + inset 0 1px $window_outline_color; + } + + &.flush-right { + box-shadow: inset 1px 0 $window_outline_color, + inset 0 1px $window_outline_color; + } + + &.flush-left.flush-right { + box-shadow: inset 0 1px $window_outline_color; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_buttons.scss b/gtk/theme/libadwaita/widgets/_buttons.scss new file mode 100644 index 0000000000..d3f7bb4e6e --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_buttons.scss @@ -0,0 +1,628 @@ +$button_color: gtkalpha(currentColor, .1); +$button_hover_color: gtkalpha(currentColor, .15); +$button_active_color: gtkalpha(currentColor, .3); +$button_checked_color: gtkalpha(currentColor, .3); +$button_checked_hover_color: gtkalpha(currentColor, .35); +$button_checked_active_color: gtkalpha(currentColor, .4); + +$opaque_button_default_bg: gtkmix($window_bg_color, $window_fg_color, 85%); + +%button, +button { + @at-root %button_basic, & { + min-height: 24px; + min-width: 16px; + padding: 5px 10px; + border-radius: $button_radius; + font-weight: bold; + + @include focus-ring($transition: $button_transition); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + @at-root %button_basic_raised, & { + background-color: $button_color; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + + &:hover { + background-color: $button_hover_color; + } + + &.keyboard-activating, + &:active { + background-color: $button_active_color; + } + + &:checked { + background-color: $button_checked_color; + + &:hover { + background-color: $button_checked_hover_color; + } + + &.keyboard-activating, + &:active { + background-color: $button_checked_active_color; + } + } + } + + &:disabled { + filter: opacity($disabled_opacity); + + label { + filter: none; + } + } + + &.image-button { + min-width: 24px; + padding-left: 5px; + padding-right: 5px; + } + + &.text-button { + padding-left: 17px; + padding-right: 17px; + } + + &.text-button.image-button, + &.image-text-button { + padding-left: 9px; + padding-right: 9px; + + > box, + > box > box { + border-spacing: 4px; + + > label { + padding-left: 2px; + padding-right: 2px; + } + } + } + + &.arrow-button { + padding-left: 9px; + padding-right: 9px; + + > box { border-spacing: 4px; } + + &.text-button { + > box { border-spacing: 4px; } + } + } + + @at-root %button_basic_drop_active, + &:drop(active) { + color: $drop_target_color; + box-shadow: inset 0 0 0 2px $drop_target_color; + } + } + + // big standalone buttons like in Documents pager + @at-root %osd_button, + &.osd { + min-width: 32px; + min-height: 32px; + @include focus-ring($outer: true, $offset: 1px, $transition: $button_transition); + + color: $osd_fg_color; + background-color: transparentize(black, .35); + + @if $contrast == 'high' { + box-shadow: 0 0 0 1px currentColor; + } + + &:hover { + color: white; + background-color: gtkalpha(gtkmix(black, currentColor, 85%), .65); + } + + &.keyboard-activating, + &:active { + color: white; + background-color: gtkalpha(gtkmix(black, currentColor, 75%), .65); + } + + &:checked { + background-color: gtkalpha(gtkmix(black, currentColor, 80%), .65); + + &:hover { + background-color: gtkalpha(gtkmix(black, currentColor, 75%), .65); + } + + &.keyboard-activating, + &:active { + background-color: gtkalpha(gtkmix(black, currentColor, 65%), .65); + } + } + + // Specificity bump + &:drop(active) { + @extend %button_basic_drop_active; + } + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + } + + @at-root %opaque_button { + box-shadow: none; + + @include focus-ring($outer: true, $offset: 1px, $transition: $button_transition); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + &:hover { + background-image: image(gtkalpha(currentColor, .1)); + } + + &.keyboard-activating, + &:active { + background-image: image(transparentize(black, .8)); + } + + &:checked { + background-image: image(transparentize(black, .85)); + + &:hover { + background-image: image(transparentize(black, .95)); + } + + &.keyboard-activating, + &:active { + background-image: image(transparentize(black, .7)); + } + } + } + + &.opaque { + @extend %opaque_button; + + background-color: $opaque_button_default_bg; + color: $window_fg_color; + } + + &.destructive-action { + @extend %opaque_button; + + color: $destructive_fg_color; + + &, &:checked { + background-color: $destructive_bg_color; + } + } + + &.suggested-action { + @extend %opaque_button; + + color: $accent_fg_color; + + &, &:checked { + background-color: $accent_bg_color; + } + } + + @at-root %button_basic_flat, + &.flat { + background: transparent; + @include focus-ring($transition: $button_transition); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + box-shadow: none; + + @if $contrast == 'high' { + &:hover, + &.keyboard-activating, + &:active, + &:checked { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + &:hover { + background: $hover_color; + } + + &.keyboard-activating, + &:active { + background: $active_color; + } + + &:checked { + background: $selected_color; + + &:hover { + background: $selected_hover_color; + } + + &.keyboard-activating, + &:active { + background: $selected_active_color; + } + } + + &:disabled:not(:checked) { + filter: opacity($strong_disabled_opacity); + } + + // Specificity bump + &:drop(active) { + @extend %button_basic_drop_active; + } + } + + stackswitcher > & { + // to position the needs attention dot, padding is added to the button + // child, a label needs just lateral padding while an icon needs vertical + // padding added too. + + > label { + padding: 0 6px; + margin: 0 -6px; + } + + > image { + padding: 3px 6px; + margin: -3px -6px; + } + + &.text-button { min-width: 100px; } + + &.needs-attention { + > label, + > image { @extend %needs_attention; } + } + } + + // hide separators + &.font { + separator { background-color: transparent; } + > box { border-spacing: 6px; } + > box > box > label { font-weight: bold; } + } + + @at-root %circular_button, + &.circular { // force circular button shape + min-width: 34px; + min-height: 34px; + padding: 0; + border-radius: 9999px; + + label { padding: 0; } + } + + @at-root %pill_button, + &.pill { + padding: 10px 32px; + border-radius: 9999px; + } + + &.card { + background-color: $card_bg_color; + background-clip: padding-box; + font-weight: inherit; + padding: 0; + + @include focus-ring($offset: -1px, $transition: $button_transition); + + &:hover { + background-image: image($view_hover_color); + } + + &.keyboard-activating, + &:active { + background-image: image($view_active_color); + } + + &:checked { + background-color: $card_bg_color; + background-image: image($view_selected_color); + + &:hover { background-image: image($view_selected_hover_color); } + + &.keyboard-activating, + &:active { background-image: image($view_selected_active_color); } + + &.has-open-popup { background-image: image($view_selected_hover_color); } + + .osd & { + background-color: gtkalpha(currentColor, .1); + } + } + + &:drop(active) { + color: $drop_target_color; + box-shadow: inset 0 0 0 1px $drop_target_color; + } + } +} + +%undecorated_button { + background-color: transparent; +} + +button.color { + padding: 5px; + + > colorswatch:only-child { + border-radius: 2.5px; + + > overlay { + border-radius: 2px; + } + + &:disabled { + filter: none; + } + + &.light > overlay { + border-color: gtkalpha($view_fg_color, 0.1); + } + } +} + +menubutton { + &.osd { + background: none; + color: inherit; + + > button { @extend %osd_button; } + } + + &.circular > button { @extend %circular_button; } + &.flat > button { @extend %button_basic_flat; } + &.pill > button { @extend %pill_button; } + + &.suggested-action { + background-color: $accent_bg_color; + color: $accent_fg_color; + } + + &.destructive-action { + background-color: $destructive_bg_color; + color: $destructive_fg_color; + } + + &.opaque { + background-color: $opaque_button_default_bg; + color: $window_fg_color; + } + + &.suggested-action, + &.destructive-action, + &.opaque { + border-radius: $button_radius; + + &.circular, &.pill { + border-radius: 9999px; + } + + > button { + @extend %opaque_button; + + &, &:checked { + background-color: transparent; + color: inherit; + } + } + } + + &.image-button > button { + min-width: 24px; + padding-left: 5px; + padding-right: 5px; + } + + &.card > button { + border-radius: $card_radius; + } + + arrow { + min-height: 16px; + min-width: 16px; + &.none { + -gtk-icon-source: -gtk-icontheme('open-menu-symbolic'); + } + &.down { + -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); + } + &.up { + -gtk-icon-source: -gtk-icontheme('pan-up-symbolic'); + } + &.left { + -gtk-icon-source: -gtk-icontheme('pan-start-symbolic'); + } + &.right { + -gtk-icon-source: -gtk-icontheme('pan-end-symbolic'); + } + } +} + +splitbutton { + border-radius: $button_radius; + + &, & > separator { + transition: $button_transition; + transition-property: background; + } + + > separator { + margin-top: 6px; + margin-bottom: 6px; + background: none; + } + + > menubutton > button { + padding-left: 4px; + padding-right: 4px; + } + + // Since the inner button doesn't have any style classes on it, + // we have to add them manually + &.image-button > button { + min-width: 24px; + padding-left: 5px; + padding-right: 5px; + } + + &.text-button.image-button > button, + &.image-text-button > button { + padding-left: 9px; + padding-right: 9px; + + > box { + border-spacing: 6px; + } + } + + &:disabled { + filter: opacity($disabled_opacity); + + > button, > menubutton > button { + filter: none; + } + } + + // Reimplementing linked so we don't blow up css + > button:dir(ltr), + > menubutton > button:dir(rtl) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin-right: -1px; + } + + > button:dir(rtl), + > menubutton > button:dir(ltr) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + } + + @at-root %flat_split_button, + &.flat { + > separator { + background: gtkalpha(currentColor, $dimmer_opacity); + } + + &:hover, + &:active, + &:checked { + background: $hover_color; + + > separator { + background: none; + } + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $thin_border_color; + } + } + + &:disabled { + filter: opacity($strong_disabled_opacity); + + > button:disabled, > menubutton > button:disabled { + filter: none; + } + } + + &:focus-within:focus-visible > separator { + background: none; + } + + > button, + > menubutton > button { + @extend %button_basic_flat; + + border-radius: $button_radius; + } + } + + &.suggested-action { + background-color: $accent_bg_color; + color: $accent_fg_color; + } + + &.destructive-action { + background-color: $destructive_bg_color; + color: $destructive_fg_color; + } + + &.opaque { + background-color: $opaque_button_default_bg; + color: $window_fg_color; + } + + &.suggested-action, + &.destructive-action, + &.opaque { + > button, > menubutton > button { + @extend %opaque_button; + + &, &:checked { + color: inherit; + background-color: transparent; + } + } + + $_separator_color: gtkalpha(currentColor, $dimmer_opacity); + > menubutton > button { + &:dir(ltr) { box-shadow: inset 1px 0 $_separator_color; } + &:dir(rtl) { box-shadow: inset -1px 0 $_separator_color; } + } + } + + > menubutton > button > arrow.none { + -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); + } +} + +buttoncontent { + > box { + border-spacing: 6px; + + > label { + font-weight: bold; + + &:dir(ltr) { padding-right: 2px; } + &:dir(rtl) { padding-left: 2px; } + } + } + + .arrow-button > box > &, + splitbutton > button > & { + > box > label { + &:dir(ltr) { padding-right: 0; } + &:dir(rtl) { padding-left: 0; } + } + } +} + +tabbutton { + label { + font-weight: 800; + font-size: 8pt; + + &.small { + font-size: 6pt; + } + } + + indicatorbin > indicator, + indicatorbin > mask { + transform: translate(-1px, 1px); + } +} diff --git a/gtk/theme/libadwaita/widgets/_calendar.scss b/gtk/theme/libadwaita/widgets/_calendar.scss new file mode 100644 index 0000000000..e2fdc04c71 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_calendar.scss @@ -0,0 +1,54 @@ +calendar { + color: $view_fg_color; + background-clip: padding-box; + border: 1px solid $border_color; + font-feature-settings: "tnum"; + + > header { + border-bottom: 1px solid $border_color; + + > button { + @extend %button_basic_flat; + border-radius: 0; + } + } + + > grid { + padding-left: 3px; + padding-bottom: 3px; + + > label.today { + box-shadow: inset 0px -2px $border_color; + + &:selected { + box-shadow: none; + } + } + + > label { + @include focus-ring($focus-state: ':focus'); + margin-top: 3px; + margin-right: 3px; + + &.day-number { + padding: 3px; + + &:checked { + border-radius: $button_radius; + background-color: gtkalpha($accent_bg_color, 0.3); + } + + &:selected { + border-radius: $button_radius; + + background-color: $accent_bg_color; + color: $accent_fg_color; + } + } + + &.day-number.other-month { + color: gtkalpha(currentColor, 0.3); + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_checks.scss b/gtk/theme/libadwaita/widgets/_checks.scss new file mode 100644 index 0000000000..d87f675007 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_checks.scss @@ -0,0 +1,104 @@ +checkbutton { + border-spacing: 4px; + border-radius: $button_radius + 3px; + padding: 3px; + + @include focus-ring(); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + &.text-button { + // this is for a nice focus on check and radios text + padding: 4px; + } +} + +check, +radio { + min-height: 14px; + min-width: 14px; + -gtk-icon-size: 14px; + padding: 3px; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 2px $border_color; + } @else { + box-shadow: inset 0 0 0 2px $trough_color; + } + + &:not(:checked):not(:indeterminate) { + &:hover { + @if $contrast == 'high' { + box-shadow: inset 0 0 0 2px gtkalpha(currentColor, .6); + } @else { + box-shadow: inset 0 0 0 2px $trough_hover_color; + } + } + + &:active { + @if $contrast == 'high' { + background-color: gtkalpha(currentColor, .6); + } @else { + background-color: $trough_active_color; + } + box-shadow: none; + } + } + + &:checked, + &:indeterminate { + background-color: $fill_color; + color: $fill_text_color; + box-shadow: none; + + &:hover { background-image: image(gtkalpha(currentColor, .1)); } + &:active { background-image: image(transparentize(black, .8)); } + } + + &:disabled { + filter: opacity($disabled_opacity); + } + + .osd & { + &:checked, + &:indeterminate { + background-color: $osd_fill_bg_color; + color: $osd_fill_fg_color; + } + } +} + +check { + border-radius: $button_radius; + + &:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/check-symbolic.symbolic.png")), + -gtk-recolor(url("assets/check@2-symbolic.symbolic.png"))); } +} + +radio { + border-radius: 100%; + + &:checked { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/bullet-symbolic.symbolic.png")), + -gtk-recolor(url("assets/bullet@2-symbolic.symbolic.png"))); } +} + +check, radio { + &:indeterminate { -gtk-icon-source: -gtk-scaled(-gtk-recolor(url("assets/dash-symbolic.symbolic.png")), + -gtk-recolor(url("assets/dash@2-symbolic.symbolic.png"))); } +} + +checkbutton.selection-mode { + border-radius: 100px; + + check, radio { + padding: 7px; + border-radius: 100px; + } + + label { + &:dir(ltr) { margin-right: 6px; } + &:dir(rtl) { margin-left: 6px; } + } +} diff --git a/gtk/theme/libadwaita/widgets/_color-chooser.scss b/gtk/theme/libadwaita/widgets/_color-chooser.scss new file mode 100644 index 0000000000..514d33e851 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_color-chooser.scss @@ -0,0 +1,109 @@ +colorswatch { + // This widget is made of two boxes one on top of the other, the lower box is colorswatch {} the other one + // is colorswatch overlay {}, colorswatch has the programmatically set background, so most of the style is + // applied to the overlay box. + + @include focus-ring($width: 4px, $offset: -2px); + + // base color corners rounding + // to avoid the artifacts caused by rounded corner anti-aliasing the base color + // sports a bigger radius. + // nth-child is needed by the custom color strip. + + &.top { + border-top-left-radius: $button_radius + 0.5px; + border-top-right-radius: $button_radius + 0.5px; + + > overlay { + border-top-left-radius: $button_radius; + border-top-right-radius: $button_radius; + } + } + + &.bottom { + border-bottom-left-radius: $button_radius + 0.5px; + border-bottom-right-radius: $button_radius + 0.5px; + + > overlay { + border-bottom-left-radius: $button_radius; + border-bottom-right-radius: $button_radius; + } + } + + &.left, + &:first-child:not(.top) { + border-top-left-radius: $button_radius + 0.5px; + border-bottom-left-radius: $button_radius + 0.5px; + + > overlay { + border-top-left-radius: $button_radius; + border-bottom-left-radius: $button_radius; + } + } + + &.right, + &:last-child:not(.bottom) { + border-top-right-radius: $button_radius + 0.5px; + border-bottom-right-radius: $button_radius + 0.5px; + + > overlay { + border-top-right-radius: $button_radius; + border-bottom-right-radius: $button_radius; + } + } + + @if $contrast == 'high' { + > overlay { + box-shadow: inset 0 0 0 1px gtkalpha($view_fg_color, .5); + } + } + + &.dark > overlay { + color: white; + } + + &.light > overlay { + color: transparentize(black, .25); + + @if $contrast != 'high' { + box-shadow: inset 0 0 0 1px gtkalpha($view_fg_color, 0.1); + } + } + + &:drop(active) { + &.light > overlay { + box-shadow: inset 0 0 0 2px $drop_target_color; + } + + &.dark > overlay { + box-shadow: inset 0 0 0 2px $drop_target_color; + } + } + + &#add-color-button { + > overlay { + @extend %button_basic; + + border-radius: $button_radius 0 0 $button_radius; + } + + &:only-child > overlay { border-radius: $button_radius; } + } + + &:disabled { + filter: opacity($disabled_opacity); + } + + &#editor-color-sample { + border-radius: $button_radius; + + > overlay { border-radius: $button_radius + 0.5px; } + } +} + +plane { + @include focus-ring($offset: 2px, $outer: true); +} + +// colorscale popup +colorchooser .popover.osd { border-radius: $popover_radius; } diff --git a/gtk/theme/libadwaita/widgets/_column-view.scss b/gtk/theme/libadwaita/widgets/_column-view.scss new file mode 100644 index 0000000000..422442e57c --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_column-view.scss @@ -0,0 +1,115 @@ +columnview { + @include focus-ring(); + + &:drop(active) { + box-shadow: none; + } + + > header > button { + @extend %undecorated_button; + padding-top: 3px; + padding-bottom: 3px; + padding-left: 6px; + padding-right: 6px; + border-radius: 0; + box-shadow: none; + line-height: 100%; + border-left: 1px solid transparent; + + &:first-child { + border-left-width: 0; + } + + > box { + color: gtkalpha(currentColor, if($contrast == 'high', .6, .4)); + font-weight: 700; + font-size: 9pt; + border-spacing: 6px; + } + + &:hover > box { + color: gtkalpha(currentColor, if($contrast == 'high', .9, .7)); + box-shadow: none; + } + + &:active > box { + color: currentColor; + } + + sort-indicator { + &.ascending { + -gtk-icon-source: -gtk-icontheme('pan-up-symbolic'); + } + &.descending { + -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); + } + + min-height: 16px; + min-width: 16px; + } + } + + button.dnd, + header.button.dnd { // for treeview-like derive widgets + &:active, &:selected, &:hover, & { + color: $accent_fg_color; + background-color: $accent_bg_color; + transition: none; + } + } + + // Remove the default background of the internal list view + // since we already apply a background to the column view + // with the .view class. Doing this will avoid overdraw. + &.view > listview.view { + background: none; + color: inherit; + } + + // move padding to child cells + > listview > row { + padding: 0; + + // align horizontal sizing with header buttons + > cell { + padding: 8px 6px; + + &:not(:first-child) { + border-left: 1px solid transparent; + } + } + } + + // make column separators visible when :show-column-separators is true + &.column-separators { + > listview > row > cell, + > header > button { + border-left-color: $border_color; + } + } + + > listview:not(.horizontal).separators > row:not(.separator) { + border-top: 1px solid $border_color; + border-bottom: none; + } + + // shrink vertically for .data-table + &.data-table > listview > row > cell { + padding-top: 2px; + padding-bottom: 2px; + } + + @include undershoot(top, $shade_color, true); +} + +columnview row:not(:selected) cell editablelabel:not(.editing):focus-within { + outline: 2px solid $focus_border_color; +} + +columnview row:not(:selected) cell editablelabel.editing:focus-within { + outline: 2px solid $accent_color; +} + +treeexpander { + border-spacing: 4px; +} diff --git a/gtk/theme/libadwaita/widgets/_deprecated.scss b/gtk/theme/libadwaita/widgets/_deprecated.scss new file mode 100644 index 0000000000..faefe5765c --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_deprecated.scss @@ -0,0 +1,343 @@ +// The following styles are deprecated in GTK and should be removed for GTK 5.x + +// .linked > element child +$deprecated_linked_widgets: ("combobox", "> box > button.combo"), + ("appchooserbutton", "> combobox > box > button.combo"); + +/*********************** + * GtkAppChooserDialog * + ***********************/ + +window.appchooser { + headerbar.titlebar { + @extend .flat; + @extend %headerbar-shrunk; + + > windowhandle { + padding-top: 3px; + } + + box.start + box { + margin-top: -6px; + margin-bottom: -6px; + min-height: 12px; + } + } + + searchbar { + @extend %searchbar-flat; + + background: none; + } + + &.csd searchbar { + @extend %searchbar-shrunk; + } + + .dialog-vbox > box > box:not(.dialog-action-area) { + margin: 6px; + } + + .dialog-action-area { + margin-top: 0; + } +} + +/**************** + * GtkAssistant * + ****************/ + +window.assistant { + .sidebar { + padding: $menu-margin; + background-color: $sidebar_bg_color; + color: $sidebar_fg_color; + + &:not(separator) { + &:dir(ltr) { + border-right: none; + box-shadow: inset -1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + + &:dir(rtl) { + box-shadow: inset 1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + } + + &:backdrop { + background-color: $sidebar_backdrop_color; + transition: background-color $backdrop_transition; + } + + > label { + padding: 6px 12px; + border-radius: $menu_radius; + + &.highlight { + background-color: $selected_color; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + } + } + } +} + +/*************** + * GtkComboBox * + ***************/ + +combobox { + @extend dropdown; + + // Since cell view is taller than a plain label, make sure + // the button doesn't get stretched with a larger font + button { + padding-top: 2px; + padding-bottom: 2px; + min-height: 30px; + } +} + +/*************** + * GtkIconView * + ***************/ + +iconview { + @extend %view; + + @if $contrast == 'high' { + &:selected { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + @include focus-ring(); + + &:drop(active) { + box-shadow: none; + } + + > dndtarget:drop(active) { + border-style: solid; + border-width: 1px; + border-color: $drop_target_color; + } +} + +/************** + * GtkInfoBar * + **************/ + +infobar { + > revealer > box { + padding: 6px; + padding-bottom: 7px; + border-spacing: 6px; + box-shadow: inset 0 -1px if($contrast == 'high', $border_color, $shade_color); + + > box { + border-spacing: 6px; + } + } + + &.action:hover > revealer > box { + background-image: image(gtkalpha(currentColor, .05)); + } + + &.action:active > revealer > box { + background-image: image(gtkalpha(currentColor, .1)); + } + + @each $i_type, $i_color in (info, $accent_bg_color), + (question, $accent_bg_color), + (warning, $warning_bg_color), + (error, $error_bg_color) { + &.#{$i_type} > revealer > box { + background-color: gtkmix($i_color, $window_bg_color, 30%); + color: $window_fg_color; + } + } + + .close { + min-width: 18px; + min-height: 18px; + padding: 4px; + border-radius: 50%; + @extend %button_basic_flat; + } +} + +/**************** + * GtkStatusBar * + ****************/ + +statusbar { + padding: 6px 10px 6px 10px; +} + +/*************** + * GtkTreeView * + ***************/ + +// To be used for opaque elements overlaid atop the selected row +$treeview_selection_opaque: gtkmix(currentColor, $view_bg_color, 10%); +$treeview_borders_opaque: gtkmix(currentColor, $view_bg_color, if($contrast == 'high', 40%, 20%)); + +treeview.view { + @extend columnview; + + border-left-color: $treeview_borders_opaque; // this is actually the tree lines color, + border-top-color: $treeview_borders_opaque; // while this is the grid lines color, better then nothing + + &:selected { + &:focus, & { + border-radius: 0; + } + } + + &.separator { + min-height: 2px; + color: $border_color; + } + + &.expander { + // GtkTreeView uses the larger of the expander’s min-width and min-height + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme('pan-end-symbolic'); + + &:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); } + + color: gtkalpha(currentColor, .7); + + &:hover, &:active { color: currentColor; } + + &:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); } + + &:disabled { color: gtkalpha(currentColor, $disabled_opacity); } + } + + > dndtarget:drop(active) { + border-style: solid none; + border-width: 1px; + border-color: $drop_target_color; + + &.after { border-top-style: none; } + + &.before { border-bottom-style: none; } + } + + > header > button { + padding-left: 4px; + padding-right: 4px; + border-bottom: 1px solid $border_color; + } + + &.progressbar { // progress bar in treeviews + &, &:selected { + background-color: $accent_bg_color; + color: $accent_fg_color; + } + + box-shadow: none; + } + + &.trough { // progress bar trough in treeviews + background-color: gtkalpha(currentColor, 0.1); + } + + ~ undershoot.top { + box-shadow: none; + background: none; + } + + acceleditor > label { + // see tests/testaccel in GTK to test + background-color: $treeview_selection_opaque; + } +} + +treeview.navigation-sidebar { + padding: 0; + + &:selected { + &:focus, & { + background-color: $selected_color; + } + } +} + +treeview entry { + &:focus-within { + &:dir(rtl), &:dir(ltr) { // specificity bump hack + background-color: $view_bg_color; + transition-property: color, background; + } + } + + &.flat, & { + border-radius: 0; + background-image: none; + background-color: $view_bg_color; + + &:focus-within { border-color: $accent_color; } + } +} + +treeview spinbutton:not(.vertical) { + min-height: 0; + border-style: none; + border-radius: 0; + + > text { + min-height: 0; + padding: 1px 2px; + } +} + +// The following styles are deprecated in libadwaita and should be removed in 2.x + +// Deprecated: use .boxed-list instead +list.content { + @extend .boxed-list; +} + +// Deprecated: use .navigation-sidebar instead +.sidebar { + &:not(separator) { + &:dir(ltr), + &.left, + &.left:dir(rtl) { + border-right: 1px solid $border_color; + border-left-style: none; + } + + &:dir(rtl), + &.right { + border-left: 1px solid $border_color; + border-right-style: none; + } + } + + listview.view, + list { + background-color: transparent; + color: inherit; + } + + paned & { &.left, &.right, &.left:dir(rtl), &:dir(rtl), &:dir(ltr), & { border-style: none; }} +} + +// Deprecated: use .title-1 +.large-title { + font-weight: 300; + font-size: 24pt; +} + +// Deprecated: use AdwToolbarView + +headerbar.flat { + @extend %headerbar-flat; +} diff --git a/gtk/theme/libadwaita/widgets/_dialogs.scss b/gtk/theme/libadwaita/widgets/_dialogs.scss new file mode 100644 index 0000000000..3ff6b00040 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_dialogs.scss @@ -0,0 +1,125 @@ +.dialog-action-area { + margin: 6px; + border-spacing: 6px; +} + +/**************** + * Print dialog * +*****************/ + +window.print { + drawing { + color: $window_fg_color; + background: none; + border: none; + padding: 0; + + paper { + background-color: white; + color: transparentize(black, .2); + background-clip: padding-box; + border: 1px solid $border_color; + } + } + + headerbar.titlebar { + @extend .flat; + } + + .dialog-action-box { + @extend .view; + } +} + +/******************** + * Page setup dalog * + ********************/ + +window.pagesetup { + headerbar.titlebar { + @extend .flat; + } +} + +/****************** + * GtkAboutDialog * + ******************/ + +window.aboutdialog { + headerbar.titlebar { + @extend .flat; + } + + image.large-icons { + -gtk-icon-size: 128px; + } +} + +/************************* + * GtkColorChooserDialog * + *************************/ +window.colorchooser { + headerbar.titlebar { + @extend .flat; + } +} + +/************* + * AdwDialog * + *************/ + +floating-sheet { + > dimming { + background-color: gtkalpha($shade_color, 2); + } + + > sheet { + border-radius: $window_radius; + box-shadow: 0 2px 8px 2px transparentize(black, 0.93), + 0 3px 20px 10px transparentize(black, 0.95), + 0 6px 32px 16px transparentize(black, 0.98), + 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .95)); + outline: 1px solid $window_outline_color; + outline-offset: -1px; + } +} + +dialog.bottom-sheet { + &.landscape sheet { + margin-left: 30px; + margin-right: 30px; + + > outline { + &.flush-left, &.flush-right, &.flush-left.flush-right { + box-shadow: inset 1px 0 $window_outline_color, + inset -1px 0 $window_outline_color, + inset 0 1px $window_outline_color; + } + } + } +} + +dialog-host > dialog.background { + background: none; + + sheet { + background-color: $window_bg_color; + color: $window_fg_color; + } +} + +dialog-host > dialog.view { + background: none; + + sheet { + @extend %view; + } +} + +dialog-host > dialog.osd { + background: none; + + sheet { + @extend %osd; + } +} diff --git a/gtk/theme/libadwaita/widgets/_dropdowns.scss b/gtk/theme/libadwaita/widgets/_dropdowns.scss new file mode 100644 index 0000000000..efdb07b7de --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_dropdowns.scss @@ -0,0 +1,38 @@ +dropdown { + > button > box { + border-spacing: 6px; + + > stack > row.activatable { + &:hover, &:active { background: none; } + } + } + + arrow { + -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); + min-height: 16px; + min-width: 16px; + } + + &:drop(active) { // FIXME: untested + box-shadow: none; + + button.combo { @extend %button_basic_drop_active; } + } + + popover.menu { + padding-top: 6px; + + listview > row { + min-width: 0; + } + + // dropdowns with searchboxes on top + .dropdown-searchbar { + padding: 6px; + + + scrolledwindow { + @include undershoot(top, $popover_shade_color); + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_emoji-chooser.scss b/gtk/theme/libadwaita/widgets/_emoji-chooser.scss new file mode 100644 index 0000000000..b52ffac717 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_emoji-chooser.scss @@ -0,0 +1,91 @@ +popover.emoji-picker > contents { + padding: 0; +} + +.emoji-searchbar { + padding: 6px; +} + +.emoji-toolbar { + // flowbox children already have 3px padding, so we only need 3px more to + // get the regular 6px. We also don't need spacing, for the same reason. + padding: 3px; +} + +button.emoji-section.image-button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + @extend %circular_button; + @extend %button_basic_flat; + + min-width: 32px; + min-height: 32px; +} + +popover.emoji-picker emoji { + font-size: x-large; + padding: 6px; + border-radius: $button_radius; + + &:focus, + &:hover { + background: $hover_color; + } + + &:active { + background: $active_color; + } + + @if $contrast == 'high' { + &:focus, + &:hover, + &:active { + box-shadow: inset 0 0 0 1px $border_color; + } + } +} + +popover.emoji-picker scrolledwindow.view { + background: none; + color: inherit; + + @include undershoot(top, $popover_shade_color); + @include undershoot(bottom, $popover_shade_color); +} + +// Emoji completion popover + +popover.emoji-completion > contents { + padding: $menu_margin; + padding-bottom: $menu_margin - 2px; +} + +emoji-completion-row { + // emoji extends quite a bit into the padding, so we can't use the same padding on all sides + padding: $menu_padding - 6px; + margin-bottom: 2px; + border-radius: $menu_radius; + + &:dir(ltr) { padding-right: $menu_padding; } + &:dir(rtl) { padding-left: $menu_padding; } + + > box { + border-spacing: $menu_padding - 6px; + } + + &:focus, + &:hover { + background-color: $selected_color; + color: $popover_fg_color; + } + + &:active { + background-color: $active_color; // matching buttons + } + + @if $contrast == 'high' { + &:focus, + &:hover, + &:active { + box-shadow: inset 0 0 0 1px $border_color; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_entries.scss b/gtk/theme/libadwaita/widgets/_entries.scss new file mode 100644 index 0000000000..271294edb7 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_entries.scss @@ -0,0 +1,107 @@ +%entry, +entry { + %entry_basic, & { + min-height: 34px; + padding-left: 9px; + padding-right: 9px; + border-radius: $button_radius; + border-spacing: 6px; + background-color: $button_color; + background-clip: padding-box; + caret-color: currentColor; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + + @include focus-ring($focus-state: ':focus-within'); + + .osd &:focus-within { + outline-color: $osd_focus_color; + } + + > text { + > placeholder { + @extend .dim-label; + } + + > block-cursor { + color: $view_bg_color; + background-color: $view_fg_color; + } + } + + &.flat { + &:focus-within, &:disabled, & { + min-height: 0; + padding: 2px; + background-color: transparent; + box-shadow: none; + border-radius: 0; + } + } + + &:disabled { filter: opacity($disabled_opacity); } + + // entry error and warning style + @each $e_type, $e_color in (error, $error_color), + (warning, $warning_color), + (success, $success_color) { + &.#{$e_type} { + @include focus-ring($focus-state: ':focus-within', $fc: gtkalpha(currentColor, $focus_border_opacity)); + + > text { + > selection:focus-within { background-color: gtkalpha($e_color, .2); } + + > cursor-handle > contents { background-color: currentColor; } + } + + > progress > trough > progress { + border-color: currentColor; + } + } + } + + > image { // icons inside the entry + opacity: if($contrast == 'high', .85, .7); + + &:hover { opacity: 1; } + + &:active { + opacity: if($contrast == 'high', .9, .8); + } + + &.left { margin-right: 6px; } + &.right { margin-left: 6px; } + } + + &.password image.caps-lock-indicator { + opacity: $dimmer_opacity; + } + + &:drop(active) { + &:focus-within, & { + border-color: $drop_target_color; + box-shadow: inset 0 0 0 1px $drop_target_color; + } + } + } + + > progress { + margin-bottom: 3px; + + > trough > progress { + background-color: transparent; + background-image: none; + border-radius: 0; + border-width: 0 0 2px; + border-color: $accent_bg_color; + border-style: solid; + box-shadow: none; + } + } + + .osd & > progress > trough > progress { + border-color: $osd_fill_bg_color; + } +} diff --git a/gtk/theme/libadwaita/widgets/_expanders.scss b/gtk/theme/libadwaita/widgets/_expanders.scss new file mode 100644 index 0000000000..77de60c74b --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_expanders.scss @@ -0,0 +1,27 @@ +expander { + min-width: 16px; + min-height: 16px; + -gtk-icon-source: -gtk-icontheme('pan-end-symbolic'); + &:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); } + + &:disabled { filter: opacity($disabled_opacity); } + + &:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); } +} + +expander-widget { + @include focus-ring("> box > title"); + + > box > title { + border-radius: $button_radius; + + > expander { + opacity: .7; + } + + &:hover > expander, + &:active > expander { + opacity: 1; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_file-chooser.scss b/gtk/theme/libadwaita/widgets/_file-chooser.scss new file mode 100644 index 0000000000..49455c646d --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_file-chooser.scss @@ -0,0 +1,230 @@ +placessidebar { + .navigation-sidebar > row { + // Needs overriding of the `.navigation-sidebar > row` padding + padding: 0; + + // Using margins/padding directly in the SidebarRow + // will make the animation of the new bookmark row jump + > revealer { padding: 0 14px; } + + image.sidebar-icon { + &:dir(ltr) { padding-right: 8px; } + &:dir(rtl) { padding-left: 8px; } + } + + label.sidebar-label { + &:dir(ltr) { padding-right: 2px; } + &:dir(rtl) { padding-left: 2px; } + } + + @at-root button.sidebar-button { + @extend %button_basic_flat; + + min-height: 26px; + min-width: 26px; + margin-top: 3px; + margin-bottom: 3px; + padding: 0; + border-radius: 100%; + } + + // in the sidebar case it makes no sense to click the selected row + &:selected:active { box-shadow: none; } + + &.sidebar-placeholder-row { + padding: 0 8px; + min-height: 2px; + background-image: image($drop_target_color); + background-clip: content-box; + } + + &.sidebar-new-bookmark-row { color: $accent_color; } + + &:drop(active):not(:disabled) { + color: $drop_target_color; + box-shadow: inset 0 0 0 1px $drop_target_color; + } + } +} + +row { + image.sidebar-icon { + opacity: 0.7; // see bug #786613 for details on this oddity + } + + .sidebar-button { + opacity: 0.7; + + &:hover, + &:active, + &.keyboard-activating { + opacity: 1; + } + } +} + +placesview { + .server-list-button > image { + transition: -gtk-icon-transform 200ms $ease-out-quad; + -gtk-icon-transform: rotate(0turn); + } + + .server-list-button:checked > image { + -gtk-icon-transform: rotate(-0.5turn); + } + + > actionbar > revealer > box > box { + border-spacing: 6px; + } +} + +filechooser { + box-shadow: 0 1px $border_color; + + // Make the toolbar buttons flat like on an actual toolbar + #pathbarbox > stack > box > { + button, + box > button, + menubutton > button { + @extend %button_basic_flat; + } + } + + pathbar button { + &:not(.image-button) { + padding-left: 9px; + padding-right: 9px; + } + + // Icon + label buttons + > box { + border-spacing: 4px; + + > label { + padding-left: 2px; + padding-right: 2px; + } + } + } + + columnview > listview > row > cell { + padding: 0; + + > filelistcell { + padding: 8px 6px; + } + } + + gridview { + @include undershoot(top, $shade_color, true); + padding: 15px; + + > child { + border-radius: 12px; + padding: 0; + margin: 3px; + + > filelistcell { + padding: 6px 12px; + } + + & filethumbnail image { + filter: drop-shadow(0px 1px 1px rgba(0,0,0,0.3)); + } + + & box { + border-spacing: 6px; + } + } + } + + // Style the outer action bar with a toolbar view-like shadow + > box > actionbar { + box-shadow: 0 -1px if($contrast == 'high', $border_color, gtkalpha($headerbar_shade_color, .5)), + 0 -2px 4px gtkalpha($headerbar_shade_color, .5); + + > revealer > box { + box-shadow: none; + padding-top: 6px; + } + } + + // Style the remote search action bar like a banner + scrolledwindow + actionbar > revealer > box { + background-color: gtkmix($accent_bg_color, $view_bg_color, 30%); + color: $window_fg_color; + box-shadow: none; + padding-top: 6px; + font-weight: bold; + + &:backdrop { + background-color: gtkmix($accent_bg_color, $view_bg_color, 15%); + } + } + + placesview { + // Only the bottom undershoot, since the action bar is guaranteed to be + // there, while the search bar can show and hide. That's a problem, since + // we only need top undershoot when it's visible, to avoid a double shadow. + > stack > scrolledwindow { + @include undershoot(bottom); + } + + // Make the Connect to Server action bar flat + > actionbar > revealer > box { + background: $view_bg_color; + color: $view_fg_color; + box-shadow: none; + padding-top: 6px; + + &:backdrop { + background: $view_bg_color; + transition: none; + } + } + } + + placessidebar { + background-color: $sidebar_bg_color; + color: $sidebar_fg_color; + + &:backdrop { + background-color: $sidebar_backdrop_color; + transition: background-color $backdrop_transition; + } + } + + // The separator is a part of GtkPaned, so it needs to be styled separately + paned.horizontal > separator { + &:dir(ltr) { + box-shadow: inset 1px 0 $sidebar_bg_color, + inset 1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + + &:backdrop { + box-shadow: inset 1px 0 $sidebar_backdrop_color, + inset 1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + } + + &:dir(rtl) { + box-shadow: inset -1px 0 $sidebar_bg_color, + inset -1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + + &:backdrop { + box-shadow: inset -1px 0 $sidebar_backdrop_color, + inset -1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + } + + &:backdrop { + transition: box-shadow $backdrop_transition; + } + } +} + +/* Fix header bar height in the file chooser */ +window.filechooser headerbar box.start + box.vertical { + margin-top: -6px; + margin-bottom: -6px; + min-height: 12px; +} diff --git a/gtk/theme/libadwaita/widgets/_header-bar.scss b/gtk/theme/libadwaita/widgets/_header-bar.scss new file mode 100644 index 0000000000..29e22edd89 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_header-bar.scss @@ -0,0 +1,230 @@ +headerbar { + min-height: 47px; + background-color: $headerbar_bg_color; + color: $headerbar_fg_color; + box-shadow: inset 0 -1px if($contrast == 'high', $headerbar_border_color, $headerbar_shade_color), + inset 1px 0 $headerbar_border_color, + inset -1px 0 $headerbar_border_color; + + margin-left: -1px; + margin-right: -1px; + + @extend %toolbar; + + > windowhandle > box { + padding: 6px 7px 7px 7px; + + > box.start, + > box.end { + border-spacing: 6px; + } + + &, > widget { + > box.start:dir(ltr), + > box.end:dir(rtl) { + margin-right: 6px; + } + + > box.start:dir(rtl), + > box.end:dir(ltr) { + margin-left: 6px; + } + } + } + + &:backdrop { + background-color: $headerbar_backdrop_color; + transition: background-color $backdrop_transition; + + > windowhandle { + // opacity looks weird with GtkSwitch, but filter works fine + filter: opacity(0.5); + + transition: filter $backdrop_transition; + } + } + + &.default-decoration { + min-height: 37px; + + > windowhandle > box { + padding: 3px 4px 4px 4px; + } + + windowcontrols { + > button { + min-height: 22px; + min-width: 22px; + padding: 4px; + } + + > .icon { + margin: 7px; + } + } + } +} + +window > { + .titlebar:not(.flat) { + box-shadow: 0 1px if($contrast == 'high', $border_color, gtkalpha($headerbar_shade_color, .5)), + 0 2px 4px gtkalpha($headerbar_shade_color, .5); + } + + .titlebar headerbar:not(.flat) { + box-shadow: inset 1px 0 $headerbar_border_color, + inset -1px 0 $headerbar_border_color; + } + + headerbar.titlebar, + .titlebar headerbar { + min-height: 46px; + + > windowhandle > box { + padding-bottom: 6px; + } + + &.default-decoration { + min-height: 36px; + + > windowhandle > box { + padding-bottom: 3px; + } + } + } +} + +%headerbar-flat { + background: none; + box-shadow: none; + color: inherit; + + min-height: 46px; + + > windowhandle > box { + padding-bottom: 6px; + } + + &.default-decoration { + min-height: 36px; + + > windowhandle > box { + padding-bottom: 3px; + } + } +} + +%headerbar-inline { + @extend %headerbar-flat; + + &:backdrop { + transition: none; + + > windowhandle { + filter: none; + transition: none; + } + } + + window.devel & > windowhandle { + background-image: none; + } +} + +%headerbar-shrunk { + min-height: 40px; + + > windowhandle > box { + padding-top: 3px; + padding-bottom: 3px; + } + + &.default-decoration { + min-height: 30px; + + > windowhandle > box { + padding-top: 0px; + padding-bottom: 0px; + } + } +} + +.titlebar:not(headerbar) { + separator { background-color: $headerbar_border_color; } +} + +/********************* + * GtkWindowControls * + *********************/ + +windowcontrols { + border-spacing: 3px; + + > button { + min-width: 24px; + padding: 5px; + box-shadow: none; + + > image { + background-color: $button_color; + border-radius: 100%; + padding: 2px; + transition: $button_transition; + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + &, &:hover, &:active { + background: none; + } + + &:hover > image { background-color: $button_hover_color; } + &:active > image { background-color: $button_active_color; } + } + + > .icon { + margin: 9px; + } +} + +/****************** + * AdwWindowTitle * + ******************/ + +headerbar, +windowtitle { + .title { + padding-left: 12px; + padding-right: 12px; + font-weight: bold; + } + + .subtitle { + font-size: smaller; + padding-left: 12px; + padding-right: 12px; + @extend .dim-label; + } +} + +windowtitle { + margin-top: -6px; + margin-bottom: -6px; + min-height: 12px; +} + +// Development versions of apps to use a differently styled headerbar + +window.devel { + headerbar > windowhandle { + background-image: cross-fade(5% -gtk-recolor(url("assets/devel-symbolic.svg")), + image(transparent)); + background-repeat: repeat-x; + } + + dialog headerbar > windowhandle { + background-image: unset; + background-repeat: unset; + } +} diff --git a/gtk/theme/libadwaita/widgets/_labels.scss b/gtk/theme/libadwaita/widgets/_labels.scss new file mode 100644 index 0000000000..10f3a18709 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_labels.scss @@ -0,0 +1,92 @@ +label { + caret-color: currentColor; + + &.separator { + @extend .dim-label; + } + + &:disabled { + filter: opacity($disabled_opacity); + } +} + +.dim-label { + opacity: $dim_label_opacity; +} + +.accent { + color: $accent_color; +} + +.success { + color: $success_color; +} + +.warning { + color: $warning_color; +} + +.error { + color: $error_color; +} + +/********************** + * General Typography * + **********************/ + +.title-1 { + font-weight: 800; + font-size: 20pt; +} + +.title-2 { + font-weight: 800; + font-size: 15pt; +} + +.title-3 { + font-weight: 700; + font-size: 15pt; +} + +.title-4 { + font-weight: 700; + font-size: 13pt; +} + +.heading { + font-weight: 700; + font-size: 11pt; +} + +.body { + font-weight: 400; + font-size: 11pt; +} + +.caption-heading { + font-weight: 700; + font-size: 9pt; +} + +.caption { + font-weight: 400; + font-size: 9pt; +} + +.monospace { + font-family: monospace; +} + +.numeric { + font-feature-settings: "tnum"; +} + +/******************* + * Editable Labels * + *******************/ + +editablelabel > stack > text { + color: $view_fg_color; + background-color: $view_bg_color; +} diff --git a/gtk/theme/libadwaita/widgets/_level-bar.scss b/gtk/theme/libadwaita/widgets/_level-bar.scss new file mode 100644 index 0000000000..bf75593df7 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_level-bar.scss @@ -0,0 +1,100 @@ +$_levelbar_size: 8px; +$_levelbar_border_radius: 99px; + +levelbar { + &:disabled { + filter: opacity($disabled_opacity); + } + + &.horizontal { + trough > block { + min-height: $_levelbar_size; + border-radius: $_levelbar_border_radius; + + &.empty, + &.full { + border-radius: $_levelbar_border_radius; + } + } + + // segmented level bar + &.discrete > trough > block { + min-height: $_levelbar_size; + margin-right: 2px; + min-width: 26px; + border-radius: 0; + + &:first-child { + border-radius: $_levelbar_border_radius 0 0 $_levelbar_border_radius; + } + + &:last-child { + border-radius: 0 $_levelbar_border_radius $_levelbar_border_radius 0; + margin-right: 0; + } + } + } + + &.vertical { + trough > block { + min-width: $_levelbar_size; + border-radius: $_levelbar_border_radius; + + &.empty, + &.full { + border-radius: $_levelbar_border_radius; + } + } + + // segmented level bar + &.discrete > trough > block { + min-width: $_levelbar_size; + margin-bottom: 2px; + min-height: 26px; + border-radius: 0; + + &:first-child { + border-radius: $_levelbar_border_radius $_levelbar_border_radius 0 0; + } + + &:last-child { + border-radius: 0 0 $_levelbar_border_radius $_levelbar_border_radius; + margin-bottom: 0; + } + } + } + + > trough { + padding: 0; + + // level bar colours + > block { + &.low { + background-color: $warning_bg_color; + } + + &.high, + &:not(.empty) { + background-color: $fill_color; + } + + &.full { + background-color: $success_bg_color; + } + + &.empty { + background-color: $trough_color; + + @if $contrast == "high" { + box-shadow: inset 0 0 0 1px $border_color; + } + } + } + } + + .osd & > trough > block { + &.high, &:not(.empty) { + background-color: $osd_fill_bg_color; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_linked.scss b/gtk/theme/libadwaita/widgets/_linked.scss new file mode 100644 index 0000000000..90e71884d2 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_linked.scss @@ -0,0 +1,46 @@ +// .linked > element child +$_linked_widgets: ("%button", ""), + ("button", ""), + ("menubutton", "> button"), + ("dropdown", "> button"), + ("colorbutton", "> button"), + ("fontbutton", "> button"), + ("tabbutton", "> button"), + ("%entry", ""), + ("entry", ""); + +$_linked_widgets: join($_linked_widgets, $deprecated_linked_widgets); + +@each $widget, $child in $_linked_widgets { + .linked:not(.vertical) > { + #{$widget} { + &:dir(ltr):not(:first-child) #{$child}, + &:dir(rtl):not(:last-child) #{$child} { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin-left: -1px; + } + + &:dir(ltr):not(:last-child) #{$child}, + &:dir(rtl):not(:first-child) #{$child} { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + } + } + + .linked.vertical { + #{$widget} { + &:not(:first-child) #{$child} { + border-top-left-radius: 0; + border-top-right-radius: 0; + margin-top: -1px; + } + + &:not(:last-child) #{$child} { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_links.scss b/gtk/theme/libadwaita/widgets/_links.scss new file mode 100644 index 0000000000..3377f266e7 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_links.scss @@ -0,0 +1,53 @@ +link, +button.link { + color: $link_color; + text-decoration: underline; + font-weight: inherit; + + &:visited { + color: $link_visited_color; + } + + &:hover { + color: gtkshade($link_color, 1.1); + } + + &:active { + color: $link_color; + } + + &:disabled { color: gtkalpha(currentColor, $disabled_opacity); } + + .osd & { + color: $osd_link_color; + + &:visited { + color: $osd_link_visited_color; + } + + &:active { + color: $osd_link_color; + } + } +} + +link { + @include focus-ring(); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } +} + +button.link { + &, + &:hover, + &:active, + &:checked { + @extend %undecorated_button; + } + + > label { + text-decoration: underline; + } +} diff --git a/gtk/theme/libadwaita/widgets/_lists.scss b/gtk/theme/libadwaita/widgets/_lists.scss new file mode 100644 index 0000000000..2693d514f8 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_lists.scss @@ -0,0 +1,547 @@ +$row_transition: background-color 200ms $ease-out-quad, + background-image 200ms $ease-out-quad, + border-radius 200ms $ease-out-quad; + +listview, +list { + color: $view_fg_color; + background-color: $view_bg_color; + background-clip: padding-box; + border-color: $border_color; + + > row { + padding: 2px; + background-clip: padding-box; + } + + > row.expander { padding: 0px; } + > row.expander .row-header { padding: 2px; } + + &.horizontal row.separator, + &.separators.horizontal > row:not(.separator) { + border-left: 1px solid $border_color; + } + + &:not(.horizontal) row.separator, + &.separators:not(.horizontal) > row:not(.separator) { + border-bottom: 1px solid $border_color; + } +} + +listview > header { + @extend .heading; + padding: 2px; + padding-top: 18px; + padding-bottom: 6px; +} + +row { + @include focus-ring(); + + .osd & { + &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + &.activatable { + &:hover { background-color: $hover_color; } + + &:active { background-color: $active_color; } + + // this is for indicathing which row generated a popover see https://bugzilla.gnome.org/show_bug.cgi?id=754411 + &.has-open-popup { background-color: $hover_color; } + + &:selected { + &:hover { background-color: $selected_hover_color; } + + &:active { background-color: $selected_active_color; } + + &.has-open-popup { background-color: $selected_hover_color; } + } + } + + &:selected { + background-color: $selected_color; + } + } + + background-clip: padding-box; + + &.activatable { + &:hover { background-color: $view_hover_color; } + + &:active { background-color: $view_active_color; } + + // this is for indicathing which row generated a popover see https://bugzilla.gnome.org/show_bug.cgi?id=754411 + &.has-open-popup { background-color: $view_hover_color; } + + &:selected { + &:hover { background-color: $view_selected_hover_color; } + + &:active { background-color: $view_selected_active_color; } + + &.has-open-popup { background-color: $view_selected_hover_color; } + } + } + + &:selected { + background-color: $view_selected_color; + } +} + +/******************************************************* + * Rich Lists * + * Large list usually containing lots of widgets * + * https://gitlab.gnome.org/GNOME/gtk/-/issues/3073 * + *******************************************************/ + +.rich-list { /* rich lists usually containing other widgets than just labels/text */ + > row { + padding: 8px 12px; + min-height: 32px; /* should be tall even when only containing a label */ + + > box { + border-spacing: 12px; + } + } + + > header { + padding-left: 12px; + padding-right: 12px; + } +} + +/**************** + * AdwActionRow * + ****************/ + +row { + label.subtitle { + font-size: smaller; + @extend .dim-label; + } + + > box.header { + margin-left: 12px; + margin-right: 12px; + border-spacing: 6px; + min-height: 50px; + + > .icon:disabled { + filter: opacity($disabled_opacity); + } + + > box.title { + margin-top: 6px; + margin-bottom: 6px; + border-spacing: 3px; + padding: 0; + + // Specificity bump for header bar + &, + > .title, + > .subtitle { + padding: 0; + font-weight: inherit; + } + } + + > .prefixes, + > .suffixes { + border-spacing: 6px; + } + + > .icon, + > .prefixes { + &:dir(ltr) { margin-right: 6px; } + &:dir(rtl) { margin-left: 6px; } + } + } + + &.property > box.header > box.title > { + .title { + font-size: smaller; + @extend .dim-label; + } + + .subtitle { + font-size: inherit; + opacity: 1; + } + } +} + +/****************************** + * AdwEntryRow and AdwSpinRow * + ******************************/ + +row.entry { + &:disabled { + text { + opacity: $disabled_opacity; + } + + .dim-label, .subtitle { + opacity: 1; + } + } + + .edit-icon, .indicator { + min-width: 24px; + min-height: 24px; + padding: 5px; + } + + .edit-icon:disabled { + opacity: $strong_disabled_opacity; + } + + .indicator { + opacity: $dimmer_opacity; + } + + &.monospace { + font-family: inherit; + + text { + font-family: monospace; + } + } +} + +row.spin { + spinbutton { + background: none; + border-spacing: 6px; + box-shadow: none; + + &, &:focus { + outline: none; + } + + > button.image-button.up:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque):last-child, + > button.image-button.down:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &, &:dir(ltr):last-child, &:dir(rtl):first-child { + @extend %button_basic; + @extend %circular_button; + min-width: 30px; + min-height: 30px; + margin: 10px 2px; + border: none; + } + } + } + + &:disabled spinbutton { + > button.image-button.up:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque):last-child, + > button.image-button.down:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &, &:dir(ltr):last-child, &:dir(rtl):first-child { + &:disabled { + filter: none; + } + } + } + } +} + +row.entry, +row.spin { + @include focus-ring($focus-state: '.focused', $offset: -1px, $transition: $row_transition); + + &:not(:selected).activatable.focused:hover, + &:not(:selected).activatable.focused:active { + background-color: transparent; + } + + @each $e_type, $e_color, $e_bg_color, $e_fg_color in (error, $error_color, $error_bg_color, $error_fg_color), + (warning, $warning_color, $warning_bg_color, $warning_fg_color), + (success, $success_color, $success_bg_color, $success_fg_color) { + &.#{$e_type} { + @include focus-ring($focus-state: '.focused', $offset: -1px, $fc: gtkalpha(currentColor, $focus_border_opacity), $transition: $row_transition); + + text { + > selection:focus-within { background-color: gtkalpha($e_color, .2); } + + > cursor-handle > contents { background-color: currentColor; } + } + + .dim-label, .subtitle { + opacity: 1; + } + + .suggested-action { + background-color: $e_bg_color; + color: $e_fg_color; + } + } + } +} + +/*************** + * AdwComboRow * + ***************/ + +row.combo { + image.dropdown-arrow:disabled { + filter: opacity($disabled_opacity); + } + + listview.inline { + background: none; + border: none; + box-shadow: none; + color: inherit; + + &, &:disabled { + background: none; + color: inherit; + } + } + + popover > contents { + min-width: 120px; + + .combo-searchbar { + margin: 6px; + + + scrolledwindow { + @include undershoot(top, $popover_shade_color); + } + } + } +} + +/****************** + * AdwExpanderRow * + ******************/ + +@mixin margin-start($margin) { + &:dir(ltr) { + margin-left: $margin; + } + + &:dir(rtl) { + margin-right: $margin; + } +} + +%boxed_list_row { + @include focus-ring($offset: -1px, $transition: $row_transition); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + border-bottom: 1px solid if($contrast == 'high', $border_color, $card_shade_color); + + &:not(:selected).activatable { + &:hover { + background-color: gtkalpha(currentColor, .03); + } + + &:active { + background-color: gtkalpha(currentColor, .08); + } + + &.has-open-popup { + background-color: gtkalpha(currentColor, .03); + } + } +} + +row.expander { + // Drop transparent background on expander rows to let nested rows handle it, + // avoiding double highlights. + background: none; + padding: 0px; + + > box > list { + background: none; + color: inherit; + } + + list.nested { + background-color: gtkalpha($card_shade_color, .5); + color: inherit; + } + + list.nested > row { + @extend %boxed_list_row; + } + + // AdwExpanderRow arrow rotation + + image.expander-row-arrow { + @extend .dim-label; + + transition: -gtk-icon-transform 200ms $ease-out-quad; + @include margin-start(3px); + + &:dir(ltr) { + -gtk-icon-transform: rotate(0.5turn); + } + + &:dir(rtl) { + -gtk-icon-transform: rotate(-0.5turn); + } + + &:disabled { + filter: opacity($disabled_opacity); + } + } + + &:checked image.expander-row-arrow { + -gtk-icon-transform: rotate(0turn); + opacity: 1; + + &:not(:disabled) { + color: $accent_color; + } + } + + .osd &:checked image.expander-row-arrow:not(:disabled) { + color: inherit; + } + + &.property box > list > row { + @extend .property; + } +} + +/*************** + * AdwButtonRow * + ***************/ + +row.button { + > box { + margin-left: 12px; + margin-right: 12px; + border-spacing: 6px; + min-height: 42px; + } + + .title { + @extend .heading; + } + + &.suggested-action { + color: $accent_color; + } + + &.destructive-action { + color: $destructive_color; + } +} + +/***************** + * Boxed Lists * + *****************/ + +list.boxed-list { + @extend %card; + + > row { + // Regular rows and expander header rows background + &, &.expander row.header { + @extend %boxed_list_row; + } + + &.expander { + border: none; + } + + // Rounded top + &:first-child { + &, &.expander row.header { + border-top-left-radius: $card_radius; + border-top-right-radius: $card_radius; + } + } + + // Rounded bottom + &:last-child { + &, + &.expander:not(:checked), + &.expander:not(:checked) row.header, + &.expander:checked list.nested, + &.expander:checked list.nested > row:last-child { + border-bottom-left-radius: $card_radius; + border-bottom-right-radius: $card_radius; + border-bottom-width: 0; + } + } + } +} + +list.boxed-list-separate { + background: none; + color: $card_fg_color; + + > row { + @extend %card; + + border: none; + margin-bottom: 12px; + + &:last-child { + margin-bottom: 0; + } + + @include focus-ring($offset: -1px, $transition: $row_transition); + + .osd &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + &:not(.expander) { + &:not(:selected).activatable { + &:hover { + background-color: $card_bg_color; + background-image: image(gtkalpha(currentColor, .03)); + } + + &:active { + background-color: $card_bg_color; + background-image: image(gtkalpha(currentColor, .08)); + } + + &.has-open-popup { + background-color: $card_bg_color; + background-image: image(gtkalpha(currentColor, .03)); + } + } + } + + &.entry, &.spin { + &:not(:selected).activatable.focused:hover, + &:not(:selected).activatable.focused:active { + background-color: $card_bg_color; + background-image: none; + } + + @each $e_type, $e_color in (error, $error_color), + (warning, $warning_color), + (success, $success_color) { + &.#{$e_type} { + color: $e_color; + } + } + } + + &.expander { + row.header { + @extend %boxed_list_row; + border-top-left-radius: $card_radius; + border-top-right-radius: $card_radius; + } + + &:not(:checked) row.header, + &.expander:checked list.nested, + &.expander:checked list.nested > row:last-child { + border-bottom-left-radius: $card_radius; + border-bottom-right-radius: $card_radius; + border-bottom: none; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_menus.scss b/gtk/theme/libadwaita/widgets/_menus.scss new file mode 100644 index 0000000000..4080f61ad4 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_menus.scss @@ -0,0 +1,275 @@ +popover.menu { + > contents { + min-width: 120px; + } + + scrollbar.vertical > range > trough > slider { + min-height: 30px; + } + + box.inline-buttons { + padding: 0 $menu_padding; + + button.image-button.model { + @extend %button_basic_flat; + + min-height: 32px; + min-width: 32px; + padding: 0; + border: none; + outline: none; + transition: none; + + &:selected { + background-color: $selected_color; + + &:active { + background-color: $selected_active_color; + } + } + } + } + + box.circular-buttons { + padding: $menu_padding $menu_padding 6px; + + button.circular.image-button.model { + @extend %button_basic_flat; + + outline: none; + padding: 11px; + + box-shadow: inset 0 0 0 1px $border_color; + + &:selected { + background-color: $selected_hover_color; + + @if $contrast != 'high' { + box-shadow: none; + } + + &:active { + background-color: $selected_active_color; + } + } + } + } + + > contents { + padding: 0; + + &, > scrolledwindow > viewport { + > stack > box { + padding: $menu_margin; + } + } + } + + separator { + margin: 6px 0; + } + + list separator { + margin: 0; + } + + accelerator { + color: gtkalpha(currentColor, $dim_label_opacity); + + &:dir(ltr) { margin-left: $menu_padding; } + &:dir(rtl) { margin-right: $menu_padding; } + } + + check, + radio { + min-width: 14px; + min-height: 14px; + -gtk-icon-size: 14px; + padding: 2px; + + &, + &:hover:checked, + &:hover:indeterminate, + &:hover:not(:checked):not(:indeterminate), + &:active:checked, + &:active:indeterminate, + &:active:not(:checked):not(:indeterminate), { + background: none; + box-shadow: none; + color: inherit; + } + } + + .osd & { + check, radio { + background: none; + color: inherit; + } + } + + //only menu radios have a border + radio { + padding: 1px; + border: 1px solid gtkalpha(currentColor, $dimmer_opacity); + } + + check, + radio, + arrow { + &.left { + margin-left: -2px; + margin-right: 6px; + } + + &.right { + margin-left: 6px; + margin-right: -2px; + } + } + + modelbutton { + min-height: 32px; + min-width: 40px; + padding: 0 $menu_padding; + border-radius: $menu_radius; + + @extend %undecorated_button; + + &:hover, + &:selected { + background-color: $selected_color; + } + + &:active { + background-color: $selected_active_color; // matching buttons + } + + @if $contrast == 'high' { + &:hover, + &:selected, + &:active { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + arrow { + background: none; + min-width: 16px; + min-height: 16px; + opacity: $dimmer_opacity; + + &:hover { background: none; } + + &:disabled { + filter: opacity($disabled_opacity); + } + + &.left { -gtk-icon-source: -gtk-icontheme("go-previous-symbolic"); } + + &.right { -gtk-icon-source: -gtk-icontheme("go-next-symbolic"); } + } + } + + label.title { + font-weight: bold; + padding: 4px ($menu_padding + 20px); //this will fall apart with font sizing + } + + list, listview { + background: none; + color: inherit; + + > row { + border-radius: $menu_radius; + padding: 0 $menu_padding; + min-height: 32px; + min-width: 40px; + + &:selected { + background: none; + } + + &:hover { + &, &:selected.activatable { + background-color: $selected_color; + } + } + + &:active { + &, &:selected.activatable { + background-color: $selected_active_color; + } + } + + &.has-open-popup { + &, &:selected.activatable { + background-color: $selected_color; + } + } + + @if $contrast == 'high' { + &:hover, + &:active, + &.has-open-popup { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + > box { + border-spacing: 6px; + } + } + } + + // Standalone lists should have same margins as menu sections, + // but we don't want that on lists inside sections themselves + contents > list, + contents > listview, + scrolledwindow > viewport > list, + scrolledwindow > listview { + padding: $menu_margin 0; //only vertical padding. horizontal row size would clip + + > row { + margin: 0 $menu_margin; + + padding: 9px $menu_padding; + min-height: 0; + } + } +} + +menubar { + box-shadow: inset 0 -1px $border_color; + padding-bottom: 1px; + + > item { + min-height: 16px; + padding: 4px 8px; + border-radius: $button_radius; + + &:selected { //Seems like it :hover even with keyboard focus + background-color: $selected_color; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + //nested submenus + popover.menu popover.menu { + padding: 0 0 4px 0; + } + + popover.menu popover.menu > contents { + margin: 0; + border-radius: $popover_radius; //including top + } + } +} + +%menubar-inline { + box-shadow: none; + padding-bottom: 0; +} + +%menubar-shrunk {} diff --git a/gtk/theme/libadwaita/widgets/_message-dialog.scss b/gtk/theme/libadwaita/widgets/_message-dialog.scss new file mode 100644 index 0000000000..eed5af6fab --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_message-dialog.scss @@ -0,0 +1,170 @@ +/******************** + * GtkMessageDialog * + ********************/ + +window.dialog.message { + .titlebar { + min-height: 20px; + background: none; + box-shadow: none; + border-style: none; + border-top-left-radius: 7px; + border-top-right-radius: 7px; + } + + box.dialog-vbox.vertical { + margin-top: 6px; + border-spacing: 24px; + + > box > box > box > label.title { + font-weight: 800; + font-size: 15pt; + } + } + + &.csd { + // bigger radius for better antialiasing + border-bottom-left-radius: $window_radius+1; + border-bottom-right-radius: $window_radius+1; + + .dialog-action-area { + border-top: 1px solid $border_color; + margin: 0; + border-spacing: 0; + + > button { + @extend %button_basic_flat; + padding: 10px 14px; // labels are not vertically centered on message dialog, this is a workaround + border-radius: 0; + border: none; + background-clip: padding-box; + border-left: 1px solid $border_color; + + &:first-child { + border-bottom-left-radius: $window_radius+1; + border-left: none; + } + + &:last-child { + border-bottom-right-radius: $window_radius+1; + } + + &.suggested-action { + color: $accent_color; + } + + &.destructive-action { + color: $destructive_color; + } + } + } + } +} + +/******************** + * AdwMessageDialog * + ********************/ + +window.messagedialog, +dialog-host > dialog.alert sheet, +window.dialog-window.alert { + background-color: $dialog_bg_color; + color: $dialog_fg_color; +} + +window.messagedialog { + @if $contrast != 'high' { + outline: none; + } +} + +dialog-host > dialog.alert.floating sheet, +window.dialog-window.alert { + border-radius: $window_radius+1; + outline: none; +} + +window.messagedialog, +dialog.alert { + .message-area { + padding: 24px 30px; + border-spacing: 24px; + + &.has-heading.has-body { + border-spacing: 10px; + } + } + + .response-area > button { + padding: 10px 14px; + border-radius: 0; + + @if $contrast == 'high' { + &:hover, + &.keyboard-activating, + &:active, + &:checked { + box-shadow: none; + } + } + + &.suggested { + color: $accent_color; + } + + &.destructive { + color: $destructive_color; + } + } + + .response-area { + &:not(.compact) > button { + margin-top: -1px; + margin-right: -1px; + margin-left: -1px; + + &:first-child:dir(ltr), + &:last-child:dir(rtl) { + margin-left: 0; + } + + &:last-child:dir(ltr), + &:first-child:dir(rtl) { + margin-right: 0; + } + } + + &.compact > button { + margin-top: -1px; + margin-bottom: -1px; + + &:first-child { + margin-bottom: 0; + } + } + } +} + +window.messagedialog, +dialog.alert.floating { + .response-area { + &:not(.compact) > button { + &:first-child:dir(ltr), + &:last-child:dir(rtl) { + border-bottom-left-radius: $window_radius+1; + } + + &:last-child:dir(ltr), + &:first-child:dir(rtl) { + border-bottom-right-radius: $window_radius+1; + } + } + + &.compact > button { + &:first-child { + border-bottom-left-radius: $window_radius+1; + border-bottom-right-radius: $window_radius+1; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_misc.scss b/gtk/theme/libadwaita/widgets/_misc.scss new file mode 100644 index 0000000000..140a8abd1d --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_misc.scss @@ -0,0 +1,228 @@ +/********** + * Frames * + **********/ +frame, +.frame { + border: 1px solid $border_color; +} + +frame { + border-radius: $card_radius; + + > label { + margin: 4px; + } +} + +/************** + * Separators * + **************/ + +separator { + background: $border_color; + min-width: 1px; + min-height: 1px; + + &.spacer { + background: none; + + &.horizontal { min-width: 12px; } + &.vertical { min-height: 12px; } + } +} + +/********************* + * App Notifications * + *********************/ + +.app-notification { + @extend %osd; + + padding: 10px; + border-spacing: 10px; + border-radius: 0 0 $card_radius $card_radius; + background-color: $osd_bg_color; + background-image: linear-gradient(to bottom, transparentize(black, 0.8), + transparent 2px); + background-clip: padding-box; + + border { border: none; } +} + +/********** + * Toasts * + **********/ + +toast { + @extend %osd; + + margin: 12px; + margin-bottom: 24px; + + border-radius: 150px; + border-spacing: 6px; + padding: 6px; + + &:dir(ltr) { padding-left: 12px; } + &:dir(rtl) { padding-right: 12px; } + + > widget { + margin: 0 6px; + } + + @if $contrast == 'high' { + box-shadow: 0 0 0 1px $border_color; + } +} + +/************** + * GtkVideo * + **************/ + +video { + & image.osd { + min-width: 64px; + min-height: 64px; + border-radius: 32px; + } +} + +/****************** + * AdwAboutWindow * + ******************/ + +window.about, +dialog.about { + .main-page { + > viewport > clamp > box { + margin: 12px; + border-spacing: 6px; + + > box { + margin-top: 18px; + border-spacing: 18px; + margin-bottom: 6px; + } + } + + .app-version { + padding: 3px 18px; + color: $accent_color; + border-radius: 999px; + margin-top: 3px; + } + } + + .subpage { + > viewport > clamp > box { + margin: 18px 12px; + border-spacing: 18px; + } + + > clamp > textview { + background: none; + color: inherit; + } + } +} + +/***************** + * AdwStatusPage * + *****************/ + +statuspage { + > scrolledwindow > viewport > box { + margin: 36px 12px; + border-spacing: 36px; + + > clamp > box { + border-spacing: 12px; + + > .icon { + -gtk-icon-size: 128px; + + color: gtkalpha(currentColor, $dim_label_opacity); + + &:disabled { + opacity: $disabled_opacity; + } + + &:not(:last-child) { + margin-bottom: 24px; + } + } + } + } + + &.compact > scrolledwindow > viewport > box { + margin: 24px 12px; + border-spacing: 24px; + + > clamp > box { + > .icon { + -gtk-icon-size: 96px; + + &:not(:last-child) { + margin-bottom: 12px; + } + } + + > .title { + font-size: 18pt; + } + } + } +} + +/* Cards */ + +.card { + @at-root %card, & { + background-color: $card_bg_color; + color: $card_fg_color; + border-radius: $card_radius; + box-shadow: 0 0 0 1px if($contrast == 'high', $border_color, transparentize(black, 0.97)), + 0 1px 3px 1px transparentize(black, .93), + 0 2px 6px 2px transparentize(black, .97); + + .osd &, &.osd { + background-color: gtkalpha(currentColor, .1); + color: inherit; + + @if $contrast == 'high' { + box-shadow: 0 0 0 1px $border_color; + } @else { + box-shadow: none; + } + } + } + + @include focus-ring($offset: -1px); + + .osd &, &.osd { + &:focus:focus-visible { + outline-color: $osd_focus_color; + } + } + + &.activatable { + transition: $focus_transition, $button_transition; + + &:hover { + background-image: image(gtkalpha(currentColor, .03)); + } + + &:active { + background-image: image(gtkalpha(currentColor, .08)); + } + } +} + +/* Transition shadows */ + +flap, +leaflet, +navigation-view, +overlay-split-view { + @include transition-shadows($shade_color); +} diff --git a/gtk/theme/libadwaita/widgets/_notebook.scss b/gtk/theme/libadwaita/widgets/_notebook.scss new file mode 100644 index 0000000000..3bade4722b --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_notebook.scss @@ -0,0 +1,216 @@ +notebook { + @include focus-ring("> header > tabs > tab:checked", $offset: -2px, $focus-state: ':focus:focus-visible'); + + > header { + padding: 1px; + border-color: $border_color; + border-width: 1px; + background-clip: padding-box; + + > tabs { margin: -1px; } + + &.top { + border-bottom-style: solid; + > tabs { + margin-bottom: -2px; + > tab { + &:hover { box-shadow: inset 0 -4px $border_color; } + + &:checked { box-shadow: inset 0 -4px $accent_bg_color; } + } + } + } + + &.bottom { + border-top-style: solid; + > tabs { + margin-top: -2px; + > tab { + &:hover { box-shadow: inset 0 4px $border_color; } + + &:checked { box-shadow: inset 0 4px $accent_bg_color; } + } + } + } + + &.left { + border-right-style: solid; + > tabs { + margin-right: -2px; + > tab { + &:hover { box-shadow: inset -4px 0 $border_color; } + + &:checked { box-shadow: inset -4px 0 $accent_bg_color; } + } + } + } + + &.right { + border-left-style: solid; + > tabs { + margin-left: -2px; + > tab { + &:hover { box-shadow: inset 4px 0 $border_color; } + + &:checked { box-shadow: inset 4px 0 $accent_bg_color; } + } + } + } + + &.top > tabs > arrow { + @extend %notebook_vert_arrows; + + border-top-style: none; + } + + &.bottom > tabs > arrow { + @extend %notebook_vert_arrows; + + border-bottom-style: none; + } + + @at-root %notebook_vert_arrows { + margin-left: -5px; + margin-right: -5px; + padding-left: 4px; + padding-right: 4px; + + &.down { -gtk-icon-source: -gtk-icontheme('pan-start-symbolic'); } + + &.up { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic'); } + } + + &.left > tabs > arrow { + @extend %notebook_horz_arrows; + + border-left-style: none; + } + + &.right > tabs > arrow { + @extend %notebook_horz_arrows; + + border-right-style: none; + } + + @at-root %notebook_horz_arrows { + margin-top: -5px; + margin-bottom: -5px; + padding-top: 4px; + padding-bottom: 4px; + + &.down { -gtk-icon-source: -gtk-icontheme('pan-up-symbolic'); } + + &.up { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); } + } + + > tabs > arrow { + @extend %button_basic; + @extend %button_basic_flat; + + min-height: 16px; + min-width: 16px; + border-radius: 0; + + &:hover:not(:active) { + box-shadow: none; + } + } + + > tabs > tab { + transition: $focus_transition; + min-height: 30px; + min-width: 30px; + padding: 3px 12px; + + font-weight: normal; + + &:hover, &:active { + background-color: $hover_color; + } + + &:not(:checked) { + outline-color: transparent; + } + + &:disabled { + filter: opacity($disabled_opacity); + + label, button { + filter: none; + } + } + + // colors the button like the label, overridden otherwise + button.flat { + color: gtkalpha(currentColor, 0.3); + &:hover, &:active { color: currentColor; } + + padding: 0; + margin-top: 4px; + margin-bottom: 4px; + // FIXME: generalize .small-button? + min-width: 20px; + min-height: 20px; + + &:last-child { + margin-left: 4px; + margin-right: -4px; + } + + &:first-child { + margin-left: -4px; + margin-right: 4px; + } + } + } + + &.top, + &.bottom { + > tabs { + padding-left: 4px; + padding-right: 4px; + + &:not(:only-child) { + margin-left: 3px; + margin-right: 3px; + + &:first-child { margin-left: -1px; } + &:last-child { margin-right: -1px; } + } + + > tab { + margin-left: 4px; + margin-right: 4px; + } + } + } + + &.left, + &.right { + > tabs { + padding-top: 4px; + padding-bottom: 4px; + + &:not(:only-child) { + margin-top: 3px; + margin-bottom: 3px; + + &:first-child { margin-top: -1px; } + &:last-child { margin-bottom: -1px; } + } + + > tab { + margin-top: 4px; + margin-bottom: 4px; + } + } + } + + &.top > tabs > tab { padding-bottom: 4px; } + &.bottom > tabs > tab { padding-top: 4px; } + } + + > stack:not(:only-child) { // the :not(:only-child) is for "hidden" notebooks + background-color: $view_bg_color; + } +} diff --git a/gtk/theme/libadwaita/widgets/_paned.scss b/gtk/theme/libadwaita/widgets/_paned.scss new file mode 100644 index 0000000000..baf320af5c --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_paned.scss @@ -0,0 +1,46 @@ +paned { + > separator { + min-width: 1px; + min-height: 1px; + background: none; + background-size: 1px 1px; + + &.wide { + min-width: 5px; + min-height: 5px; + } + } + + &.horizontal > separator { + &:dir(ltr) { + margin: 0 -8px 0 0; + padding: 0 8px 0 0; + box-shadow: inset 1px 0 $border_color; + } + &:dir(rtl) { + margin: 0 0 0 -8px; + padding: 0 0 0 8px; + box-shadow: inset -1px 0 $border_color; + } + + &.wide { + margin: 0; + padding: 0; + box-shadow: inset 1px 0 $border_color, + inset -1px 0 $border_color; + } + } + + &.vertical > separator { + margin: 0 0 -8px 0; + padding: 0 0 8px 0; + box-shadow: inset 0 1px $border_color; + + &.wide { + margin: 0; + padding: 0; + box-shadow: inset 0 1px $border_color, + inset 0 -1px $border_color; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_popovers.scss b/gtk/theme/libadwaita/widgets/_popovers.scss new file mode 100644 index 0000000000..03586c363a --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_popovers.scss @@ -0,0 +1,83 @@ +toolbarview.undershoot-top popover scrolledwindow undershoot.top, +toolbarview.undershoot-bottom popover scrolledwindow undershoot.bottom { + background: none; + box-shadow: none; +} + +popover { + &.background { + background-color: transparent; + font: initial; + } + + > arrow, + > contents { + background-color: $popover_bg_color; + color: $popover_fg_color; + background-clip: padding-box; + border: 1px solid if($contrast == 'high', $border_color, transparentize(black, .86)); + box-shadow: 0 1px 5px 1px transparentize(black, .91), + 0 2px 14px 3px transparentize(black, .95); + } + + > contents { + padding: 8px; + border-radius: $popover_radius; + + > list, + > .view, + > toolbar { + border-style: none; + background-color: transparent; + } + } + + .osd &, + &.touch-selection, + &.magnifier { + background-color: transparent; + + > arrow, + > contents { + @extend %osd; + + border: 1px solid transparentize(white, 0.9); + box-shadow: none; + } + } + + toolbarview.undershoot-top scrolledwindow { + @include undershoot(top, $popover_shade_color); + } + + toolbarview.undershoot-bottom scrolledwindow { + @include undershoot(bottom, $popover_shade_color); + } + + scrolledwindow { + &.undershoot-top { + @include undershoot(top, $popover_shade_color); + } + + &.undershoot-bottom { + @include undershoot(bottom, $popover_shade_color) + } + + &.undershoot-start { + &:dir(ltr) { @include undershoot(left, $popover_shade_color); } + &:dir(rtl) { @include undershoot(right, $popover_shade_color); } + } + + &.undershoot-end { + &:dir(ltr) { @include undershoot(right, $popover_shade_color); } + &:dir(rtl) { @include undershoot(left, $popover_shade_color); } + } + } + + flap, + leaflet, + navigation-view, + overlay-split-view { + @include transition-shadows($popover_shade_color); + } +} diff --git a/gtk/theme/libadwaita/widgets/_preferences.scss b/gtk/theme/libadwaita/widgets/_preferences.scss new file mode 100644 index 0000000000..7996d584b8 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_preferences.scss @@ -0,0 +1,18 @@ +preferencespage > scrolledwindow > viewport > clamp > box { + margin: 24px 12px; + border-spacing: 24px; +} + +preferencesgroup > box { + &, .labels { + border-spacing: 6px; + } + + > box.header:not(.single-line) { + margin-bottom: 6px; + } + + > box.single-line { + min-height: 34px; + } +} diff --git a/gtk/theme/libadwaita/widgets/_progress-bar.scss b/gtk/theme/libadwaita/widgets/_progress-bar.scss new file mode 100644 index 0000000000..8386f9522f --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_progress-bar.scss @@ -0,0 +1,93 @@ +progressbar { + // sizing + &.horizontal { + > trough { + min-width: 150px; + &, > progress { min-height: 8px; } + } + } + + &.vertical { + > trough { + min-height: 80px; + &, > progress { min-width: 8px; } + } + } + + > text { + @extend .dim-label; + @extend .numeric; + font-size: smaller; + } + + &:disabled { + filter: opacity($disabled_opacity); + } + + > trough { + @extend %scale_trough; + + > progress { + @extend %scale_highlight; /* share most of scales' */ + + $_progress-radius: 99px; + + border-radius: $_progress-radius; + + &.left { + border-top-left-radius: $_progress-radius; + border-bottom-left-radius: $_progress-radius; + } + + &.right { + border-top-right-radius: $_progress-radius; + border-bottom-right-radius: $_progress-radius; + } + + &.top { + border-top-right-radius: $_progress-radius; + border-top-left-radius: $_progress-radius; + } + + &.bottom { + border-bottom-right-radius: $_progress-radius; + border-bottom-left-radius: $_progress-radius; + } + } + } + + &.osd { + // Thin progress bar with no trough, usually goes under the header bar + min-width: 2px; + min-height: 2px; + background-color: transparent; + color: inherit; + + > trough { + border-style: none; + border-radius: 0; + background-color: transparent; + box-shadow: none; + + > progress { + border-style: none; + border-radius: 0; + } + + } + + &.horizontal { + > trough, > trough > progress { min-height: 2px; } + } + + &.vertical { + > trough, > trough > progress { min-width: 2px; } + } + } + + > trough.empty > progress { all: unset; } // makes the progress indicator disappear, when the fraction is 0 + + .osd & > trough > progress { + background-color: $osd_fill_bg_color; + } +} diff --git a/gtk/theme/libadwaita/widgets/_scale.scss b/gtk/theme/libadwaita/widgets/_scale.scss new file mode 100644 index 0000000000..bb3155e6d6 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_scale.scss @@ -0,0 +1,232 @@ +$_slider_border_color: transparentize(black, if($contrast == 'high', .65, .9)); + +%scale_trough { + border-radius: 99px; + background-color: $trough_color; + + @if $contrast == "high" { + box-shadow: inset 0 0 0 1px $border_color; + } +} + +%scale_highlight { + border-radius: 99px; + background-color: $fill_color; + color: $fill_text_color; +} + +scale { + // sizing + $_marks_length: 6px; + $_marks_distance: 6px; + + min-height: 10px; + min-width: 10px; + padding: 12px; + + @include focus-ring("> trough > slider", $offset: 0); + + > trough { + @extend %scale_trough; + + // the colored part of the backing bit + > highlight { @extend %scale_highlight; } + + // this is another differently styled part of the backing bit, the most relevant use case is for example + // in media player to indicate how much video stream as been cached + > fill { + @extend %scale_trough; + } + + > slider { + background-color: $slider_color; + box-shadow: 0 0 0 1px $_slider_border_color, 0 2px 4px transparentize(black, .8); + + border-radius: 100%; + + // the slider is inside the trough, so to have make it bigger there's a negative margin + min-width: 20px; + min-height: 20px; + margin: -8px; + } + } + + &:hover, &:active { + > trough { + background-color: $trough_hover_color; + + > highlight { + background-image: image(gtkalpha(currentColor, .1)); + } + + > slider { + background-color: $slider_hover_color; + } + } + } + + .osd & { + &:focus:focus-visible > trough { + outline-color: $osd_focus_color; + } + + > trough > highlight { + background-color: $osd_fill_bg_color; + color: $osd_fill_fg_color; + } + } + + &:disabled { + filter: opacity($disabled_opacity); + + > trough > slider { + box-shadow: 0 0 0 1px $_slider_border_color, 0 2px 4px transparent; + outline-color: transparentize(black, if($contrast == 'high', .5, .8)); + } + } + + // click-and-hold the slider to activate + &.fine-tune { + padding: 9px; + + &.horizontal { + min-height: 16px; + } + + &.vertical { + min-width: 16px; + } + + > trough { + // to make the trough grow in fine-tune mode + > slider { margin: -5px; } + } + } + + > value { + @extend .dim-label; + @extend .numeric; + } + + &.marks-before:not(.marks-after), + &.marks-after:not(.marks-before) { + > trough > slider { + transform: rotate(45deg); + + // Adjust box-shadow for the 45deg rotation, for 0px 2px we ideally want + // 1/√2px 1/√2px, round that to 1px 1px + box-shadow: 0 0 0 1px $_slider_border_color, 1px 1px 4px transparentize(black, .8); + + &:disabled { + box-shadow: 0 0 0 1px $_slider_border_color, 1px 1px 4px transparent; + } + } + } + + &.horizontal { + > marks { + color: gtkalpha(currentColor, $dim_label_opacity); + &.top { margin-bottom: $_marks_distance; } + &.bottom { margin-top: $_marks_distance; } + + indicator { + background-color: currentColor; + min-height: $_marks_length; + min-width: 1px; + } + } + + > value.left { margin-right: 9px; } + > value.right { margin-left: 9px; } + + &.fine-tune > marks { + &.top { margin-top: 3px; } + &.bottom { margin-bottom: 3px; } + + indicator { min-height: ($_marks_length - 3px); } + } + + &.marks-before { + padding-top: 0; + + > trough > slider { + border-top-left-radius: 0; + } + } + + &.marks-after { + padding-bottom: 0; + + > trough > slider { + border-bottom-right-radius: 0; + } + } + + &.marks-before.marks-after > trough > slider { + border-radius: 100%; + } + } + + &.vertical { + > marks { + color: gtkalpha(currentColor, $dim_label_opacity); + &.top { margin-right: $_marks_distance; } + &.bottom { margin-left: $_marks_distance; } + + indicator { + background-color: currentColor; + min-height: 1px; + min-width: $_marks_length; + } + } + + > value.top { margin-bottom: 9px; } + > value.bottom { margin-top: 9px; } + + &.fine-tune > marks { + &.top { margin-left: 3px; } + &.bottom { margin-right: 3px; } + + indicator { min-height: ($_marks_length - 3px); } + } + + &.marks-before { + padding-left: 0; + + > trough > slider { + border-bottom-left-radius: 0; + } + } + + &.marks-after { + padding-right: 0; + + > trough > slider { + border-top-right-radius: 0; + } + } + } + + &.color { + padding: 0; + + > trough { + border: none; + background: none; + border-radius: 10px; + + > slider { + margin: 0; + background-color: transparentize(white, .2); + } + } + + &.fine-tune { + padding: 2px; + + > trough > slider { + margin: -2px; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_scrolling.scss b/gtk/theme/libadwaita/widgets/_scrolling.scss new file mode 100644 index 0000000000..cb78c88f6e --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_scrolling.scss @@ -0,0 +1,184 @@ +$osd_scrollbar_outline_color: transparentize(black, .5); + +scrollbar { + $_slider_min_length: 40px; + $_slider_width: 8px; + $_scrollbar_transition: all 200ms linear; + + > range > trough { + margin: 7px; + transition: $_scrollbar_transition; + border-radius: 10px; + + > slider { + min-width: $_slider_width; + min-height: $_slider_width; + margin: -6px; + border: 6px solid transparent; + border-radius: 10px; + background-clip: padding-box; + transition: $_scrollbar_transition; + + @if $contrast == 'high' { + background-color: gtkalpha(currentColor, .4); + + &:hover { background-color: gtkalpha(currentColor, .6); } + + &:active { background-color: currentColor; } + } @else { + background-color: gtkalpha(currentColor, .2); + + &:hover { background-color: gtkalpha(currentColor, .4); } + + &:active { background-color: gtkalpha(currentColor, .6); } + } + + &:disabled { opacity: 0; } + } + } + + &.horizontal > range > trough { + margin-top: 6px; + margin-bottom: 6px; + } + + &.vertical > range > trough { + margin-left: 6px; + margin-right: 6px; + } + + &.overlay-indicator { + background: none; + color: inherit; + box-shadow: none; + padding: 0; + + > range > trough { + outline: 1px solid transparent; + + > slider { + @if $contrast == 'high' { + outline: 1px solid $scrollbar_outline_color; + } @else { + outline: 1px solid gtkalpha($scrollbar_outline_color, .6); + } + + .osd & { + @if $contrast == 'high' { + outline: 1px solid $osd_scrollbar_outline_color; + } @else { + outline: 1px solid gtkalpha($osd_scrollbar_outline_color, .6); + } + } + + outline-offset: -6px; + } + } + + &:not(.hovering) > range > trough > slider { + min-width: 3px; + min-height: 3px; + + @if $contrast == 'high' { + outline-color: gtkalpha($scrollbar_outline_color, .6); + } @else { + outline-color: gtkalpha($scrollbar_outline_color, .35); + } + + .osd & { + @if $contrast == 'high' { + outline-color: gtkalpha($osd_scrollbar_outline_color, .6); + } @else { + outline-color: gtkalpha($osd_scrollbar_outline_color, .35); + } + } + } + + &.hovering > range > trough { + @if $contrast == 'high' { + background-color: gtkalpha(currentColor, .25); + } @else { + background-color: gtkalpha(currentColor, .1); + } + } + + &.horizontal { + > range > trough > slider { + min-width: $_slider_min_length; + } + + &.hovering > range > trough > slider { + min-height: $_slider_width; + } + + &:not(.hovering) > range > trough { + margin-top: 3px; + margin-bottom: 3px; + } + } + + &.vertical { + > range > trough > slider { + min-height: $_slider_min_length; + } + + &.hovering > range > trough > slider { + min-width: $_slider_width; + } + + &:not(.hovering) > range > trough { + margin-left: 3px; + margin-right: 3px; + } + } + } + + &.horizontal > range > trough > slider { min-width: $_slider_min_length; } + &.vertical > range > trough > slider { min-height: $_slider_min_length; } + + > range.fine-tune > trough > slider { + &, &:hover, &:active { + background-color: if($contrast == 'high', $accent_color, gtkalpha($accent_color, .6)); + } + } +} + +scrolledwindow { + // This is used when content is touch-dragged past boundaries. + // draws a box on top of the content, the size changes programmatically. + > overshoot { + &.top { + @include overshoot(top); + } + + &.bottom { + @include overshoot(bottom); + } + + &.left { + @include overshoot(left); + } + + &.right { + @include overshoot(right); + } + } + + &.undershoot-top { + @include undershoot(top); + } + + &.undershoot-bottom { + @include undershoot(bottom); + } + + &.undershoot-start { + &:dir(ltr) { @include undershoot(left); } + &:dir(rtl) { @include undershoot(right); } + } + + &.undershoot-end { + &:dir(ltr) { @include undershoot(right); } + &:dir(rtl) { @include undershoot(left); } + } +} diff --git a/gtk/theme/libadwaita/widgets/_shortcuts-window.scss b/gtk/theme/libadwaita/widgets/_shortcuts-window.scss new file mode 100644 index 0000000000..04f3b04f71 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_shortcuts-window.scss @@ -0,0 +1,55 @@ +shortcuts-section { + margin: 20px; +} + +.shortcuts-search-results { + margin: 20px; + border-spacing: 24px; +} + +// shortcut window keys +shortcut { + border-spacing: 6px; + border-radius: 6px; + @include focus-ring($outer: true, $offset: 4px); + + > .keycap { + min-width: 20px; + min-height: 25px; + padding: 2px 6px; + + @extend %card; + + border-radius: $button_radius; + font-size: smaller; + } +} + +shortcuts-section stackswitcher.circular { + border-spacing: 12px; + + > button.circular, + > button.text-button.circular { + min-width: 32px; + min-height: 32px; + padding: 0; + } +} + +window.shortcuts { + headerbar.titlebar { + @extend .flat; + @extend %headerbar-shrunk; + + > windowhandle { + padding-top: 3px; + } + } + + searchbar { + @extend %searchbar-flat; + @extend %searchbar-shrunk; + + background: none; + } +} diff --git a/gtk/theme/libadwaita/widgets/_sidebars.scss b/gtk/theme/libadwaita/widgets/_sidebars.scss new file mode 100644 index 0000000000..af024d28a8 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_sidebars.scss @@ -0,0 +1,215 @@ +.sidebar-pane { + background-color: $sidebar_bg_color; + color: $sidebar_fg_color; + + &:backdrop { + background-color: $sidebar_backdrop_color; + transition: background-color $backdrop_transition; + } + + toolbarview.undershoot-top scrolledwindow { + @include undershoot(top, $sidebar_shade_color); + } + + toolbarview.undershoot-bottom scrolledwindow { + @include undershoot(bottom, $sidebar_shade_color); + } + + scrolledwindow { + &.undershoot-top { + @include undershoot(top, $sidebar_shade_color); + } + + &.undershoot-bottom { + @include undershoot(bottom, $sidebar_shade_color) + } + + &.undershoot-start { + &:dir(ltr) { @include undershoot(left, $sidebar_shade_color); } + &:dir(rtl) { @include undershoot(right, $sidebar_shade_color); } + } + + &.undershoot-end { + &:dir(ltr) { @include undershoot(right, $sidebar_shade_color); } + &:dir(rtl) { @include undershoot(left, $sidebar_shade_color); } + } + } + + flap, + leaflet, + navigation-view, + overlay-split-view { + @include transition-shadows($sidebar_shade_color); + } + + banner > revealer > widget { + background-color: gtkmix($accent_bg_color, $sidebar_bg_color, 30%); + color: $sidebar_fg_color; + + &:backdrop { + background-color: gtkmix($accent_bg_color, $sidebar_backdrop_color, 15%); + } + } + + &:dir(ltr), &.end:dir(rtl) { + &, banner > revealer > widget { + box-shadow: inset -1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + } + + &:dir(rtl), &.end:dir(ltr) { + &, banner > revealer > widget { + box-shadow: inset 1px 0 if($contrast == 'high', $border_color, $sidebar_border_color); + } + } +} + +/* Middle pane in three-pane setups */ +.content-pane .sidebar-pane, +.sidebar-pane .content-pane { + background-color: $secondary_sidebar_bg_color; + color: $secondary_sidebar_fg_color; + + &:backdrop { + background-color: $secondary_sidebar_backdrop_color; + transition: background-color $backdrop_transition; + } + + toolbarview.undershoot-top scrolledwindow { + @include undershoot(top, $secondary_sidebar_shade_color); + } + + toolbarview.undershoot-bottom scrolledwindow { + @include undershoot(bottom, $secondary_sidebar_shade_color); + } + + scrolledwindow { + &.undershoot-top { + @include undershoot(top, $secondary_sidebar_shade_color); + } + + &.undershoot-bottom { + @include undershoot(bottom, $secondary_sidebar_shade_color) + } + + &.undershoot-start { + &:dir(ltr) { @include undershoot(left, $secondary_sidebar_shade_color); } + &:dir(rtl) { @include undershoot(right, $secondary_sidebar_shade_color); } + } + + &.undershoot-end { + &:dir(ltr) { @include undershoot(right, $secondary_sidebar_shade_color); } + &:dir(rtl) { @include undershoot(left, $secondary_sidebar_shade_color); } + } + } + + flap, + leaflet, + navigation-view, + overlay-split-view { + @include transition-shadows($secondary_sidebar_shade_color); + } + + banner > revealer > widget { + background-color: gtkmix($accent_bg_color, $secondary_sidebar_bg_color, 30%); + color: $secondary_sidebar_fg_color; + + &:backdrop { + background-color: gtkmix($accent_bg_color, $secondary_sidebar_backdrop_color, 15%); + } + } + + &:dir(ltr), &.end:dir(rtl) { + &, banner > revealer > widget { + box-shadow: inset -1px 0 if($contrast == 'high', $border_color, $secondary_sidebar_border_color); + } + } + + &:dir(rtl), &.end:dir(ltr) { + &, banner > revealer > widget { + box-shadow: inset 1px 0 if($contrast == 'high', $border_color, $secondary_sidebar_border_color); + } + } +} + +.sidebar-pane .sidebar-pane { + background-color: transparent; + color: inherit; +} + +stacksidebar row { + padding: 10px 4px; + + > label { + padding-left: 6px; + padding-right: 6px; + } + + &.needs-attention > label { + @extend %needs_attention; + background-size: 6px 6px, 0 0; + } +} + +/********************** + * Navigation Sidebar * + **********************/ + +.navigation-sidebar { + &, &.view, &.view:disabled { + background-color: transparent; + color: inherit; + } + + &.background { + &, &:disabled { + background-color: $window_bg_color; + color: $window_fg_color; + } + } + + row { + &.activatable { + &:hover { background-color: $hover_color; } + + &:active { background-color: $active_color; } + + // this is for indicathing which row generated a popover see https://bugzilla.gnome.org/show_bug.cgi?id=754411 + &.has-open-popup { background-color: $hover_color; } + + &:selected { + &:hover { background-color: $selected_hover_color; } + + &:active { background-color: $selected_active_color; } + + &.has-open-popup { background-color: $selected_hover_color; } + } + } + + &:selected { + background-color: $selected_color; + } + } + + padding: $menu-margin 0; //only vertical padding. horizontal row size would clip + + > separator { + margin: $menu-margin; + } + + > row { + min-height: 36px; + padding: 0 8px; + border-radius: $menu_radius; + margin: 0 $menu_margin 2px; + + @if $contrast == 'high' { + &.activatable:hover, + &.activatable:active, + &.activatable.has-open-popup, + &:selected { + box-shadow: inset 0 0 0 1px $border_color; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_spin-button.scss b/gtk/theme/libadwaita/widgets/_spin-button.scss new file mode 100644 index 0000000000..4f806add96 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_spin-button.scss @@ -0,0 +1,72 @@ +spinbutton { + @extend %entry; + @extend .numeric; + + padding: 0; + border-spacing: 0; + + /* :not here just to bump specificity above that of the list button styling */ + > button.image-button.up:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque), + > button.image-button.down:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + @extend %button_basic_flat; + + margin: 0; + + border-radius: 0; + box-shadow: none; + + border-style: solid; + border-color: gtkalpha(currentColor, if($contrast == 'high', .5, .1)); + } + + &:not(.vertical) { + > text { + min-width: 28px; + padding: 6px; + } + + /* :not here just to bump specificity above that of the list button styling */ + > button.image-button.up:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque), + > button.image-button.down:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + min-height: 16px; + min-width: 22px; + padding-bottom: 0; + padding-top: 0; + border-left-width: 1px; + + &:dir(rtl) { + border-left-width: 0; + border-right-width: 1px; + } + + &:dir(ltr):last-child { + border-radius: 0 $button_radius $button_radius 0; + } + + &:dir(rtl):first-child { + border-radius: $button_radius 0 0 $button_radius; + } + } + } + + &.vertical { + > text { + min-height: 30px; + min-width: 30px; + } + + /* :not here just to bump specificity above that of the list button styling */ + > button.image-button.up:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque), + > button.image-button.down:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &:last-child { + border-top-width: 1px; + border-radius: 0 0 $button_radius $button_radius; + } + + &:first-child { + border-bottom-width: 1px; + border-radius: $button_radius $button_radius 0 0; + } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_spinner.scss b/gtk/theme/libadwaita/widgets/_spinner.scss new file mode 100644 index 0000000000..ab1f020271 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_spinner.scss @@ -0,0 +1,16 @@ +@keyframes spin { + to { transform: rotate(1turn); } +} + +spinner { + background: none; + opacity: 0; // non spinning spinner makes no sense + -gtk-icon-source: -gtk-icontheme('process-working-symbolic'); + + &:checked { + opacity: 1; + animation: spin 1s linear infinite; + + &:disabled { opacity: $disabled_opacity; } + } +} diff --git a/gtk/theme/libadwaita/widgets/_switch.scss b/gtk/theme/libadwaita/widgets/_switch.scss new file mode 100644 index 0000000000..1cbb8835fd --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_switch.scss @@ -0,0 +1,60 @@ +switch { + // similar to GtkScale + border-radius: 14px; + padding: 3px; + + background-color: $trough_color; + + &:hover { background-color: $trough_hover_color; } + &:active { background-color: $trough_active_color; } + + @include focus-ring($offset: 1px, $outer: true); + + &:disabled { + filter: opacity($disabled_opacity); + } + + > slider { + min-width: 20px; + min-height: 20px; + border-radius: 50%; + background-color: $slider_color; + box-shadow: 0 2px 4px transparentize(black, .8); + + &:disabled { + box-shadow: 0 2px 4px transparent; + } + } + + &:hover > slider, + &:active > slider { + background: $slider_hover_color; + } + + &:checked { + color: $fill_text_color; + background-color: $fill_color; + + &:hover { background-image: image(gtkalpha(currentColor, .1)); } + &:active { background-image: image(transparentize(black, .8)); } + + > slider { + background-color: $slider_hover_color; + } + + @if $contrast == "high" { + > image { color: inherit; } + } + } + + .osd & { + &:focus:focus-visible { + outline-color: $osd_focus_color; + } + + &:checked { + background-color: transparentize($osd_fill_bg_color, .15); + color: $osd_fill_fg_color; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_tab-view.scss b/gtk/theme/libadwaita/widgets/_tab-view.scss new file mode 100644 index 0000000000..8b69f08466 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_tab-view.scss @@ -0,0 +1,268 @@ +tabbar { + .box { + background-color: $headerbar_bg_color; + color: $headerbar_fg_color; + box-shadow: inset 0 -1px if($contrast == 'high', $headerbar_border_color, $headerbar_shade_color); + padding: 1px; + padding-top: 0; + + &:backdrop { + background-color: $headerbar_backdrop_color; + transition: background-color $backdrop_transition; + + > scrolledwindow, + > .start-action, + > .end-action { + filter: opacity(0.5); + transition: filter $backdrop_transition; + } + } + } + + tabbox { + padding-bottom: 6px; + padding-top: 6px; + min-height: 34px; + + > tabboxchild { + @include focus-ring($focus-state: ':focus-within:focus-visible'); + border-radius: $button_radius; + } + + > separator { + margin-top: 3px; + margin-bottom: 3px; + transition: opacity 150ms ease-in-out; + + &.hidden { + opacity: 0; + } + } + + > revealer > indicator { + min-width: 2px; + border-radius: 2px; + margin: 3px 6px; + background: if($contrast == 'high', $accent_color, gtkalpha($accent_color, 0.5)); + } + } + + tab { + transition: background 150ms ease-in-out; + + @if $contrast == 'high' { + &:hover, + &:active, + &:selected { + box-shadow: inset 0 0 0 1px $border_color; + } + } + + &:selected { + background-color: $selected_color; + + &:hover { background-color: $selected_hover_color; } + &:active { background-color: $selected_active_color; } + } + + &:hover { background-color: $hover_color; } + &:active { background-color: $active_color; } + } + + tabbox.single-tab tab { + &, &:hover, &:active { + background: none; + + @if $contrast == 'high' { + box-shadow: none; + } + } + } + + .start-action, + .end-action { + padding: 6px 5px; + } + + .start-action:dir(ltr), + .end-action:dir(rtl) { + padding-right: 0; + } + + .start-action:dir(rtl), + .end-action:dir(ltr) { + padding-left: 0; + } + + &.inline { + @extend %tabbar-inline; + } +} + +%tabbar-inline .box { + background-color: transparent; + color: inherit; + box-shadow: none; + padding-bottom: 0; + + &:backdrop { + background-color: transparent; + transition: none; + + > scrolledwindow, + > .start-action, + > .end-action { + filter: none; + transition: none; + } + } +} + +%tabbar-shrunk { + tabbox, + .start-action, + .end-action { + padding-top: 3px; + padding-bottom: 3px; + } +} + +dnd tab { + background-color: $headerbar_bg_color; + background-image: image($selected_active_color); + color: $headerbar_fg_color; + + box-shadow: 0 0 0 1px transparentize(black, 0.97), + 0 1px 3px 1px transparentize(black, .93), + 0 2px 6px 2px transparentize(black, .97); + + @if $contrast == 'high' { + outline: 1px solid $border_color; + outline-offset: -1px; + } + + margin: 25px; +} + +tabbar, +dnd { + tab { + min-height: 26px; + padding: 4px; + border-radius: $button_radius; + + button.image-button { + padding: 0; + margin: 0; + min-width: 24px; + min-height: 24px; + border-radius: 99px; + } + + indicator { + min-height: 2px; + border-radius: 2px; + background: if($contrast == 'high', $accent_color, gtkalpha($accent_color, 0.5)); + transform: translateY(4px); + } + } +} + +tabgrid > tabgridchild { + @include focus-ring(".card", $offset: 0, $outer: true); +} + +tabthumbnail { + border-radius: $card_radius + 4px; + + > box { + margin: 6px; + } + + &:drop(active) { + box-shadow: inset 0 0 0 2px gtkalpha($drop_target_color, .4); + background-color: gtkalpha($drop_target_color, .1); + } + + transition: box-shadow 200ms $ease-out-quad, background-color $ease-out-quad; + + .needs-attention { + &:dir(ltr) { transform: translate(8px, -8px); } + &:dir(rtl) { transform: translate(-8px, -8px); } + + > widget { + background: $accent_color; + min-width: 12px; + min-height: 12px; + border-radius: 8px; + margin: 3px; + box-shadow: 0 1px 2px gtkalpha($accent_color, .4); + } + } + + .card { + picture { + outline: 1px solid $window_outline_color; + outline-offset: -1px; + border-radius: $card_radius; + } + + background: none; + color: inherit; + + @if $contrast == 'high' { + box-shadow: 0 0 0 1px transparentize(black, 0.5), + 0 1px 3px 1px transparentize(black, .93), + 0 2px 6px 2px transparentize(black, .97); + } + } + + &.pinned .card { + background-color: $thumbnail_bg_color; + color: $thumbnail_fg_color; + + @if $contrast == 'high' { + outline: 1px solid $window_outline_color; + outline-offset: -1px; + } + } + + .icon-title-box { + border-spacing: 6px; + } + + .tab-unpin-icon { + margin: 6px; + min-width: 24px; + min-height: 24px; + } + + button.circular { + margin: 6px; + background-color: gtkalpha($thumbnail_bg_color, .75); + min-width: 24px; + min-height: 24px; + + @if $contrast == 'high' { + box-shadow: 0 0 0 1px currentColor; + } + + &:hover { + background-color: gtkalpha(gtkmix($thumbnail_bg_color, currentColor, 90%), .75); + } + + &:active { + background-color: gtkalpha(gtkmix($thumbnail_bg_color, currentColor, 80%), .75); + } + } +} + +taboverview > .overview .new-tab-button { + margin: 18px; +} + +tabview:drop(active), +tabbox:drop(active), +tabgrid:drop(active) { + box-shadow: none; +} diff --git a/gtk/theme/libadwaita/widgets/_text-selection.scss b/gtk/theme/libadwaita/widgets/_text-selection.scss new file mode 100644 index 0000000000..2d596f5ba7 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_text-selection.scss @@ -0,0 +1,30 @@ +cursor-handle { + all: unset; + padding: 24px 20px; + + > contents { + min-width: 20px; + min-height: 20px; + border-radius: 50%; + + background-color: $accent_bg_color; + } + + &.top > contents { + border-top-right-radius: 0; + } + + &.bottom > contents { + border-top-left-radius: 0; + transform: translateX(1px); + } + + &.insertion-cursor > contents { + border-top-left-radius: 0; + transform: translateX(1px) translateY(4px) rotate(45deg); + } +} + +magnifier { + background-color: $view_bg_color; +} diff --git a/gtk/theme/libadwaita/widgets/_toolbars.scss b/gtk/theme/libadwaita/widgets/_toolbars.scss new file mode 100644 index 0000000000..62b3d67fbf --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_toolbars.scss @@ -0,0 +1,310 @@ +%toolbar { + button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.arrow-button, + &.image-button, + &.image-text-button { + @extend %button_basic_flat; + } + } + + &.osd button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &:focus:focus-visible { + outline-color: $osd_focus_color; + } + } + + menubutton:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.image-button > button { + @extend %button_basic_flat; + } + } + + .linked button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.arrow-button, + &.image-button, + &.image-text-button { + @extend %button_basic_raised; + } + } + + menubutton.raised > button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.arrow-button, + &.image-button, + &.image-text-button { + @extend %button_basic_raised; + } + } + + menubutton.suggested-action, + menubutton.destructive-action, + menubutton.opaque { + > button:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + @extend %opaque_button; + + color: inherit; + background-color: transparent; + } + } + + splitbutton:not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + @extend %flat_split_button; + } + + switch { + margin-top: 4px; + margin-bottom: 4px; + } + + // Reset styles for popovers + popover { + button:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.arrow-button, + &.image-button, + &.image-text-button { + @extend %button_basic_raised; + } + } + + menubutton:not(.flat):not(.raised):not(.suggested-action):not(.destructive-action):not(.opaque) { + &.image-button > button { + @extend %button_basic_raised; + } + } + } +} + +.toolbar { + padding: 6px; + border-spacing: 6px; + + @extend %toolbar; + + // stand-alone OSD toolbars + &.osd { + padding: 12px; + border-radius: $card_radius; + } +} + +%toolbar-shrunk { + padding-top: 3px; + padding-bottom: 3px; +} + +/**************** + * GtkSearchBar * + ****************/ + +searchbar { + > revealer > box { + padding: 6px 6px 7px 6px; + + background-color: $headerbar_bg_color; + color: $headerbar_fg_color; + box-shadow: inset 0 -1px if($contrast == 'high', $headerbar_border_color, $headerbar_shade_color); + + &:backdrop { + background-color: $headerbar_backdrop_color; + transition: background-color $backdrop_transition; + + > * { + filter: opacity(.5); + transition: filter $backdrop_transition; + } + } + + @extend %toolbar; + + .close { + min-width: 18px; + min-height: 18px; + padding: 4px; + border-radius: 50%; + @extend %button_basic_flat; + + &:dir(ltr) { + margin-left: 10px; + margin-right: 4px; + } + + &:dir(rtl) { + margin-left: 4px; + margin-right: 10px; + } + } + } + + &.inline { + @extend %searchbar-inline; + } +} + +%searchbar-flat > revealer > box { + background-color: transparent; + color: inherit; + box-shadow: none; + padding-bottom: 6px; +} + +%searchbar-inline { + @extend %searchbar-flat; + + > revealer > box:backdrop { + background-color: transparent; + transition: none; + + > * { + filter: none; + transition: none; + } + } +} + +%searchbar-shrunk > revealer > box { + padding-top: 3px; + padding-bottom: 3px; +} + +/**************** + * GtkActionBar * + ****************/ + +actionbar > revealer > box { + background-color: $headerbar_bg_color; + color: $headerbar_fg_color; + box-shadow: inset 0 1px if($contrast == 'high', $headerbar_border_color, $headerbar_shade_color); + padding: 7px 6px 6px 6px; + + @extend %toolbar; + + &, > box.start, > box.end { + border-spacing: 6px; + } + + &:backdrop { + background-color: $headerbar_backdrop_color; + transition: background-color $backdrop_transition; + + > * { + filter: opacity(.5); + transition: filter $backdrop_transition; + } + } +} + +%actionbar-inline > revealer > box { + background-color: transparent; + color: inherit; + box-shadow: none; + padding-top: 6px; + + &:backdrop { + background-color: transparent; + transition: none; + + > * { + filter: none; + transition: none; + } + } +} + +%actionbar-shrunk > revealer > box { + padding-top: 3px; + padding-bottom: 3px; +} + +/************* + * AdwBanner * + *************/ +banner > revealer > widget { + /* There are 2 more instances in _sidebars.css, keep in sync with that */ + background-color: gtkmix($accent_bg_color, $window_bg_color, 30%); + color: $window_fg_color; + padding: 6px; + + &:backdrop { + background-color: gtkmix($accent_bg_color, $window_bg_color, 15%); + transition: background-color $backdrop_transition; + + > label, > button { + filter: opacity(.5); + transition: filter $backdrop_transition; + } + } +} + +/****************** + * AdwToolbarView * + ******************/ +toolbarview { + > .top-bar, + > .bottom-bar { + headerbar { @extend %headerbar-inline; } + searchbar { @extend %searchbar-inline; } + actionbar { @extend %actionbar-inline; } + menubar { @extend %menubar-inline; } + tabbar { @extend %tabbar-inline; } + + .collapse-spacing { + padding-top: 3px; + padding-bottom: 3px; + + headerbar { @extend %headerbar-shrunk; } + searchbar { @extend %searchbar-shrunk; } + actionbar { @extend %actionbar-shrunk; } + menubar { @extend %menubar-shrunk; } + .toolbar { @extend %toolbar-shrunk; } + tabbar { @extend %tabbar-shrunk; } + + viewswitcherbar { @extend %viewswitcherbar-shrunk; } + } + + &.raised { + background-color: $headerbar_bg_color; + color: $headerbar_fg_color; + + &:backdrop { + background-color: $headerbar_backdrop_color; + transition: background-color $backdrop_transition; + } + } + + &:backdrop > windowhandle { + filter: opacity(.5); + transition: filter $backdrop_transition; + } + } + + > .top-bar.raised { + box-shadow: 0 1px if($contrast == 'high', $border_color, gtkalpha($headerbar_shade_color, .5)), + 0 2px 4px gtkalpha($headerbar_shade_color, .5); + + &.border { + box-shadow: 0 1px if($contrast == 'high', $border_color, $headerbar_darker_shade_color); + } + } + + > .bottom-bar.raised { + box-shadow: 0 -1px if($contrast == 'high', $border_color, gtkalpha($headerbar_shade_color, .5)), + 0 -2px 4px gtkalpha($headerbar_shade_color, .5); + + &.border { + box-shadow: 0 -1px if($contrast == 'high', $border_color, $headerbar_darker_shade_color); + } + } + + &.undershoot-top scrolledwindow { @include undershoot(top); } + &.undershoot-bottom scrolledwindow { @include undershoot(bottom); } + + window.devel & > .top-bar { + background-image: cross-fade(5% -gtk-recolor(url("assets/devel-symbolic.svg")), + image(transparent)); + background-repeat: repeat-x; + } + + window.devel dialog & > .top-bar { + background-image: unset; + background-repeat: unset; + } +} diff --git a/gtk/theme/libadwaita/widgets/_tooltip.scss b/gtk/theme/libadwaita/widgets/_tooltip.scss new file mode 100644 index 0000000000..d9e6c92eac --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_tooltip.scss @@ -0,0 +1,20 @@ +tooltip { + &.background { + // background-color needs to be set this way otherwise it gets drawn twice + // see https://bugzilla.gnome.org/show_bug.cgi?id=736155 for details. + background-color: transparentize(black, 0.2); + background-clip: padding-box; + border: 1px solid $tooltip_border_color; // this subtle border is meant to + // not make the tooltip melt with + // very dark backgrounds + color: white; + } + + padding: 6px 10px; + border-radius: 9px; + box-shadow: none; // otherwise it gets inherited by windowframe.csd + + > box { + border-spacing: 6px; + } +} diff --git a/gtk/theme/libadwaita/widgets/_view-switcher.scss b/gtk/theme/libadwaita/widgets/_view-switcher.scss new file mode 100644 index 0000000000..afc708fd55 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_view-switcher.scss @@ -0,0 +1,123 @@ +viewswitcher { + border-spacing: 3px; + + &.narrow { + margin-top: -3px; + margin-bottom: -3px; + min-height: 6px; + } + + button.toggle { + padding: 0; + + > stack > box { + &.narrow { + font-size: 0.75rem; + padding-top: 4px; + + > label { + min-height: 18px; + padding-left: 3px; + padding-right: 3px; + padding-bottom: 2px; + } + } + + &.wide { + padding: 2px 12px; + border-spacing: 6px; + } + } + } +} + +/********************** + * AdwViewSwitcherBar * + **********************/ + +viewswitcherbar actionbar > revealer > box { + padding-left: 0; + padding-right: 0; + padding-top: 7px; +} + +%viewswitcherbar-shrunk actionbar > revealer > box { + // Not 0px because view switcher has negative margin + padding-top: 6px; +} + +/************************ + * AdwViewSwitcherTitle * + ************************/ + +viewswitchertitle { + margin-top: -6px; + margin-bottom: -6px; + + viewswitcher { + margin-left: 12px; + margin-right: 12px; + + &.narrow { + margin-top: 3px; + margin-bottom: 3px; + } + + &.wide { + margin-top: 6px; + margin-bottom: 6px; + } + } + + windowtitle { + margin-top: 0; + margin-bottom: 0; + } +} + +/******************* + * AdwIndicatorBin * + *******************/ + +indicatorbin { + > indicator, > mask { + min-width: 6px; + min-height: 6px; + border-radius: 100px; + } + + > indicator { + margin: 1px; + background: gtkalpha(currentColor, .4); + } + + > mask { + padding: 1px; + background: black; + } + + &.needs-attention > indicator { + background: $accent_color; + } + + &.badge { + > indicator, + > mask { + min-height: 13px; + } + + > indicator > label { + font-size: 0.6rem; + font-weight: bold; + padding-left: 4px; + padding-right: 4px; + color: white; + } + + &.needs-attention > indicator { + background: $accent_bg_color; + + > label { color: $accent_fg_color; } + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_views.scss b/gtk/theme/libadwaita/widgets/_views.scss new file mode 100644 index 0000000000..f39ae5bf9d --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_views.scss @@ -0,0 +1,75 @@ +.view, +%view { + color: $view_fg_color; + background-color: $view_bg_color; + + &:disabled { + color: gtkalpha(currentColor, .5); + background-color: gtkmix($window_bg_color, $view_bg_color, 60%); + } + + &:selected { + &:focus, & { + background-color: $view_selected_color; + + border-radius: $button_radius; + } + } +} + +textview { + caret-color: currentColor; + + > text { + @extend %view; + + background-color: transparent; + } + + > border { + background-color: gtkmix($window_bg_color, $view_bg_color, 50%); + } + + &:drop(active) { + caret-color: $drop_target_color; + } +} + +rubberband { + border: 1px solid $accent_color; + background-color: gtkalpha($accent_color, 0.2); +} + +flowbox > flowboxchild, +gridview > child { + padding: 3px; + border-radius: $button_radius; + + @include focus-ring(); + + &:selected { + background-color: $view_selected_color; + + @if $contrast == 'high' { + box-shadow: inset 0 0 0 1px $border_color; + } + } +} + +gridview > child.activatable { + &:hover { background-color: $view_hover_color; } + + &:active { background-color: $view_active_color; } + + &:selected { + &:hover { background-color: $view_selected_hover_color; } + + &:active { background-color: $view_selected_active_color; } + } + + @if $contrast == 'high' { + &:hover, &:active { + box-shadow: inset 0 0 0 1px $border_color; + } + } +} diff --git a/gtk/theme/libadwaita/widgets/_window.scss b/gtk/theme/libadwaita/widgets/_window.scss new file mode 100644 index 0000000000..5f18de2d43 --- /dev/null +++ b/gtk/theme/libadwaita/widgets/_window.scss @@ -0,0 +1,81 @@ +window { + &.csd { + box-shadow: 0 1px 3px 3px transparent, + 0 2px 8px 2px transparentize(black, 0.87), + 0 3px 20px 10px transparentize(black, 0.91), + 0 6px 32px 16px transparentize(black, 0.96), + 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .95)); + margin: 0px; + border-radius: $window_radius; + + outline: 1px solid $window_outline_color; + outline-offset: -1px; + + &:backdrop { + // the transparent shadow here is to enforce that the shadow extents don't + // change when we go to backdrop, to prevent jumping windows. + // The biggest shadow should be in the same order then in the active state + // or the jumping will happen during the transition. + box-shadow: 0 1px 3px 3px transparentize(black, 0.91), + 0 2px 14px 5px transparentize(black, 0.95), + 0 4px 28px 12px transparentize(black, 0.97), + 0 6px 32px 16px transparent, + 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .98)); + transition: box-shadow $backdrop_transition; + } + + &.dialog.message, + &.messagedialog { + box-shadow: 0 2px 8px 2px transparentize(black, 0.93), + 0 3px 20px 10px transparentize(black, 0.95), + 0 6px 32px 16px transparentize(black, 0.98), + 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .95)); + } + + &.tiled, + &.tiled-top, + &.tiled-left, + &.tiled-right, + &.tiled-bottom { + border-radius: 0; + outline: none; + + box-shadow: 0 0 0 1px $border_color, + 0 0 0 20px transparent; //transparent control workaround -- #3670 + + &:backdrop { + box-shadow: 0 0 0 1px $border_color, + 0 0 0 20px transparent; + } + } + + &.maximized, + &.fullscreen { + border-radius: 0; + outline: none; + box-shadow: none; + transition: none; + } + } + + &.solid-csd { + margin: 0; + padding: 5px; + border-radius: 0; + box-shadow: inset 0 0 0 5px $border_color, + inset 0 0 0 4px $headerbar_bg_color, + inset 0 0 0 1px $border_color; + + &:backdrop { + box-shadow: inset 0 0 0 5px $border_color, + inset 0 0 0 4px $headerbar_backdrop_color, + inset 0 0 0 1px $border_color; + } + } + + // server-side decorations as used by mutter + &.ssd { + // just doing borders, wm draws actual shadows + box-shadow: 0 0 0 1px transparentize(black, if($contrast == 'high', .2, .95)); + } +}