[gnome-shell] status/volume: Port to quick settings



commit 62c62eced03f835c709020e5121d2b34e7b26c20
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Jul 30 01:37:07 2022 +0200

    status/volume: Port to quick settings
    
    Thanks to the preparations and QuickSlider, this is again
    straight-forward.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2393>

 js/ui/panel.js         |   7 ++-
 js/ui/status/volume.js | 133 +++++++++++++++++--------------------------------
 2 files changed, 49 insertions(+), 91 deletions(-)
---
diff --git a/js/ui/panel.js b/js/ui/panel.js
index cc9fd4d8ba..e1f4f65a69 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -378,15 +378,11 @@ class AggregateMenu extends PanelMenu.Button {
         else
             this._network = null;
 
-        this._volume = new imports.ui.status.volume.Indicator();
         this._system = new imports.ui.status.system.Indicator();
 
         if (this._network)
             this._indicators.add_child(this._network);
-        this._indicators.add_child(this._volume);
 
-        this.menu.addMenuItem(this._volume.menu);
-        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
         if (this._network)
             this.menu.addMenuItem(this._network.menu);
 
@@ -414,6 +410,7 @@ class QuickSettings extends PanelMenu.Button {
         else
             this._bluetooth = null;
 
+        this._volume = new imports.ui.status.volume.Indicator();
         this._brightness = new imports.ui.status.brightness.Indicator();
         this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet();
         this._location = new imports.ui.status.location.Indicator();
@@ -437,9 +434,11 @@ class QuickSettings extends PanelMenu.Button {
             this._indicators.add_child(this._bluetooth);
         this._indicators.add_child(this._rfkill);
         this._indicators.add_child(this._autoRotate);
+        this._indicators.add_child(this._volume);
         this._indicators.add_child(this._unsafeMode);
         this._indicators.add_child(this._power);
 
+        this._addItems(this._volume.quickSettingsItems, N_QUICK_SETTINGS_COLUMNS);
         this._addItems(this._brightness.quickSettingsItems, N_QUICK_SETTINGS_COLUMNS);
 
         this._addItems(this._remoteAccess.quickSettingsItems);
diff --git a/js/ui/status/volume.js b/js/ui/status/volume.js
index 256240319d..71a91cb049 100644
--- a/js/ui/status/volume.js
+++ b/js/ui/status/volume.js
@@ -1,13 +1,12 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported Indicator */
 
-const { Clutter, Gio, GLib, GObject, Gvc, St } = imports.gi;
-const Signals = imports.misc.signals;
+const {Clutter, Gio, GLib, GObject, Gvc} = imports.gi;
 
 const Main = imports.ui.main;
-const PanelMenu = imports.ui.panelMenu;
 const PopupMenu = imports.ui.popupMenu;
-const Slider = imports.ui.slider;
+
+const {QuickSlider, SystemIndicator} = imports.ui.quickSettings;
 
 const ALLOW_AMPLIFIED_VOLUME_KEY = 'allow-volume-above-100-percent';
 
@@ -27,30 +26,19 @@ function getMixerControl() {
     return _mixerControl;
 }
 
-var StreamSlider = class extends Signals.EventEmitter {
-    constructor(control) {
-        super();
+const StreamSlider = GObject.registerClass({
+    Signals: {
+        'stream-updated': {},
+    },
+}, class StreamSlider extends QuickSlider {
+    _init(control) {
+        super._init();
 
         this._control = control;
 
-        this.item = new PopupMenu.PopupMenuSection();
-
-        const sliderItem = new PopupMenu.PopupBaseMenuItem({activate: false});
-        this.item.addMenuItem(sliderItem);
-
-        const submenuItem = new PopupMenu.PopupSubMenuMenuItem('');
-        this.item.addMenuItem(submenuItem);
-
-        // HACK: Hide the submenu item, its menu is controlled from sliderItem
-        submenuItem.hide();
-
-        this.menu = submenuItem.menu;
-
         this._inDrag = false;
         this._notifyVolumeChangeId = 0;
 
-        this._slider = new Slider.Slider(0);
-
         this._soundSettings = new Gio.Settings({
             schema_id: 'org.gnome.desktop.sound',
         });
@@ -58,48 +46,20 @@ var StreamSlider = class extends Signals.EventEmitter {
             () => this._amplifySettingsChanged());
         this._amplifySettingsChanged();
 
-        this._sliderChangedId = this._slider.connect('notify::value',
+        this._sliderChangedId = this.slider.connect('notify::value',
             () => this._sliderChanged());
-        this._slider.connect('drag-begin', () => (this._inDrag = true));
-        this._slider.connect('drag-end', () => {
+        this.slider.connect('drag-begin', () => (this._inDrag = true));
+        this.slider.connect('drag-end', () => {
             this._inDrag = false;
             this._notifyVolumeChange();
         });
 
-        this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
-        sliderItem.add(this._icon);
-        sliderItem.add_child(this._slider);
-        sliderItem.connect('button-press-event',
-            (actor, event) => this._slider.startDragging(event));
-        sliderItem.connect('key-press-event',
-            (actor, event) => this._slider.emit('key-press-event', event));
-        sliderItem.connect('scroll-event',
-            (actor, event) => this._slider.emit('scroll-event', event));
-
-        this._menuButton = new St.Button({
-            child: new St.Icon({
-                iconName: 'pan-end-symbolic',
-                style_class: 'popup-menu-arrow',
-            }),
-            y_expand: true,
-        });
-        sliderItem.add_child(this._menuButton);
-
-        this._menuButton.connect('clicked', () => this.menu.toggle());
-
-        // In order to keep sliders aligned, do not hide
-        // the menu button, but make it fully transparent
-        this._menuButton.bind_property_full('reactive',
-            this._menuButton, 'opacity',
-            GObject.BindingFlags.DEFAULT,
-            (bind, source) => [true, source ? 255 : 0],
-            null);
-
         this._deviceItems = new Map();
 
         this._deviceSection = new PopupMenu.PopupMenuSection();
         this.menu.addMenuItem(this._deviceSection);
 
+        this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
         this.menu.addSettingsAction(_('Sound Settings'),
             'gnome-sound-panel.desktop');
 
@@ -182,19 +142,15 @@ var StreamSlider = class extends Signals.EventEmitter {
     }
 
     _sync() {
-        this.item.actor.visible = this._shouldBeVisible();
-        this._menuButton.reactive = this._deviceItems.size > 1;
-    }
-
-    scroll(event) {
-        return this._slider.scroll(event);
+        this.visible = this._shouldBeVisible();
+        this.menuEnabled = this._deviceItems.size > 1;
     }
 
     _sliderChanged() {
         if (!this._stream)
             return;
 
-        let value = this._slider.value;
+        let value = this.slider.value;
         let volume = value * this._control.get_vol_max_norm();
         let prevMuted = this._stream.is_muted;
         let prevVolume = this._stream.volume;
@@ -236,9 +192,9 @@ var StreamSlider = class extends Signals.EventEmitter {
     }
 
     _changeSlider(value) {
-        this._slider.block_signal_handler(this._sliderChangedId);
-        this._slider.value = value;
-        this._slider.unblock_signal_handler(this._sliderChangedId);
+        this.slider.block_signal_handler(this._sliderChangedId);
+        this.slider.value = value;
+        this.slider.unblock_signal_handler(this._sliderChangedId);
     }
 
     _updateVolume() {
@@ -251,7 +207,7 @@ var StreamSlider = class extends Signals.EventEmitter {
     _amplifySettingsChanged() {
         this._allowAmplified = this._soundSettings.get_boolean(ALLOW_AMPLIFIED_VOLUME_KEY);
 
-        this._slider.maximum_value = this._allowAmplified
+        this.slider.maximum_value = this._allowAmplified
             ? this.getMaxLevel() : 1;
 
         if (this._stream)
@@ -287,13 +243,14 @@ var StreamSlider = class extends Signals.EventEmitter {
 
         return maxVolume / this._control.get_vol_max_norm();
     }
-};
+});
 
-var OutputStreamSlider = class extends StreamSlider {
-    constructor(control) {
-        super(control);
+const OutputStreamSlider = GObject.registerClass(
+class OutputStreamSlider extends StreamSlider {
+    _init(control) {
+        super._init(control);
 
-        this._slider.accessible_name = _('Volume');
+        this.slider.accessible_name = _('Volume');
 
         this._control.connectObject(
             'output-added', (c, id) => this._addDevice(id),
@@ -308,6 +265,8 @@ var OutputStreamSlider = class extends StreamSlider {
             'audio-volume-high-symbolic',
             'audio-volume-overamplified-symbolic',
         ];
+
+        this.menu.setHeader('audio-headphones-symbolic', _('Sound Output'));
     }
 
     _connectStream(stream) {
@@ -346,17 +305,18 @@ var OutputStreamSlider = class extends StreamSlider {
             return;
 
         this._hasHeadphones = hasHeadphones;
-        this._icon.icon_name = this._hasHeadphones
+        this.iconName = this._hasHeadphones
             ? 'audio-headphones-symbolic'
             : 'audio-speakers-symbolic';
     }
-};
+});
 
-var InputStreamSlider = class extends StreamSlider {
-    constructor(control) {
-        super(control);
+const InputStreamSlider = GObject.registerClass(
+class InputStreamSlider extends StreamSlider {
+    _init(control) {
+        super._init(control);
 
-        this._slider.accessible_name = _('Microphone');
+        this.slider.accessible_name = _('Microphone');
 
         this._control.connectObject(
             'input-added', (c, id) => this._addDevice(id),
@@ -366,13 +326,15 @@ var InputStreamSlider = class extends StreamSlider {
             'stream-removed', () => this._maybeShowInput(),
             this);
 
-        this._icon.icon_name = 'audio-input-microphone-symbolic';
+        this.iconName = 'audio-input-microphone-symbolic';
         this._icons = [
             'microphone-sensitivity-muted-symbolic',
             'microphone-sensitivity-low-symbolic',
             'microphone-sensitivity-medium-symbolic',
             'microphone-sensitivity-high-symbolic',
         ];
+
+        this.menu.setHeader('audio-input-microphone-symbolic', _('Sound Input'));
     }
 
     _connectStream(stream) {
@@ -410,10 +372,10 @@ var InputStreamSlider = class extends StreamSlider {
     _shouldBeVisible() {
         return super._shouldBeVisible() && this._showInput;
     }
-};
+});
 
 var Indicator = GObject.registerClass(
-class Indicator extends PanelMenu.SystemIndicator {
+class Indicator extends SystemIndicator {
     _init() {
         super._init();
 
@@ -428,8 +390,6 @@ class Indicator extends PanelMenu.SystemIndicator {
         this._inputIndicator.connect('scroll-event',
             (actor, event) => this._handleScrollEvent(this._input, event));
 
-        const volumeMenu = new PopupMenu.PopupMenuSection();
-
         this._control = getMixerControl();
         this._control.connectObject(
             'state-changed', () => this._onControlStateChanged(),
@@ -445,7 +405,6 @@ class Indicator extends PanelMenu.SystemIndicator {
                 this._primaryIndicator.icon_name = icon;
             this._primaryIndicator.visible = icon !== null;
         });
-        volumeMenu.addMenuItem(this._output.item);
 
         this._input = new InputStreamSlider(this._control);
         this._input.connect('stream-updated', () => {
@@ -454,13 +413,13 @@ class Indicator extends PanelMenu.SystemIndicator {
             if (icon)
                 this._inputIndicator.icon_name = icon;
         });
-        volumeMenu.addMenuItem(this._input.item);
 
-        this._input.item.actor.bind_property('visible',
+        this._input.bind_property('visible',
             this._inputIndicator, 'visible',
             GObject.BindingFlags.SYNC_CREATE);
 
-        this.menu.addMenuItem(volumeMenu);
+        this.quickSettingsItems.push(this._output);
+        this.quickSettingsItems.push(this._input);
 
         this._onControlStateChanged();
     }
@@ -483,8 +442,8 @@ class Indicator extends PanelMenu.SystemIndicator {
     }
 
     _handleScrollEvent(item, event) {
-        const result = item.scroll(event);
-        if (result === Clutter.EVENT_PROPAGATE || this.menu.actor.mapped)
+        const result = item.slider.scroll(event);
+        if (result === Clutter.EVENT_PROPAGATE || item.mapped)
             return result;
 
         const gicon = new Gio.ThemedIcon({name: item.getIcon()});


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]