From 78bf5bfd969b6268571c0a28cd6d95b392edfab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 16 Oct 2023 10:30:09 -0700 Subject: [PATCH] Port to Gtk4 (#229) * Initial port * Update CI * Use description for HeaderLabel * Update README * Output: use event controller * Update main.yml * Update README.md * Fix canberra thingy * DeviceMonitor: fix typo * fix uses of get_style_context * Use RICH_LIST for device boxes * replace grid with box * re-fix app ID --- .github/workflows/main.yml | 2 +- README.md | 13 +-- data/icons.gresource.xml | 2 +- data/meson.build | 2 +- data/sound.metainfo.xml.in | 6 +- meson.build | 7 +- ...g.pot => io.elementary.settings.sound.pot} | 0 po/meson.build | 2 +- src/CanberraGtk4.vala | 76 +++++++++++++++ src/DeviceRow.vala | 18 ++-- src/InputDeviceMonitor.vala | 6 +- src/InputPanel.vala | 24 ++--- src/OutputPanel.vala | 97 ++++++++----------- src/Plug.vala | 15 +-- src/PulseAudioManager.vala | 2 +- src/TestPopover.vala | 48 +++++---- src/meson.build | 11 ++- vapi/libcanberra-gtk3.deps | 2 - vapi/libcanberra-gtk3.vapi | 37 ------- 19 files changed, 203 insertions(+), 167 deletions(-) rename po/{sound-plug.pot => io.elementary.settings.sound.pot} (100%) create mode 100644 src/CanberraGtk4.vala delete mode 100644 vapi/libcanberra-gtk3.deps delete mode 100644 vapi/libcanberra-gtk3.vapi diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 846da22c..6ab7e62e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y libcanberra-gtk3-dev libgranite-dev libgtk-3-dev libswitchboard-2.0-dev libpulse-dev meson valac + apt install -y libadwaita-1-dev libcanberra-dev libgranite-7-dev libgtk-4-dev libswitchboard-3-dev libpulse-dev meson valac - name: Build env: DESTDIR: out diff --git a/README.md b/README.md index f4caecb7..31a3da8d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Switchboard Sound Plug +# Sound Settings [![Translation status](https://l10n.elementary.io/widgets/switchboard/-/switchboard-plug-sound/svg-badge.svg)](https://l10n.elementary.io/engage/switchboard/?utm_source=widget) ![screenshot](data/screenshot-output.png?raw=true) @@ -7,11 +7,12 @@ You'll need the following dependencies: -* libcanberra-gtk3-dev -* libgranite-dev -* libgtk-3-dev +* libadwaita-1-dev +* libcanberra-dev +* libgranite-7-dev +* libgtk-4-dev * libpulse-dev -* libswitchboard-2.0-dev +* libswitchboard-3-dev * meson * valac @@ -23,4 +24,4 @@ Run `meson` to configure the build environment and then `ninja` to build To install, use `ninja install` - sudo ninja install + ninja install diff --git a/data/icons.gresource.xml b/data/icons.gresource.xml index a814e003..51f0671b 100644 --- a/data/icons.gresource.xml +++ b/data/icons.gresource.xml @@ -1,6 +1,6 @@ - + audio-speaker-center-back-testing.svg audio-speaker-center.svg audio-speaker-center-testing.svg diff --git a/data/meson.build b/data/meson.build index 77ac57ee..64c26070 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,6 +1,6 @@ i18n.merge_file( input: 'sound.metainfo.xml.in', - output: 'io.elementary.switchboard.sound.metainfo.xml', + output: meson.project_name() + '.metainfo.xml', po_dir: meson.source_root() / 'po' / 'extra', type: 'xml', install: true, diff --git a/data/sound.metainfo.xml.in b/data/sound.metainfo.xml.in index 433628f4..54edbe91 100644 --- a/data/sound.metainfo.xml.in +++ b/data/sound.metainfo.xml.in @@ -1,8 +1,8 @@ - io.elementary.switchboard.sound - io.elementary.switchboard - sound-plug + io.elementary.settings.sound + io.elementary.settings + io.elementary.settings.sound CC0-1.0 GPL-2.0+ diff --git a/meson.build b/meson.build index 617bd0ff..34e9c5de 100644 --- a/meson.build +++ b/meson.build @@ -1,10 +1,9 @@ project( - 'sound', + 'io.elementary.settings.sound', 'vala', 'c', version: '2.3.3' ) -gettext_name = meson.project_name() + '-plug' gnome = import('gnome') i18n = import('i18n') @@ -13,7 +12,7 @@ datadir = join_paths(prefix, get_option('datadir')) libdir = join_paths(prefix, get_option('libdir')) add_project_arguments( - '-DGETTEXT_PACKAGE="@0@"'.format(gettext_name), + '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), language:'c' ) @@ -30,7 +29,7 @@ plug_resources = gnome.compile_resources( config_data = configuration_data() config_data.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir'))) -config_data.set_quoted('GETTEXT_PACKAGE', meson.project_name() + '-plug') +config_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) config_file = configure_file( input: 'src/Config.vala.in', output: '@BASENAME@', diff --git a/po/sound-plug.pot b/po/io.elementary.settings.sound.pot similarity index 100% rename from po/sound-plug.pot rename to po/io.elementary.settings.sound.pot diff --git a/po/meson.build b/po/meson.build index c1dea450..27ec9520 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,4 +1,4 @@ -i18n.gettext(gettext_name, +i18n.gettext(meson.project_name(), args: ['--directory=' + meson.source_root()], preset: 'glib' ) diff --git a/src/CanberraGtk4.vala b/src/CanberraGtk4.vala new file mode 100644 index 00000000..4a3a34c7 --- /dev/null +++ b/src/CanberraGtk4.vala @@ -0,0 +1,76 @@ +/* + * Copyright 2022 elementary, Inc. (https://elementary.io) + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/* code adapted from libcanberra */ + +namespace CanberraGtk4 { + private Canberra.Context? context = null; + + public unowned Canberra.Context? context_get () { + Canberra.Proplist proplist; + + if (context != null) { + return context; + } if (Canberra.Context.create (out context) != Canberra.SUCCESS) { + return null; + } if (Canberra.Proplist.create (out proplist) != Canberra.SUCCESS) { + return null; + } + + unowned var name = GLib.Environment.get_application_name (); + if (name != null) { + proplist.sets (Canberra.PROP_APPLICATION_NAME, name); + } else { + proplist.sets (Canberra.PROP_APPLICATION_NAME, "libcanberra-gtk"); + proplist.sets (Canberra.PROP_APPLICATION_VERSION, "%i.%i".printf (Canberra.MAJOR, Canberra.MINOR)); + proplist.sets (Canberra.PROP_APPLICATION_ID, "org.freedesktop.libcanberra.gtk"); + } + + unowned var icon = Gtk.Window.get_default_icon_name (); + if (icon != null) { + proplist.sets (Canberra.PROP_APPLICATION_ICON_NAME, icon); + } + + unowned var display = Gdk.Display.get_default (); + if (display is Gdk.X11.Display) { + unowned var display_name = display.get_name (); + if (display_name != null) { + proplist.sets (Canberra.PROP_WINDOW_X11_SCREEN, display_name); + } + + var screen = "%i".printf (((Gdk.X11.Display) display).get_screen ().get_screen_number ()); + proplist.sets (Canberra.PROP_WINDOW_X11_SCREEN, screen); + } + + context.change_props_full (proplist); + + var val = Value (typeof (string)); + if (display.get_setting ("gtk-sound-theme-name", val)) { + context.change_props (Canberra.PROP_CANBERRA_XDG_THEME_NAME, val.get_string ()); + } + + val = Value (typeof (bool)); + if (display.get_setting ("gtk-enable-event-sounds", val)) { + unowned var env = GLib.Environment.get_variable ("CANBERRA_FORCE_EVENT_SOUNDS"); + context.change_props (Canberra.PROP_CANBERRA_ENABLE, env != null ? true : val.get_boolean ()); + } + + display.setting_changed.connect ((setting) => { + Value new_val; + if (setting == "gtk-sound-theme-name") { + new_val = Value (typeof (string)); + display.get_setting ("gtk-sound-theme-name", new_val); + context.change_props (Canberra.PROP_CANBERRA_ENABLE, new_val.get_string ()); + } else if (setting == "gtk-enable-event-sounds") { + new_val = Value (typeof (bool)); + unowned var env = GLib.Environment.get_variable ("CANBERRA_FORCE_EVENT_SOUNDS"); + display.get_setting ("gtk-enable-event-sounds", new_val); + context.change_props (Canberra.PROP_CANBERRA_ENABLE, env != null ? true : new_val.get_boolean ()); + } + }); + + return context; + } +} diff --git a/src/DeviceRow.vala b/src/DeviceRow.vala index 35e4abb8..9ff7fecb 100644 --- a/src/DeviceRow.vala +++ b/src/DeviceRow.vala @@ -24,7 +24,7 @@ public class Sound.DeviceRow : Gtk.ListBoxRow { public Device device { get; construct; } - private Gtk.RadioButton activate_radio; + private Gtk.CheckButton activate_radio; private bool ignore_default = false; public DeviceRow (Device device) { @@ -32,9 +32,10 @@ public class Sound.DeviceRow : Gtk.ListBoxRow { } construct { - activate_radio = new Gtk.RadioButton (null); + activate_radio = new Gtk.CheckButton (); - var image = new Gtk.Image.from_icon_name (device.icon_name, Gtk.IconSize.DND) { + var image = new Gtk.Image.from_icon_name (device.icon_name) { + pixel_size = 32, tooltip_text = device.get_nice_form_factor (), use_fallback = true }; @@ -46,13 +47,10 @@ public class Sound.DeviceRow : Gtk.ListBoxRow { var description_label = new Gtk.Label (device.description) { xalign = 0 }; - - unowned var description_style_context = description_label.get_style_context (); - description_style_context.add_class (Gtk.STYLE_CLASS_DIM_LABEL); - description_style_context.add_class (Granite.STYLE_CLASS_SMALL_LABEL); + description_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + description_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); var grid = new Gtk.Grid () { - margin = 6, column_spacing = 12, orientation = Gtk.Orientation.HORIZONTAL }; @@ -61,7 +59,7 @@ public class Sound.DeviceRow : Gtk.ListBoxRow { grid.attach (name_label, 2, 0); grid.attach (description_label, 2, 1); - add (grid); + child = grid; activate.connect (() => { activate_radio.active = true; @@ -85,7 +83,7 @@ public class Sound.DeviceRow : Gtk.ListBoxRow { } public void link_to_row (DeviceRow row) { - activate_radio.join_group (row.activate_radio); + activate_radio.group = row.activate_radio; activate_radio.active = device.is_default; } } diff --git a/src/InputDeviceMonitor.vala b/src/InputDeviceMonitor.vala index cb9ace51..2775abfd 100644 --- a/src/InputDeviceMonitor.vala +++ b/src/InputDeviceMonitor.vala @@ -71,9 +71,9 @@ public class Sound.InputDeviceMonitor : GLib.Object { }; var props = new PulseAudio.Proplist (); - props.sets (PulseAudio.Proplist.PROP_APPLICATION_NAME, "Switchboard sound"); - props.sets (PulseAudio.Proplist.PROP_APPLICATION_ID, "org.pantheon.switchboard.plug.sound"); - props.sets (PulseAudio.Proplist.PROP_APPLICATION_ICON_NAME, "multimedia-volume-control"); + props.sets (PulseAudio.Proplist.PROP_APPLICATION_NAME, "Sound Settings"); + props.sets (PulseAudio.Proplist.PROP_APPLICATION_ID, "io.elementary.settings.sound"); + props.sets (PulseAudio.Proplist.PROP_APPLICATION_ICON_NAME, "preferences-desktop-sound"); props.sets (PulseAudio.Proplist.PROP_APPLICATION_VERSION, "0.1"); steam = new PulseAudio.Stream (c, _("Peak detect"), ss, null, props); diff --git a/src/InputPanel.vala b/src/InputPanel.vala index 8ddbdb14..28a473c3 100644 --- a/src/InputPanel.vala +++ b/src/InputPanel.vala @@ -17,24 +17,25 @@ public class Sound.InputPanel : Gtk.Box { construct { margin_bottom = 12; - var no_device_grid = new Granite.Widgets.AlertView ( - _("No Connected Audio Devices Detected"), - _("Check that all cables are securely attached and audio input devices are powered on."), - "audio-input-microphone-symbolic" - ); - no_device_grid.show_all (); + var no_device_grid = new Granite.Placeholder ( + _("No Connected Audio Devices Detected") + ) { + description = _("Check that all cables are securely attached and audio input devices are powered on."), + icon = new ThemedIcon ("audio-input-microphone-symbolic") + }; devices_listbox = new Gtk.ListBox () { activate_on_single_click = true, vexpand = true }; devices_listbox.set_placeholder (no_device_grid); + devices_listbox.add_css_class (Granite.STYLE_CLASS_RICH_LIST); devices_listbox.row_activated.connect ((row) => { pam.set_default_device.begin (((Sound.DeviceRow) row).device); }); - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = devices_listbox }; @@ -58,7 +59,7 @@ public class Sound.InputPanel : Gtk.Box { }; level_bar = new Gtk.LevelBar.for_interval (0.0, 1.0); - level_bar.get_style_context ().add_class ("inverted"); + level_bar.add_css_class ("inverted"); level_bar.add_offset_value ("low", 0.8); level_bar.add_offset_value ("high", 0.95); @@ -75,8 +76,8 @@ public class Sound.InputPanel : Gtk.Box { orientation = VERTICAL; spacing = 18; - add (devices_frame); - add (volume_grid); + append (devices_frame); + append (volume_grid); device_monitor = new InputDeviceMonitor (); device_monitor.update_fraction.connect ((fraction) => { @@ -172,8 +173,7 @@ public class Sound.InputPanel : Gtk.Box { device_row.link_to_row ((DeviceRow) row); } - device_row.show_all (); - devices_listbox.add (device_row); + devices_listbox.append (device_row); device_row.set_as_default.connect (() => { pam.set_default_device.begin (device); }); diff --git a/src/OutputPanel.vala b/src/OutputPanel.vala index 60b8c32a..9fc69d8c 100644 --- a/src/OutputPanel.vala +++ b/src/OutputPanel.vala @@ -35,20 +35,21 @@ public class Sound.OutputPanel : Gtk.Box { } construct { - var no_device_grid = new Granite.Widgets.AlertView ( - _("No Connected Output Devices Detected"), - _("Check that all cables are securely attached and audio output devices are powered on."), - "audio-volume-muted-symbolic" - ); - no_device_grid.show_all (); + var no_device_grid = new Granite.Placeholder ( + _("No Connected Output Devices Detected") + ) { + description = _("Check that all cables are securely attached and audio output devices are powered on."), + icon = new ThemedIcon ("audio-volume-muted-symbolic") + }; devices_listbox = new Gtk.ListBox () { activate_on_single_click = true, vexpand = true }; devices_listbox.set_placeholder (no_device_grid); + devices_listbox.add_css_class (Granite.STYLE_CLASS_RICH_LIST); - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = devices_listbox }; @@ -58,11 +59,14 @@ public class Sound.OutputPanel : Gtk.Box { var volume_label = new Granite.HeaderLabel (_("Volume")); + var legacy_controller = new Gtk.EventControllerLegacy (); + volume_scale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL, 0, 100, 5) { draw_value = false, hexpand = true }; volume_scale.adjustment.page_increment = 5; + volume_scale.add_controller (legacy_controller); volume_switch = new Gtk.Switch () { valign = Gtk.Align.CENTER, @@ -79,7 +83,9 @@ public class Sound.OutputPanel : Gtk.Box { balance_scale.add_mark (0, Gtk.PositionType.BOTTOM, _("Center")); balance_scale.add_mark (1, Gtk.PositionType.BOTTOM, _("Right")); - var alerts_label = new Granite.HeaderLabel (_("Event Alerts")); + var alerts_label = new Granite.HeaderLabel (_("Event Alerts")) { + secondary_text = _("Notify when the system can't do something in response to input, like attempting to backspace in an empty input or switch windows when only one is open.") + }; var audio_alert_check = new Gtk.CheckButton.with_label (_("Play sound")) { margin_top = 6 @@ -89,24 +95,20 @@ public class Sound.OutputPanel : Gtk.Box { margin_top = 6 }; - var alerts_info = new Gtk.Label ( - _("Notify when the system can't do something in response to input, like attempting to backspace in an empty input or switch windows when only one is open.") - ) { - wrap = true, - xalign = 0 - }; - - alerts_info.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - var test_popover = new TestPopover (); var test_button = new Gtk.MenuButton () { + direction = Gtk.ArrowType.UP, halign = Gtk.Align.END, label = _("Test Speakers…"), popover = test_popover }; - var screen_reader_label = new Granite.HeaderLabel (_("Screen Reader")); + media_keys_settings = new Settings ("org.gnome.settings-daemon.plugins.media-keys"); + + var screen_reader_label = new Granite.HeaderLabel (_("Screen Reader")) { + secondary_text = screenreader_shortcut_label + }; var screen_reader_switch = new Gtk.Switch () { halign = END, @@ -114,13 +116,6 @@ public class Sound.OutputPanel : Gtk.Box { hexpand = true }; - media_keys_settings = new Settings ("org.gnome.settings-daemon.plugins.media-keys"); - var screen_reader_description_label = new Gtk.Label (screenreader_shortcut_label) { - wrap = true, - xalign = 0 - }; - screen_reader_description_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - var output_grid = new Gtk.Grid () { column_spacing = 12 }; @@ -129,26 +124,22 @@ public class Sound.OutputPanel : Gtk.Box { output_grid.attach (volume_switch, 1, 1); output_grid.attach (balance_scale, 0, 2); - var alerts_box = new Gtk.Box (VERTICAL, 0); - alerts_box.add (alerts_label); - alerts_box.add (alerts_info); - alerts_box.add (audio_alert_check); - alerts_box.add (visual_alert_check); + var alerts_box = new Gtk.Box (VERTICAL, 3); + alerts_box.append (alerts_label); + alerts_box.append (audio_alert_check); + alerts_box.append (visual_alert_check); - var screen_reader_grid = new Gtk.Grid () { - column_spacing = 12 - }; - screen_reader_grid.attach (screen_reader_label, 0, 0); - screen_reader_grid.attach (screen_reader_description_label, 0, 1); - screen_reader_grid.attach (screen_reader_switch, 1, 0, 1, 2); + var screen_reader_box = new Gtk.Box (HORIZONTAL, 12); + screen_reader_box.append (screen_reader_label); + screen_reader_box.append (screen_reader_switch); orientation = VERTICAL; spacing = 18; - add (devices_frame); - add (output_grid); - add (alerts_box); - add (screen_reader_grid); - add (test_button); + append (devices_frame); + append (output_grid); + append (alerts_box); + append (screen_reader_box); + append (test_button); var applications_settings = new GLib.Settings ("org.gnome.desktop.a11y.applications"); applications_settings.bind ("screen-reader-enabled", this, "screen_reader_active", SettingsBindFlags.DEFAULT); @@ -168,10 +159,10 @@ public class Sound.OutputPanel : Gtk.Box { var wm_settings = new Settings ("org.gnome.desktop.wm.preferences"); wm_settings.bind ("visual-bell", visual_alert_check, "active", GLib.SettingsBindFlags.DEFAULT); - ca_context = CanberraGtk.context_get (); + ca_context = CanberraGtk4.context_get (); var locale = Intl.setlocale (LocaleCategory.MESSAGES, null); - ca_context.change_props (Canberra.PROP_APPLICATION_NAME, "switchboard-plug-sound", - Canberra.PROP_APPLICATION_ID, "io.elementary.switchboard.sound", + ca_context.change_props (Canberra.PROP_APPLICATION_NAME, "Sound Settings", + Canberra.PROP_APPLICATION_ID, "io.elementary.settings.sound", Canberra.PROP_APPLICATION_LANGUAGE, locale, null); ca_context.open (); @@ -182,19 +173,16 @@ public class Sound.OutputPanel : Gtk.Box { }); media_keys_settings.changed["screenreader"].connect (() => { - screen_reader_description_label.label = screenreader_shortcut_label; + screen_reader_label.secondary_text = screenreader_shortcut_label; }); - volume_scale.button_release_event.connect (e => { - notify_change (); - return false; - }); - - volume_scale.scroll_event.connect (e => { - if (volume_scale.get_value () < 100) { + legacy_controller.event.connect ((e) => { + var event_type = e.get_event_type (); + if (event_type == SCROLL || event_type == BUTTON_RELEASE) { notify_change (); } - return false; + + return Gdk.EVENT_PROPAGATE; }); } @@ -282,8 +270,7 @@ public class Sound.OutputPanel : Gtk.Box { device_row.link_to_row ((DeviceRow) row); } - device_row.show_all (); - devices_listbox.add (device_row); + devices_listbox.append (device_row); device_row.set_as_default.connect (() => { pam.set_default_device.begin (device); }); diff --git a/src/Plug.vala b/src/Plug.vala index 96f544e0..c95f02c8 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -19,7 +19,7 @@ public class Sound.Plug : Switchboard.Plug { settings.set ("sound/input", "input"); settings.set ("sound/output", "output"); Object (category: Category.HARDWARE, - code_name: "io.elementary.switchboard.sound", + code_name: "io.elementary.settings.sound", display_name: _("Sound"), description: _("Change sound and microphone volume"), icon: "preferences-desktop-sound", @@ -40,20 +40,21 @@ public class Sound.Plug : Switchboard.Plug { var stack_switcher = new Gtk.StackSwitcher () { halign = Gtk.Align.CENTER, - homogeneous = true, stack = stack }; - var clamp = new Hdy.Clamp () { + var clamp = new Adw.Clamp () { child = stack }; box = new Gtk.Box (VERTICAL, 12) { - margin = 12 + margin_top = 12, + margin_end = 12, + margin_bottom = 12, + margin_start = 12 }; - box.add (stack_switcher); - box.add (clamp); - box.show_all (); + box.append (stack_switcher); + box.append (clamp); var pam = PulseAudioManager.get_default (); pam.start (); diff --git a/src/PulseAudioManager.vala b/src/PulseAudioManager.vala index b09f9cd8..21aa7e6b 100644 --- a/src/PulseAudioManager.vala +++ b/src/PulseAudioManager.vala @@ -285,7 +285,7 @@ public class Sound.PulseAudioManager : GLib.Object { } var props = new PulseAudio.Proplist (); - props.sets (PulseAudio.Proplist.PROP_APPLICATION_ID, "org.pantheon.switchboard.plug.sound"); + props.sets (PulseAudio.Proplist.PROP_APPLICATION_ID, "io.elementary.settings.sound"); context = new PulseAudio.Context (loop.get_api (), null, props); context.set_state_callback (context_state_callback); diff --git a/src/TestPopover.vala b/src/TestPopover.vala index 208df330..e8dc132a 100644 --- a/src/TestPopover.vala +++ b/src/TestPopover.vala @@ -26,23 +26,28 @@ public class Sound.TestPopover : Gtk.Popover { construct { main_grid = new Gtk.Grid () { - margin = 12, + margin_top = 12, + margin_end = 12, + margin_bottom = 12, + margin_start = 12, column_spacing = 6, row_spacing = 6 }; - var me = new Granite.Widgets.Avatar.with_default_icon (48); - main_grid.attach (me, 2, 1, 1, 1); - main_grid.show_all (); - add (main_grid); + var me = new Adw.Avatar (48, null, true) { + icon_name = "avatar-default-symbolic" + }; + main_grid.attach (me, 2, 1); + + child = main_grid; unowned PulseAudioManager pam = PulseAudioManager.get_default (); pam.notify["default-output"].connect (() => { default_changed (); }); - var icon_theme = Gtk.IconTheme.get_default (); - icon_theme.add_resource_path ("/io/elementary/switchboard/sound/icons/"); + var icon_theme = Gtk.IconTheme.get_for_display (Gdk.Display.get_default ()); + icon_theme.add_resource_path ("/io/elementary/settings/sound/icons/"); } private void create_position_button (PulseAudio.ChannelPosition pa_position) { @@ -105,11 +110,14 @@ public class Sound.TestPopover : Gtk.Popover { } private void clear_buttons () { - main_grid.get_children ().foreach ((child) => { + unowned var child = main_grid.get_first_child (); + while (child != null) { if (child is PositionButton) { - child.destroy (); + main_grid.remove (child); } - }); + + child = child.get_next_sibling (); + } } private void add_buttons () { @@ -118,21 +126,25 @@ public class Sound.TestPopover : Gtk.Popover { create_position_button (position); } } - - main_grid.show_all (); } public class PositionButton : Gtk.Button { public PulseAudio.ChannelPosition pa_position { get; construct; } private bool playing = false; + private Gtk.Image image; + public PositionButton (PulseAudio.ChannelPosition pa_position) { Object (pa_position: pa_position); - image = new Gtk.Image.from_icon_name (get_icon (), Gtk.IconSize.DIALOG); - ((Gtk.Image) image).pixel_size = 48; } construct { - get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); + add_css_class (Granite.STYLE_CLASS_FLAT); + + image = new Gtk.Image.from_icon_name (get_icon ()) { + pixel_size = 48 + }; + + child = image; } private string get_icon () { @@ -207,7 +219,7 @@ public class Sound.TestPopover : Gtk.Popover { public override void clicked () { playing = true; - ((Gtk.Image) image).icon_name = get_icon (); + image.icon_name = get_icon (); Canberra.Proplist proplist; Canberra.Proplist.create (out proplist); proplist.sets (Canberra.PROP_MEDIA_ROLE, "test"); @@ -215,13 +227,13 @@ public class Sound.TestPopover : Gtk.Popover { proplist.sets (Canberra.PROP_CANBERRA_FORCE_CHANNEL, pa_position.to_string ()); proplist.sets (Canberra.PROP_CANBERRA_ENABLE, "1"); proplist.sets (Canberra.PROP_EVENT_ID, get_sound_name ()); - unowned Canberra.Context? canberra = CanberraGtk.context_get (); + unowned Canberra.Context? canberra = CanberraGtk4.context_get (); canberra.play_full (1, proplist, play_full_callback); } private void play_full_callback (Canberra.Context c, uint32 id, int code) { playing = false; - ((Gtk.Image) image).icon_name = get_icon (); + image.icon_name = get_icon (); } } } diff --git a/src/meson.build b/src/meson.build index c3a161b0..2d4165a3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,5 @@ plug_files = files( + 'CanberraGtk4.vala', 'TestPopover.vala', 'PulseAudioManager.vala', 'Plug.vala', @@ -9,7 +10,7 @@ plug_files = files( 'Device.vala' ) -switchboard_dep = dependency('switchboard-2.0') +switchboard_dep = dependency('switchboard-3') switchboard_plugsdir = switchboard_dep.get_pkgconfig_variable('plugsdir', define_variable: ['libdir', libdir]) shared_module( @@ -21,13 +22,13 @@ shared_module( dependency('glib-2.0'), dependency('gio-2.0'), dependency('gobject-2.0'), - dependency('granite'), - dependency('gtk+-3.0'), + dependency('granite-7'), + dependency('gtk4'), + dependency('gtk4-x11'), + dependency('libadwaita-1'), dependency('libpulse'), dependency('libpulse-mainloop-glib'), dependency('libcanberra'), - dependency('libcanberra-gtk3'), - dependency('libhandy-1'), meson.get_compiler('vala').find_library('libpulse-ext', dirs: join_paths(meson.source_root(), 'vapi')), switchboard_dep ], diff --git a/vapi/libcanberra-gtk3.deps b/vapi/libcanberra-gtk3.deps deleted file mode 100644 index 7bd6beca..00000000 --- a/vapi/libcanberra-gtk3.deps +++ /dev/null @@ -1,2 +0,0 @@ -libcanberra -gtk+-3.0 diff --git a/vapi/libcanberra-gtk3.vapi b/vapi/libcanberra-gtk3.vapi deleted file mode 100644 index f788f8e0..00000000 --- a/vapi/libcanberra-gtk3.vapi +++ /dev/null @@ -1,37 +0,0 @@ -/*** - This file is part of libcanberra. - - Copyright 2009 Lennart Poettering - - libcanberra is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 2.1 of the - License, or (at your option) any later version. - - libcanberra is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with libcanberra. If not, see - . -***/ - -using Canberra; -using Gdk; -using Gtk; - -[CCode (cprefix = "CA_GTK_", lower_case_cprefix = "ca_gtk_", cheader_filename = "canberra-gtk.h")] -namespace CanberraGtk { - - public unowned Context? context_get(); - public unowned Context? context_get_for_screen(Gdk.Screen? screen); - - public int proplist_set_for_widget(Proplist p, Gtk.Widget w); - public int play_for_widget(Gtk.Widget w, uint32 id, ...); - public int proplist_set_for_event(Proplist p, Gdk.Event e); - public int play_for_event(Gdk.Event e, uint32 id, ...); - - public void widget_disable_sounds(Gtk.Widget w, bool enable = false); -}