diff --git a/.github/workflows/gettext.yml b/.github/workflows/gettext.yml index 3f5087d51..839f84b27 100644 --- a/.github/workflows/gettext.yml +++ b/.github/workflows/gettext.yml @@ -2,7 +2,7 @@ name: Gettext Updates on: push: - branches: [master] + branches: [main] jobs: build: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a2f2ffc09..969d693d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y libgranite-dev libgranite-7-dev libgtk-3-dev libgtk-4-dev libswitchboard-2.0-dev libgexiv2-dev meson valac + apt install -y libadwaita-1-dev libgranite-7-dev libgtk-4-dev libswitchboard-3-dev libgexiv2-dev meson valac - name: Build env: DESTDIR: out diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 504e2b799..0b795bfff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,7 +2,7 @@ name: Release on: pull_request: - branches: [master] + branches: [main] types: [closed] jobs: release: diff --git a/README.md b/README.md index 695e098e9..a685a36e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Switchboard Desktop Plug +# Desktop Settings [![Translation status](https://l10n.elementary.io/widgets/switchboard/-/switchboard-plug-pantheon-shell/svg-badge.svg)](https://l10n.elementary.io/engage/switchboard/?utm_source=widget) ![screenshot](data/screenshot-appearance.png?raw=true) @@ -7,13 +7,10 @@ You'll need the following dependencies: -* gnome-settings-daemon-dev -* libswitchboard-2.0-dev +* libswitchboard-3-dev * libgee-0.8-dev * libgexiv2-dev -* libgtk-3-dev (>= 3.22) * libgtk-4-dev -* libgranite-dev * libgranite-7-dev * meson * valac @@ -26,4 +23,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/pantheon-shell.metainfo.xml.in b/data/desktop.metainfo.xml.in similarity index 96% rename from data/pantheon-shell.metainfo.xml.in rename to data/desktop.metainfo.xml.in index c629dc891..ed51fdf6e 100644 --- a/data/pantheon-shell.metainfo.xml.in +++ b/data/desktop.metainfo.xml.in @@ -1,8 +1,8 @@ - io.elementary.switchboard.pantheon-shell - io.elementary.switchboard - pantheon-desktop-plug + io.elementary.settings.desktop + io.elementary.settings + io.elementary.settings.desktop CC0-1.0 GPL-3.0 diff --git a/data/icons.gresource.xml b/data/icons.gresource.xml index 803f64fbf..828e9a714 100644 --- a/data/icons.gresource.xml +++ b/data/icons.gresource.xml @@ -1,11 +1,11 @@ - + appearance-default.svg appearance-dark.svg plug.css - + icons/32.svg icons/32.svg icons/48.svg diff --git a/data/meson.build b/data/meson.build index ae8eae898..ce22e167f 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,6 +1,6 @@ i18n.merge_file( - input: 'pantheon-shell.metainfo.xml.in', - output: 'io.elementary.switchboard.pantheon-shell.metainfo.xml', + input: 'desktop.metainfo.xml.in', + output: gettext_name + '.metainfo.xml', po_dir: meson.source_root() / 'po' / 'extra', type: 'xml', install: true, diff --git a/data/plug.css b/data/plug.css index 8040f7c04..faef8bd3d 100644 --- a/data/plug.css +++ b/data/plug.css @@ -78,13 +78,19 @@ 0 3px 3px alpha(#000, 0.22); } -.wallpaper-container radio { +.wallpaper-container check { + border-radius: 50%; min-height: 20px; min-width: 20px; -gtk-icon-transform: scale(0.6); } -appearance-view radiobutton .card { +.wallpaper-container picture { + min-width: 162px; + min-height: 100px; +} + +appearance-view checkbutton .card { background-position: center; background-repeat: no-repeat; background-size: 86px 64px, cover; @@ -93,10 +99,10 @@ appearance-view radiobutton .card { margin: 6px 6px 12px 12px; } -appearance-view radiobutton .card.prefer-default { +appearance-view checkbutton .card.prefer-default { background-color: white; background-image: - url("resource:///io/elementary/switchboard/plug/pantheon-shell/appearance-default.svg"), + url("resource:///io/elementary/settings/desktop/appearance-default.svg"), linear-gradient( to bottom, alpha(@accent_color_300, 0.1), @@ -104,10 +110,10 @@ appearance-view radiobutton .card.prefer-default { ); } -appearance-view radiobutton .card.prefer-dark { +appearance-view checkbutton .card.prefer-dark { background-color: mix(@BLACK_300, @BLACK_500, 0.25); background-image: - url("resource:///io/elementary/switchboard/plug/pantheon-shell/appearance-dark.svg"), + url("resource:///io/elementary/settings/desktop/appearance-dark.svg"), linear-gradient( to bottom, alpha(@accent_color_300, 0.1), diff --git a/meson.build b/meson.build index 9bac300f4..43de0e810 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,9 @@ project( - 'pantheon-desktop', + 'desktop', 'vala', 'c', version: '6.5.0' ) -gettext_name = meson.project_name() + '-plug' +gettext_name = 'io.elementary.settings.' + meson.project_name() gnome = import('gnome') i18n = import('i18n') @@ -20,9 +20,9 @@ add_project_arguments( gio_dep = dependency('gio-2.0') glib_dep = dependency('glib-2.0') gobject_dep = dependency('gobject-2.0') -granite_dep = dependency('granite', version: '>=6.0.0') -gtk_dep = dependency('gtk+-3.0', version: '>= 3.22') -hdy_dep = dependency ('libhandy-1') +granite_dep = dependency('granite-7', version: '>=7.4.0') +gtk_dep = dependency('gtk4') +hdy_dep = dependency ('libadwaita-1') posix_dep = meson.get_compiler('vala').find_library('posix') plug_resources = gnome.compile_resources( diff --git a/po/extra/POTFILES b/po/extra/POTFILES index 9a55e13f3..4a0419119 100644 --- a/po/extra/POTFILES +++ b/po/extra/POTFILES @@ -1 +1 @@ -data/pantheon-shell.metainfo.xml.in +data/desktop.metainfo.xml.in diff --git a/set-wallpaper-contract/meson.build b/set-wallpaper-contract/meson.build index bfef309c8..284edde48 100644 --- a/set-wallpaper-contract/meson.build +++ b/set-wallpaper-contract/meson.build @@ -28,11 +28,8 @@ executable( glib_dep, gio_dep, gobject_dep, -# granite_dep, -# gtk_dep, - # TODO: Re-use the variables above when the plug itself is ported to GTK 4 - dependency('gtk4'), - dependency('granite-7'), + granite_dep, + gtk_dep, posix_dep, meson.get_compiler('c').find_library('m') ], diff --git a/src/Plug.vala b/src/Plug.vala index 55893e149..422704f3e 100644 --- a/src/Plug.vala +++ b/src/Plug.vala @@ -37,15 +37,15 @@ public class PantheonShell.Plug : Switchboard.Plug { settings.set ("desktop/text", "text"); var provider = new Gtk.CssProvider (); - provider.load_from_resource ("/io/elementary/switchboard/plug/pantheon-shell/plug.css"); - Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + provider.load_from_resource ("/io/elementary/settings/desktop/plug.css"); + Gtk.StyleContext.add_provider_for_display (Gdk.Display.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); // DEPRECATED settings.set ("desktop/wallpaper", "wallpaper"); settings.set ("desktop/hot-corners", "multitasking"); Object (category: Category.PERSONAL, - code_name: "io.elementary.switchboard.pantheon-shell", + code_name: "io.elementary.settings.desktop", display_name: _("Desktop"), description: _("Configure the dock, hot corners, and change wallpaper"), icon: "preferences-desktop", @@ -54,8 +54,6 @@ public class PantheonShell.Plug : Switchboard.Plug { public override Gtk.Widget get_widget () { if (main_grid == null) { - main_grid = new Gtk.Grid (); - wallpaper_view = new Wallpaper (this); var multitasking = new Multitasking (); @@ -74,15 +72,25 @@ public class PantheonShell.Plug : Switchboard.Plug { stack.add_titled (multitasking, "multitasking", _("Multitasking")); - var stack_switcher = new Gtk.StackSwitcher (); - stack_switcher.stack = stack; - stack_switcher.halign = Gtk.Align.CENTER; - stack_switcher.homogeneous = true; - stack_switcher.margin = 24; + var stack_switcher = new Gtk.StackSwitcher () { + stack = stack, + halign = CENTER, + margin_top = 24, + margin_end = 24, + margin_bottom = 24, + margin_start = 24 + }; + + var switcher_sizegroup = new Gtk.SizeGroup (HORIZONTAL); + unowned var switcher_child = stack_switcher.get_first_child (); + while (switcher_child != null) { + switcher_sizegroup.add_widget (switcher_child); + switcher_child = switcher_child.get_next_sibling (); + } - main_grid.attach (stack_switcher, 0, 0, 1, 1); - main_grid.attach (stack, 0, 1, 1, 1); - main_grid.show_all (); + main_grid = new Gtk.Grid (); + main_grid.attach (stack_switcher, 0, 0); + main_grid.attach (stack, 0, 1); } return main_grid; diff --git a/src/Views/Appearance.vala b/src/Views/Appearance.vala index 98f15bb65..f16df0152 100644 --- a/src/Views/Appearance.vala +++ b/src/Views/Appearance.vala @@ -69,77 +69,76 @@ public class PantheonShell.Appearance : Gtk.Box { } construct { - var dark_label = new Granite.HeaderLabel (_("Style")); + var dark_label = new Granite.HeaderLabel (_("Style")) { + secondary_text = _("Preferred visual style for system components. Apps may also choose to follow this preference.") + }; var prefer_default_card = new Gtk.Grid (); - prefer_default_card.get_style_context ().add_class (Granite.STYLE_CLASS_CARD); - prefer_default_card.get_style_context ().add_class (Granite.STYLE_CLASS_ROUNDED); - prefer_default_card.get_style_context ().add_class ("prefer-default"); + prefer_default_card.add_css_class (Granite.STYLE_CLASS_CARD); + prefer_default_card.add_css_class (Granite.STYLE_CLASS_ROUNDED); + prefer_default_card.add_css_class ("prefer-default"); - var prefer_default_radio = new Gtk.RadioButton (null); - prefer_default_radio.get_style_context ().add_class ("image-button"); + var prefer_default_radio = new Gtk.CheckButton (); + prefer_default_radio.add_css_class ("image-button"); var prefer_default_grid = new Gtk.Grid (); prefer_default_grid.attach (prefer_default_card, 0, 0); prefer_default_grid.attach (new Gtk.Label (_("Default")), 0, 1); - prefer_default_radio.add (prefer_default_grid); + prefer_default_grid.set_parent (prefer_default_radio); var prefer_dark_card = new Gtk.Grid (); - prefer_dark_card.get_style_context ().add_class (Granite.STYLE_CLASS_CARD); - prefer_dark_card.get_style_context ().add_class (Granite.STYLE_CLASS_ROUNDED); - prefer_dark_card.get_style_context ().add_class ("prefer-dark"); + prefer_dark_card.add_css_class (Granite.STYLE_CLASS_CARD); + prefer_dark_card.add_css_class (Granite.STYLE_CLASS_ROUNDED); + prefer_dark_card.add_css_class ("prefer-dark"); - var prefer_dark_radio = new Gtk.RadioButton (null) { + var prefer_dark_radio = new Gtk.CheckButton () { group = prefer_default_radio }; - prefer_dark_radio.get_style_context ().add_class ("image-button"); + prefer_dark_radio.add_css_class ("image-button"); var prefer_dark_grid = new Gtk.Grid (); prefer_dark_grid.attach (prefer_dark_card, 0, 0); prefer_dark_grid.attach (new Gtk.Label (_("Dark")), 0, 1); - prefer_dark_radio.add (prefer_dark_grid); + prefer_dark_grid.set_parent (prefer_dark_radio); var prefer_style_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12); - prefer_style_box.add (prefer_default_radio); - prefer_style_box.add (prefer_dark_radio); - - var dark_info = new Gtk.Label (_("Preferred visual style for system components. Apps may also choose to follow this preference.")) { - wrap = true, - xalign = 0 - }; - dark_info.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + prefer_style_box.append (prefer_default_radio); + prefer_style_box.append (prefer_dark_radio); var schedule_label = new Granite.HeaderLabel (_("Schedule")); - var schedule_disabled_radio = new Gtk.RadioButton.with_label (null, _("Disabled")) { + var schedule_disabled_radio = new Gtk.CheckButton.with_label (_("Disabled")) { margin_bottom = 3 }; - var schedule_sunset_radio = new Gtk.RadioButton.with_label_from_widget ( - schedule_disabled_radio, + var schedule_sunset_radio = new Gtk.CheckButton.with_label ( _("Sunset to Sunrise") - ); + ) { + group = schedule_disabled_radio + }; var from_label = new Gtk.Label (_("From:")); - var from_time = new Granite.Widgets.TimePicker () { + var from_time = new Granite.TimePicker () { hexpand = true, margin_end = 6 }; var to_label = new Gtk.Label (_("To:")); - var to_time = new Granite.Widgets.TimePicker () { + var to_time = new Granite.TimePicker () { hexpand = true }; var schedule_manual_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - schedule_manual_box.add (from_label); - schedule_manual_box.add (from_time); - schedule_manual_box.add (to_label); - schedule_manual_box.add (to_time); + schedule_manual_box.append (from_label); + schedule_manual_box.append (from_time); + schedule_manual_box.append (to_label); + schedule_manual_box.append (to_time); - var schedule_manual_radio = new Gtk.RadioButton.from_widget (schedule_disabled_radio) ; + var schedule_manual_radio = new Gtk.CheckButton () { + group = schedule_disabled_radio + }; Pantheon.AccountsService? pantheon_act = null; @@ -170,7 +169,6 @@ public class PantheonShell.Appearance : Gtk.Box { } var grid = new Gtk.Grid () { - column_spacing = 7, // Off by one with Gtk.RadioButton row_spacing = 6, margin_start = 12, margin_end = 12, @@ -179,7 +177,6 @@ public class PantheonShell.Appearance : Gtk.Box { if (((GLib.DBusProxy) pantheon_act).get_cached_property ("PrefersColorScheme") != null) { grid.attach (dark_label, 0, 0, 2); - grid.attach (dark_info, 0, 1, 2); grid.attach (prefer_style_box, 0, 2, 2); grid.attach (schedule_label, 0, 3, 2); grid.attach (schedule_disabled_radio, 0, 4, 2); @@ -257,20 +254,22 @@ public class PantheonShell.Appearance : Gtk.Box { /* Connect to focus_in_event so that this is only triggered * through user interaction, not if scheduling changes the selection */ - prefer_default_radio.focus_in_event.connect (() => { + var prefer_default_radio_controller = new Gtk.EventControllerFocus (); + prefer_default_radio.add_controller (prefer_default_radio_controller); + prefer_default_radio_controller.enter.connect (() => { // Check if selection changed if (pantheon_act.prefers_color_scheme != Granite.Settings.ColorScheme.NO_PREFERENCE) { schedule_disabled_radio.active = true; } - return Gdk.EVENT_PROPAGATE; }); - prefer_dark_radio.focus_in_event.connect (() => { + var prefer_dark_radio_controller = new Gtk.EventControllerFocus (); + prefer_dark_radio.add_controller (prefer_dark_radio_controller); + prefer_dark_radio_controller.enter.connect (() => { // Check if selection changed if (pantheon_act.prefers_color_scheme != Granite.Settings.ColorScheme.DARK) { schedule_disabled_radio.active = true; } - return Gdk.EVENT_PROPAGATE; }); ((GLib.DBusProxy) pantheon_act).g_properties_changed.connect ((changed, invalid) => { @@ -306,7 +305,8 @@ public class PantheonShell.Appearance : Gtk.Box { if (current_stylesheet.has_prefix (STYLESHEET_PREFIX)) { var accent_label = new Granite.HeaderLabel (_("Accent Color")) { - margin_top = 18 + margin_top = 18, + secondary_text = _("Used across the system by default. Apps can always use their own accent color.") }; var blueberry_button = new PrefersAccentColorButton (pantheon_act, AccentColor.BLUE); @@ -343,35 +343,22 @@ public class PantheonShell.Appearance : Gtk.Box { auto_button.tooltip_text = _("Automatic based on wallpaper"); var accent_box = new Gtk.Box (HORIZONTAL, 6); - accent_box.add (blueberry_button); - accent_box.add (mint_button); - accent_box.add (lime_button); - accent_box.add (banana_button); - accent_box.add (orange_button); - accent_box.add (strawberry_button); - accent_box.add (bubblegum_button); - accent_box.add (grape_button); - accent_box.add (cocoa_button); - accent_box.add (slate_button); - accent_box.add (auto_button); - - var accent_info = new Gtk.Label (_("Used across the system by default. Apps can always use their own accent color.")) { - xalign = 0, - wrap = true - }; - accent_info.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + accent_box.append (blueberry_button); + accent_box.append (mint_button); + accent_box.append (lime_button); + accent_box.append (banana_button); + accent_box.append (orange_button); + accent_box.append (strawberry_button); + accent_box.append (bubblegum_button); + accent_box.append (grape_button); + accent_box.append (cocoa_button); + accent_box.append (slate_button); + accent_box.append (auto_button); grid.attach (accent_label, 0, 7, 2); - grid.attach (accent_info, 0, 8, 2); - grid.attach (accent_box, 0, 9, 2); + grid.attach (accent_box, 0, 8, 2); } - var animations_description = new Gtk.Label (_("Disable animations in the window manager and some other interface elements.")) { - wrap = true, - xalign = 0 - }; - animations_description.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - var animations_switch = new Gtk.Switch () { halign = Gtk.Align.END, hexpand = true, @@ -380,35 +367,33 @@ public class PantheonShell.Appearance : Gtk.Box { var animations_label = new Granite.HeaderLabel (_("Reduce Motion")) { margin_top = 18, - mnemonic_widget = animations_switch + mnemonic_widget = animations_switch, + secondary_text = _("Disable animations in the window manager and some other interface elements.") }; - var animations_grid = new Gtk.Grid () { - column_spacing = 12 - }; - animations_grid.attach (animations_label, 0, 0); - animations_grid.attach (animations_description, 0, 1); - animations_grid.attach (animations_switch, 1, 0, 1, 2); + var animations_box = new Gtk.Box (HORIZONTAL, 12); + animations_box.append (animations_label); + animations_box.append (animations_switch); - grid.attach (animations_grid, 0, 10, 2); + grid.attach (animations_box, 0, 10, 2); - var clamp = new Hdy.Clamp () { + var clamp = new Adw.Clamp () { child = grid }; - add (clamp); + append (clamp); var animations_settings = new Settings ("org.pantheon.desktop.gala.animations"); animations_settings.bind ("enable-animations", animations_switch, "active", SettingsBindFlags.INVERT_BOOLEAN); } - private class PrefersAccentColorButton : Gtk.RadioButton { + private class PrefersAccentColorButton : Gtk.CheckButton { public AccentColor color { get; construct; } public Pantheon.AccountsService? pantheon_act { get; construct; default = null; } private static GLib.Settings interface_settings; - public PrefersAccentColorButton (Pantheon.AccountsService? pantheon_act, AccentColor color, Gtk.RadioButton? group_member = null) { + public PrefersAccentColorButton (Pantheon.AccountsService? pantheon_act, AccentColor color, Gtk.CheckButton? group_member = null) { Object ( pantheon_act: pantheon_act, color: color, diff --git a/src/Views/Dock.vala b/src/Views/Dock.vala index 419fcd974..3fbd67e8e 100644 --- a/src/Views/Dock.vala +++ b/src/Views/Dock.vala @@ -10,58 +10,47 @@ public class PantheonShell.Dock : Gtk.Box { construct { var icon_header = new Granite.HeaderLabel (_("Dock Icon Size")); - var image_32 = new Gtk.Image () { - icon_name = "dock-icon-symbolic", + var image_32 = new Gtk.Image.from_icon_name ("dock-icon-symbolic") { pixel_size = 32 }; - var icon_size_32 = new Gtk.RadioButton (null) { - image = image_32, + var icon_size_32 = new Gtk.CheckButton () { tooltip_text = _("Small") }; + image_32.set_parent (icon_size_32); - var image_48 = new Gtk.Image () { - icon_name = "dock-icon-symbolic", + var image_48 = new Gtk.Image.from_icon_name ("dock-icon-symbolic") { pixel_size = 48 }; - var icon_size_48 = new Gtk.RadioButton (null) { + var icon_size_48 = new Gtk.CheckButton () { group = icon_size_32, - image = image_48, tooltip_text = _("Default") }; + image_48.set_parent (icon_size_48); - var image_64 = new Gtk.Image () { - icon_name = "dock-icon-symbolic", + var image_64 = new Gtk.Image.from_icon_name ("dock-icon-symbolic") { pixel_size = 64 }; - var icon_size_64 = new Gtk.RadioButton (null) { + var icon_size_64 = new Gtk.CheckButton () { group = icon_size_32, - image = image_64, tooltip_text = _("Large") }; + image_64.set_parent (icon_size_64); - var icon_size_unsupported = new Gtk.RadioButton (null) { + var icon_size_unsupported = new Gtk.CheckButton () { group = icon_size_32 }; var icon_size_box = new Gtk.Box (HORIZONTAL, 24); - icon_size_box.add (icon_size_32); - icon_size_box.add (icon_size_48); - icon_size_box.add (icon_size_64); + icon_size_box.append (icon_size_32); + icon_size_box.append (icon_size_48); + icon_size_box.append (icon_size_64); var icon_box = new Gtk.Box (VERTICAL, 0); - icon_box.add (icon_header); - icon_box.add (icon_size_box); - - var translucency_header = new Granite.HeaderLabel (_("Panel Translucency")); - - var translucency_subtitle = new Gtk.Label (_("Automatically transparent or opaque based on the wallpaper")) { - wrap = true, - xalign = 0 - }; - translucency_subtitle.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + icon_box.append (icon_header); + icon_box.append (icon_size_box); var translucency_switch = new Gtk.Switch () { halign = END, @@ -69,23 +58,25 @@ public class PantheonShell.Dock : Gtk.Box { valign = CENTER }; - var translucency_grid = new Gtk.Grid () { - column_spacing = 12 + var translucency_header = new Granite.HeaderLabel (_("Panel Translucency")) { + mnemonic_widget = translucency_switch, + secondary_text = _("Automatically transparent or opaque based on the wallpaper") }; - translucency_grid.attach (translucency_header, 0, 0); - translucency_grid.attach (translucency_subtitle, 0, 1); - translucency_grid.attach (translucency_switch, 1, 0, 1, 2); + + var translucency_box = new Gtk.Box (HORIZONTAL, 12); + translucency_box.append (translucency_header); + translucency_box.append (translucency_switch); var indicators_header = new Granite.HeaderLabel (_("Show in Panel")); var indicators_box = new Gtk.Box (VERTICAL, 6); - indicators_box.add (indicators_header); + indicators_box.append (indicators_header); var a11y_schema = SettingsSchemaSource.get_default ().lookup ("io.elementary.desktop.wingpanel.a11y", true); if (a11y_schema != null && a11y_schema.has_key ("show-indicator")) { var a11y_check = new Gtk.CheckButton.with_label (_("Accessibility")); - indicators_box.add (a11y_check); + indicators_box.append (a11y_check); var a11y_settings = new Settings ("io.elementary.desktop.wingpanel.a11y"); a11y_settings.bind ("show-indicator", a11y_check, "active", DEFAULT); @@ -96,8 +87,8 @@ public class PantheonShell.Dock : Gtk.Box { var caps_check = new Gtk.CheckButton.with_label (_("Caps Lock ⇪")); var num_check = new Gtk.CheckButton.with_label (_("Num Lock")); - indicators_box.add (caps_check); - indicators_box.add (num_check); + indicators_box.append (caps_check); + indicators_box.append (num_check); var keyboard_settings = new Settings ("io.elementary.wingpanel.keyboard"); keyboard_settings.bind ("capslock", caps_check, "active", DEFAULT); @@ -109,23 +100,23 @@ public class PantheonShell.Dock : Gtk.Box { margin_end = 12, margin_bottom = 12 }; - box.add (icon_box); - box.add (translucency_grid); + box.append (icon_box); + box.append (translucency_box); // Only add this box if it has more than the header in it - if (indicators_box.get_children ().length () > 1) { - box.add (indicators_box); + if (indicators_header.get_next_sibling () != null) { + box.append (indicators_box); } - var clamp = new Hdy.Clamp () { + var clamp = new Adw.Clamp () { child = box }; - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = clamp }; - add (scrolled); + append (scrolled); var dock_schema = SettingsSchemaSource.get_default ().lookup ("io.elementary.dock", true); if (dock_schema != null && dock_schema.has_key ("icon-size")) { diff --git a/src/Views/Multitasking.vala b/src/Views/Multitasking.vala index 4a7c1caf8..2e0750cfc 100644 --- a/src/Views/Multitasking.vala +++ b/src/Views/Multitasking.vala @@ -41,12 +41,11 @@ public class PantheonShell.Multitasking : Gtk.Box { var fullscreen_checkbutton = new Gtk.CheckButton.with_label (_("When entering fullscreen")); var maximize_checkbutton = new Gtk.CheckButton.with_label (_("When maximizing")); - var checkbutton_grid = new Gtk.Grid () { - column_spacing = 12, + var checkbutton_box = new Gtk.Box (HORIZONTAL, 12) { margin_bottom = 12 }; - checkbutton_grid.add (fullscreen_checkbutton); - checkbutton_grid.add (maximize_checkbutton); + checkbutton_box.append (fullscreen_checkbutton); + checkbutton_box.append (maximize_checkbutton); var grid = new Gtk.Grid () { column_spacing = 12, @@ -61,17 +60,18 @@ public class PantheonShell.Multitasking : Gtk.Box { grid.attach (bottomleft, 0, 3, 2); grid.attach (bottomright, 0, 4, 2); grid.attach (workspaces_label, 0, 6, 2); - grid.attach (checkbutton_grid, 0, 7, 2); + grid.attach (checkbutton_box, 0, 7, 2); - var clamp = new Hdy.Clamp (); - clamp.add (grid); + var clamp = new Adw.Clamp () { + child = grid + }; - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { + child = clamp, hscrollbar_policy = Gtk.PolicyType.NEVER }; - scrolled.add (clamp); - add (scrolled); + append (scrolled); behavior_settings = new GLib.Settings ("org.pantheon.desktop.gala.behavior"); behavior_settings.bind ("move-fullscreened-workspace", fullscreen_checkbutton, "active", GLib.SettingsBindFlags.DEFAULT); @@ -130,10 +130,10 @@ public class PantheonShell.Multitasking : Gtk.Box { }; var command_revealer = new Gtk.Revealer () { + child = command_entry, margin_top = 6, transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN }; - command_revealer.add (command_entry); margin_bottom = 12; column_spacing = 12; diff --git a/src/Views/Text.vala b/src/Views/Text.vala index 60da4b2ea..4f98777bf 100644 --- a/src/Views/Text.vala +++ b/src/Views/Text.vala @@ -51,39 +51,33 @@ public class PantheonShell.Text : Gtk.Box { size_grid.attach (size_scale, 0, 1); size_grid.attach (size_spinbutton, 1, 1); - var dyslexia_font_label = new Granite.HeaderLabel (_("Dyslexia-friendly")); - var dyslexia_font_switch = new Gtk.Switch () { valign = Gtk.Align.CENTER }; - var dyslexia_font_description_label = new Gtk.Label ( - _("Bottom-heavy shapes and increased character spacing can help improve legibility and reading speed.") - ) { - wrap = true, - xalign = 0 + var dyslexia_font_label = new Granite.HeaderLabel (_("Dyslexia-friendly")) { + hexpand = true, + mnemonic_widget = dyslexia_font_switch, + secondary_text = _("Bottom-heavy shapes and increased character spacing can help improve legibility and reading speed.") }; - dyslexia_font_description_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - var dyslexia_grid = new Gtk.Grid () { - column_spacing = 12 - }; - dyslexia_grid.attach (dyslexia_font_label, 0, 0); - dyslexia_grid.attach (dyslexia_font_description_label, 0, 1); - dyslexia_grid.attach (dyslexia_font_switch, 1, 0, 1, 2); + var dyslexia_box = new Gtk.Box (HORIZONTAL, 12); + dyslexia_box.append (dyslexia_font_label); + dyslexia_box.append (dyslexia_font_switch); var box = new Gtk.Box (VERTICAL, 24) { margin_start = 12, margin_end = 12, margin_bottom = 24 }; - box.add (size_grid); - box.add (dyslexia_grid); + box.append (size_grid); + box.append (dyslexia_box); - var clamp = new Hdy.Clamp (); - clamp.add (box); + var clamp = new Adw.Clamp () { + child = box + }; - add (clamp); + append (clamp); var interface_settings = new Settings ("org.gnome.desktop.interface"); interface_settings.bind ("text-scaling-factor", size_adjustment, "value", SettingsBindFlags.GET); diff --git a/src/Views/Wallpaper.vala b/src/Views/Wallpaper.vala index bcfd5f638..cd9a0394c 100644 --- a/src/Views/Wallpaper.vala +++ b/src/Views/Wallpaper.vala @@ -54,23 +54,22 @@ public class PantheonShell.Wallpaper : Gtk.Box { construct { var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL); + var drop_target = new Gtk.DropTarget (typeof (Gdk.FileList), Gdk.DragAction.COPY); + wallpaper_view = new Gtk.FlowBox () { activate_on_single_click = true, homogeneous = true, selection_mode = SINGLE }; - wallpaper_view.get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW); + wallpaper_view.add_css_class (Granite.STYLE_CLASS_VIEW); wallpaper_view.child_activated.connect (update_checked_wallpaper); wallpaper_view.set_sort_func (wallpapers_sort_function); + wallpaper_view.add_controller (drop_target); var color = gnome_background_settings.get_string ("primary-color"); create_solid_color_container (color); - Gtk.TargetEntry e = {"text/uri-list", 0, 0}; - wallpaper_view.drag_data_received.connect (on_drag_data_received); - Gtk.drag_dest_set (wallpaper_view, Gtk.DestDefaults.ALL, {e}, Gdk.DragAction.COPY); - - wallpaper_scrolled_window = new Gtk.ScrolledWindow (null, null) { + wallpaper_scrolled_window = new Gtk.ScrolledWindow () { child = wallpaper_view, hexpand = true, vexpand = true @@ -125,7 +124,7 @@ public class PantheonShell.Wallpaper : Gtk.Box { load_settings (); var actionbar = new Gtk.ActionBar (); - actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); + actionbar.add_css_class (Granite.STYLE_CLASS_FLAT); actionbar.pack_start (add_wallpaper_button); actionbar.pack_end (color_button); actionbar.pack_end (combo); @@ -133,11 +132,13 @@ public class PantheonShell.Wallpaper : Gtk.Box { actionbar.pack_end (dim_label); orientation = VERTICAL; - add (separator); - add (view_overlay); - add (actionbar); + append (separator); + append (view_overlay); + append (actionbar); add_wallpaper_button.clicked.connect (show_wallpaper_chooser); + + drop_target.drop.connect (on_drag_data_received); } private void show_wallpaper_chooser () { @@ -152,25 +153,28 @@ public class PantheonShell.Wallpaper : Gtk.Box { chooser.filter = filter; chooser.select_multiple = true; - if (chooser.run () == Gtk.ResponseType.ACCEPT) { - SList uris = chooser.get_uris (); - foreach (unowned string uri in uris) { - var file = GLib.File.new_for_uri (uri); - if (WallpaperOperation.get_is_file_in_bg_dir (file)) { - continue; - } + chooser.show (); + chooser.response.connect ((response) => { + if (response == Gtk.ResponseType.ACCEPT) { + var files = chooser.get_files (); + for (var i = 0; i <= files.get_n_items (); i++) { + var file = (File) files.get_item (i); - string local_uri = uri; - var dest = WallpaperOperation.copy_for_library (file); - if (dest != null) { - local_uri = dest.get_uri (); - } + if (WallpaperOperation.get_is_file_in_bg_dir (file)) { + continue; + } - add_wallpaper_from_file (file, local_uri); - } - } + var local_uri = file.get_uri (); + var dest = WallpaperOperation.copy_for_library (file); + if (dest != null) { + local_uri = dest.get_uri (); + } - chooser.destroy (); + add_wallpaper_from_file (file, local_uri); + } + } + chooser.destroy (); + }); } private void load_settings () { @@ -242,7 +246,7 @@ public class PantheonShell.Wallpaper : Gtk.Box { if (finished) { set_combo_disabled_if_necessary (); create_solid_color_container (color_button.rgba.to_string ()); - wallpaper_view.add (solid_color); + wallpaper_view.append (solid_color); wallpaper_view.select_child (solid_color); if (active_wallpaper != null) { @@ -264,7 +268,8 @@ public class PantheonShell.Wallpaper : Gtk.Box { if (active_wallpaper == solid_color) { active_wallpaper.checked = false; - foreach (var child in wallpaper_view.get_children ()) { + var child = wallpaper_view.get_first_child (); + while (child != null) { var container = (WallpaperContainer) child; if (container.uri == current_wallpaper_path) { container.checked = true; @@ -272,6 +277,8 @@ public class PantheonShell.Wallpaper : Gtk.Box { active_wallpaper = container; break; } + + child = child.get_next_sibling (); } } } else { @@ -343,7 +350,7 @@ public class PantheonShell.Wallpaper : Gtk.Box { if (toplevel_folder) { create_solid_color_container (color_button.rgba.to_string ()); - wallpaper_view.add (solid_color); + wallpaper_view.append (solid_color); finished = true; if (gnome_background_settings.get_string ("picture-options") == "none") { @@ -373,49 +380,30 @@ public class PantheonShell.Wallpaper : Gtk.Box { } solid_color = new SolidColorContainer (color); - solid_color.show_all (); } private void clean_wallpapers () { - foreach (var child in wallpaper_view.get_children ()) { - child.destroy (); + while (wallpaper_view.get_first_child () != null) { + wallpaper_view.remove (wallpaper_view.get_first_child ()); } solid_color = null; } - private void on_drag_data_received (Gtk.Widget widget, Gdk.DragContext ctx, int x, int y, Gtk.SelectionData sel, uint information, uint timestamp) { - if (sel.get_length () > 0) { - try { - var file = File.new_for_uri (sel.get_uris ()[0]); - var info = file.query_info (string.joinv (",", REQUIRED_FILE_ATTRS), 0); + private bool on_drag_data_received (Value val, double x, double y) { + var file_list = (Gdk.FileList) val; + foreach (var file in file_list.get_files ()) { + var local_uri = file.get_uri (); - if (!IOHelper.is_valid_file_type (info)) { - Gtk.drag_finish (ctx, false, false, timestamp); - return; - } - - if (WallpaperOperation.get_is_file_in_bg_dir (file)) { - Gtk.drag_finish (ctx, true, false, timestamp); - return; - } - - string local_uri = file.get_uri (); - var dest = WallpaperOperation.copy_for_library (file); - if (dest != null) { - local_uri = dest.get_uri (); - } - - add_wallpaper_from_file (file, local_uri); - - Gtk.drag_finish (ctx, true, false, timestamp); - } catch (Error e) { - warning (e.message); + var dest = WallpaperOperation.copy_for_library (file); + if (dest != null) { + local_uri = dest.get_uri (); } + + add_wallpaper_from_file (file, local_uri); } - Gtk.drag_finish (ctx, false, false, timestamp); - return; + return true; } private void add_wallpaper_from_file (GLib.File file, string uri) { @@ -429,9 +417,7 @@ public class PantheonShell.Wallpaper : Gtk.Box { var thumb_path = info.get_attribute_as_string (FileAttribute.THUMBNAIL_PATH); var thumb_valid = info.get_attribute_boolean (FileAttribute.THUMBNAIL_IS_VALID); var wallpaper = new WallpaperContainer (uri, thumb_path, thumb_valid); - wallpaper_view.add (wallpaper); - - wallpaper.show_all (); + wallpaper_view.append (wallpaper); wallpaper.trash.connect (() => { send_undo_toast (); @@ -500,29 +486,26 @@ public class PantheonShell.Wallpaper : Gtk.Box { } private void send_undo_toast () { - foreach (weak Gtk.Widget child in view_overlay.get_children ()) { - if (child is Granite.Widgets.Toast) { - child.destroy (); + unowned var child = view_overlay.get_first_child (); + while (child != null) { + if (child is Granite.Toast) { + ((Granite.Toast) child).withdraw (); } + child = child.get_next_sibling (); } if (wallpaper_for_removal != null) { confirm_removal (); } - var toast = new Granite.Widgets.Toast (_("Wallpaper Deleted")); + var toast = new Granite.Toast (_("Wallpaper Deleted")); toast.set_default_action (_("Undo")); - toast.show_all (); toast.default_action.connect (() => { undo_removal (); }); - toast.notify["child-revealed"].connect (() => { - if (!toast.child_revealed) { - confirm_removal (); - } - }); + toast.closed.connect (confirm_removal); view_overlay.add_overlay (toast); toast.send_notification (); @@ -545,7 +528,7 @@ public class PantheonShell.Wallpaper : Gtk.Box { } private void undo_removal () { - wallpaper_view.add (wallpaper_for_removal); + wallpaper_view.append (wallpaper_for_removal); wallpaper_for_removal = null; } } diff --git a/src/Widgets/WallpaperContainer.vala b/src/Widgets/WallpaperContainer.vala index 21849ed09..cc94c7575 100644 --- a/src/Widgets/WallpaperContainer.vala +++ b/src/Widgets/WallpaperContainer.vala @@ -26,7 +26,7 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { private Gtk.Box card_box; private Gtk.Revealer check_revealer; - private Granite.AsyncImage image; + private Gtk.Picture image; public string? thumb_path { get; construct set; } public bool thumb_valid { get; construct; } @@ -34,8 +34,6 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { public Gdk.Pixbuf thumb { get; set; } public uint64 creation_date = 0; - private Gtk.GestureMultiPress secondary_click_gesture; - private int scale; public bool checked { @@ -78,21 +76,20 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { scale = style_context.get_scale (); - image = new Granite.AsyncImage () { - halign = CENTER, - valign = CENTER - }; + image = new Gtk.Picture (); image.get_style_context ().set_scale (1); // We need an extra grid to not apply a scale == 1 to the "card" style. card_box = new Gtk.Box (VERTICAL, 0); - card_box.get_style_context ().add_class (Granite.STYLE_CLASS_CARD); - card_box.add (image); + card_box.add_css_class (Granite.STYLE_CLASS_CARD); + card_box.append (image); - var check = new Gtk.RadioButton (null) { + var check = new Gtk.CheckButton () { + active = true, halign = START, valign = START, - can_focus = false + can_focus = false, + can_target = false }; check_revealer = new Gtk.Revealer () { @@ -131,17 +128,25 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { var menu_model = new Menu (); menu_model.append (_("Remove"), "wallpaper.trash"); - var context_menu = new Gtk.Menu.from_model (menu_model) { - attach_widget = this + var context_menu = new Gtk.PopoverMenu.from_model (menu_model) { + halign = START, + has_arrow = false }; - context_menu.show_all (); + context_menu.set_parent (this); - secondary_click_gesture = new Gtk.GestureMultiPress (overlay) { + var secondary_click_gesture = new Gtk.GestureClick () { button = Gdk.BUTTON_SECONDARY }; - secondary_click_gesture.released.connect (() => { - context_menu.popup_at_pointer (null); + secondary_click_gesture.released.connect ((n_press, x, y) => { + secondary_click_gesture.set_state (CLAIMED); + context_menu.pointing_to = Gdk.Rectangle () { + x = (int) x, + y = (int) y + }; + context_menu.popup (); }); + + add_controller (secondary_click_gesture); } activate.connect (() => { @@ -156,7 +161,7 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { } } else { thumb = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, THUMB_WIDTH * scale, THUMB_HEIGHT * scale); - image.gicon = thumb; + image.paintable = Gdk.Texture.for_pixbuf (thumb); } } catch (Error e) { critical ("Failed to load wallpaper thumbnail: %s", e.message); @@ -183,11 +188,14 @@ public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild { } try { - yield image.set_from_file_async (File.new_for_path (thumb_path), THUMB_WIDTH, THUMB_HEIGHT, false); + var pixbuf = new Gdk.Pixbuf.from_file_at_scale (thumb_path, THUMB_WIDTH * scale, THUMB_HEIGHT * scale, false); + image.paintable = Gdk.Texture.for_pixbuf (pixbuf); } catch (Error e) { - warning (e.message); + critical ("Unable to set wallpaper thumbnail: %s", e.message); + return; } + if (uri != null) { string path = ""; GExiv2.Metadata metadata; diff --git a/src/meson.build b/src/meson.build index b4c7d2917..6b3e04054 100644 --- a/src/meson.build +++ b/src/meson.build @@ -13,7 +13,7 @@ plug_files = files( 'Widgets/WallpaperContainer.vala', ) -switchboard_dep = dependency('switchboard-2.0') +switchboard_dep = dependency('switchboard-3') switchboard_plugsdir = switchboard_dep.get_pkgconfig_variable('plugsdir', define_variable: ['libdir', libdir]) configuration = configuration_data()