From 2fa876e83999a2f4010f7a14ff23f0343b398adc Mon Sep 17 00:00:00 2001 From: nana-4 Date: Thu, 30 Apr 2020 23:15:04 +0900 Subject: [PATCH] Adwaita: Use a mixin for visible focus rings The focus-ring() mixin allows we to flexibly style the focus ring for each widget. By using this, we can get rid of the "Outlines" section, which is out of place in the _common.scss file. This commit also has the following changes: - Transition the focus rings on most widgets. - Add a missing focus ring to iconview. - Move the expander-widget focus ring to its title. - Move the notebook focus ring to its checked tab. Closes https://gitlab.gnome.org/GNOME/gtk/-/issues/2653 --- gtk/theme/Adwaita/_common.scss | 184 ++++++++++++++------------------ gtk/theme/Adwaita/_drawing.scss | 21 ++++ 2 files changed, 102 insertions(+), 103 deletions(-) diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss index 50b8f8a713..3612b011f9 100644 --- a/gtk/theme/Adwaita/_common.scss +++ b/gtk/theme/Adwaita/_common.scss @@ -6,6 +6,7 @@ $ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94); $asset_suffix: if($variant=='dark', '-dark', ''); $backdrop_transition: 200ms ease-out; $button_transition: all 200ms $ease-out-quad; +$focus_transition: outline-width 200ms $ease-out-quad, outline-offset 200ms $ease-out-quad; $button_radius: 5px; $menu_radius: 5px; $window_radius: $button_radius + 3; @@ -38,90 +39,6 @@ dnd { -gtk-icon-size: 32px; } -/********* - * Outlines * - ********/ - -expander-widget:focus:focus-visible, -:focus-visible link, -plane:focus-visible, -label:focus-visible:not(.link), -row:focus-visible, -flowboxchild:focus-visible { - // We use the outline properties to signal the focus properties - // to the adwaita engine: using real CSS properties is faster, - // and we don't use any outlines for now. - - outline-color: $focus_border_color; - outline-style: solid; - outline-offset: -1px; - outline-width: 2px; - :selected & { outline-color: $alt_focus_border_color; } -} - -// Widgets that draw their focus indicator outset and not inset -scale:focus-visible > trough { - outline-color: $focus_border_color; - outline-style: solid; - outline-offset: 10px; - outline-width: 2px; -} - -button:focus-visible, modelbutton:focus-visible { - outline-color: $focus_border_color; - outline-style: solid; - outline-offset: -2px; - outline-width: 2px; - - row:selected & { outline-color: $alt_focus_border_color; } - - &.suggested-action, &.destructive-action { &, &:hover, &:active { outline-color: $alt_focus_border_color; } } -} - -// Draw the "outline" around the whole switch not the slider -switch:focus-visible { - &, &:hover { slider { outline-color: transparent; } } - &:focus { - box-shadow: 0 0 0 3px if($variant=='light', lighten(opacify($focus_border_color, 1), 20%), $focus_border_color); - } - row:selected & { outline-color: $alt_focus_border_color; } -} - -checkbutton:focus-visible, -radiobutton:focus-visible { - outline-color: $focus_border_color; - outline-style: solid; - outline-offset: 2px; - outline-width: 2px; - border-radius: $button_radius; - row:selected & , treeview:selected & { outline-color: $alt_focus_border_color; } -} - -row:focus-visible { - outline-color: $focus_border_color; - outline-offset: -2px; - outline-style: solid; - &:selected { - outline-color: $alt_focus_border_color; - } -} - -treeview:focus-visible { - outline-color: $focus_border_color; - outline-style: solid; - outline-width: 2px; - &:selected { - outline-color: $alt_focus_border_color; - } -} - -notebook:focus:focus-visible { - outline-color: $focus_border_color; - outline-style: solid; - outline-offset: -1px; - outline-width: 2px; -} - /* These wildcard seems unavoidable, need to investigate. Wildcards are bad and troublesome, use them with care, @@ -161,12 +78,7 @@ treeview.expander:disabled { -gtk-icon-filter: opacity(0.5); } } } -.view { - outline: none; -} - textview { - outline: none; > text { @extend %view; @@ -180,9 +92,11 @@ textview { textview > border { background-color: mix($bg_color, $base_color, 50%); } -iconview { +iconview { @extend .view; + @include focus-ring(); + &:drop(active) { box-shadow: none; } @@ -204,8 +118,13 @@ flowbox { > flowboxchild { padding: 3px; + transition: $focus_transition; + + @include focus-ring(); &:selected { + outline-color: $alt_focus_border_color; + @extend %selected_items; } } @@ -223,6 +142,8 @@ flowbox { } label { + @include focus-ring(); + &.separator { @extend .dim-label; } @@ -581,6 +502,8 @@ button { @include button(normal); + @include focus-ring(); + @at-root %button_basic_flat, &.flat { @include button(undecorated); @@ -1080,6 +1003,10 @@ link { *:selected & { color: mix($selected_fg_color, $link_color, 80%); } } +link { + @include focus-ring(); +} + button.link { @extend %link; @@ -1698,11 +1625,14 @@ treeview.view { border-left-color: $_treeview_borders_color; // this is actually the tree lines color, border-top-color: $_treeview_borders_color; // while this is the grid lines color, better then nothing + @include focus-ring(); + > rubberband { @extend rubberband; } // to avoid borders being overridden by the previously set props &:selected { &:focus, & { border-radius: 0; + outline-color: $alt_focus_border_color; @extend %selected_items; } @@ -1962,6 +1892,8 @@ popover.background { * Notebooks * *************/ notebook { + @include focus-ring("> header > tabs > tab", $offset: -7px); + > header { padding: 1px; border-color: $borders_color; @@ -2098,6 +2030,7 @@ notebook { } > tabs > tab { + transition: $focus_transition; min-height: 30px; min-width: 30px; padding: 3px 12px; @@ -2126,6 +2059,10 @@ notebook { } } + &:not(:checked) { + outline-color: transparent; + } + &:checked { color: $fg_color; &.reorderable-page { @@ -2332,6 +2269,9 @@ switch { color: $fg_color; background-color: $dark_fill; text-shadow: 0 1px transparentize(black, 0.9); + transition: $focus_transition; + + @include focus-ring($offset: 0, $outer: true); &:checked { color: $selected_fg_color; @@ -2409,6 +2349,8 @@ switch { } row:selected & { + outline-color: $alt_focus_border_color; + @if $variant == 'light' { box-shadow: none; border-color: $checkradio_borders_color; @@ -2456,10 +2398,18 @@ switch { } } -checkbutton.text-button, radiobutton.text-button { - // this is for a nice focus on check and radios text - padding: 2px 0; +checkbutton, +radiobutton { border-spacing: 4px; + border-radius: $button_radius; + transition: $focus_transition; + + @include focus-ring(); + + &.text-button { + // this is for a nice focus on check and radios text + padding: 4px 2px; + } } check, @@ -2613,7 +2563,12 @@ treeview.view radio:selected { &:focus, & { @extend %radio; }} // This is a work } // ...on selected list rows - row:selected & { &:disabled, & { border-color: $selected_borders_color; }} + row:selected & { + &:disabled, & { + outline-color: $alt_focus_border_color; + border-color: $selected_borders_color; + } + } // OSD .osd & { @@ -2663,8 +2618,12 @@ scale { min-width: 10px; padding: 12px; + @include focus-ring("> trough", $offset: 10px); + // those are inside the trough node, I need them to show their own border over the trough one, so negative margin > trough { + transition: $focus_transition; + > fill, > highlight { margin: -1px; } @@ -3385,6 +3344,8 @@ list { row { transition: all 150ms $ease-out-quad; + @include focus-ring(); + &:hover { transition: none; } &:backdrop { transition: $backdrop_transition; } @@ -3408,7 +3369,11 @@ row { } } - &:selected { @extend %selected_items; } + &:selected { + outline-color: $alt_focus_border_color; + + @extend %selected_items; + } } @@ -3452,8 +3417,17 @@ expander { &:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); } } -expander-widget title:hover > expander { - color: lighten($fg_color,30%); //only lightens the icon +expander-widget { + @include focus-ring("> box > title"); + + > box > title { + transition: $focus_transition; + border-radius: $button_radius; + + &:hover > expander { + color: lighten($fg_color,30%); //only lightens the icon + } + } } placessidebar, @@ -3900,6 +3874,10 @@ colorswatch { // is colorswatch overlay {}, colorswatch has the programmatically set background, so most of the style is // applied to the overlay box. + transition: $focus_transition; + + @include focus-ring(); + &:drop(active), & { border-style: none; } // FIXME: implement a proper drop(active) state $_colorswatch_radius: 5px; @@ -3975,12 +3953,6 @@ colorswatch { } } - &:focus-visible { - outline-offset: -2px; - outline-width: 2px; - outline-style: solid; - } - &:drop(active) { box-shadow: none; @@ -4043,6 +4015,12 @@ colorswatch { } } +plane { + transition: $focus_transition; + + @include focus-ring($offset: 2px, $outer: true); +} + // colorscale popup colorchooser .popover.osd { border-radius: 5px; } diff --git a/gtk/theme/Adwaita/_drawing.scss b/gtk/theme/Adwaita/_drawing.scss index e6fd259074..7e67786f1a 100644 --- a/gtk/theme/Adwaita/_drawing.scss +++ b/gtk/theme/Adwaita/_drawing.scss @@ -2,6 +2,24 @@ // 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. +// +@mixin focus-ring($target: null, $width: 2px, $offset: -$width, $outer: false) { + & #{$target} { + outline: 0 solid $focus_border_color; + outline-offset: if($outer, $offset, $offset + $width); + } + + &:focus:focus-visible #{$target} { + outline-width: $width; + outline-offset: $offset; + } +} + @function _widget_edge($c:$borders_edge) { // outer highlight "used" on most widgets @if $c == none { @return none; } @@ -167,6 +185,7 @@ // normal button // color: $tc; + outline-color: if($c != $bg_color, $alt_focus_border_color, $focus_border_color); border-color: if($c != $bg_color, _border_color($c), $borders_color); border-bottom-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); $button_fill: if($variant == 'light', linear-gradient(to top, darken($c, 4%) 2px, $c), @@ -198,6 +217,7 @@ // normal button alternative look // color: $tc; + outline-color: if($c != $bg_color, $alt_focus_border_color, $focus_border_color); border-color: if($c != $bg_color, _border_color($c, true), $alt_borders_color); //colored buttons @if $variant == 'light' { background-image: linear-gradient(to bottom, lighten($c, 5%) 20%, $c 90%); @@ -348,6 +368,7 @@ $_bg: if($c != $bg_color, transparentize($c, 0.5), $osd_bg_color); color: $osd_fg_color; + outline-color: if($c != $bg_color, $alt_focus_border_color, $focus_border_color); border-color: $osd_borders_color; background-color: transparent; $button_fill: image($_bg) !global;