Skip to content

Draft: Improve Breeze GTK buttons to match Qt better

Tabby Kitten requested to merge nyanpasu/breeze-gtk:fix-buttons into master

Definitions

In GTK3 jargon, "backdrop" describes how a widget in an inactive window should be drawn. "focus" describes tab focus, "active" describes a button being pressed, and "checked" describes toggle buttons which are enabled (and checkboxes too).

Screenshots

If desired, I can share screenshots of various apps like gtk3-widget-factory, Gedit, pavucontrol, and other suggestions as well.

Changelog

  • Change button animation duration to match Breeze Qt (100ms)
  • Breeze Qt widget shadows, tweak Breeze GTK shadows

Shadow color was chosen empirically to approximately match the RGB values of Breeze shadows, which are computed using a complex procedure difficult to replicate in CSS.

The formula I use to compute shadow colors fails if the user picks a near-black window background. In this case, Breeze-GTK's button shadows will be black and not gray like in Breeze Qt. Unfortunately I don't know how to easily fix this mismatching (by adding a CSS conditional branch based on the luma of the color scheme picked by the user at runtime). However this isn't a major concern, since none of the color schemes shipping with KDE have window backgrounds dark enough to trigger gray shadows (not even Breeze Dark).

Breeze buttons at 4x DPI

Breeze Qt draws the shadow as a rounded rectangle with the same top-left corner as the widget, a bottom-right corner larger by 1 pixel, and a larger corner radius. This causes the top-right and bottom-left corners of the shadow to "encompass" the corners of the widget. Someone (forgot who, can't look it up) on Matrix commented that "encompassing" was intentional. (There are also some rendering artifacts not worth reproducing, like the gap between the shadow and widget's corners, and the notch in the bottom-right of the shadow.)

In any case, Breeze-GTK's shadow was a drop shadow with a 1px blur radius. I changed the shadow to a 0px blur radius because it looked closer to Breeze Qt to my eyes. I chose to not copy the "encompassing" corners because I don't like them, and the difference isn't very visible at 1x DPI.

  • Rename button(normal) to button(base)
  • Rename button() values

Is renaming button() values (either normal->base or active->focus) appreciated or not? The old names including active didn't match the actual function they serve in Breeze GTK, so I thought it was worth changing them.

I removed the button() comment because I found it useless, but I don't know if others will agree. The line containing $c and $tc is dead code originating from Adwaita but later commented out, and the comments describing $c, $tc, and $edge describe parameters that no longer exist. And the "possible $t values" wasn't useful in my opinion.

  • Fix button border colors, add background gradients

The biggest improvement in this pull request. Fixes buttons to almost exactly resemble Breeze Qt.

I didn't fix toggle buttons (visible in pavucontrol and gtk3-widget-factory). They still suck.

QPushButton has a checkable mode (prominently featured in pavucontrol-qt's mute/etc. buttons) where buttons turn dark gray when checked. If the button is focused via the Tab key, clicking or pressing Space to toggle the button has no visual difference aside from moving 1 pixel down+right. In breeze-gtk, the situation is worse because merely clicking the button focuses it (which doesn't happen in breeze-qt), and breeze-gtk3 currently can't move the button down+right when checked (aside from hacks involving margin, which tend to have layout issues in corner cases)

Breeze's flat buttons add another layer of jank and inconsistency. The good thing is that flat (but not bordered) checkable buttons can have their checked/unchecked status visually identified (through background color), even when focused (which changes border color). The bad thing is that flat checked buttons are blue, but bordered checked buttons are gray, causing them to look mismatched next to each other.

In fact, fixing Breeze GTK's flat/bordered toggle buttons to look like Breeze Qt would cause problems in apps! The original GTK pavucontrol puts flat and bordered checkable buttons right next to each other (eg. mute buttons), and they would look mismatched if flat buttons turned blue and bordered buttons turned gray. I suspect that's the reason why pavucontrol-qt (built for LXQt, but looks good in Breeze) makes all the checkable buttons (mute/etc.) bordered.

  • Redesign colored button appearance

I decided to fix colored buttons since they are very visible (every time you close Gedit with unsaved changes) and looked ugly before (blue borders on red buttons). Unfortunately, I could not use Breeze's styling system (button starts out gray, changes color when focused or focus-hovered) directly for buttons that must maintain their color. Instead, they have a strong background gradient of the same intensity as Breeze's focused buttons. When hovered, they lighten, and when pressed, they darken. When focused, the border darkens and a white focus ring appears within the button. This is inspired primarily by Adwaita's buttons, and fits acceptably well next to Breeze buttons.

Backdrop colored buttons are black on red, which looks ugly. This has the same underlying cause as https://bugs.kde.org/show_bug.cgi?id=438185. Should I hard-code backdrop colored buttons to either white or "foreground button text color", instead of keeping the current "background button text color" which is white in Breeze GTK but black in colors.css (which overrides Breeze GTK)?

  • [wip] Split selectors for :focus:hover and :active

I decided to make the CSS selectors more semantically correct, but stopped midway through. Hopefully this results in no behavioral regressions, and possibly improvements in some cases, but I haven't tested all edge cases thoroughly. Should I finish editing the rest of the file to match, or drop the effort?

  • When hovering buttons in backdrop windows, recolor border as backdrop
  • Don't override background of hovered backdrop windows (eg. headerbars)

This deviates from Breeze-GTK's original appearance, since it makes backdrop headerbar buttons not gain a gradient when hovered. Non-backdrop headerbar buttons don't gain a gradient when hovered (since it's ugly), and I thought that backdrop windows should also behave the same for consistency.

  • Darken unfocused button border colors to match Breeze Qt

"Regular" button borders were already present in breeze-gtk master, and grandfathered into "Fix button border colors, add background gradients", despite being the wrong color. This commit increases their contrast slightly to match Breeze Qt (where button borders are darker than separators).

Edited by Tabby Kitten

Merge request reports