From 34130bb2f5f49fcf3dd17624986fb5fb5e093b47 Mon Sep 17 00:00:00 2001
From: guinux <nuxgui@gmail.com>
Date: Thu, 21 Sep 2017 12:43:57 +0200
Subject: [PATCH] refresh packages when external app changed dbs

---
 src/alpm_config.vala    |  2 +-
 src/manager_window.vala | 58 +++++++++++++++++++++++++++++------------
 src/transaction.vala    | 14 ++++++++++
 src/user_daemon.vala    | 43 +++++++++++++++++++-----------
 4 files changed, 85 insertions(+), 32 deletions(-)

diff --git a/src/alpm_config.vala b/src/alpm_config.vala
index 368fa6eb..d983b6d6 100644
--- a/src/alpm_config.vala
+++ b/src/alpm_config.vala
@@ -142,7 +142,7 @@ class AlpmConfig {
 			try {
 				Process.spawn_command_line_sync ("mkdir -p %s".printf (tmp_dbpath));
 				Process.spawn_command_line_sync ("ln -sf %s/local %s".printf (dbpath, tmp_dbpath));
-				Process.spawn_command_line_sync ("cp -au %s/sync %s".printf (dbpath, tmp_dbpath));
+				Process.spawn_command_line_sync ("cp -a %s/sync %s".printf (dbpath, tmp_dbpath));
 				Process.spawn_command_line_sync ("chmod -R 777 %s/sync".printf (tmp_dbpath));
 				handle = new Alpm.Handle (rootdir, tmp_dbpath, out error);
 			} catch (SpawnError e) {
diff --git a/src/manager_window.vala b/src/manager_window.vala
index 5f98e1d5..3cf46101 100644
--- a/src/manager_window.vala
+++ b/src/manager_window.vala
@@ -175,7 +175,8 @@ namespace Pamac {
 
 		AlpmPackage[] repos_updates;
 		AURPackage[] aur_updates;
-		bool updates_checked;
+
+		bool extern_lock;
 
 		uint search_entry_timeout_id;
 		string search_string;
@@ -184,7 +185,6 @@ namespace Pamac {
 		public ManagerWindow (Gtk.Application application) {
 			Object (application: application);
 
-			updates_checked = false;
 			button_back.visible = false;
 			pending_stacksidebar.visible = false;
 			searchbar.connect_entry (search_entry);
@@ -342,6 +342,8 @@ namespace Pamac {
 			main_stack.add_named (transaction.term_window, "term");
 			transaction_infobox.pack_start (transaction.progress_box);
 
+			Timeout.add (500, check_extern_lock);
+
 			display_package_queue = new Queue<string> ();
 
 			main_stack.notify["visible-child"].connect (on_main_stack_visible_child_changed);
@@ -367,6 +369,23 @@ namespace Pamac {
 			}
 		}
 
+		bool check_extern_lock () {
+			if (extern_lock) {
+				if (!transaction.lockfile.query_exists ()) {
+					extern_lock = false;
+					transaction.refresh_handle ();
+					refresh_packages_list ();
+				}
+			} else {
+				if (transaction.lockfile.query_exists ()) {
+					if (!transaction_running && !refreshing && !sysupgrade_running) {
+						extern_lock = true;
+					}
+				}
+			}
+			return true;
+		}
+
 		void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon,
 											bool enable_aur) {
 			support_aur (enable_aur);
@@ -1176,7 +1195,6 @@ namespace Pamac {
 			if (filters_stack.visible_child_name != "search") {
 				searchbar.search_mode_enabled = false;
 				search_button.active = false;
-				origin_stack.visible_child_name = "repos";
 			}
 			if (filters_stack.visible_child_name != "pending") {
 				uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length;
@@ -1187,6 +1205,7 @@ namespace Pamac {
 			}
 			switch (filters_stack.visible_child_name) {
 				case "categories":
+					origin_stack.visible_child_name = "repos";
 					show_sidebar ();
 					set_pendings_operations ();
 					on_categories_listbox_row_activated (categories_listbox.get_selected_row ());
@@ -1228,16 +1247,19 @@ namespace Pamac {
 					}
 					break;
 				case "groups":
+					origin_stack.visible_child_name = "repos";
 					show_sidebar ();
 					set_pendings_operations ();
 					on_groups_listbox_row_activated (groups_listbox.get_selected_row ());
 					break;
 				case "installed":
+					origin_stack.visible_child_name = "repos";
 					show_sidebar ();
 					set_pendings_operations ();
 					on_installed_listbox_row_activated (installed_listbox.get_selected_row ());
 					break;
 				case "repos":
+					origin_stack.visible_child_name = "repos";
 					show_sidebar ();
 					set_pendings_operations ();
 					on_repos_listbox_row_activated (repos_listbox.get_selected_row ());
@@ -1252,13 +1274,9 @@ namespace Pamac {
 					filters_stack.child_set_property (filters_stack.get_child_by_name ("updates"),
 														"needs-attention",
 														attention_val);
-					if (updates_checked) {
-						populate_updates ();
-					} else {
-						apply_button.sensitive = false;
-						this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-						transaction.start_get_updates ();
-					}
+					apply_button.sensitive = false;
+					this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+					transaction.start_get_updates ();
 					break;
 				case "pending":
 					if (transaction.to_build.length != 0) {
@@ -2267,7 +2285,6 @@ namespace Pamac {
 		}
 
 		void on_get_updates_finished (Updates updates) {
-			updates_checked = true;
 			repos_updates = updates.repos_updates;
 			aur_updates = updates.aur_updates;
 			if (filters_stack.visible_child_name == "updates") {
@@ -2307,13 +2324,23 @@ namespace Pamac {
 					show_sidebar ();
 				}
 				if (origin_stack.visible_child_name == "repos") {
-					if (repos_updates.length == 0) {
-						origin_stack.visible_child_name = "aur";
-					} else {
+					if (repos_updates.length > 0) {
 						populate_packages_list (repos_updates);
+					} else {
+						origin_stack.visible_child_name = "aur";
 					}
 				} else if (origin_stack.visible_child_name == "aur") {
-					populate_aur_list (aur_updates);
+					if (repos_updates.length > 0) {
+						origin_stack.visible_child_name = "repos";
+					} else {
+						populate_aur_list (aur_updates);
+					}
+				} else {
+					if (repos_updates.length > 0) {
+						origin_stack.visible_child_name = "repos";
+					} else {
+						origin_stack.visible_child_name = "aur";
+					}
 				}
 				if (main_stack.visible_child_name == "browse") {
 					select_all_button.visible = true;
@@ -2355,7 +2382,6 @@ namespace Pamac {
 		}
 
 		void on_transaction_finished (bool success) {
-			updates_checked = false;
 			show_last_search = true;
 			transaction.refresh_handle ();
 			if (main_stack.visible_child_name == "details") {
diff --git a/src/transaction.vala b/src/transaction.vala
index 05e72810..e4707fef 100644
--- a/src/transaction.vala
+++ b/src/transaction.vala
@@ -21,6 +21,7 @@ namespace Pamac {
 	[DBus (name = "org.manjaro.pamac.user")]
 	interface UserDaemon : Object {
 		public abstract void refresh_handle () throws IOError;
+		public abstract string get_lockfile () throws IOError;
 		public abstract AlpmPackage get_installed_pkg (string pkgname) throws IOError;
 		public abstract bool get_checkspace () throws IOError;
 		public abstract string[] get_ignorepkgs () throws IOError;
@@ -135,6 +136,7 @@ namespace Pamac {
 		GenericSet<string?> previous_to_remove;
 		public GenericSet<string?> transaction_summary;
 		public GenericSet<string?> temporary_ignorepkgs;
+		public GLib.File lockfile;
 
 		uint64 total_download;
 		uint64 already_downloaded;
@@ -198,6 +200,7 @@ namespace Pamac {
 			transaction_summary = new GenericSet<string?> (str_hash, str_equal);
 			temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal);
 			connecting_user_daemon ();
+			get_lockfile ();
 			//creating dialogs
 			this.application_window = application_window;
 			preferences_available_countries = {};
@@ -490,11 +493,22 @@ namespace Pamac {
 		public void refresh_handle () {
 			try {
 				user_daemon.refresh_handle ();
+				get_lockfile ();
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
 			}
 		}
 
+		void get_lockfile () {
+			try {
+				lockfile = GLib.File.new_for_path (user_daemon.get_lockfile ());
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				//try standard lock file
+				lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck");
+			}
+		}
+
 		public bool get_checkspace () {
 			bool checkspace = false;
 			try {
diff --git a/src/user_daemon.vala b/src/user_daemon.vala
index 10885424..5a670cf6 100644
--- a/src/user_daemon.vala
+++ b/src/user_daemon.vala
@@ -84,9 +84,11 @@ namespace Pamac {
 		private AlpmConfig alpm_config;
 		private Alpm.Handle? alpm_handle;
 		private Alpm.Handle? files_handle;
+		private bool repos_updates_checked;
+		private AlpmPackage[] repos_updates;
 		private bool check_aur_updates;
 		private bool aur_updates_checked;
-		private Json.Array aur_updates_results;
+		private AURPackage[] aur_updates;
 		private HashTable<string, Json.Array> aur_search_results;
 		private HashTable<string, Json.Object> aur_infos;
 		private As.Store app_store;
@@ -96,7 +98,8 @@ namespace Pamac {
 
 		public UserDaemon () {
 			alpm_config = new AlpmConfig ("/etc/pacman.conf");
-			aur_updates_results = new Json.Array ();
+			repos_updates = {};
+			aur_updates = {};
 			aur_search_results = new HashTable<string, Json.Array> (str_hash, str_equal);
 			aur_infos = new HashTable<string, Json.Object> (str_hash, str_equal);
 			refresh_handle ();
@@ -124,6 +127,8 @@ namespace Pamac {
 			} else {
 				files_handle = alpm_config.get_handle (true);
 			}
+			repos_updates_checked = false;
+			aur_updates_checked = false;
 		}
 
 		public bool get_checkspace () {
@@ -1096,7 +1101,15 @@ namespace Pamac {
 		}
 
 		private int get_updates () {
-			AlpmPackage[] updates_infos = {};
+			if (repos_updates_checked && (aur_updates_checked || !check_aur_updates)) {
+				var updates = Updates () {
+					repos_updates = repos_updates,
+					aur_updates = aur_updates
+				};
+				get_updates_finished (updates);
+				return 0;
+			}
+			AlpmPackage[] repos_updates = {};
 			unowned Alpm.Package? pkg = null;
 			unowned Alpm.Package? candidate = null;
 			// use a tmp handle
@@ -1126,7 +1139,7 @@ namespace Pamac {
 					if (candidate != null) {
 						var infos = initialise_pkg_struct (candidate);
 						infos.installed_version = installed_pkg.version;
-						updates_infos += (owned) infos;
+						repos_updates += (owned) infos;
 					} else {
 						if (check_aur_updates && (!aur_updates_checked)) {
 							// check if installed_pkg is a local pkg
@@ -1151,24 +1164,25 @@ namespace Pamac {
 				// get aur updates
 				if (!aur_updates_checked) {
 					AUR.multiinfo.begin (local_pkgs, (obj, res) => {
-						aur_updates_results = AUR.multiinfo.end (res);
+						var aur_updates_json = AUR.multiinfo.end (res);
 						aur_updates_checked = true;
+						get_aur_updates (aur_updates_json);
 						var updates = Updates () {
-							repos_updates = (owned) updates_infos,
-							aur_updates = get_aur_updates_infos ()
+							repos_updates = repos_updates,
+							aur_updates = aur_updates
 						};
 						get_updates_finished (updates);
 					});
 				} else {
 					var updates = Updates () {
-						repos_updates = (owned) updates_infos,
-						aur_updates = get_aur_updates_infos ()
+						repos_updates = repos_updates,
+						aur_updates = aur_updates
 					};
 					get_updates_finished (updates);
 				}
 			} else {
 				var updates = Updates () {
-					repos_updates = (owned) updates_infos,
+					repos_updates = repos_updates,
 					aur_updates = {}
 				};
 				get_updates_finished (updates);
@@ -1176,9 +1190,9 @@ namespace Pamac {
 			return 0;
 		}
 
-		private AURPackage[] get_aur_updates_infos () {
-			AURPackage[] aur_updates_infos = {};
-			aur_updates_results.foreach_element ((array, index, node) => {
+		private void get_aur_updates (Json.Array aur_updates_json) {
+			aur_updates = {};
+			aur_updates_json.foreach_element ((array, index, node) => {
 				unowned Json.Object pkg_info = node.get_object ();
 				unowned string name = pkg_info.get_string_member ("Name");
 				unowned string new_version = pkg_info.get_string_member ("Version");
@@ -1186,10 +1200,9 @@ namespace Pamac {
 				if (Alpm.pkg_vercmp (new_version, old_version) == 1) {
 					var infos = initialise_aur_struct (pkg_info);
 					infos.installed_version = old_version;
-					aur_updates_infos += (owned) infos;
+					aur_updates += (owned) infos;
 				}
 			});
-			return aur_updates_infos;
 		}
 
 		public void start_get_updates (bool check_aur_updates_) {
-- 
GitLab