diff --git a/src/Core/Main.vala b/src/Core/Main.vala index 28f5bc2..01119d0 100644 --- a/src/Core/Main.vala +++ b/src/Core/Main.vala @@ -53,6 +53,9 @@ public class Main : GLib.Object{ public bool include_btrfs_home_for_backup = false; public bool include_btrfs_home_for_restore = false; public static bool btrfs_version__can_recursive_delete = false; + + public string root_subvolume_name = "@"; + public string home_subvolume_name = "@home"; public bool stop_cron_emails = true; @@ -289,6 +292,23 @@ public class Main : GLib.Object{ this.app_conf_path_old = "/etc/timeshift.json"; this.app_conf_path_default = GLib.Path.build_path (GLib.Path.DIR_SEPARATOR_S, Constants.SYSCONFDIR, "timeshift", "default.json"); //sys_root and sys_home will be initialized by update_partition_list() + + // Detect subvolume names based on distro id. + // Only has effect when timeshift is opened the first time, + // otherwise the setting is overwritten by loading the config. + if (this.current_distro.dist_id.down() == "fedora") { + this.root_subvolume_name = "root"; + this.home_subvolume_name = "home"; + } + else if (this.current_distro.dist_id.down() == "debian") { + this.root_subvolume_name = "@rootfs"; + this.home_subvolume_name = ""; + this.include_btrfs_home_for_backup = false; + } + else { //if (this.current_distro.dist_id.down() == "ubuntu") + this.root_subvolume_name = "@"; + this.home_subvolume_name = "@home"; + } // check if running locally ------------------------ @@ -488,9 +508,9 @@ public class Main : GLib.Object{ log_debug("check_btrfs_layout_system()"); - bool supported = sys_subvolumes.has_key("@"); + bool supported = sys_subvolumes.has_key(root_subvolume_name); if (include_btrfs_home_for_backup){ - supported = supported && sys_subvolumes.has_key("@home"); + supported = supported && sys_subvolumes.has_key(home_subvolume_name); } if (!supported){ @@ -521,10 +541,10 @@ public class Main : GLib.Object{ if (dev_home != dev_root){ - supported = supported && check_btrfs_volume(dev_root, "@", unlock); + supported = supported && check_btrfs_volume(dev_root, root_subvolume_name, unlock); if (include_btrfs_home_for_backup){ - supported = supported && check_btrfs_volume(dev_home, "@home", unlock); + supported = supported && check_btrfs_volume(dev_home, home_subvolume_name, unlock); } } else{ @@ -532,7 +552,7 @@ public class Main : GLib.Object{ supported = supported && check_btrfs_volume(dev_root, "@,@home", unlock); } else{ - supported = supported && check_btrfs_volume(dev_root, "@", unlock); + supported = supported && check_btrfs_volume(dev_root, root_subvolume_name, unlock); } } } @@ -1720,9 +1740,9 @@ public class Main : GLib.Object{ log_msg(_("Creating new backup...") + "(BTRFS)"); - log_msg(_("Saving to device") + ": %s".printf(repo.device.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths["@"])); + log_msg(_("Saving to device") + ": %s".printf(repo.device.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths[root_subvolume_name])); if ((repo.device_home != null) && (repo.device_home.uuid != repo.device.uuid)){ - log_msg(_("Saving to device") + ": %s".printf(repo.device_home.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths["@home"])); + log_msg(_("Saving to device") + ": %s".printf(repo.device_home.device) + ", " + _("mounted at path") + ": %s".printf(repo.mount_paths[home_subvolume_name])); } // take new backup --------------------------------- @@ -1739,11 +1759,11 @@ public class Main : GLib.Object{ // create subvolume snapshots - var subvol_names = new string[] { "@" }; + var subvol_names = new string[] { root_subvolume_name }; if (include_btrfs_home_for_backup){ - subvol_names = new string[] { "@","@home" }; + subvol_names = new string[] { root_subvolume_name,home_subvolume_name }; } foreach(var subvol_name in subvol_names){ @@ -1786,7 +1806,7 @@ public class Main : GLib.Object{ //log_msg(_("Writing control file...")); - snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); + snapshot_path = path_combine(repo.mount_paths[root_subvolume_name], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); string initial_tags = (tag == "ondemand") ? "" : tag; @@ -2344,11 +2364,11 @@ public class Main : GLib.Object{ // final check - check if target root device is mounted if (btrfs_mode){ - if (repo.mount_paths["@"].length == 0){ + if (repo.mount_paths[root_subvolume_name].length == 0){ log_error(_("BTRFS device is not mounted") + ": @"); return false; } - if (include_btrfs_home_for_restore && (repo.mount_paths["@home"].length == 0)){ + if (include_btrfs_home_for_restore && (repo.mount_paths[home_subvolume_name].length == 0)){ log_error(_("BTRFS device is not mounted") + ": @home"); return false; } @@ -2430,7 +2450,7 @@ public class Main : GLib.Object{ if (!App.snapshot_to_restore.subvolumes.has_key(entry.subvolume_name())){ continue; } - if ((entry.subvolume_name() == "@home") && !include_btrfs_home_for_restore){ continue; } + if ((entry.subvolume_name() == home_subvolume_name) && !include_btrfs_home_for_restore){ continue; } } string dev_name = entry.device.full_name_with_parent; @@ -2466,7 +2486,7 @@ public class Main : GLib.Object{ if (!App.snapshot_to_restore.subvolumes.has_key(entry.subvolume_name())){ continue; } - if ((entry.subvolume_name() == "@home") && !include_btrfs_home_for_restore){ continue; } + if ((entry.subvolume_name() == home_subvolume_name) && !include_btrfs_home_for_restore){ continue; } } string dev_name = entry.device.full_name_with_parent; @@ -3166,7 +3186,7 @@ public class Main : GLib.Object{ foreach(var subvol in snapshot_to_restore.subvolumes.values){ - if ((subvol.name == "@home") && !include_btrfs_home_for_restore){ continue; } + if ((subvol.name == home_subvolume_name) && !include_btrfs_home_for_restore){ continue; } subvol.restore(); } @@ -3230,12 +3250,12 @@ public class Main : GLib.Object{ if (found){ //delete system subvolumes - if (sys_subvolumes.has_key("@") && snapshot_to_restore.subvolumes.has_key("@")){ - sys_subvolumes["@"].remove(); + if (sys_subvolumes.has_key(root_subvolume_name) && snapshot_to_restore.subvolumes.has_key(root_subvolume_name)){ + sys_subvolumes[root_subvolume_name].remove(); log_msg(_("Deleted subvolume") + ": @"); } - if (include_btrfs_home_for_restore && sys_subvolumes.has_key("@home") && snapshot_to_restore.subvolumes.has_key("@home")){ - sys_subvolumes["@home"].remove(); + if (include_btrfs_home_for_restore && sys_subvolumes.has_key(home_subvolume_name) && snapshot_to_restore.subvolumes.has_key(home_subvolume_name)){ + sys_subvolumes[home_subvolume_name].remove(); log_msg(_("Deleted subvolume") + ": @home"); } @@ -3263,9 +3283,9 @@ public class Main : GLib.Object{ var subvol_list = new Gee.ArrayList(); - var subvol_names = new string[] { "@" }; + var subvol_names = new string[] { root_subvolume_name }; if (include_btrfs_home_for_restore){ - subvol_names = new string[] { "@","@home" }; + subvol_names = new string[] { root_subvolume_name,home_subvolume_name }; } foreach(string subvol_name in subvol_names){ @@ -3294,7 +3314,7 @@ public class Main : GLib.Object{ return false; } else{ - var subvol_dev = (subvol_name == "@") ? repo.device : repo.device_home; + var subvol_dev = (subvol_name == root_subvolume_name) ? repo.device : repo.device_home; subvol_list.add(new Subvolume(subvol_name, dst_path, subvol_dev.uuid, repo)); log_msg(_("Moved system subvolume to snapshot directory") + ": %s".printf(subvol_name)); @@ -3308,11 +3328,11 @@ public class Main : GLib.Object{ else{ // write control file ----------- - snapshot_path = path_combine(repo.mount_paths["@"], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); + snapshot_path = path_combine(repo.mount_paths[root_subvolume_name], "timeshift-btrfs/snapshots/%s".printf(snapshot_name)); var snap = Snapshot.write_control_file( snapshot_path, dt_created, repo.device.uuid, - LinuxDistro.get_dist_info(path_combine(snapshot_path,"@")).full_name(), + LinuxDistro.get_dist_info(path_combine(snapshot_path,root_subvolume_name)).full_name(), "ondemand", "", 0, true, false, repo); snap.description = "Before restoring '%s'".printf(snapshot_to_restore.date_formatted); @@ -3357,6 +3377,9 @@ public class Main : GLib.Object{ config.set_string_member("parent_device_uuid", backup_parent_uuid); } + config.set_string_member("root_subvolume_name", root_subvolume_name); + config.set_string_member("home_subvolume_name", home_subvolume_name); + config.set_string_member("do_first_run", false.to_string()); config.set_string_member("btrfs_mode", btrfs_mode.to_string()); config.set_string_member("include_btrfs_home_for_backup", include_btrfs_home_for_backup.to_string()); @@ -3476,6 +3499,9 @@ public class Main : GLib.Object{ if (cmd_btrfs_mode != null){ btrfs_mode = cmd_btrfs_mode; //override } + + root_subvolume_name = json_get_string(config,"root_subvolume_name", root_subvolume_name); + home_subvolume_name = json_get_string(config,"home_subvolume_name", home_subvolume_name); backup_uuid = json_get_string(config,"backup_device_uuid", backup_uuid); backup_parent_uuid = json_get_string(config,"parent_device_uuid", backup_parent_uuid); @@ -3544,7 +3570,7 @@ public class Main : GLib.Object{ // load some defaults for first-run based on user's system type - bool supported = sys_subvolumes.has_key("@") && cmd_exists("btrfs"); // && sys_subvolumes.has_key("@home") + bool supported = sys_subvolumes.has_key(root_subvolume_name) && cmd_exists("btrfs"); // && sys_subvolumes.has_key(home_subvolume_name) if (supported || (cmd_btrfs_mode == true)){ log_msg(_("Selected default snapshot type") + ": %s".printf("BTRFS")); btrfs_mode = true; @@ -3959,8 +3985,8 @@ public class Main : GLib.Object{ update_partitions(); // In BTRFS mode, select the system disk if system disk is BTRFS - if (btrfs_mode && sys_subvolumes.has_key("@")){ - var subvol_root = sys_subvolumes["@"]; + if (btrfs_mode && sys_subvolumes.has_key(root_subvolume_name)){ + var subvol_root = sys_subvolumes[root_subvolume_name]; repo = new SnapshotRepo.from_device(subvol_root.get_device(), parent_win, btrfs_mode); return; } @@ -3983,7 +4009,7 @@ public class Main : GLib.Object{ if (dev.has_children()) { return false; } if (btrfs_mode && ((dev.fstype == "btrfs")||(dev.fstype == "luks"))){ - if (check_btrfs_volume(dev, "@", unlock)){ + if (check_btrfs_volume(dev, root_subvolume_name, unlock)){ return true; } } @@ -4109,9 +4135,9 @@ public class Main : GLib.Object{ } public bool query_subvolume_ids(){ - bool ok = query_subvolume_id("@"); + bool ok = query_subvolume_id(root_subvolume_name); if ((repo.device_home != null) && (repo.device.uuid != repo.device_home.uuid)){ - ok = ok && query_subvolume_id("@home"); + ok = ok && query_subvolume_id(home_subvolume_name); } return ok; } @@ -4119,6 +4145,10 @@ public class Main : GLib.Object{ public bool query_subvolume_id(string subvol_name){ log_debug("query_subvolume_id():%s".printf(subvol_name)); + + // Early out when configured subvolume name != actual. + if(sys_subvolumes[root_subvolume_name] == null || sys_subvolumes[home_subvolume_name] == null) + return false; string cmd = ""; string std_out; @@ -4149,14 +4179,14 @@ public class Main : GLib.Object{ Subvolume subvol = null; - if ((sys_subvolumes.size > 0) && line.has_suffix(sys_subvolumes["@"].path.replace(repo.mount_paths["@"] + "/"," "))){ - subvol = sys_subvolumes["@"]; + if ((sys_subvolumes.size > 0) && line.has_suffix(sys_subvolumes[root_subvolume_name].path.replace(repo.mount_paths[root_subvolume_name] + "/"," "))){ + subvol = sys_subvolumes[root_subvolume_name]; } else if ((sys_subvolumes.size > 0) - && sys_subvolumes.has_key("@home") - && line.has_suffix(sys_subvolumes["@home"].path.replace(repo.mount_paths["@home"] + "/"," "))){ + && sys_subvolumes.has_key(home_subvolume_name) + && line.has_suffix(sys_subvolumes[home_subvolume_name].path.replace(repo.mount_paths[home_subvolume_name] + "/"," "))){ - subvol = sys_subvolumes["@home"]; + subvol = sys_subvolumes[home_subvolume_name]; } else { foreach(var bak in repo.snapshots){ @@ -4178,9 +4208,9 @@ public class Main : GLib.Object{ } public bool query_subvolume_quotas(){ - bool ok = query_subvolume_quota("@"); + bool ok = query_subvolume_quota(root_subvolume_name); if (repo.device.uuid != repo.device_home.uuid){ - ok = ok && query_subvolume_quota("@home"); + ok = ok && query_subvolume_quota(home_subvolume_name); } return ok; } @@ -4241,15 +4271,15 @@ public class Main : GLib.Object{ Subvolume subvol = null; - if ((sys_subvolumes.size > 0) && (sys_subvolumes["@"].id == subvol_id)){ + if ((sys_subvolumes.size > 0) && (sys_subvolumes[root_subvolume_name].id == subvol_id)){ - subvol = sys_subvolumes["@"]; + subvol = sys_subvolumes[root_subvolume_name]; } else if ((sys_subvolumes.size > 0) - && sys_subvolumes.has_key("@home") - && (sys_subvolumes["@home"].id == subvol_id)){ + && sys_subvolumes.has_key(home_subvolume_name) + && (sys_subvolumes[home_subvolume_name].id == subvol_id)){ - subvol = sys_subvolumes["@home"]; + subvol = sys_subvolumes[home_subvolume_name]; } else { foreach(var bak in repo.snapshots){ diff --git a/src/Core/Snapshot.vala b/src/Core/Snapshot.vala index 4898925..32880f0 100644 --- a/src/Core/Snapshot.vala +++ b/src/Core/Snapshot.vala @@ -228,7 +228,7 @@ public class Snapshot : GLib.Object{ live = json_get_bool(config,"live",false); string type = config.get_string_member_with_default("type", "rsync"); - string extension = (type == "btrfs") ? "@" : "localhost"; + string extension = (type == "btrfs") ? App.root_subvolume_name : "localhost"; distro = LinuxDistro.get_dist_info(path_combine(path, extension)); //log_debug("repo.mount_path: %s".printf(repo.mount_path)); @@ -239,7 +239,7 @@ public class Snapshot : GLib.Object{ foreach(string subvol_name in subvols.get_members()){ - if ((subvol_name != "@")&&(subvol_name != "@home")){ continue; } + if ((subvol_name != App.root_subvolume_name)&&(subvol_name != App.home_subvolume_name)){ continue; } paths[subvol_name] = path.replace(repo.mount_path, repo.mount_paths[subvol_name]); diff --git a/src/Core/SnapshotRepo.vala b/src/Core/SnapshotRepo.vala index 5be7293..650a821 100644 --- a/src/Core/SnapshotRepo.vala +++ b/src/Core/SnapshotRepo.vala @@ -193,31 +193,31 @@ public class SnapshotRepo : GLib.Object{ } // rsync - mount_paths["@"] = ""; - mount_paths["@home"] = ""; + mount_paths[App.root_subvolume_name] = ""; + mount_paths[App.home_subvolume_name] = ""; if (btrfs_mode){ - mount_paths["@"] = mount_path; - mount_paths["@home"] = mount_path; //default + mount_paths[App.root_subvolume_name] = mount_path; + mount_paths[App.home_subvolume_name] = mount_path; //default device_home = device; //default // mount @home if on different disk ------- - var repo_subvolumes = Subvolume.detect_subvolumes_for_system_by_path(path_combine(mount_path,"@"), this, parent_window); + var repo_subvolumes = Subvolume.detect_subvolumes_for_system_by_path(path_combine(mount_path,App.root_subvolume_name), this, parent_window); - if (repo_subvolumes.has_key("@home")){ + if (repo_subvolumes.has_key(App.home_subvolume_name)){ - var subvol = repo_subvolumes["@home"]; + var subvol = repo_subvolumes[App.home_subvolume_name]; if (subvol.device_uuid != device.uuid){ // @home is on a separate device device_home = subvol.get_device(); - mount_paths["@home"] = unlock_and_mount_device(device_home, App.mount_point_app + "/backup-home"); + mount_paths[App.home_subvolume_name] = unlock_and_mount_device(device_home, App.mount_point_app + "/backup-home"); - if (mount_paths["@home"].length == 0){ + if (mount_paths[App.home_subvolume_name].length == 0){ return false; } } @@ -505,7 +505,7 @@ public class SnapshotRepo : GLib.Object{ log_debug("SnapshotRepo: has_btrfs_system()"); - var root_path = path_combine(mount_paths["@"],"@"); + var root_path = path_combine(mount_paths[App.root_subvolume_name],App.root_subvolume_name); log_debug("root_path=%s".printf(root_path)); log_debug("btrfs_mode=%s".printf(btrfs_mode.to_string())); if (btrfs_mode){ diff --git a/src/Core/Subvolume.vala b/src/Core/Subvolume.vala index 27ef3ab..1afe573 100644 --- a/src/Core/Subvolume.vala +++ b/src/Core/Subvolume.vala @@ -124,11 +124,11 @@ public class Subvolume : GLib.Object{ public bool remove(){ if (is_system_subvolume){ - if (name == "@"){ - path = path_combine(App.mount_point_app + "/backup", "@"); + if (name == App.root_subvolume_name){ + path = path_combine(App.mount_point_app + "/backup", App.root_subvolume_name); } - else if (name == "@home"){ - path = path_combine(App.mount_point_app + "/backup-home", "@home"); + else if (name == App.home_subvolume_name){ + path = path_combine(App.mount_point_app + "/backup-home", App.home_subvolume_name); } } diff --git a/src/Gtk/RestoreWindow.vala b/src/Gtk/RestoreWindow.vala index b88f4bd..64e536c 100644 --- a/src/Gtk/RestoreWindow.vala +++ b/src/Gtk/RestoreWindow.vala @@ -268,7 +268,7 @@ class RestoreWindow : Gtk.Window{ if (App.btrfs_mode){ - if (App.snapshot_to_restore.subvolumes.has_key("@home")){ + if (App.snapshot_to_restore.subvolumes.has_key(App.home_subvolume_name)){ notebook.page = Tabs.USERS; } diff --git a/src/Gtk/SnapshotBackendBox.vala b/src/Gtk/SnapshotBackendBox.vala index 9df9191..a11c35c 100644 --- a/src/Gtk/SnapshotBackendBox.vala +++ b/src/Gtk/SnapshotBackendBox.vala @@ -37,7 +37,9 @@ class SnapshotBackendBox : Gtk.Box{ private Gtk.RadioButton opt_rsync; private Gtk.RadioButton opt_btrfs; private Gtk.Label lbl_description; + private Gtk.ComboBox combo_subvol_layout; private Gtk.Window parent_window; + private Gtk.Box vbox_subvolume_custom; public signal void type_changed(); @@ -82,6 +84,7 @@ class SnapshotBackendBox : Gtk.Box{ opt_rsync.toggled.connect(()=>{ if (opt_rsync.active){ App.btrfs_mode = false; + combo_subvol_layout.sensitive = false; Main.first_snapshot_size = 0; init_backend(); type_changed(); @@ -97,6 +100,8 @@ class SnapshotBackendBox : Gtk.Box{ hbox.add (opt); opt_btrfs = opt; + create_btrfs_subvolume_selection(hbox); + if (!check_for_btrfs_tools()) { opt.sensitive = false; opt_rsync.active = true; @@ -105,6 +110,7 @@ class SnapshotBackendBox : Gtk.Box{ opt_btrfs.toggled.connect(()=>{ if (opt_btrfs.active){ App.btrfs_mode = true; + combo_subvol_layout.sensitive = true; init_backend(); type_changed(); update_description(); @@ -112,6 +118,155 @@ class SnapshotBackendBox : Gtk.Box{ }); } + private void create_btrfs_subvolume_selection(Gtk.Box vbox) { + + // subvolume layout + var hbox_subvolume = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6); + vbox.add(hbox_subvolume); + + var sg_label = new Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL); + var sg_edit = new Gtk.SizeGroup(Gtk.SizeGroupMode.HORIZONTAL); + + var lbl_subvol_name = new Gtk.Label(_("Subvolume layout:")); + lbl_subvol_name.xalign = (float) 0.0; + hbox_subvolume.add(lbl_subvol_name); + sg_label.add_widget(lbl_subvol_name); + + // Combobox + var layout = new string[]{ + App.root_subvolume_name, + App.home_subvolume_name + }; + + var possible_layouts = new string[,]{ + {"", "", "Custom"}, + {"@", "@home", "Ubuntu (@, @home)"}, + {"@rootfs", "", "Debian (@rootfs)"}, + {"root", "home", "Fedora (root, home)"} + }; + + Gtk.ListStore list_store = new Gtk.ListStore (3, + typeof (string), + typeof (string), + typeof (string)); + Gtk.TreeIter strore_iter; + int active = -1; + for (int idx = 0; idx < possible_layouts.length[0]; idx++) { + list_store.append(out strore_iter); + list_store.set(strore_iter, + 0, possible_layouts[idx, 0], + 1, possible_layouts[idx, 1], + 2, possible_layouts[idx, 2]); + + // Find our layout in the options + if (possible_layouts[idx, 0] == layout[0] && + possible_layouts[idx, 1] == layout[1]) active = idx; + } + + if (active < 0){ + active = 0; + } + + combo_subvol_layout = new Gtk.ComboBox.with_model (list_store); + hbox_subvolume.add (combo_subvol_layout); + sg_edit.add_widget(combo_subvol_layout); + + Gtk.CellRendererText renderer = new Gtk.CellRendererText (); + combo_subvol_layout.pack_start (renderer, true); + combo_subvol_layout.add_attribute (renderer, "text", 2); + + // Set active index + combo_subvol_layout.active = active; + + // Create custom inputs + vbox_subvolume_custom = new Gtk.Box(Gtk.Orientation.VERTICAL, 6); + vbox.add(vbox_subvolume_custom); + + var custom_root_subvol_entry = add_opt_btrfs_subvolume_name_entry(vbox_subvolume_custom, sg_label, sg_edit, + "Root", App.root_subvolume_name); + + var custom_home_subvol_entry = add_opt_btrfs_subvolume_name_entry(vbox_subvolume_custom, sg_label, sg_edit, + "Home", App.home_subvolume_name); + + combo_subvol_layout.changed.connect (() => { + Gtk.TreeIter iter; + combo_subvol_layout.get_active_iter (out iter); + + // Handle custom names + if (combo_subvol_layout.active == 0) { + custom_root_subvol_entry.text = App.root_subvolume_name; + custom_home_subvol_entry.text = App.home_subvolume_name; + } + // Handle selection from combobox + else { + Value val1; + list_store.get_value (iter, 0, out val1); + App.root_subvolume_name = (string) val1; + + Value val2; + list_store.get_value (iter, 1, out val2); + App.home_subvolume_name = (string) val2; + + // If home subolume name is empty, do not backup home. + if (App.home_subvolume_name == "") + App.include_btrfs_home_for_backup = false; + } + + init_backend(); + type_changed(); + update_custom_subvol_name_visibility(); + }); + + custom_root_subvol_entry.focus_out_event.connect((entry1, event1) => { + App.root_subvolume_name = custom_root_subvol_entry.text; + + init_backend(); + type_changed(); + + return false; + }); + + custom_home_subvol_entry.focus_out_event.connect((entry1, event1) => { + App.home_subvolume_name = custom_home_subvol_entry.text; + + // If home subolume name is empty, do not backup home. + if (App.home_subvolume_name == "") + App.include_btrfs_home_for_backup = false; + + init_backend(); + type_changed(); + + return false; + }); + + // Add custom subvolume names + } + + private Gtk.Entry add_opt_btrfs_subvolume_name_entry(Gtk.Box vbox, Gtk.SizeGroup sg_title, + Gtk.SizeGroup sg_edit, string name, string value) { + // root subvolume name layout + var hbox_subvolume_edit = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6); + vbox.add(hbox_subvolume_edit); + + var lbl_subvol_name = new Gtk.Label(_(@"$name subvolume:")); + lbl_subvol_name.xalign = (float) 0.0; + hbox_subvolume_edit.add(lbl_subvol_name); + sg_title.add_widget(lbl_subvol_name); + + var entry_subvol = new Gtk.Entry(); + entry_subvol.text = value; + hbox_subvolume_edit.add(entry_subvol); + sg_edit.add_widget(entry_subvol); + + return entry_subvol; + } + + public void update_custom_subvol_name_visibility() { + if(combo_subvol_layout.active == 0) + vbox_subvolume_custom.visible = true; + else vbox_subvolume_custom.visible = false; + } + private bool check_for_btrfs_tools() { try { const string args[] = {"lsblk", "-o", "FSTYPE", null}; @@ -214,5 +369,6 @@ class SnapshotBackendBox : Gtk.Box{ opt_btrfs.active = App.btrfs_mode; type_changed(); update_description(); + update_custom_subvol_name_visibility(); } } diff --git a/src/Gtk/SnapshotListBox.vala b/src/Gtk/SnapshotListBox.vala index 1e85169..9203607 100644 --- a/src/Gtk/SnapshotListBox.vala +++ b/src/Gtk/SnapshotListBox.vala @@ -431,12 +431,12 @@ class SnapshotListBox : Gtk.Box{ int64 size = 0; - if (bak.subvolumes.has_key("@")){ - size += bak.subvolumes["@"].total_bytes; + if (bak.subvolumes.has_key(App.root_subvolume_name)){ + size += bak.subvolumes[App.root_subvolume_name].total_bytes; } - if (bak.subvolumes.has_key("@home")){ - size += bak.subvolumes["@home"].total_bytes; + if (bak.subvolumes.has_key(App.home_subvolume_name)){ + size += bak.subvolumes[App.home_subvolume_name].total_bytes; } ctxt.text = format_file_size(size); @@ -467,11 +467,11 @@ class SnapshotListBox : Gtk.Box{ int64 size = 0; - if (bak.subvolumes.has_key("@")){ - size += bak.subvolumes["@"].unshared_bytes; + if (bak.subvolumes.has_key(App.root_subvolume_name)){ + size += bak.subvolumes[App.root_subvolume_name].unshared_bytes; } - if (bak.subvolumes.has_key("@home")){ - size += bak.subvolumes["@home"].unshared_bytes; + if (bak.subvolumes.has_key(App.home_subvolume_name)){ + size += bak.subvolumes[App.home_subvolume_name].unshared_bytes; } ctxt.text = format_file_size(size); diff --git a/src/Gtk/UsersBox.vala b/src/Gtk/UsersBox.vala index be549c0..f9370c0 100644 --- a/src/Gtk/UsersBox.vala +++ b/src/Gtk/UsersBox.vala @@ -357,6 +357,9 @@ class UsersBox : Gtk.Box{ box_btrfs.set_no_show_all(false); box_btrfs.show_all(); + + if (App.home_subvolume_name == "") chk_include_btrfs_home.sensitive = false; + else chk_include_btrfs_home.sensitive = true; if (restore_mode){ chk_include_btrfs_home.active = App.include_btrfs_home_for_restore;