quickSettings: Split menu toggle

Menu toggles are currently regular toggles with an additional
arrow button. This allows for a simpler implementation, but
has downsides with regards to keyboard navigation and hover
feedback.

To make it more obvious that the two parts of the menu toggle
perform different actions, change the overall structure of the
toggle to *contain* a regular toggle and the menu button.

That way each element uses its own hover effect, and shows up
in the keynav focus chain.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5964

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2632>
This commit is contained in:
Florian Müllner 2022-08-23 01:29:10 +02:00 committed by Marge Bot
parent 3fba10efa6
commit cf89a6d01e
3 changed files with 71 additions and 10 deletions

View File

@ -12,13 +12,15 @@
spacing-columns: $base_padding*2; spacing-columns: $base_padding*2;
} }
.quick-toggle { .quick-toggle, .quick-menu-toggle {
border-radius: 99px; border-radius: 99px;
min-width: 12em; min-width: 12em;
max-width: 12em; max-width: 12em;
min-height: 48px; min-height: 48px;
border:none; border:none;
}
.quick-toggle {
&:checked { @include button(default, $c:$selected_bg_color); } &:checked { @include button(default, $c:$selected_bg_color); }
& > StBoxLayout { spacing: $base_padding*1.5; } & > StBoxLayout { spacing: $base_padding*1.5; }
@ -37,16 +39,26 @@
font-size: 12px; font-size: 12px;
} }
.quick-toggle-icon, .quick-toggle-arrow { icon-size: $base_icon_size; } .quick-toggle-icon { icon-size: $base_icon_size; }
} }
.quick-menu-toggle { .quick-menu-toggle {
&:ltr > StBoxLayout { padding-right: 0; } & .quick-toggle {
&:rtl > StBoxLayout { padding-left: 0; } min-width: auto;
max-width: auto;
&:ltr { border-radius: 99px 0 0 99px; }
&:rtl { border-radius: 0 99px 99px 0; }
&:ltr:last-child { border-radius: 99px; }
&:rtl:last-child { border-radius: 99px; }
}
& .quick-toggle-arrow { & .quick-toggle-arrow {
background-color: transparentize($fg_color, 0.9);
padding: $base_padding $base_padding*1.75; padding: $base_padding $base_padding*1.75;
border: none;
&:checked { @include button(default, $c:$selected_bg_color); }
&:ltr { border-radius: 0 99px 99px 0; } &:ltr { border-radius: 0 99px 99px 0; }
&:rtl { border-radius: 99px 0 0 99px; } &:rtl { border-radius: 99px 0 0 99px; }

View File

@ -10,6 +10,8 @@ const {PopupAnimation} = imports.ui.boxpointer;
const DIM_BRIGHTNESS = -0.4; const DIM_BRIGHTNESS = -0.4;
const POPUP_ANIMATION_TIME = 400; const POPUP_ANIMATION_TIME = 400;
const MENU_BUTTON_BRIGHTNESS = 0.1;
var QuickSettingsItem = GObject.registerClass({ var QuickSettingsItem = GObject.registerClass({
Properties: { Properties: {
'has-menu': GObject.ParamSpec.boolean( 'has-menu': GObject.ParamSpec.boolean(
@ -130,12 +132,22 @@ var QuickToggle = GObject.registerClass({
var QuickMenuToggle = GObject.registerClass({ var QuickMenuToggle = GObject.registerClass({
Properties: { Properties: {
'title': GObject.ParamSpec.string('title', '', '',
GObject.ParamFlags.READWRITE,
null),
'subtitle': GObject.ParamSpec.string('subtitle', '', '',
GObject.ParamFlags.READWRITE,
null),
'icon-name': GObject.ParamSpec.override('icon-name', St.Button),
'gicon': GObject.ParamSpec.object('gicon', '', '',
GObject.ParamFlags.READWRITE,
Gio.Icon),
'menu-enabled': GObject.ParamSpec.boolean( 'menu-enabled': GObject.ParamSpec.boolean(
'menu-enabled', '', '', 'menu-enabled', '', '',
GObject.ParamFlags.READWRITE, GObject.ParamFlags.READWRITE,
true), true),
}, },
}, class QuickMenuToggle extends QuickToggle { }, class QuickMenuToggle extends QuickSettingsItem {
_init(params) { _init(params) {
super._init({ super._init({
...params, ...params,
@ -144,23 +156,59 @@ var QuickMenuToggle = GObject.registerClass({
this.add_style_class_name('quick-menu-toggle'); this.add_style_class_name('quick-menu-toggle');
this._box = new St.BoxLayout();
this.set_child(this._box);
const contents = new QuickToggle({
x_expand: true,
});
this._box.add_child(contents);
// Use an effect to lighten the menu button a bit, so we don't
// have to define two full sets of button styles (normal/default)
// with slightly different colors
const menuHighlight = new Clutter.BrightnessContrastEffect();
menuHighlight.set_brightness(MENU_BUTTON_BRIGHTNESS);
this._menuButton = new St.Button({ this._menuButton = new St.Button({
child: new St.Icon({ style_class: 'quick-toggle-arrow icon-button',
style_class: 'quick-toggle-arrow', child: new St.Icon({icon_name: 'go-next-symbolic'}),
icon_name: 'go-next-symbolic', accessible_name: _('Open menu'),
}), effect: menuHighlight,
can_focus: true,
x_expand: false, x_expand: false,
y_expand: true, y_expand: true,
}); });
this._box.add_child(this._menuButton); this._box.add_child(this._menuButton);
this.bind_property('checked',
contents, 'checked',
GObject.BindingFlags.SYNC_CREATE);
this.bind_property('title',
contents, 'title',
GObject.BindingFlags.SYNC_CREATE);
this.bind_property('subtitle',
contents, 'subtitle',
GObject.BindingFlags.SYNC_CREATE);
this.bind_property('icon-name',
contents, 'icon-name',
GObject.BindingFlags.SYNC_CREATE);
this.bind_property('gicon',
contents, 'gicon',
GObject.BindingFlags.SYNC_CREATE);
this.bind_property('menu-enabled', this.bind_property('menu-enabled',
this._menuButton, 'visible', this._menuButton, 'visible',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
this.bind_property('reactive', this.bind_property('reactive',
this._menuButton, 'reactive', this._menuButton, 'reactive',
GObject.BindingFlags.SYNC_CREATE); GObject.BindingFlags.SYNC_CREATE);
this.bind_property('checked',
this._menuButton, 'checked',
GObject.BindingFlags.SYNC_CREATE);
this._menuButton.connect('clicked', () => this.menu.open()); this._menuButton.connect('clicked', () => this.menu.open());
this._menuButton.connect('popup-menu', () => this.emit('popup-menu'));
contents.connect('popup-menu', () => this.emit('popup-menu'));
this.connect('popup-menu', () => { this.connect('popup-menu', () => {
if (this.menuEnabled) if (this.menuEnabled)
this.menu.open(); this.menu.open();

View File

@ -48,6 +48,7 @@ js/ui/overview.js
js/ui/padOsd.js js/ui/padOsd.js
js/ui/panel.js js/ui/panel.js
js/ui/popupMenu.js js/ui/popupMenu.js
js/ui/quickSettings.js
js/ui/runDialog.js js/ui/runDialog.js
js/ui/screenShield.js js/ui/screenShield.js
js/ui/screenshot.js js/ui/screenshot.js