diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 57fa85c7f..6f931c4f7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,7 +14,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
- apt install -y libgnome-desktop-3-dev libgranite-dev libgtk-3-dev libplank-dev libswitchboard-2.0-dev libgexiv2-dev meson valac
+ apt install -y libgranite-7-dev libgtk-4-dev libadwaita-1-dev libswitchboard-3-dev libgexiv2-dev meson valac
- name: Build
env:
DESTDIR: out
diff --git a/README.md b/README.md
index 6d37d1488..ccd580172 100644
--- a/README.md
+++ b/README.md
@@ -8,13 +8,11 @@
You'll need the following dependencies:
* gnome-settings-daemon-dev
-* libswitchboard-2.0-dev
-* libgnome-desktop-3-dev
+* libswitchboard-3-dev
* libgee-0.8-dev
* libgexiv2-dev
-* libgtk-3-dev (>= 3.22)
-* libplank-dev
-* libgranite-dev
+* libgtk-4-dev
+* libgranite-7-dev
* meson
* valac
diff --git a/data/Check.css b/data/Check.css
index 6c755c857..9f58c21a8 100644
--- a/data/Check.css
+++ b/data/Check.css
@@ -1,4 +1,23 @@
-radio {
+/*
+* Copyright 2022 elementary, Inc. (https://elementary.io)
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This program 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
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public
+* License along with this program; if not, write to the
+* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301 USA.
+*/
+
+check {
min-height: 20px;
min-width: 20px;
-gtk-icon-transform: scale(0.6);
diff --git a/data/RemoveButton.css b/data/RemoveButton.css
new file mode 100644
index 000000000..21cdbca12
--- /dev/null
+++ b/data/RemoveButton.css
@@ -0,0 +1,22 @@
+/*
+* Copyright 2022 elementary, Inc. (https://elementary.io)
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This program 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
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public
+* License along with this program; if not, write to the
+* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301 USA.
+*/
+
+.remove-button {
+ transition: background-color 0s;
+}
diff --git a/data/appearance-styles.css b/data/appearance-styles.css
new file mode 100644
index 000000000..6a2c0369e
--- /dev/null
+++ b/data/appearance-styles.css
@@ -0,0 +1,46 @@
+/*
+* Copyright 2020 elementary, Inc. (https://elementary.io)
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public
+* License as published by the Free Software Foundation; either
+* version 2 of the License, or (at your option) any later version.
+*
+* This program 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
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public
+* License along with this program; if not, write to the
+* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+* Boston, MA 02110-1301 USA.
+*/
+
+checkbutton .card {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 112px 80px, cover;
+ min-width: 112px;
+ min-height: 80px;
+}
+
+checkbutton .card.prefer-default {
+ background-image:
+ url("resource:///io/elementary/switchboard/plug/pantheon-shell/appearance-default.svg"),
+ linear-gradient(
+ to bottom,
+ alpha(@accent_color_300, 0.1),
+ alpha(@accent_color_500, 0.1)
+ );
+}
+
+checkbutton .card.prefer-dark {
+ background-image:
+ url("resource:///io/elementary/switchboard/plug/pantheon-shell/appearance-dark.svg"),
+ linear-gradient(
+ to bottom,
+ alpha(@accent_color_300, 0.1),
+ alpha(@accent_color_500, 0.1)
+ );
+}
diff --git a/data/icons.gresource.xml b/data/icons.gresource.xml
index dd1fd2811..12371cadb 100644
--- a/data/icons.gresource.xml
+++ b/data/icons.gresource.xml
@@ -10,6 +10,8 @@
appearance-default.svg
appearance-dark.svg
Check.css
+ RemoveButton.css
plug.css
+ appearance-styles.css
diff --git a/data/plug.css b/data/plug.css
index e5b343a48..2a82f61d8 100644
--- a/data/plug.css
+++ b/data/plug.css
@@ -26,8 +26,8 @@
),
linear-gradient(
to bottom,
- alpha (@accent_color_500, 0.1),
- alpha (@accent_color_500, 0.1)
+ alpha(@accent_color_500, 0.1),
+ alpha(@accent_color_500, 0.1)
);
background-repeat: no-repeat;
background-size: 48px 48px, cover;
@@ -58,29 +58,29 @@
}
.wallpaper-container .card {
- border-radius: 1px;
- border: none;
+ margin: 9px;
+ min-height: 128px;
}
.wallpaper-container .card:checked {
box-shadow:
- 0 0 0 4px alpha (@text_color, 0.2),
- 0 0 0 1px alpha (#000, 0.05),
- 0 3px 3px alpha (#000, 0.22);
+ 0 0 0 4px alpha(@text_color, 0.2),
+ 0 0 0 1px alpha(#000, 0.05),
+ 0 3px 3px alpha(#000, 0.22);
}
.wallpaper-container:focus .card {
box-shadow:
0 0 0 4px @accent_color,
- 0 0 0 1px alpha (#000, 0.05),
- 0 3px 3px alpha (#000, 0.22);
+ 0 0 0 1px alpha(#000, 0.05),
+ 0 3px 3px alpha(#000, 0.22);
}
radiobutton .card {
background-image:
linear-gradient(
to bottom,
- alpha (@accent_color_300, 0.1),
- alpha (@accent_color_500, 0.1)
+ alpha(@accent_color_300, 0.1),
+ alpha(@accent_color_500, 0.1)
);
}
diff --git a/meson.build b/meson.build
index 96bd07b43..64693d186 100644
--- a/meson.build
+++ b/meson.build
@@ -26,10 +26,10 @@ 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')
-plank_dep = dependency('plank', version: '>=0.10.9')
+
+granite_dep = dependency('granite-7')
+gtk_dep = dependency('gtk4')
+adw_dep = dependency ('libadwaita-1')
posix_dep = meson.get_compiler('vala').find_library('posix')
plug_resources = gnome.compile_resources(
diff --git a/po/POTFILES b/po/POTFILES
index c0b6b5220..e33f42161 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -1,4 +1,3 @@
-src/IOHelper.vala
src/Plug.vala
src/ThumbnailGenerator.vala
src/Translations.vala
@@ -7,6 +6,9 @@ src/Views/Dock.vala
src/Views/Multitasking.vala
src/Views/Text.vala
src/Views/Wallpaper.vala
+src/Widgets/GenericContainer.vala
+src/Widgets/ImageContainer.vala
src/Widgets/SolidColorContainer.vala
-src/Widgets/WallpaperContainer.vala
+src/Widgets/UriContainer.vala
+src/Widgets/XMLContainer.vala
set-wallpaper-contract/set-wallpaper.vala
diff --git a/set-wallpaper-contract/set-wallpaper.vala b/set-wallpaper-contract/set-wallpaper.vala
index 6aa24c911..57d5b85ae 100644
--- a/set-wallpaper-contract/set-wallpaper.vala
+++ b/set-wallpaper-contract/set-wallpaper.vala
@@ -173,7 +173,6 @@ namespace SetWallpaperContractor {
}
public static int main (string[] args) {
- Gtk.init (ref args);
AccountsServiceUser? accounts_service = null;
try {
@@ -238,20 +237,25 @@ namespace SetWallpaperContractor {
};
dialog.add_button (_("Create Slideshow"), Gtk.ResponseType.OK);
dialog.set_default_response (Gtk.ResponseType.OK);
- dialog.custom_bin.add (duration);
- dialog.show_all ();
+ dialog.custom_bin.append (duration);
+ dialog.present ();
delay_value_changed (duration, dialog.secondary_label);
duration.value_changed.connect (() => delay_value_changed (duration, dialog.secondary_label));
- if (dialog.run () == Gtk.ResponseType.OK) {
- dialog.destroy ();
+ int return_val = 1;
+ dialog.response.connect ((id) => {
+ if (id == Gtk.ResponseType.OK) {
+ dialog.destroy ();
- var path = folder.get_child (SLIDESHOW_FILENAME).get_path ();
- update_slideshow (path, files, delay_value);
- return 0;
- }
+ var path = folder.get_child (SLIDESHOW_FILENAME).get_path ();
+ update_slideshow (path, files, delay_value);
+ return_val = 0;
+ } else {
+ return_val = 1;
+ }
+ });
- return 1;
+ return return_val;
}
}
diff --git a/src/Config.vala.in b/src/Config.vala.in
index e29e292f6..995886c21 100644
--- a/src/Config.vala.in
+++ b/src/Config.vala.in
@@ -1,5 +1,4 @@
namespace Constants {
- public const string PLANKDATADIR = "@PLANKDATADIR@";
public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@";
public const string LOCALEDIR = "@LOCALEDIR@";
}
diff --git a/src/IOHelper.vala b/src/IOHelper.vala
deleted file mode 100644
index 6c33e4887..000000000
--- a/src/IOHelper.vala
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 2017-2018 elementary LLC.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- */
-public class PantheonShell.IOHelper : GLib.Object {
- private const string[] ACCEPTED_TYPES = {
- "image/jpeg",
- "image/png",
- "image/tiff",
- "image/svg+xml",
- "image/gif"
- };
-
- // Check if the filename has a picture file extension.
- public static bool is_valid_file_type (GLib.FileInfo file_info) {
- // Check for correct file type, don't try to load directories and such
- if (file_info.get_file_type () != GLib.FileType.REGULAR) {
- return false;
- }
-
- foreach (var type in ACCEPTED_TYPES) {
- if (GLib.ContentType.equals (file_info.get_content_type (), type)) {
- return true;
- }
- }
-
- return false;
- }
-}
diff --git a/src/Plug.vala b/src/Plug.vala
index 9216b8d86..5aad30dd1 100644
--- a/src/Plug.vala
+++ b/src/Plug.vala
@@ -20,7 +20,7 @@
public class PantheonShell.Plug : Switchboard.Plug {
private Gtk.Stack stack;
- private Gtk.Grid main_grid;
+ private Gtk.Box main_box;
private Wallpaper wallpaper_view;
@@ -38,7 +38,7 @@ public class PantheonShell.Plug : Switchboard.Plug {
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);
+ Gtk.StyleContext.add_provider_for_display (Gdk.Display.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
// DEPRECATED
settings.set ("desktop/wallpaper", "wallpaper");
@@ -53,10 +53,10 @@ public class PantheonShell.Plug : Switchboard.Plug {
}
public override Gtk.Widget get_widget () {
- if (main_grid == null) {
- main_grid = new Gtk.Grid ();
+ if (main_box == null) {
+ main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
- wallpaper_view = new Wallpaper (this);
+ wallpaper_view = new Wallpaper ();
var multitasking = new Multitasking ();
var appearance = new Appearance ();
@@ -74,22 +74,32 @@ 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 = Gtk.Align.CENTER,
+ margin_start = 24,
+ margin_end = 24,
+ margin_top = 24,
+ margin_bottom = 24
+ };
+
+ var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
+ var switcher_toggles = stack_switcher.observe_children ();
+ if (size_group.get_widgets ().length () == 0) {
+ for (var index = 0; index < switcher_toggles.get_n_items (); index++) {
+ size_group.add_widget ((Gtk.ToggleButton) switcher_toggles.get_item (index));
+ }
+ }
- main_grid.attach (stack_switcher, 0, 0, 1, 1);
- main_grid.attach (stack, 0, 1, 1, 1);
- main_grid.show_all ();
+ main_box.append (stack_switcher);
+ main_box.append (stack);
}
- return main_grid;
+ return main_box;
}
public override void shown () {
- wallpaper_view.update_wallpaper_folder ();
+ wallpaper_view.load_wallpapers ();
}
public override void hidden () {
diff --git a/src/Views/Appearance.vala b/src/Views/Appearance.vala
index 0b91e51f3..36e286045 100644
--- a/src/Views/Appearance.vala
+++ b/src/Views/Appearance.vala
@@ -18,7 +18,7 @@
*
*/
-public class PantheonShell.Appearance : Gtk.Box {
+public class PantheonShell.Appearance : Gtk.Widget {
private const string INTERFACE_SCHEMA = "org.gnome.desktop.interface";
private const string STYLESHEET_KEY = "gtk-theme";
private const string STYLESHEET_PREFIX = "io.elementary.stylesheet.";
@@ -58,105 +58,114 @@ public class PantheonShell.Appearance : Gtk.Box {
return "cocoa";
case GRAY:
return "slate";
+ case NO_PREFERENCE:
+ return "no preference";
}
return "auto";
}
}
+ static construct {
+ set_layout_manager_type (typeof (Gtk.BinLayout));
+ }
+
construct {
var dark_label = new Granite.HeaderLabel (_("Style"));
- var prefer_default_image = new Gtk.Image.from_resource ("/io/elementary/switchboard/plug/pantheon-shell/appearance-default.svg");
+ var css_provider = new Gtk.CssProvider ();
+ css_provider.load_from_resource ("/io/elementary/switchboard/plug/pantheon-shell/appearance-styles.css");
+
+ var prefer_default_radio = new Gtk.CheckButton () {
+ halign = Gtk.Align.START
+ };
+ prefer_default_radio.add_css_class ("image-button");
var prefer_default_card = new Gtk.Grid () {
- margin = 6,
+ margin_top = 6,
+ margin_bottom = 6,
+ margin_end = 6,
margin_start = 12
};
- prefer_default_card.add (prefer_default_image);
-
- unowned Gtk.StyleContext prefer_default_card_context = prefer_default_card.get_style_context ();
- prefer_default_card_context.add_class (Granite.STYLE_CLASS_CARD);
- prefer_default_card_context.add_class (Granite.STYLE_CLASS_ROUNDED);
+ 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");
+ prefer_default_card.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
var prefer_default_grid = new Gtk.Grid () {
row_spacing = 6
};
prefer_default_grid.attach (prefer_default_card, 0, 0);
prefer_default_grid.attach (new Gtk.Label (_("Default")), 0, 1);
+ prefer_default_grid.set_parent (prefer_default_radio);
- var prefer_default_radio = new Gtk.RadioButton (null) {
- halign = Gtk.Align.START
+ var prefer_dark_radio = new Gtk.CheckButton () {
+ halign = Gtk.Align.START,
+ hexpand = true,
+ group = prefer_default_radio
};
- prefer_default_radio.get_style_context ().add_class ("image-button");
- prefer_default_radio.add (prefer_default_grid);
-
- var prefer_dark_image = new Gtk.Image.from_resource ("/io/elementary/switchboard/plug/pantheon-shell/appearance-dark.svg");
+ prefer_dark_radio.add_css_class ("image-button");
var prefer_dark_card = new Gtk.Grid () {
- margin = 6,
+ margin_top = 6,
+ margin_bottom = 6,
+ margin_end = 6,
margin_start = 12
};
- prefer_dark_card.add (prefer_dark_image);
-
- unowned Gtk.StyleContext prefer_dark_card_context = prefer_dark_card.get_style_context ();
- prefer_dark_card_context.add_class (Granite.STYLE_CLASS_CARD);
- prefer_dark_card_context.add_class (Granite.STYLE_CLASS_ROUNDED);
+ 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");
+ prefer_dark_card.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
var prefer_dark_grid = new Gtk.Grid () {
row_spacing = 6
};
prefer_dark_grid.attach (prefer_dark_card, 0, 0);
prefer_dark_grid.attach (new Gtk.Label (_("Dark")), 0, 1);
-
- var prefer_dark_radio = new Gtk.RadioButton.from_widget (prefer_default_radio) {
- halign = Gtk.Align.START,
- hexpand = true
- };
- prefer_dark_radio.get_style_context ().add_class ("image-button");
- 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);
+ prefer_style_box.append (prefer_default_radio);
+ prefer_style_box.append (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);
+ dark_info.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);
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,
- _("Sunset to Sunrise")
- );
+ 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;
@@ -271,24 +280,23 @@ public class PantheonShell.Appearance : Gtk.Box {
pantheon_act.prefers_color_scheme = Granite.Settings.ColorScheme.DARK;
});
- /* 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_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_default_radio.add_controller (prefer_default_radio_controller);
- prefer_dark_radio.focus_in_event.connect (() => {
+ var prefer_dark_radio_controller = new Gtk.EventControllerFocus ();
+ 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;
});
+ prefer_dark_radio.add_controller (prefer_dark_radio_controller);
((GLib.DBusProxy) pantheon_act).g_properties_changed.connect ((changed, invalid) => {
var color_scheme = changed.lookup_value ("PrefersColorScheme", new VariantType ("i"));
@@ -359,44 +367,48 @@ public class PantheonShell.Appearance : Gtk.Box {
var auto_button = new PrefersAccentColorButton (pantheon_act, AccentColor.NO_PREFERENCE, blueberry_button);
auto_button.tooltip_text = _("Automatic based on wallpaper");
- var accent_grid = new Gtk.Grid ();
- accent_grid.column_spacing = 6;
- accent_grid.add (blueberry_button);
- accent_grid.add (mint_button);
- accent_grid.add (lime_button);
- accent_grid.add (banana_button);
- accent_grid.add (orange_button);
- accent_grid.add (strawberry_button);
- accent_grid.add (bubblegum_button);
- accent_grid.add (grape_button);
- accent_grid.add (cocoa_button);
- accent_grid.add (slate_button);
- accent_grid.add (auto_button);
+ var accent_grid = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
+ accent_grid.append (blueberry_button);
+ accent_grid.append (mint_button);
+ accent_grid.append (lime_button);
+ accent_grid.append (banana_button);
+ accent_grid.append (orange_button);
+ accent_grid.append (strawberry_button);
+ accent_grid.append (bubblegum_button);
+ accent_grid.append (grape_button);
+ accent_grid.append (cocoa_button);
+ accent_grid.append (slate_button);
+ accent_grid.append (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_info.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);
grid.attach (accent_label, 0, 7, 2);
grid.attach (accent_info, 0, 8, 2);
grid.attach (accent_grid, 0, 9, 2);
}
- var clamp = new Hdy.Clamp ();
- clamp.add (grid);
+ var clamp = new Adw.Clamp () {
+ child = grid
+ };
- add (clamp);
+ clamp.set_parent (this);
}
- private class PrefersAccentColorButton : Gtk.RadioButton {
+ ~Appearance () {
+ this.get_last_child ().unparent ();
+ }
+
+ 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,
@@ -411,9 +423,12 @@ public class PantheonShell.Appearance : Gtk.Box {
}
construct {
- unowned Gtk.StyleContext context = get_style_context ();
- context.add_class (Granite.STYLE_CLASS_COLOR_BUTTON);
- context.add_class (color.to_string ());
+ add_css_class (Granite.STYLE_CLASS_COLOR_BUTTON);
+ if (color == AccentColor.NO_PREFERENCE) {
+ add_css_class ("auto");
+ } else {
+ add_css_class (color.to_string ());
+ }
realize.connect (() => {
active = color == pantheon_act.prefers_accent_color;
diff --git a/src/Views/Dock.vala b/src/Views/Dock.vala
index f4d8885ae..d9effb47c 100644
--- a/src/Views/Dock.vala
+++ b/src/Views/Dock.vala
@@ -17,53 +17,88 @@
* Boston, MA 02110-1301 USA
*/
-public class PantheonShell.Dock : Gtk.Box {
+public class PantheonShell.Dock : Gtk.Widget {
private const string PANEL_SCHEMA = "io.elementary.desktop.wingpanel";
private const string TRANSLUCENCY_KEY = "use-transparency";
private Gtk.Label primary_monitor_label;
private Gtk.Switch primary_monitor;
private Gtk.Label monitor_label;
- private Gtk.ComboBoxText monitor;
- private Plank.DockPreferences dock_preferences;
+ private Gtk.ComboBoxText monitor_combo;
+ private Settings dock_preferences;
+
+ private enum PlankHideTypes {
+ NONE,
+ INTELLIGENT,
+ AUTO,
+ DODGE_MAXIMIZED,
+ WINDOW_DODGE,
+ DODGE_ACTIVE
+ }
+
+ static construct {
+ set_layout_manager_type (typeof (Gtk.BinLayout));
+ }
construct {
var dock_header = new Granite.HeaderLabel (_("Dock"));
- weak Gtk.IconTheme default_theme = Gtk.IconTheme.get_default ();
+ weak Gtk.IconTheme default_theme = Gtk.IconTheme.get_for_display (Gdk.Display.get_default ());
default_theme.add_resource_path ("/io/elementary/switchboard/plug/pantheon-shell");
- var icon_size_32 = new Gtk.RadioButton (null);
- icon_size_32.image = new Gtk.Image.from_icon_name ("application-default-icon-symbolic", Gtk.IconSize.DND);
- icon_size_32.tooltip_text = _("Small");
+ var icon_size_32 = new Gtk.CheckButton () {
+ tooltip_text = _("Small")
+ };
+ icon_size_32.add_css_class ("image-button");
+ var icon_size_32_image = new Gtk.Image.from_icon_name ("application-default-icon-symbolic") {
+ pixel_size = 32
+ };
+ icon_size_32_image.set_parent (icon_size_32);
- var icon_size_48 = new Gtk.RadioButton.from_widget (icon_size_32);
- icon_size_48.image = new Gtk.Image.from_icon_name ("application-default-icon-symbolic", Gtk.IconSize.DIALOG);
- icon_size_48.tooltip_text = _("Default");
+ var icon_size_48 = new Gtk.CheckButton () {
+ tooltip_text = _("Default")
+ };
+ icon_size_48.add_css_class ("image-button");
+ icon_size_48.group = icon_size_32;
+ var icon_size_48_image = new Gtk.Image.from_icon_name ("application-default-icon-symbolic") {
+ pixel_size = 48
+ };
+ icon_size_48_image.set_parent (icon_size_48);
- var image_64 = new Gtk.Image ();
- image_64.icon_name = "application-default-icon-symbolic";
- image_64.pixel_size = 64;
+ var icon_size_64 = new Gtk.CheckButton () {
+ tooltip_text = _("Large"),
+ group = icon_size_32
+ };
+ icon_size_64.add_css_class ("image-button");
+ var image_64 = new Gtk.Image () {
+ icon_name = "application-default-icon-symbolic",
+ pixel_size = 64
+ };
+ image_64.set_parent (icon_size_64);
- var icon_size_64 = new Gtk.RadioButton.from_widget (icon_size_32);
- icon_size_64.image = image_64;
- icon_size_64.tooltip_text = _("Large");
+ var icon_size_unsupported = new Gtk.CheckButton () {
+ group = icon_size_32
+ };
- var icon_size_unsupported = new Gtk.RadioButton.from_widget (icon_size_32);
+ var icon_size_grid = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 24);
+ icon_size_grid.append (icon_size_32);
+ icon_size_grid.append (icon_size_48);
+ icon_size_grid.append (icon_size_64);
- var icon_size_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 24);
- icon_size_box.add (icon_size_32);
- icon_size_box.add (icon_size_48);
- icon_size_box.add (icon_size_64);
+ var schema_id = "net.launchpad.plank.dock.settings";
+ var schema = GLib.SettingsSchemaSource.get_default ().lookup (schema_id, true);
+ if (schema == null) {
+ error ("GSettingsSchema '%s' not found", schema_id);
+ }
- Plank.Paths.initialize ("plank", Constants.PLANKDATADIR);
- dock_preferences = new Plank.DockPreferences ("dock1");
+ dock_preferences = new Settings.full (schema, null, "/net/launchpad/plank/docks/dock1/");
- var pressure_switch = new Gtk.Switch ();
- pressure_switch.halign = Gtk.Align.START;
- pressure_switch.valign = Gtk.Align.CENTER;
+ var pressure_switch = new Gtk.Switch () {
+ halign = Gtk.Align.START,
+ valign = Gtk.Align.CENTER
+ };
- dock_preferences.bind_property ("PressureReveal", pressure_switch, "active", GLib.BindingFlags.SYNC_CREATE | GLib.BindingFlags.BIDIRECTIONAL);
+ dock_preferences.bind ("pressure-reveal", pressure_switch, "active", GLib.SettingsBindFlags.DEFAULT);
var hide_mode = new Gtk.ComboBoxText () {
hexpand = true
@@ -73,83 +108,87 @@ public class PantheonShell.Dock : Gtk.Box {
hide_mode.append_text (_("Any window overlaps the dock"));
hide_mode.append_text (_("Not being used"));
- Plank.HideType[] hide_mode_ids = {Plank.HideType.DODGE_MAXIMIZED, Plank.HideType.INTELLIGENT, Plank.HideType.WINDOW_DODGE, Plank.HideType.AUTO};
+ PlankHideTypes[] hide_mode_ids = {PlankHideTypes.DODGE_MAXIMIZED, PlankHideTypes.INTELLIGENT, PlankHideTypes.WINDOW_DODGE, PlankHideTypes.AUTO};
- var hide_switch = new Gtk.Switch ();
- hide_switch.halign = Gtk.Align.START;
- hide_switch.valign = Gtk.Align.CENTER;
+ var hide_switch = new Gtk.Switch () {
+ halign = Gtk.Align.START,
+ valign = Gtk.Align.CENTER
+ };
- var hide_none = (dock_preferences.HideMode != Plank.HideType.NONE);
+ var hide_none = (dock_preferences.get_enum ("hide-mode") != PlankHideTypes.NONE);
hide_switch.active = hide_none;
if (hide_none) {
- for (int i = 0; i < hide_mode_ids.length; i++) {
- if (hide_mode_ids[i] == dock_preferences.HideMode)
+ for (var i = 0; i < hide_mode_ids.length; i++) {
+ if (hide_mode_ids[i] == dock_preferences.get_enum ("hide-mode")) {
hide_mode.active = i;
+ }
}
} else {
hide_mode.sensitive = false;
}
- hide_mode.changed.connect (() => {
- dock_preferences.HideMode = hide_mode_ids[hide_mode.active];
- });
-
hide_switch.bind_property ("active", pressure_switch, "sensitive", BindingFlags.SYNC_CREATE);
hide_switch.bind_property ("active", hide_mode, "sensitive", BindingFlags.DEFAULT);
+ hide_mode.changed.connect (() => {
+ dock_preferences.set_enum ("hide-mode", hide_mode_ids[hide_mode.active]);
+ });
+
hide_switch.notify["active"].connect (() => {
if (hide_switch.active) {
- dock_preferences.HideMode = hide_mode_ids[hide_mode.active];
+ dock_preferences.set_enum ("hide-mode", hide_mode_ids[hide_mode.active]);
} else {
- dock_preferences.HideMode = Plank.HideType.NONE;
+ dock_preferences.set_enum ("hide-mode", PlankHideTypes.NONE);
}
});
- monitor = new Gtk.ComboBoxText ();
+ monitor_combo = new Gtk.ComboBoxText ();
- primary_monitor_label = new Gtk.Label (_("Primary display:"));
- primary_monitor_label.halign = Gtk.Align.END;
- primary_monitor_label.no_show_all = true;
+ primary_monitor_label = new Gtk.Label (_("Primary display:")) {
+ halign = Gtk.Align.END
+ };
- monitor_label = new Gtk.Label (_("Display:"));
- monitor_label.no_show_all = true;
- monitor_label.halign = Gtk.Align.END;
+ monitor_label = new Gtk.Label (_("Display:")) {
+ halign = Gtk.Align.END
+ };
primary_monitor = new Gtk.Switch ();
- primary_monitor.no_show_all = true;
primary_monitor.notify["active"].connect (() => {
if (primary_monitor.active == true) {
- dock_preferences.Monitor = "";
+ dock_preferences.set_string ("monitor", "");
monitor_label.sensitive = false;
- monitor.sensitive = false;
+ monitor_combo.sensitive = false;
} else {
var plug_names = get_monitor_plug_names (get_display ());
- if (plug_names.length > monitor.active)
- dock_preferences.Monitor = plug_names[monitor.active];
+ if (plug_names.length > monitor_combo.active) {
+ dock_preferences.set_string ("monitor", plug_names[monitor_combo.active]);
+ }
+
monitor_label.sensitive = true;
- monitor.sensitive = true;
+ monitor_combo.sensitive = true;
}
});
- primary_monitor.active = (dock_preferences.Monitor == "");
+ primary_monitor.active = (dock_preferences.get_string ("monitor") == "");
- monitor.notify["active"].connect (() => {
- if (monitor.active >= 0 && primary_monitor.active == false) {
+ monitor_combo.notify["active"].connect (() => {
+ if (monitor_combo.active >= 0 && primary_monitor.active == false) {
var plug_names = get_monitor_plug_names (get_display ());
- if (plug_names.length > monitor.active)
- dock_preferences.Monitor = plug_names[monitor.active];
+ if (plug_names.length > monitor_combo.active)
+ dock_preferences.set_string ("monitor", plug_names[monitor_combo.active]);
}
});
- get_screen ().monitors_changed.connect (() => {check_for_screens ();});
-
- var icon_label = new Gtk.Label (_("Icon size:"));
- icon_label.halign = Gtk.Align.END;
- var hide_label = new Gtk.Label (_("Hide when:"));
- hide_label.halign = Gtk.Align.END;
+ var icon_label = new Gtk.Label (_("Icon size:")) {
+ halign = Gtk.Align.END
+ };
+ var hide_label = new Gtk.Label (_("Hide when:")) {
+ halign = Gtk.Align.END
+ };
var primary_monitor_grid = new Gtk.Grid ();
- primary_monitor_grid.add (primary_monitor);
- var pressure_label = new Gtk.Label (_("Pressure reveal:"));
- pressure_label.halign = Gtk.Align.END;
+ primary_monitor_grid.attach (primary_monitor, 0, 0);
+ var pressure_label = new Gtk.Label (_("Pressure reveal:")) {
+ halign = Gtk.Align.END
+ };
var panel_header = new Granite.HeaderLabel (_("Panel")) {
margin_top = 12
@@ -172,28 +211,35 @@ public class PantheonShell.Dock : Gtk.Box {
};
grid.attach (dock_header, 0, 0, 3);
grid.attach (icon_label, 0, 1);
- grid.attach (icon_size_box, 1, 1, 2);
+ grid.attach (icon_size_grid, 1, 1, 2);
grid.attach (hide_label, 0, 2);
grid.attach (hide_mode, 1, 2);
grid.attach (hide_switch, 2, 2);
grid.attach (primary_monitor_label, 0, 3);
grid.attach (primary_monitor_grid, 1, 3);
grid.attach (monitor_label, 0, 4);
- grid.attach (monitor, 1, 4);
+ grid.attach (monitor_combo, 1, 4);
grid.attach (pressure_label, 0, 5);
grid.attach (pressure_switch, 1, 5);
grid.attach (panel_header, 0, 6, 3);
grid.attach (translucency_label, 0, 7);
grid.attach (translucency_switch, 1, 7);
- var clamp = new Hdy.Clamp ();
- clamp.add (grid);
+ var clamp = new Adw.Clamp () {
+ child = grid
+ };
- add (clamp);
+ clamp.set_parent (this);
- check_for_screens ();
+ var display = get_display ();
+ var monitors_list = display.get_monitors ();
+ monitors_list.items_changed.connect (() => {
+ check_for_screens (monitors_list);
+ });
- switch (dock_preferences.IconSize) {
+ check_for_screens (monitors_list);
+
+ switch (dock_preferences.get_int ("icon-size")) {
case 32:
icon_size_32.active = true;
break;
@@ -209,94 +255,82 @@ public class PantheonShell.Dock : Gtk.Box {
}
icon_size_32.toggled.connect (() => {
- dock_preferences.IconSize = 32;
+ dock_preferences.set_int ("icon-size", 32);
});
icon_size_48.toggled.connect (() => {
- dock_preferences.IconSize = 48;
+ dock_preferences.set_int ("icon-size", 48);
});
icon_size_64.toggled.connect (() => {
- dock_preferences.IconSize = 64;
+ dock_preferences.set_int ("icon-size", 64);
});
var panel_settings = new GLib.Settings (PANEL_SCHEMA);
panel_settings.bind (TRANSLUCENCY_KEY, translucency_switch, "active", SettingsBindFlags.DEFAULT);
}
- private void check_for_screens () {
- int i = 0;
+ private void check_for_screens (ListModel monitors) {
+ int index = 0;
int primary_screen = 0;
- var default_display = get_display ();
- var default_screen = get_screen ();
- monitor.remove_all ();
- try {
- var screen = new Gnome.RRScreen (default_screen);
- for (i = 0; i < default_display.get_n_monitors () ; i++) {
- var monitor_plug_name = default_display.get_monitor (i).model;
-
- if (monitor_plug_name != null) {
- unowned Gnome.RROutput output = screen.get_output_by_name (monitor_plug_name);
- if (output != null && output.get_display_name () != null && output.get_display_name () != "") {
- monitor.append_text (output.get_display_name ());
- if (output.get_is_primary () == true) {
- primary_screen = i;
- }
- continue;
- }
- }
+ monitor_combo.remove_all ();
- monitor.append_text (_("Monitor %d").printf (i + 1) );
- }
- } catch (Error e) {
- critical (e.message);
- for (i = 0; i < default_display.get_n_monitors () ; i ++) {
- monitor.append_text (_("Display %d").printf (i + 1));
+ // TODO: get primary display
+
+ for (index = 0; index < monitors.get_n_items (); index++) {
+ var monitor = (Gdk.Monitor) monitors.get_item (index);
+ if (monitor.connector != null || monitor.connector != "") {
+ monitor_combo.append_text (monitor.connector);
+ } else {
+ monitor_combo.insert_text (index + 1, "Display %d");
}
}
- if (i <= 1) {
+ if (index <= 1) {
primary_monitor_label.hide ();
primary_monitor.hide ();
monitor_label.hide ();
- monitor.no_show_all = true;
- monitor.hide ();
+ monitor_combo.hide ();
} else {
- if (dock_preferences.Monitor != "") {
- monitor.active = find_monitor_number (get_display (), dock_preferences.Monitor);
+ if (dock_preferences.get_string ("monitor") != "") {
+ monitor_combo.active = find_monitor_number (get_display (), dock_preferences.get_string ("monitor"));
} else {
- monitor.active = primary_screen;
+ monitor_combo.active = primary_screen;
}
primary_monitor_label.show ();
primary_monitor.show ();
monitor_label.show ();
- monitor.show ();
+ monitor_combo.show ();
}
}
static string[] get_monitor_plug_names (Gdk.Display display) {
- int n_monitors = display.get_n_monitors ();
+ var monitors = display.get_monitors ();
+ var n_monitors = monitors.get_n_items ();
var result = new string[n_monitors];
for (int i = 0; i < n_monitors; i++) {
- result[i] = display.get_monitor (i).model;
+ result[i] = ((Gdk.Monitor) monitors.get_item (i)).model;
}
return result;
}
static int find_monitor_number (Gdk.Display display, string plug_name) {
- int n_monitors = display.get_n_monitors ();
+ var monitors = display.get_monitors ();
- for (int i = 0; i < n_monitors; i++) {
- var monitor = display.get_monitor (i);
+ for (int i = 0; i < monitors.get_n_items (); i++) {
+ var monitor = (Gdk.Monitor) monitors.get_item (i);
var name = monitor.get_model ();
if (plug_name == name)
return i;
}
- return display.get_n_monitors ();
+ return (int) monitors.get_n_items ();
}
+ ~Dock () {
+ this.get_last_child ().unparent ();
+ }
}
diff --git a/src/Views/Multitasking.vala b/src/Views/Multitasking.vala
index 230bdbf91..ca3ed9b51 100644
--- a/src/Views/Multitasking.vala
+++ b/src/Views/Multitasking.vala
@@ -19,11 +19,15 @@
* Authored by: Tom Beckmann
*/
-public class PantheonShell.Multitasking : Gtk.Box {
+public class PantheonShell.Multitasking : Gtk.Widget {
private GLib.Settings behavior_settings;
private const string ANIMATIONS_SCHEMA = "org.pantheon.desktop.gala.animations";
private const string ANIMATIONS_KEY = "enable-animations";
+ static construct {
+ set_layout_manager_type (typeof (Gtk.BinLayout));
+ }
+
construct {
var hotcorner_title = new Gtk.Label (_("When the pointer enters a display corner")) {
halign = Gtk.Align.START,
@@ -44,12 +48,12 @@ 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 (Gtk.Orientation.HORIZONTAL, 12) {
+ margin_top = 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 animations_label = new Gtk.Label (_("Window animations:")) {
halign = Gtk.Align.END
@@ -73,19 +77,20 @@ 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);
grid.attach (animations_label, 0, 8);
grid.attach (animations_switch, 1, 8);
- var clamp = new Hdy.Clamp ();
- clamp.add (grid);
+ var clamp = new Adw.Clamp () {
+ child = grid
+ };
- var scrolled = new Gtk.ScrolledWindow (null, null) {
- hscrollbar_policy = Gtk.PolicyType.NEVER
+ var scrolled = new Gtk.ScrolledWindow () {
+ hscrollbar_policy = Gtk.PolicyType.NEVER,
+ child = clamp
};
- scrolled.add (clamp);
- add (scrolled);
+ scrolled.set_parent (this);
var animations_settings = new GLib.Settings (ANIMATIONS_SCHEMA);
animations_settings.bind (ANIMATIONS_KEY, animations_switch, "active", SettingsBindFlags.DEFAULT);
@@ -95,6 +100,10 @@ public class PantheonShell.Multitasking : Gtk.Box {
behavior_settings.bind ("move-maximized-workspace", maximize_checkbutton, "active", GLib.SettingsBindFlags.DEFAULT);
}
+ ~Multitasking () {
+ this.get_last_child ().unparent ();
+ }
+
private class HotcornerControl : Gtk.Grid {
public string label { get; construct; }
public string position { get; construct; }
@@ -146,9 +155,9 @@ public class PantheonShell.Multitasking : Gtk.Box {
var command_revealer = new Gtk.Revealer () {
margin_top = 6,
- transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN
+ transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN,
+ child = command_entry
};
- command_revealer.add (command_entry);
margin_bottom = 12;
column_spacing = 12;
diff --git a/src/Views/Text.vala b/src/Views/Text.vala
index 8d088e6a0..08de31bf1 100644
--- a/src/Views/Text.vala
+++ b/src/Views/Text.vala
@@ -18,7 +18,7 @@
*
*/
-public class PantheonShell.Text : Gtk.Box {
+public class PantheonShell.Text : Gtk.Widget {
private const string DYSLEXIA_KEY = "dyslexia-friendly-support";
private const string FONT_KEY = "font-name";
private const string DOCUMENT_FONT_KEY = "document-font-name";
@@ -30,6 +30,10 @@ public class PantheonShell.Text : Gtk.Box {
private uint scale_timeout;
+ static construct {
+ set_layout_manager_type (typeof (Gtk.BinLayout));
+ }
+
construct {
var size_label = new Gtk.Label (_("Size:")) {
halign = Gtk.Align.END
@@ -62,7 +66,7 @@ public class PantheonShell.Text : Gtk.Box {
wrap = true,
xalign = 0
};
- dyslexia_font_description_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
+ dyslexia_font_description_label.get_style_context ().add_class (Granite.STYLE_CLASS_DIM_LABEL);
var grid = new Gtk.Grid () {
column_spacing = 12,
@@ -78,10 +82,11 @@ public class PantheonShell.Text : Gtk.Box {
grid.attach (dyslexia_font_switch, 1, 1);
grid.attach (dyslexia_font_description_label, 1, 2, 2);
- var clamp = new Hdy.Clamp ();
- clamp.add (grid);
+ var clamp = new Adw.Clamp () {
+ child = grid
+ };
- add (clamp);
+ clamp.set_parent (this);
var interface_settings = new Settings ("org.gnome.desktop.interface");
interface_settings.bind ("text-scaling-factor", size_adjustment, "value", SettingsBindFlags.GET);
@@ -118,4 +123,8 @@ public class PantheonShell.Text : Gtk.Box {
return Gdk.EVENT_PROPAGATE;
});
}
+
+ ~Text () {
+ this.get_last_child ().unparent ();
+ }
}
diff --git a/src/Views/Wallpaper.vala b/src/Views/Wallpaper.vala
index eac24b515..f87d51d95 100644
--- a/src/Views/Wallpaper.vala
+++ b/src/Views/Wallpaper.vala
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2015-2016 elementary LLC.
+/*
+ * Copyright 2015-2022 elementary, Inc. (https://elementary.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,12 +22,7 @@ interface PantheonShell.AccountsServiceUser : Object {
public abstract string background_file { owned get; set; }
}
-public class PantheonShell.Wallpaper : Gtk.Grid {
- public enum ColumnType {
- ICON,
- NAME
- }
-
+public class PantheonShell.Wallpaper : Gtk.Box {
private const string [] REQUIRED_FILE_ATTRS = {
FileAttribute.STANDARD_NAME,
FileAttribute.STANDARD_TYPE,
@@ -39,11 +34,18 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
FileAttribute.THUMBNAIL_IS_VALID
};
- public Switchboard.Plug plug { get; construct set; }
- private GLib.Settings settings;
+ private const string [] ALLOWED_MIMETYPES = {
+ "image/jpeg",
+ "image/png",
+ "image/tiff",
+ "image/svg+xml",
+ "image/gif"
+ };
+
+ private static GLib.Settings settings;
- //Instance of the AccountsServices-Interface for this user
- private AccountsServiceUser? accountsservice = null;
+ // Instance of the AccountsServices-Interface for this user
+ private static AccountsServiceUser? accountsservice = null;
private Gtk.ScrolledWindow wallpaper_scrolled_window;
private Gtk.FlowBox wallpaper_view;
@@ -51,271 +53,241 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
private Gtk.ComboBoxText combo;
private Gtk.ColorButton color_button;
- private WallpaperContainer active_wallpaper = null;
+ private GenericContainer? previous_wallpaper { get; set; default = null; }
+
private SolidColorContainer solid_color = null;
- private WallpaperContainer wallpaper_for_removal = null;
+ private UriContainer? wallpaper_for_removal = null;
private Cancellable last_cancellable;
- private string current_wallpaper_path;
- private bool prevent_update_mode = false; // When restoring the combo state, don't trigger the update.
- private bool finished; // Shows that we got or wallpapers together
-
- public Wallpaper (Switchboard.Plug _plug) {
- Object (plug: _plug);
- }
-
- construct {
+ static construct {
settings = new GLib.Settings ("org.gnome.desktop.background");
// DBus connection needed in update_wallpaper for
// passing the wallpaper-information to accountsservice.
- try {
- int uid = (int)Posix.getuid ();
- accountsservice = Bus.get_proxy_sync (BusType.SYSTEM,
- "org.freedesktop.Accounts",
- "/org/freedesktop/Accounts/User%i".printf (uid));
- } catch (Error e) {
+ try {
+ int uid = (int) Posix.getuid ();
+ accountsservice = Bus.get_proxy_sync (
+ BusType.SYSTEM,
+ "org.freedesktop.Accounts",
+ "/org/freedesktop/Accounts/User%i".printf (uid)
+ );
+ } catch (IOError e) {
warning (e.message);
}
+ }
+ construct {
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
- wallpaper_view = new Gtk.FlowBox ();
- wallpaper_view.activate_on_single_click = true;
- wallpaper_view.get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);
- wallpaper_view.homogeneous = true;
- wallpaper_view.selection_mode = Gtk.SelectionMode.SINGLE;
- wallpaper_view.child_activated.connect (update_checked_wallpaper);
- wallpaper_view.set_sort_func (wallpapers_sort_function);
+ var drop_target = new Gtk.DropTarget (typeof (Gdk.FileList), Gdk.DragAction.COPY);
- var color = 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.expand = true;
- wallpaper_scrolled_window.add (wallpaper_view);
-
- view_overlay = new Gtk.Overlay ();
- view_overlay.add (wallpaper_scrolled_window);
-
- var add_wallpaper_button = new Gtk.Button.with_label (_("Import Photo…"));
- add_wallpaper_button.margin = 12;
-
- combo = new Gtk.ComboBoxText ();
- combo.valign = Gtk.Align.CENTER;
+ wallpaper_view = new Gtk.FlowBox () {
+ activate_on_single_click = true,
+ selection_mode = Gtk.SelectionMode.SINGLE,
+ homogeneous = true,
+ row_spacing = 18,
+ column_spacing = 18
+ };
+ wallpaper_view.add_css_class (Granite.STYLE_CLASS_VIEW);
+ wallpaper_view.set_sort_func (wallpapers_sort_function);
+ wallpaper_view.add_controller (drop_target);
+
+ wallpaper_scrolled_window = new Gtk.ScrolledWindow () {
+ hexpand = true,
+ vexpand = true,
+ child = wallpaper_view
+ };
+
+ view_overlay = new Gtk.Overlay () {
+ child = wallpaper_scrolled_window
+ };
+
+ var import_button = new Gtk.Button.with_label (_("Import Photo…")) {
+ margin_start = 12,
+ margin_end = 12,
+ margin_top = 12,
+ margin_bottom = 12
+ };
+
+ combo = new Gtk.ComboBoxText () {
+ valign = Gtk.Align.CENTER
+ };
combo.append ("centered", _("Centered"));
combo.append ("zoom", _("Zoom"));
combo.append ("spanned", _("Spanned"));
- combo.changed.connect (update_mode);
- Gdk.RGBA rgba_color = {};
- if (!rgba_color.parse (color)) {
- rgba_color = { 1, 1, 1, 1 };
- }
-
- color_button = new Gtk.ColorButton ();
- color_button.margin = 12;
- color_button.margin_start = 0;
- color_button.rgba = rgba_color;
- color_button.color_set.connect (update_color);
+ color_button = new Gtk.ColorButton () {
+ margin_start = 6,
+ margin_end = 12,
+ margin_top = 12,
+ margin_bottom = 12
+ };
var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL);
- size_group.add_widget (add_wallpaper_button);
+ size_group.add_widget (import_button);
size_group.add_widget (combo);
size_group.add_widget (color_button);
- load_settings ();
-
var actionbar = new Gtk.ActionBar ();
- actionbar.get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR);
- actionbar.pack_start (add_wallpaper_button);
+ actionbar.add_css_class ("inline-toolbar");
+ actionbar.pack_start (import_button);
actionbar.pack_end (color_button);
actionbar.pack_end (combo);
- attach (separator, 0, 0, 1, 1);
- attach (view_overlay, 0, 1, 1, 1);
- attach (actionbar, 0, 2, 1, 1);
-
- add_wallpaper_button.clicked.connect (show_wallpaper_chooser);
- }
-
- private void show_wallpaper_chooser () {
- var filter = new Gtk.FileFilter ();
- filter.add_mime_type ("image/*");
+ orientation = Gtk.Orientation.VERTICAL;
+ append (separator);
+ append (view_overlay);
+ append (actionbar);
- var preview_area = new Granite.AsyncImage (false);
- preview_area.pixel_size = 256;
- preview_area.margin_end = 12;
+ load_settings ();
- var chooser = new Gtk.FileChooserNative (
- _("Import Photo"), null, Gtk.FileChooserAction.OPEN,
- _("Import"),
- _("Cancel")
- );
- chooser.filter = filter;
- chooser.select_multiple = true;
- chooser.set_preview_widget (preview_area);
-
- chooser.update_preview.connect (() => {
- string uri = chooser.get_preview_uri ();
-
- if (uri != null && uri.has_prefix ("file://") == true) {
- var file = GLib.File.new_for_uri (uri);
- preview_area.set_from_gicon_async.begin (new FileIcon (file), 256);
- preview_area.show ();
- } else {
- preview_area.hide ();
- }
+ // connect signals
+ drop_target.on_drop.connect (on_drag_data_received);
+ wallpaper_view.child_activated.connect (update_checked_wallpaper);
+ import_button.clicked.connect (show_wallpaper_chooser);
+ combo.changed.connect (() => {
+ settings.set_string ("picture-options", combo.get_active_id ());
+ });
+ color_button.color_set.connect (() => {
+ settings.set_string ("primary-color", color_button.rgba.to_string ());
+ wallpaper_view.child_activated (solid_color);
});
-
- 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);
- string local_uri = uri;
- var dest = copy_for_library (file);
- if (dest != null) {
- local_uri = dest.get_uri ();
- }
-
- add_wallpaper_from_file (file, local_uri);
- }
- }
-
- chooser.destroy ();
}
private void load_settings () {
// TODO: need to store the previous state, before changing to none
// when a solid color is selected, because the combobox doesn't know
// about it anymore. The previous state should be loaded instead here.
- string picture_options = settings.get_string ("picture-options");
+
+ var picture_options = settings.get_string ("picture-options");
if (picture_options == "none") {
- combo.set_sensitive (false);
+ combo.sensitive = false;
picture_options = "zoom";
}
- prevent_update_mode = true;
- combo.set_active_id (picture_options);
+ combo.active_id = picture_options;
- current_wallpaper_path = settings.get_string ("picture-uri");
+ // load color button
+ var color = settings.get_string ("primary-color");
+ Gdk.RGBA rgba_color = {};
+ if (!rgba_color.parse (color)) {
+ rgba_color = { 1, 1, 1, 1 };
+ }
+ color_button.rgba = rgba_color;
}
- /*
- * This integrates with LightDM
- */
- private void update_accountsservice () {
- var file = File.new_for_uri (current_wallpaper_path);
- string uri = file.get_uri ();
- string path = file.get_path ();
-
- bool path_has_prefix_bg_dir = false;
- foreach (unowned string directory in get_bg_directories ()) {
- if (path.has_prefix (directory)) {
- path_has_prefix_bg_dir = true;
- break;
- }
+ private void show_wallpaper_chooser () {
+ var filter = new Gtk.FileFilter ();
+ foreach (var type in ALLOWED_MIMETYPES) {
+ filter.add_mime_type (type);
}
- if (!path_has_prefix_bg_dir) {
- var local_file = copy_for_library (file);
- if (local_file != null) {
- uri = local_file.get_uri ();
- }
- }
+ var chooser = new Gtk.FileChooserNative (
+ _("Import Photo"),
+ (Gtk.Window) get_root (),
+ Gtk.FileChooserAction.OPEN,
+ _("Import"),
+ _("Cancel")
+ ) {
+ filter = filter,
+ select_multiple = true,
+ modal = true
+ };
+
+ chooser.response.connect ((id) => {
+ chooser.destroy ();
+ if (id == Gtk.ResponseType.ACCEPT) {
+ var files = chooser.get_files ();
+ for (var iter = 0; iter < files.get_n_items (); iter++) {
+ var file = (File) files.get_item (iter);
+ var local_uri = file.get_uri ();
+ var dest = copy_for_library (file);
+ if (dest != null) {
+ local_uri = dest.get_uri ();
+ }
- var greeter_file = copy_for_greeter (file);
- if (greeter_file != null) {
- path = greeter_file.get_path ();
- }
+ add_wallpaper_from_uri (local_uri);
+ }
+ }
+ });
- settings.set_string ("picture-uri", uri);
- accountsservice.background_file = path;
+ chooser.show ();
}
- private void update_checked_wallpaper (Gtk.FlowBox box, Gtk.FlowBoxChild child) {
- var children = (WallpaperContainer) wallpaper_view.get_selected_children ().data;
+ private void update_checked_wallpaper (Gtk.FlowBoxChild _selected_child) {
+ // We don't do gradient backgrounds, reset the key that might interfere
+ settings.reset ("color-shading-type");
- if (!(children is SolidColorContainer)) {
- current_wallpaper_path = children.uri;
- update_accountsservice ();
+ if (previous_wallpaper != null) {
+ previous_wallpaper.checked = false;
+ }
- if (active_wallpaper == solid_color) {
- combo.set_sensitive (true);
- settings.set_string ("picture-options", combo.get_active_id ());
- }
+ var selected_child = (GenericContainer) _selected_child;
+ previous_wallpaper = selected_child;
- } else {
- set_combo_disabled_if_necessary ();
- settings.set_string ("primary-color", solid_color.color);
- }
+ selected_child.checked = true;
- // We don't do gradient backgrounds, reset the key that might interfere
- settings.reset ("color-shading-type");
+ if (selected_child is SolidColorContainer) {
+ combo.sensitive = false;
- children.checked = true;
+ settings.set_string ("picture-options", "none");
+ } else if (selected_child is UriContainer) {
+ combo.sensitive = true;
- if (active_wallpaper != null && active_wallpaper != children) {
- active_wallpaper.checked = false;
+ settings.set_string ("picture-uri", ((UriContainer) selected_child).uri);
+ settings.set_string ("picture-options", combo.active_id);
+ update_accountsservice ();
}
-
- active_wallpaper = children;
}
- private void update_color () {
- if (finished) {
- set_combo_disabled_if_necessary ();
- create_solid_color_container (color_button.rgba.to_string ());
- wallpaper_view.add (solid_color);
- wallpaper_view.select_child (solid_color);
-
- if (active_wallpaper != null) {
- active_wallpaper.checked = false;
- }
+ /*
+ * This integrates with LightDM
+ */
+ private void update_accountsservice () {
+ var file = File.new_for_uri (settings.get_string ("picture-uri"));
+ var path = file.get_path ();
- active_wallpaper = solid_color;
- active_wallpaper.checked = true;
- settings.set_string ("primary-color", solid_color.color);
+ var greeter_file = copy_for_greeter (file);
+ if (greeter_file != null) {
+ path = greeter_file.get_path ();
}
+
+ accountsservice.background_file = path;
}
- private void update_mode () {
- if (!prevent_update_mode) {
- settings.set_string ("picture-options", combo.get_active_id ());
+ public void load_wallpapers () {
+ clean_wallpapers ();
+
+ load_wallpapers_from_folders.begin ((obj, res) => {
+ solid_color = new SolidColorContainer ();
+ wallpaper_view.append (solid_color);
- // Changing the mode, while a solid color is selected, change focus to the
- // wallpaper tile.
- if (active_wallpaper == solid_color) {
- active_wallpaper.checked = false;
-
- foreach (var child in wallpaper_view.get_children ()) {
- var container = (WallpaperContainer) child;
- if (container.uri == current_wallpaper_path) {
- container.checked = true;
- wallpaper_view.select_child (container);
- active_wallpaper = container;
- break;
+ // Select current wallpaper
+ if (settings.get_string ("picture-options") == "none") {
+ wallpaper_view.child_activated (solid_color);
+ } else {
+ var children = wallpaper_view.observe_children ();
+ for (var i = 0; i < children.get_n_items (); i++) {
+ var child = (GenericContainer) children.get_item (i);
+ if (child is UriContainer && settings.get_string ("picture-uri") == ((UriContainer) child).uri) {
+ wallpaper_view.child_activated (child);
}
}
}
- } else {
- prevent_update_mode = false;
- }
+ });
}
- private void set_combo_disabled_if_necessary () {
- if (active_wallpaper != solid_color) {
- combo.set_sensitive (false);
- settings.set_string ("picture-options", "none");
+ private void clean_wallpapers () {
+ var child = wallpaper_view.get_first_child ();
+ while (child != null) {
+ wallpaper_view.remove (child);
+ child.destroy ();
+ child = wallpaper_view.get_first_child ();
}
}
- public void update_wallpaper_folder () {
+ private async void load_wallpapers_from_folders () {
if (last_cancellable != null) {
last_cancellable.cancel ();
}
@@ -323,29 +295,26 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
var cancellable = new Cancellable ();
last_cancellable = cancellable;
- clean_wallpapers ();
-
foreach (unowned string directory in get_bg_directories ()) {
- load_wallpapers.begin (directory, cancellable);
+ yield load_wallpapers_from_folder (directory);
}
}
- private async void load_wallpapers (string basefolder, Cancellable cancellable, bool toplevel_folder = true) {
- if (cancellable.is_cancelled ()) {
+ private async void load_wallpapers_from_folder (string folder) {
+ if (last_cancellable.is_cancelled ()) {
return;
}
- var directory = File.new_for_path (basefolder);
-
+ var directory = File.new_for_path (folder);
try {
// Enumerator object that will let us read through the wallpapers asynchronously
var attrs = string.joinv (",", REQUIRED_FILE_ATTRS);
- var e = yield directory.enumerate_children_async (attrs, 0, Priority.DEFAULT);
- FileInfo file_info;
+ var e = yield directory.enumerate_children_async (attrs, FileQueryInfoFlags.NONE, Priority.DEFAULT);
+ FileInfo? file_info = null;
// Loop through and add each wallpaper in the batch
while ((file_info = e.next_file ()) != null) {
- if (cancellable.is_cancelled ()) {
+ if (last_cancellable.is_cancelled ()) {
ThumbnailGenerator.get_default ().dequeue_all ();
return;
}
@@ -357,70 +326,30 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
if (file_info.get_file_type () == FileType.DIRECTORY) {
// Spawn off another loader for the subdirectory
var subdir = directory.resolve_relative_path (file_info.get_name ());
- yield load_wallpapers (subdir.get_path (), cancellable, false);
- continue;
- } else if (!IOHelper.is_valid_file_type (file_info)) {
- // Skip non-picture files
+ yield load_wallpapers_from_folder (subdir.get_path ());
continue;
}
var file = directory.resolve_relative_path (file_info.get_name ());
- string uri = file.get_uri ();
+ var uri = file.get_uri ();
- add_wallpaper_from_file (file, uri);
+ add_wallpaper_from_uri (uri);
}
-
- if (toplevel_folder) {
- create_solid_color_container (color_button.rgba.to_string ());
- wallpaper_view.add (solid_color);
- finished = true;
-
- if (settings.get_string ("picture-options") == "none") {
- wallpaper_view.select_child (solid_color);
- solid_color.checked = true;
- active_wallpaper = solid_color;
- }
-
- if (active_wallpaper != null) {
- Gtk.Allocation alloc;
- active_wallpaper.get_allocation (out alloc);
- wallpaper_scrolled_window.get_vadjustment ().value = alloc.y;
- }
- }
- } catch (Error err) {
- if (!(err is IOError.NOT_FOUND)) {
- warning (err.message);
+ } catch (Error e) {
+ if (!(e is IOError.NOT_FOUND)) {
+ warning (e.message);
}
}
}
- private void create_solid_color_container (string color) {
- if (solid_color != null) {
- wallpaper_view.unselect_child (solid_color);
- wallpaper_view.remove (solid_color);
- solid_color.destroy ();
- }
-
- solid_color = new SolidColorContainer (color);
- solid_color.show_all ();
- }
-
- private void clean_wallpapers () {
- foreach (var child in wallpaper_view.get_children ()) {
- child.destroy ();
- }
-
- solid_color = null;
- }
-
private static string get_local_bg_directory () {
- return Path.build_filename (Environment.get_user_data_dir (), "backgrounds") + "/";
+ return Path.build_filename (Environment.get_user_data_dir (), "backgrounds");
}
private static string[] get_system_bg_directories () {
string[] directories = {};
foreach (unowned string data_dir in Environment.get_system_data_dirs ()) {
- var system_background_dir = Path.build_filename (data_dir, "backgrounds") + "/";
+ var system_background_dir = Path.build_filename (data_dir, "backgrounds");
if (FileUtils.test (system_background_dir, FileTest.EXISTS)) {
debug ("Found system background directory: %s", system_background_dir);
directories += system_background_dir;
@@ -450,10 +379,9 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
private static File? copy_for_library (File source) {
File? dest = null;
- string local_bg_directory = get_local_bg_directory ();
+ var local_bg_directory = get_local_bg_directory ();
try {
- File folder = File.new_for_path (local_bg_directory);
- folder.make_directory_with_parents ();
+ File.new_for_path (local_bg_directory).make_directory_with_parents ();
} catch (Error e) {
if (e is GLib.IOError.EXISTS) {
debug ("Local background directory already exists");
@@ -477,6 +405,7 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
private static File? copy_for_greeter (File source) {
File? dest = null;
+
try {
string greeter_data_dir = Path.build_filename (Environment.get_variable ("XDG_GREETER_DATA_DIR"), "wallpaper");
if (greeter_data_dir == "") {
@@ -506,85 +435,134 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
return dest;
}
- 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 ();
+ var dest = copy_for_library (file);
+ if (dest != null) {
+ local_uri = dest.get_uri ();
+ }
- if (!IOHelper.is_valid_file_type (info)) {
- Gtk.drag_finish (ctx, false, false, timestamp);
- return;
- }
+ add_wallpaper_from_uri (local_uri);
+ }
- string local_uri = file.get_uri ();
- var dest = copy_for_library (file);
- if (dest != null) {
- local_uri = dest.get_uri ();
- }
+ return true;
+ }
- add_wallpaper_from_file (file, local_uri);
+ private void add_wallpaper_from_uri (string uri) {
+ var file = File.new_for_uri (uri);
- Gtk.drag_finish (ctx, true, false, timestamp);
- } catch (Error e) {
- warning (e.message);
- }
+ string? mime_type;
+ try {
+ var file_info = file.query_info (FileAttribute.STANDARD_CONTENT_TYPE, FileQueryInfoFlags.NONE, null);
+ mime_type = file_info.get_content_type ().to_ascii ();
+ } catch (Error e) {
+ warning ("Could not get mime type for file \"%s\": %s", uri, e.message);
+ return;
}
- Gtk.drag_finish (ctx, false, false, timestamp);
- return;
- }
+ if (!(mime_type in ALLOWED_MIMETYPES)) {
+ warning ("File with not allowed mimetype: %s, %s", uri, mime_type);
+ return;
+ }
- private void add_wallpaper_from_file (GLib.File file, string uri) {
// don't load 'removed' wallpaper on plug reload
if (wallpaper_for_removal != null && wallpaper_for_removal.uri == uri) {
return;
}
- try {
- var info = file.query_info (string.joinv (",", REQUIRED_FILE_ATTRS), 0);
- 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);
+ UriContainer wallpaper;
+ if (mime_type.has_prefix ("image/")) {
+ wallpaper = new ImageContainer (uri);
- wallpaper.show_all ();
+ // TODO: https://github.com/elementary/switchboard-plug-pantheon-shell/issues/296
+ // } else if (mime_type == "application/xml") {
+ // wallpaper = new XMLContainer (uri);
+ // ...
- wallpaper.trash.connect (() => {
- send_undo_toast ();
- mark_for_removal (wallpaper);
- });
+ } else {
+ // Fixes Use of possibly unassigned local variable `wallpaper'
+ // However, the file should never get here since it's been filtered before
+ warning ("Filtered file %s of unknown type %s", uri, mime_type);
+ return;
+ }
- // Select the wallpaper if it is the current wallpaper
- if (current_wallpaper_path.has_suffix (uri) && settings.get_string ("picture-options") != "none") {
- this.wallpaper_view.select_child (wallpaper);
- // Set the widget activated without activating it
- wallpaper.checked = true;
- active_wallpaper = wallpaper;
+ wallpaper_view.append (wallpaper);
+
+ wallpaper.trash.connect (() => {
+ send_undo_toast ();
+ mark_for_removal (wallpaper);
+ });
+ }
+
+ private void send_undo_toast () {
+ var children = view_overlay.observe_children ();
+ for (int i = 0; i < children.get_n_items (); i++) {
+ var child = (Gtk.Widget) children.get_item (i);
+ if (child is Granite.Toast) {
+ view_overlay.remove_overlay (child);
+ child.destroy ();
}
- } catch (Error e) {
- critical ("Unable to add wallpaper: %s", e.message);
}
- wallpaper_view.invalidate_sort ();
+ if (wallpaper_for_removal != null) {
+ confirm_removal ();
+ }
+
+ var toast = new Granite.Toast (_("Wallpaper Deleted"));
+ toast.set_default_action (_("Undo"));
+
+ toast.default_action.connect (() => {
+ undo_removal ();
+ });
+
+ var toast_revealer = (Gtk.Revealer) toast.get_first_child ();
+ toast_revealer.notify["reveal-child"].connect (() => {
+ // give some time for undo action to emit
+ Idle.add (() => {
+ if (!toast_revealer.reveal_child && wallpaper_for_removal != null) {
+ confirm_removal ();
+ }
+ return Source.REMOVE;
+ });
+ });
+
+ view_overlay.add_overlay (toast);
+ view_overlay.set_measure_overlay (toast, true);
+ toast.send_notification ();
}
- public void cancel_thumbnail_generation () {
- if (last_cancellable != null) {
- last_cancellable.cancel ();
- }
+ private void mark_for_removal (UriContainer wallpaper) {
+ wallpaper_for_removal = wallpaper;
+ wallpaper.hide ();
+ }
+
+ private void confirm_removal () {
+ var wallpaper_file = File.new_for_uri (wallpaper_for_removal.uri);
+ wallpaper_file.trash_async.begin ();
+ wallpaper_for_removal.destroy ();
+ wallpaper_for_removal = null;
+ }
+
+ private void undo_removal () {
+ wallpaper_for_removal.show ();
+ wallpaper_for_removal = null;
}
private int wallpapers_sort_function (Gtk.FlowBoxChild _child1, Gtk.FlowBoxChild _child2) {
- var child1 = (WallpaperContainer) _child1;
- var child2 = (WallpaperContainer) _child2;
- var uri1 = child1.uri;
- var uri2 = child2.uri;
+ var child1 = (GenericContainer) _child1;
+ var child2 = (GenericContainer) _child2;
- if (uri1 == null || uri2 == null) {
- return 0;
+ if (child1 is SolidColorContainer) {
+ return 1;
+ } else if (child2 is SolidColorContainer) {
+ return -1;
}
+ var uri1 = ((UriContainer) child1).uri;
+ var uri2 = ((UriContainer) child2).uri;
+
var uri1_is_system = false;
var uri2_is_system = false;
foreach (var bg_dir in get_system_bg_directories ()) {
@@ -600,8 +578,8 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
return -1;
}
- var child1_date = child1.creation_date;
- var child2_date = child2.creation_date;
+ var child1_date = ((UriContainer) child1).creation_date;
+ var child2_date = ((UriContainer) child2).creation_date;
// sort by filename if creation dates are equal
if (child1_date == child2_date) {
@@ -616,49 +594,9 @@ public class PantheonShell.Wallpaper : Gtk.Grid {
}
}
- private void send_undo_toast () {
- foreach (weak Gtk.Widget child in view_overlay.get_children ()) {
- if (child is Granite.Widgets.Toast) {
- child.destroy ();
- }
- }
-
- if (wallpaper_for_removal != null) {
- confirm_removal ();
+ public void cancel_thumbnail_generation () {
+ if (last_cancellable != null) {
+ last_cancellable.cancel ();
}
-
- var toast = new Granite.Widgets.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 && wallpaper_for_removal != null) {
- confirm_removal ();
- }
- });
-
- view_overlay.add_overlay (toast);
- toast.send_notification ();
- }
-
- private void mark_for_removal (WallpaperContainer wallpaper) {
- wallpaper_view.remove (wallpaper);
- wallpaper_for_removal = wallpaper;
- }
-
- private void confirm_removal () {
- var wallpaper_file = File.new_for_uri (wallpaper_for_removal.uri);
- wallpaper_file.trash_async.begin ();
- wallpaper_for_removal.destroy ();
- wallpaper_for_removal = null;
- }
-
- private void undo_removal () {
- wallpaper_view.add (wallpaper_for_removal);
- wallpaper_for_removal = null;
}
}
diff --git a/src/Widgets/GenericContainer.vala b/src/Widgets/GenericContainer.vala
new file mode 100644
index 000000000..b81a5c724
--- /dev/null
+++ b/src/Widgets/GenericContainer.vala
@@ -0,0 +1,139 @@
+/*-
+ * Copyright 2022 elementary, Inc. (https://elementary.io)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authored by: Erasmo Marín
+ *
+ */
+
+public class PantheonShell.GenericContainer : Gtk.FlowBoxChild {
+ public signal void trash ();
+
+ protected const int THUMB_WIDTH = 162;
+ protected const int THUMB_HEIGHT = 100;
+
+ private static Gtk.CssProvider check_css_provider;
+ private static Gtk.CssProvider move_to_trash_provider;
+ private static Gtk.CheckButton check_group; // used for turning CheckButtons into RadioButtons
+
+ protected Gtk.Box card_box;
+ protected Gtk.Picture image;
+ private Gtk.Revealer check_revealer;
+ protected Gtk.Overlay overlay;
+ protected Gtk.Box context_menu_box;
+ protected Gtk.Popover context_menu;
+ protected Gtk.Button move_to_trash_button;
+
+ public bool checked {
+ get {
+ return check_revealer.reveal_child;
+ }
+ set {
+ check_revealer.reveal_child = value;
+ if (value) {
+ card_box.set_state_flags (Gtk.StateFlags.CHECKED, false);
+ } else {
+ card_box.unset_state_flags (Gtk.StateFlags.CHECKED);
+ }
+ }
+ }
+
+ static construct {
+ check_css_provider = new Gtk.CssProvider ();
+ check_css_provider.load_from_resource ("/io/elementary/switchboard/plug/pantheon-shell/Check.css");
+
+ move_to_trash_provider = new Gtk.CssProvider ();
+ move_to_trash_provider.load_from_resource ("/io/elementary/switchboard/plug/pantheon-shell/RemoveButton.css");
+
+ check_group = new Gtk.CheckButton ();
+ }
+
+ construct {
+ image = new Gtk.Picture () {
+ can_shrink = true,
+ keep_aspect_ratio = false
+ };
+
+ card_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
+ card_box.append (image);
+ card_box.add_css_class (Granite.STYLE_CLASS_CARD);
+ card_box.add_css_class (Granite.STYLE_CLASS_ROUNDED);
+
+ var check = new Gtk.CheckButton () {
+ halign = Gtk.Align.START,
+ valign = Gtk.Align.START,
+ focusable = false,
+ active = true,
+ group = check_group
+ };
+ check.get_style_context ().add_provider (check_css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
+
+ check_revealer = new Gtk.Revealer () {
+ transition_type = Gtk.RevealerTransitionType.CROSSFADE,
+ child = check
+ };
+
+ overlay = new Gtk.Overlay () {
+ child = card_box,
+ halign = Gtk.Align.CENTER
+ };
+ overlay.add_overlay (check_revealer);
+
+ var overlay_event_controller = new Gtk.GestureClick () {
+ button = Gdk.BUTTON_SECONDARY
+ };
+ overlay.add_controller (overlay_event_controller);
+
+ add_css_class ("wallpaper-container");
+ child = overlay;
+
+ // Context menu
+ move_to_trash_button = new Gtk.Button () {
+ child = new Granite.AccelLabel (_("Remove")),
+ sensitive = false
+ };
+ move_to_trash_button.get_style_context ().add_provider (move_to_trash_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ move_to_trash_button.add_css_class (Granite.STYLE_CLASS_MENUITEM);
+ // remove background-color transition so it looks identical to menu item
+ move_to_trash_button.add_css_class ("remove-button");
+
+ context_menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) {
+ margin_top = 3,
+ margin_bottom = 3
+ };
+ context_menu_box.append (move_to_trash_button);
+
+ context_menu = new Gtk.Popover () {
+ child = context_menu_box,
+ autohide = true
+ };
+ context_menu.set_parent (overlay);
+
+ // signals
+ check.notify["active"].connect (() => {
+ check.active = true;
+ });
+
+ overlay_event_controller.pressed.connect ((n_press, x, y) => {
+ var rect = Gdk.Rectangle ();
+ rect = {(int) x, (int) y, 1, 1};
+
+ context_menu.pointing_to = rect;
+ context_menu.popup ();
+ });
+
+ move_to_trash_button.clicked.connect (() => trash ());
+ }
+}
diff --git a/src/Widgets/ImageContainer.vala b/src/Widgets/ImageContainer.vala
new file mode 100644
index 000000000..5c87df97a
--- /dev/null
+++ b/src/Widgets/ImageContainer.vala
@@ -0,0 +1,103 @@
+/*-
+ * Copyright 2015-2022 elementary, Inc. (https://elementary.io)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Authored by: Erasmo Marín
+ *
+ */
+
+public class PantheonShell.ImageContainer : UriContainer {
+ private bool thumb_valid { get; set; default = false; }
+ private string? thumb_path { get; set; default = null; }
+
+ public ImageContainer (string uri) {
+ Object (uri: uri);
+ }
+
+ construct {
+ // load file info
+ var file = File.new_for_uri (uri);
+ try {
+ var info = file.query_info ("*", FileQueryInfoFlags.NONE);
+ load_thumb_info (info);
+ move_to_trash_button.sensitive = info.get_attribute_boolean (GLib.FileAttribute.ACCESS_CAN_DELETE);
+ } catch (Error e) {
+ critical (e.message);
+ }
+
+ // load thumb
+ if (thumb_valid && thumb_path != null) {
+ update_thumb.begin ();
+ } else {
+ generate_and_load_thumb ();
+ }
+ }
+
+ private void load_thumb_info (FileInfo info) {
+ thumb_valid = info.get_attribute_boolean (FileAttribute.THUMBNAIL_IS_VALID);
+ thumb_path = info.get_attribute_as_string (FileAttribute.THUMBNAIL_PATH);
+ }
+
+ private async void update_thumb () {
+ if (!thumb_valid || thumb_path == null) {
+ return;
+ }
+
+ image.set_filename (thumb_path);
+
+ load_artist_tooltip ();
+ }
+
+ private void generate_and_load_thumb () {
+ var scale = get_style_context ().get_scale ();
+ ThumbnailGenerator.get_default ().get_thumbnail (uri, THUMB_WIDTH * scale, () => {
+ try {
+ var file = File.new_for_uri (uri);
+ var info = file.query_info (
+ string.join (",", FileAttribute.THUMBNAIL_PATH, FileAttribute.THUMBNAIL_IS_VALID),
+ FileQueryInfoFlags.NONE
+ );
+ load_thumb_info (info);
+ update_thumb.begin ();
+ } catch (Error e) {
+ warning ("Error loading thumbnail for \"%s\": %s", uri, e.message);
+ }
+ });
+ }
+
+ private void load_artist_tooltip () {
+ var metadata = new GExiv2.Metadata ();
+ try {
+ var path = Filename.from_uri (uri);
+ metadata.open_path (path);
+ } catch (Error e) {
+ warning ("Error parsing exif metadata of \"%s\": %s", uri, e.message);
+ return;
+ }
+
+ if (metadata.has_exif ()) {
+ string? artist_name = null;
+ try {
+ artist_name = metadata.try_get_tag_string ("Exif.Image.Artist");
+ } catch (Error e) {
+ warning (e.message);
+ }
+
+ if (artist_name != null) {
+ set_tooltip_text (_("Artist: %s").printf (artist_name));
+ }
+ }
+ }
+}
diff --git a/src/Widgets/SolidColorContainer.vala b/src/Widgets/SolidColorContainer.vala
index ba14817be..8f62884ca 100644
--- a/src/Widgets/SolidColorContainer.vala
+++ b/src/Widgets/SolidColorContainer.vala
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 elementary LLC.
+ * Copyright 2015-2022 elementary, Inc. (https://elementary.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,27 +18,28 @@
*
*/
-public class PantheonShell.SolidColorContainer : WallpaperContainer {
- public string color { get; construct; }
- public Gdk.RGBA rgba {
- get {
- Gdk.RGBA rgba = {};
- rgba.parse (color);
+public class PantheonShell.SolidColorContainer : GenericContainer {
+ private static GLib.Settings settings;
- return rgba;
- }
+ static construct {
+ settings = new GLib.Settings ("org.gnome.desktop.background");
}
- public SolidColorContainer (string color_value) {
- Object (color: color_value);
+ construct {
+ fill_thumb ();
+ settings.changed["primary-color"].connect (fill_thumb);
}
- construct {
+ private void fill_thumb () {
+ Gdk.RGBA rgba = {};
+ rgba.parse (settings.get_string ("primary-color"));
+ var thumb = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, THUMB_WIDTH, THUMB_HEIGHT);
thumb.fill (rgba_to_pixel (rgba));
+ image.set_pixbuf (thumb);
}
// Borrowed from
- // https://github.com/GNOME/california/blob/master/src/util/util-gfx.vala
+ // https://gitlab.gnome.org/Archive/california/-/blob/master/src/util/util-gfx.vala
private static uint32 rgba_to_pixel (Gdk.RGBA rgba) {
return (uint32) fp_to_uint8 (rgba.red) << 24
| (uint32) fp_to_uint8 (rgba.green) << 16
diff --git a/src/Widgets/UriContainer.vala b/src/Widgets/UriContainer.vala
new file mode 100644
index 000000000..bef45e6ee
--- /dev/null
+++ b/src/Widgets/UriContainer.vala
@@ -0,0 +1,37 @@
+/*-
+ * Copyright 2022 elementary, Inc. (https://elementary.io)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+public class PantheonShell.UriContainer : GenericContainer {
+ public string uri { get; construct; }
+
+ public uint64 creation_date { get; set; default = 0; } // in unix time
+
+ public UriContainer (string uri) {
+ Object (uri: uri);
+ }
+
+ construct {
+ var file = File.new_for_uri (uri);
+ try {
+ var info = file.query_info (FileAttribute.TIME_CREATED, FileQueryInfoFlags.NONE);
+ creation_date = info.get_attribute_uint64 (GLib.FileAttribute.TIME_CREATED);
+ } catch (Error e) {
+ critical (e.message);
+ }
+ }
+}
diff --git a/src/Widgets/WallpaperContainer.vala b/src/Widgets/WallpaperContainer.vala
deleted file mode 100644
index ee7d6192c..000000000
--- a/src/Widgets/WallpaperContainer.vala
+++ /dev/null
@@ -1,217 +0,0 @@
-/*-
- * Copyright 2015-2022 elementary, Inc. (https://elementary.io)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program 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 General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * Authored by: Erasmo Marín
- *
- */
-
-public class PantheonShell.WallpaperContainer : Gtk.FlowBoxChild {
- public signal void trash ();
-
- private const int THUMB_WIDTH = 162;
- private const int THUMB_HEIGHT = 100;
-
- private Gtk.Grid card_box;
- private Gtk.Menu context_menu;
- private Gtk.Revealer check_revealer;
- private Granite.AsyncImage image;
-
- public string? thumb_path { get; construct set; }
- public bool thumb_valid { get; construct; }
- public string uri { get; construct; }
- public Gdk.Pixbuf thumb { get; set; }
- public uint64 creation_date = 0;
-
- private int scale;
-
- public bool checked {
- get {
- return Gtk.StateFlags.CHECKED in get_state_flags ();
- } set {
- if (value) {
- card_box.set_state_flags (Gtk.StateFlags.CHECKED, false);
- check_revealer.reveal_child = true;
- } else {
- card_box.unset_state_flags (Gtk.StateFlags.CHECKED);
- check_revealer.reveal_child = false;
- }
-
- queue_draw ();
- }
- }
-
- public bool selected {
- get {
- return Gtk.StateFlags.SELECTED in get_state_flags ();
- } set {
- if (value) {
- set_state_flags (Gtk.StateFlags.SELECTED, false);
- } else {
- unset_state_flags (Gtk.StateFlags.SELECTED);
- }
-
- queue_draw ();
- }
- }
-
- public WallpaperContainer (string uri, string? thumb_path, bool thumb_valid) {
- Object (uri: uri, thumb_path: thumb_path, thumb_valid: thumb_valid);
- }
-
- construct {
- var style_context = get_style_context ();
- style_context.add_class ("wallpaper-container");
-
- scale = style_context.get_scale ();
-
- height_request = THUMB_HEIGHT + 18;
- width_request = THUMB_WIDTH + 18;
-
- image = new Granite.AsyncImage ();
- image.halign = Gtk.Align.CENTER;
- image.valign = Gtk.Align.CENTER;
- 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.Grid ();
- card_box.get_style_context ().add_class ("card");
- card_box.add (image);
- card_box.margin = 9;
-
- var check_provider = new Gtk.CssProvider ();
- check_provider.load_from_resource ("/io/elementary/switchboard/plug/pantheon-shell/Check.css");
-
- var check = new Gtk.RadioButton (null) {
- halign = Gtk.Align.START,
- valign = Gtk.Align.START,
- can_focus = false
- };
- check.get_style_context ().add_provider (check_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER);
-
- check_revealer = new Gtk.Revealer ();
- check_revealer.transition_type = Gtk.RevealerTransitionType.CROSSFADE;
- check_revealer.add (check);
-
- var overlay = new Gtk.Overlay ();
- overlay.add (card_box);
- overlay.add_overlay (check_revealer);
-
- var event_box = new Gtk.EventBox ();
- event_box.add (overlay);
-
- halign = Gtk.Align.CENTER;
- valign = Gtk.Align.CENTER;
- margin = 6;
- add (event_box);
-
- if (uri != null) {
- var move_to_trash = new Gtk.MenuItem.with_label (_("Remove"));
- move_to_trash.activate.connect (() => trash ());
-
- var file = File.new_for_uri (uri);
- try {
- var info = file.query_info ("*", FileQueryInfoFlags.NONE);
- creation_date = info.get_attribute_uint64 (GLib.FileAttribute.TIME_CREATED);
- move_to_trash.sensitive = info.get_attribute_boolean (GLib.FileAttribute.ACCESS_CAN_DELETE);
- } catch (Error e) {
- critical (e.message);
- }
-
- context_menu = new Gtk.Menu ();
- context_menu.append (move_to_trash);
- context_menu.show_all ();
- }
-
- activate.connect (() => {
- checked = true;
- });
-
- event_box.button_press_event.connect (show_context_menu);
-
- try {
- if (uri != null) {
- if (thumb_path != null && thumb_valid) {
- update_thumb.begin ();
- } else {
- generate_and_load_thumb ();
- }
- } else {
- thumb = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, THUMB_WIDTH * scale, THUMB_HEIGHT * scale);
- image.gicon = thumb;
- }
- } catch (Error e) {
- critical ("Failed to load wallpaper thumbnail: %s", e.message);
- return;
- }
- }
-
- private void generate_and_load_thumb () {
- ThumbnailGenerator.get_default ().get_thumbnail (uri, THUMB_WIDTH * scale, () => {
- try {
- var file = File.new_for_uri (uri);
- var info = file.query_info (FileAttribute.THUMBNAIL_PATH + "," + FileAttribute.THUMBNAIL_IS_VALID, 0);
- thumb_path = info.get_attribute_as_string (FileAttribute.THUMBNAIL_PATH);
- update_thumb.begin ();
- } catch (Error e) {
- warning ("Error loading thumbnail for '%s': %s", uri, e.message);
- }
- });
- }
-
- private void load_artist_tooltip () {
- if (uri != null) {
- string path = "";
- GExiv2.Metadata metadata;
- try {
- path = Filename.from_uri (uri);
- metadata = new GExiv2.Metadata ();
- metadata.open_path (path);
- } catch (Error e) {
- warning ("Error parsing exif metadata of \"%s\": %s", path, e.message);
- return;
- }
-
- if (metadata.has_exif ()) {
- var artist_name = metadata.get_tag_string ("Exif.Image.Artist");
- if (artist_name != null) {
- set_tooltip_text (_("Artist: %s").printf (artist_name));
- }
- }
- }
- }
-
- private bool show_context_menu (Gtk.Widget sender, Gdk.EventButton evt) {
- if (evt.type == Gdk.EventType.BUTTON_PRESS && evt.button == 3) {
- context_menu.popup_at_pointer (null);
- return Gdk.EVENT_STOP;
- }
- return Gdk.EVENT_PROPAGATE;
- }
-
- private async void update_thumb () {
- if (thumb_path == null) {
- return;
- }
-
- try {
- yield image.set_from_file_async (File.new_for_path (thumb_path), THUMB_WIDTH, THUMB_HEIGHT, false);
- } catch (Error e) {
- warning (e.message);
- }
-
- load_artist_tooltip ();
- }
-}
diff --git a/src/Widgets/XMLContainer.vala b/src/Widgets/XMLContainer.vala
new file mode 100644
index 000000000..9fffef156
--- /dev/null
+++ b/src/Widgets/XMLContainer.vala
@@ -0,0 +1,32 @@
+/*-
+ * Copyright 2022 elementary, Inc. (https://elementary.io)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+public class PantheonShell.XMLContainer : UriContainer {
+ public XMLContainer (string uri) {
+ Object (uri: uri);
+ }
+
+ construct {
+ // FIXME: https://github.com/elementary/switchboard-plug-pantheon-shell/issues/296
+ // parse_file ();
+ // create_collage ();
+ // create_overlay_icon ();
+ // add_tooltip ();
+ // ...
+ }
+}
diff --git a/src/meson.build b/src/meson.build
index 285bcd3af..26e5055ec 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,4 @@
plug_files = files(
- 'IOHelper.vala',
'PantheonAccountsServicePlugin.vala',
'Plug.vala',
'ThumbnailGenerator.vala',
@@ -8,17 +7,17 @@ plug_files = files(
'Views/Multitasking.vala',
'Views/Text.vala',
'Views/Wallpaper.vala',
+ 'Widgets/GenericContainer.vala',
+ 'Widgets/ImageContainer.vala',
'Widgets/SolidColorContainer.vala',
- 'Widgets/WallpaperContainer.vala',
+ 'Widgets/UriContainer.vala',
+ 'Widgets/XMLContainer.vala',
)
-switchboard_dep = dependency('switchboard-2.0')
+switchboard_dep = dependency('switchboard-3')
switchboard_plugsdir = switchboard_dep.get_pkgconfig_variable('plugsdir', define_variable: ['libdir', libdir])
-plank_datadir = plank_dep.get_pkgconfig_variable('pkgdatadir')
-
configuration = configuration_data()
-configuration.set('PLANKDATADIR', plank_datadir)
configuration.set('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir')))
configuration.set('GETTEXT_PACKAGE', meson.project_name() + '-plug')
@@ -39,10 +38,8 @@ shared_module(
gobject_dep,
granite_dep,
gtk_dep,
- hdy_dep,
+ adw_dep,
dependency('gexiv2'),
- dependency('gnome-desktop-3.0'),
- plank_dep,
posix_dep,
switchboard_dep
],