diff --git a/SOURCES/0001-Fix-few-memory-leaks.patch b/SOURCES/0001-Fix-few-memory-leaks.patch
new file mode 100644
index 0000000..a774cd7
--- /dev/null
+++ b/SOURCES/0001-Fix-few-memory-leaks.patch
@@ -0,0 +1,149 @@
+From 71cf63b7bb7bb212580cc7c8e6c75a4f645d79f1 Mon Sep 17 00:00:00 2001
+From: Shivaprasad G Bhat <sbhat@linux.ibm.com>
+Date: Wed, 20 May 2020 06:27:05 -0500
+Subject: [PATCH 01/18] Fix few memory leaks
+
+Valgrind showed some leaks with scandir usage in sysfs.cc.
+Patch audits all the scandir usage and fixes where required.
+
+Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
+---
+ src/core/parisc.cc | 10 ++++++----
+ src/core/spd.cc    |  4 ++++
+ src/core/sysfs.cc  | 32 ++++++++++++++++++++++++++++----
+ 3 files changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/src/core/parisc.cc b/src/core/parisc.cc
+index 80344d28c6ba..1e531e32bbc2 100644
+--- a/src/core/parisc.cc
++++ b/src/core/parisc.cc
+@@ -561,11 +561,13 @@ static bool scan_device(hwNode & node, string name = "")
+   else
+   {
+     for (int i = 0; i < n; i++)
+-      if(matches(namelist[i]->d_name, "^[0-9]+(:[0-9]+)*$"))
+     {
+-      pushd(namelist[i]->d_name);
+-      scan_device(curnode?*curnode:node, namelist[i]->d_name);
+-      popd();
++      if(matches(namelist[i]->d_name, "^[0-9]+(:[0-9]+)*$"))
++      {
++        pushd(namelist[i]->d_name);
++        scan_device(curnode?*curnode:node, namelist[i]->d_name);
++        popd();
++      }
+       free(namelist[i]);
+     }
+     free(namelist);
+diff --git a/src/core/spd.cc b/src/core/spd.cc
+index 061d0fd3e186..a304d061a008 100644
+--- a/src/core/spd.cc
++++ b/src/core/spd.cc
+@@ -192,8 +192,12 @@ static bool scan_eeproms(hwNode & memory)
+     return false;
+ 
+   for (int i = 0; i < n; i++)
++  {
+     if (scan_eeprom(memory, namelist[i]->d_name))
+       current_bank++;
++    free(namelist[i]);
++  }
++  free(namelist);
+ 
+   return true;
+ }
+diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
+index ee8b1da06c78..4e2df1c9cb09 100644
+--- a/src/core/sysfs.cc
++++ b/src/core/sysfs.cc
+@@ -83,7 +83,7 @@ static string sysfs_getbustype(const string & path)
+ {
+   struct dirent **namelist;
+   int i, n;
+-  string devname;
++  string bustype = "";
+ 
+ /*
+   to determine to which kind of bus a device is connected:
+@@ -96,17 +96,28 @@ static string sysfs_getbustype(const string & path)
+   n = scandir(".", &namelist, selectdir, alphasort);
+   popd();
+ 
++  if (n <= 0)
++    return "";
++
+   for (i = 0; i < n; i++)
+   {
+-    devname =
++    string devname =
+       string(fs.path + "/bus/") + string(namelist[i]->d_name) +
+       "/devices/" + basename(path.c_str());
+ 
+     if (samefile(devname, path))
+-      return string(namelist[i]->d_name);
++    {
++      bustype = string(namelist[i]->d_name);
++      break;
++    }
++    free(namelist[i]);
+   }
+ 
+-  return "";
++  for (int j = i; j < n; j++)
++    free(namelist[j]);
++  free(namelist);
++
++  return bustype;
+ }
+ 
+ 
+@@ -405,7 +416,11 @@ vector < entry > entry::devices() const
+     entry e = sysfs::entry(This->devpath + "/" + string(namelist[i]->d_name));
+     if(e.hassubdir("subsystem"))
+ 	    result.push_back(e);
++    free(namelist[i]);
+   }
++  if (namelist)
++    free(namelist);
++
+   if(pushd("block"))
+   {
+     int count = scandir(".", &namelist, selectdir, alphasort);
+@@ -414,7 +429,10 @@ vector < entry > entry::devices() const
+       entry e = sysfs::entry(This->devpath + "/block/" + string(namelist[i]->d_name));
+       if(e.hassubdir("subsystem"))
+ 	      result.push_back(e);
++      free(namelist[i]);
+     }
++    if (namelist)
++      free(namelist);
+     popd();
+   }
+   popd();
+@@ -435,8 +453,11 @@ vector < entry > sysfs::entries_by_bus(const string & busname)
+   {
+     entry e = sysfs::entry::byBus(busname, namelist[i]->d_name);
+     result.push_back(e);
++    free(namelist[i]);
+   }
+   popd();
++  if (namelist)
++    free(namelist);
+   return result;
+ }
+ 
+@@ -454,8 +475,11 @@ vector < entry > sysfs::entries_by_class(const string & classname)
+   {
+     entry e = sysfs::entry::byClass(classname, namelist[i]->d_name);
+     result.push_back(e);
++    free(namelist[i]);
+   }
+   popd();
++  if (namelist)
++    free(namelist);
+   return result;
+ }
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/0001-Report-correct-memory-size-on-SMBIOS-2.7.patch b/SOURCES/0001-Report-correct-memory-size-on-SMBIOS-2.7.patch
new file mode 100644
index 0000000..4c5d93f
--- /dev/null
+++ b/SOURCES/0001-Report-correct-memory-size-on-SMBIOS-2.7.patch
@@ -0,0 +1,36 @@
+From 5c4bfb1a4baae1bea11cc9f629bc48ee12e733a7 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Sun, 10 Jan 2021 00:38:10 +0100
+Subject: [PATCH] Report correct memory size on SMBIOS < 2.7
+
+Github PR#60
+
+---
+ src/core/dmi.cc | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/core/dmi.cc b/src/core/dmi.cc
+index 30b3ab3b995c..d33d4879bdca 100644
+--- a/src/core/dmi.cc
++++ b/src/core/dmi.cc
+@@ -1567,10 +1567,13 @@ int dmiversionrev)
+ 
+ // size
+           u = data[0x0D] << 8 | data[0x0C];
+-          if(u == 0x7FFF) {
+-             unsigned long long extendsize = (data[0x1F] << 24) | (data[0x1E] << 16) | (data[0x1D] << 8) | data[0x1C];
+-             extendsize &= 0x7FFFFFFFUL;
+-             size = extendsize * 1024ULL * 1024ULL;
++          if ((dmiversionmaj > 2)
++            || ((dmiversionmaj == 2) && (dmiversionmin >= 7))) {
++             if(u == 0x7FFF) {
++                unsigned long long extendsize = (data[0x1F] << 24) | (data[0x1E] << 16) | (data[0x1D] << 8) | data[0x1C];
++                extendsize &= 0x7FFFFFFFUL;
++                size = extendsize * 1024ULL * 1024ULL;
++             }
+           }
+ 	  else
+           if (u != 0xFFFF)
+-- 
+2.17.1
+
diff --git a/SOURCES/0001-devtree-Add-UUID-property.patch b/SOURCES/0001-devtree-Add-UUID-property.patch
new file mode 100644
index 0000000..a69051e
--- /dev/null
+++ b/SOURCES/0001-devtree-Add-UUID-property.patch
@@ -0,0 +1,28 @@
+From 9c5c2f0706db330114ff4624e0931ac40c1d6fe2 Mon Sep 17 00:00:00 2001
+From: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+Date: Wed, 20 Jan 2021 11:28:47 +0530
+Subject: [PATCH] devtree: Add UUID property
+
+Add UUID property to PowerVM LPAR.
+
+Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
+---
+ src/core/device-tree.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
+index d3188c6a8a27..7df6a4ee074c 100644
+--- a/src/core/device-tree.cc
++++ b/src/core/device-tree.cc
+@@ -1503,6 +1503,8 @@ bool scan_device_tree(hwNode & n)
+       scan_devtree_bootrom(*core);
+       if (exists(DEVICETREE "/ibm,lpar-capable")) {
+         n.setDescription("pSeries LPAR");
++        if (exists( DEVICETREE "/ibm,partition-uuid"))
++          n.setConfig("uuid", get_string(DEVICETREE "/ibm,partition-uuid"));
+         scan_devtree_cpu_power(*core);
+       }
+       else {
+-- 
+2.17.1
+
diff --git a/SOURCES/0002-Build-against-gtk3-instead-of-gtk2.patch b/SOURCES/0002-Build-against-gtk3-instead-of-gtk2.patch
new file mode 100644
index 0000000..62d8d56
--- /dev/null
+++ b/SOURCES/0002-Build-against-gtk3-instead-of-gtk2.patch
@@ -0,0 +1,96 @@
+From ad4ecfd29c29f6895aaf02092e6574299a2b5aa9 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 03:12:51 +0200
+Subject: [PATCH 02/18] Build against gtk3 instead of gtk2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since gtk2 is on life support, it makes sense to build the gui code with
+gtk3 nowadays.
+
+I went for 3.24 because that’s the version I have available on my
+system, but it is probable that previous versions would also work, I
+don’t know.
+
+[lijiang added the following comment]
+Note: Because rhel8 uses the cmake, update the CMakeLists instead of
+Makefile.
+
+In addition, currently, rhel8 only supports the gtk-3.22 instead of
+gtk-3.24, so downgrade to gtk-3.22, otherwise the build will fail.
+---
+ README.md              | 2 +-
+ lshw.spec.in           | 4 ++--
+ src/gui/CMakeLists.txt | 6 +++---
+ src/gui/gtk-lshw.ui    | 2 +-
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/README.md b/README.md
+index 294888c71ff0..cf50e5151228 100644
+--- a/README.md
++++ b/README.md
+@@ -18,7 +18,7 @@ Installation
+    - cmake, GNU make or Ninja
+    - an ANSI (or close enough to ANSI compliance) C++ compiler (tested with g++ 2.95.4 and 3.x)
+    - for the (optional) GTK+ graphical user interface, you will need a
+-	complete GTK+ development environment (gtk2-devel on RedHat/Fedora derivatives) 
++	complete GTK+ development environment (gtk3-devel on RedHat/Fedora derivatives) 
+    - for optional SQLite feature install SQLite
+    - for optional zlib feature install zlib and gzip
+ 
+diff --git a/lshw.spec.in b/lshw.spec.in
+index 3fe23c2ef360..78018211e1af 100644
+--- a/lshw.spec.in
++++ b/lshw.spec.in
+@@ -31,8 +31,8 @@ http://lshw.ezix.org/
+ Summary: HardWare LiSter (GUI version)
+ Group: Applications/System
+ Requires: %{name} >= %{version}
+-Requires: gtk2 >= 2.4
+-BuildRequires: gtk2-devel >= 2.4
++Requires: gtk3 >= 3.22
++BuildRequires: gtk3-devel >= 3.22
+ 
+ %description gui
+ lshw (Hardware Lister) is a small tool to provide detailed informaton on
+diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
+index 34890535a070..34c9e4383c3e 100644
+--- a/src/gui/CMakeLists.txt
++++ b/src/gui/CMakeLists.txt
+@@ -4,17 +4,17 @@ if(NOT GUI OR STATIC)
+ endif()
+ 
+ find_package(PkgConfig)
+-pkg_check_modules(GTK2 REQUIRED gtk+-2.0 gmodule-2.0)
++pkg_check_modules(GTK3 REQUIRED gtk+-3.0 gmodule-2.0)
+ 
+ file(GLOB GTK_SOURCES "*.c*")
+ 
+ include_directories("${PROJECT_BINARY_DIR}")
+ include_directories("${PROJECT_SOURCE_DIR}/src/core")
+ 
+-include_directories("${GTK2_INCLUDE_DIRS}")
++include_directories("${GTK3_INCLUDE_DIRS}")
+ 
+ add_executable(gtk-lshw ${GTK_SOURCES})
+-target_link_libraries(gtk-lshw ${SQLITE3_LIBRARIES} ${Z_LIBRARIES} ${GTK2_LIBRARIES} core resolv)
++target_link_libraries(gtk-lshw ${SQLITE3_LIBRARIES} ${Z_LIBRARIES} ${GTK3_LIBRARIES} core resolv)
+ install(TARGETS gtk-lshw DESTINATION sbin)
+ 
+ if(POLICYKIT)
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 73fc08a58d1e..25ab1ad03349 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -1,6 +1,6 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <interface>
+-  <requires lib="gtk+" version="2.22"/>
++  <requires lib="gtk+" version="3.22"/>
+   <object class="GtkDialog" id="aboutlshw">
+     <property name="can_focus">False</property>
+     <property name="title" translatable="yes">About</property>
+-- 
+2.17.1
+
diff --git a/SOURCES/0003-Remove-deprecated-stock-messages.patch b/SOURCES/0003-Remove-deprecated-stock-messages.patch
new file mode 100644
index 0000000..b3acf56
--- /dev/null
+++ b/SOURCES/0003-Remove-deprecated-stock-messages.patch
@@ -0,0 +1,27 @@
+From b79101ccdbb609e3dccfe097952ab2d3d7b55951 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 03:39:46 +0200
+Subject: [PATCH 03/18] Remove deprecated stock messages
+
+---
+ src/gui/gtk-lshw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index 50dfb8329a5c..9ac525c715d8 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -31,8 +31,8 @@ main (int argc, char *argv[])
+ 				GTK_BUTTONS_NONE,
+ 				"Executing this program as a normal user will give incomplete and maybe erroneous information.");
+     gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+-                                  GTK_STOCK_QUIT, GTK_RESPONSE_CANCEL,
+-                                  GTK_STOCK_EXECUTE, GTK_RESPONSE_ACCEPT,
++                                  "_Quit", GTK_RESPONSE_CANCEL,
++                                  "_Execute", GTK_RESPONSE_ACCEPT,
+                                   NULL);
+ 
+     proceed = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT);
+-- 
+2.17.1
+
diff --git a/SOURCES/0004-Remove-hack-which-is-apparently-not-useful-anymore.patch b/SOURCES/0004-Remove-hack-which-is-apparently-not-useful-anymore.patch
new file mode 100644
index 0000000..f8b8220
--- /dev/null
+++ b/SOURCES/0004-Remove-hack-which-is-apparently-not-useful-anymore.patch
@@ -0,0 +1,44 @@
+From 8d696376c0f044507575e933b3e438e104f3ecd2 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 03:40:04 +0200
+Subject: [PATCH 04/18] Remove hack which is apparently not useful anymore
+
+---
+ src/gui/stock.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/src/gui/stock.c b/src/gui/stock.c
+index 08675db8f037..46dfbe7173b5 100644
+--- a/src/gui/stock.c
++++ b/src/gui/stock.c
+@@ -89,7 +89,6 @@ lshw_gtk_stock_init(void)
+   static int stock_initted = 0;
+   GtkIconFactory *icon_factory;
+   int i;
+-  GtkWidget *win;
+ 
+   if (stock_initted)
+     return;
+@@ -101,10 +100,6 @@ lshw_gtk_stock_init(void)
+ 
+   gtk_icon_factory_add_default(icon_factory);
+ 
+-/* Er, yeah, a hack, but it works. :) */
+-  win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+-  gtk_widget_realize(win);
+-
+   for (i = 0; i < G_N_ELEMENTS(stock_icons); i++)
+   {
+     GdkPixbuf *pixbuf;
+@@ -128,8 +123,6 @@ lshw_gtk_stock_init(void)
+       }
+   }
+ 
+-  gtk_widget_destroy(win);
+-
+ /* register logo icon size */
+   gtk_icon_size_register(LSHW_ICON_SIZE_LOGO, LSHW_DEFAULT_ICON_SIZE, LSHW_DEFAULT_ICON_SIZE);
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/0005-Use-GtkFileChooserNative-instead-of-GtkFileChooserDi.patch b/SOURCES/0005-Use-GtkFileChooserNative-instead-of-GtkFileChooserDi.patch
new file mode 100644
index 0000000..f257c44
--- /dev/null
+++ b/SOURCES/0005-Use-GtkFileChooserNative-instead-of-GtkFileChooserDi.patch
@@ -0,0 +1,60 @@
+From 41c04d1c5ee84b1f42a9fabf7623a98ff02b9bf1 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 04:37:55 +0200
+Subject: [PATCH 05/18] Use GtkFileChooserNative instead of
+ GtkFileChooserDialog
+
+This class allows it to work even in containers.
+
+---
+ src/gui/engine.cc | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/src/gui/engine.cc b/src/gui/engine.cc
+index 2d2e58bb9a21..21e446e0359d 100644
+--- a/src/gui/engine.cc
++++ b/src/gui/engine.cc
+@@ -460,7 +460,7 @@ static void redirect_cout(std::ofstream &out, bool enable = true)
+ void save_as(GtkWidget *mainwindow)
+ {
+   struct utsname buf;
+-  GtkWidget *dialog = NULL;
++  GtkFileChooserNative *dialog = NULL;
+   GtkWidget *sanitize = NULL;
+   GtkFileFilter *filter = NULL;
+   bool proceed = true;
+@@ -469,12 +469,11 @@ void save_as(GtkWidget *mainwindow)
+   if(!computer)		// nothing to save
+     return;
+ 
+-  dialog = gtk_file_chooser_dialog_new ("Save hardware configuration",
++  dialog = gtk_file_chooser_native_new ("Save hardware configuration",
+ 				      GTK_WINDOW(mainwindow),
+ 				      GTK_FILE_CHOOSER_ACTION_SAVE,
+-				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+-				      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+-				      NULL);
++				      "_Save",
++				      "_Cancel");
+   //gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+   sanitize = gtk_check_button_new_with_label("Anonymize output");
+   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sanitize), enabled("output:sanitize")?TRUE:FALSE);
+@@ -511,7 +510,7 @@ void save_as(GtkWidget *mainwindow)
+   if(uname(&buf)==0)
+     gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), buf.nodename);
+ 
+-  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
++  if (gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+   {
+     char *filename;
+ 
+@@ -603,5 +602,5 @@ void save_as(GtkWidget *mainwindow)
+     }
+   }
+ 
+-  gtk_widget_destroy (dialog);
++  g_object_unref (dialog);
+ }
+-- 
+2.17.1
+
diff --git a/SOURCES/0006-Replace-deprecated-GtkIconFactory-with-GHashTable.patch b/SOURCES/0006-Replace-deprecated-GtkIconFactory-with-GHashTable.patch
new file mode 100644
index 0000000..711e585
--- /dev/null
+++ b/SOURCES/0006-Replace-deprecated-GtkIconFactory-with-GHashTable.patch
@@ -0,0 +1,203 @@
+From e342333d936293e82ff889aa6745b93a8c975543 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 05:04:19 +0200
+Subject: [PATCH 06/18] Replace deprecated GtkIconFactory with GHashTable
+
+This removes most warnings.  A possible further improvement would be to
+use GtkIconTheme instead, but it will require reorganising the SVG files
+around.
+
+---
+ src/gui/engine.cc    |  3 ++-
+ src/gui/print-gui.cc | 19 ++++++++-----------
+ src/gui/print-gui.h  |  2 +-
+ src/gui/stock.c      | 26 ++++++--------------------
+ src/gui/stock.h      |  1 -
+ 5 files changed, 17 insertions(+), 34 deletions(-)
+
+diff --git a/src/gui/engine.cc b/src/gui/engine.cc
+index 21e446e0359d..c66279e5f498 100644
+--- a/src/gui/engine.cc
++++ b/src/gui/engine.cc
+@@ -40,6 +40,7 @@ extern GtkWidget *description;
+ extern GtkWidget *go_up_button;
+ extern GtkWidget *save_button;
+ extern GtkWidget *statusbar;
++extern GHashTable *pixbufs;
+ 
+ enum
+ {
+@@ -224,7 +225,7 @@ static void display(GtkWidget * mainwindow)
+     create_tags(buffer);
+ 
+     string hwpath = gethwpath(*displayed, container);
+-    printmarkup(*displayed, GTK_TEXT_VIEW(description), hwpath);
++    printmarkup(*displayed, GTK_TEXT_VIEW(description), hwpath, pixbufs);
+   }
+ }
+ 
+diff --git a/src/gui/print-gui.cc b/src/gui/print-gui.cc
+index 861ec4c695da..4138424d172e 100644
+--- a/src/gui/print-gui.cc
++++ b/src/gui/print-gui.cc
+@@ -66,15 +66,12 @@ static void printsize(long long value, const hwNode & node, const string & name,
+ }
+ 
+ 
+-static  void inserticon(const string & icon, const string & comment, GtkTextBuffer *buffer, GtkTextIter &iter, GtkTextView * textview)
++static  void inserticon(const string & icon, const string & comment, GtkTextBuffer *buffer, GtkTextIter &iter, GHashTable *pixbufs)
+ {
+   GdkPixbuf *pixbuf;
+   GtkTextTag *tag;
+ 
+-  pixbuf = gtk_widget_render_icon(GTK_WIDGET(textview),
+-    icon.c_str(),
+-    gtk_icon_size_from_name(LSHW_ICON_SIZE_LOGO), /* size */
+-    NULL);
++  pixbuf = GDK_PIXBUF(g_hash_table_lookup(pixbufs, icon.c_str()));
+   if(!GDK_IS_PIXBUF(pixbuf))
+     return;
+ 
+@@ -87,7 +84,7 @@ static  void inserticon(const string & icon, const string & comment, GtkTextBuff
+ }
+ 
+ 
+-void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpath)
++void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpath, GHashTable *pixbufs)
+ {
+   vector < string > config;
+   vector < string > resources;
+@@ -125,13 +122,13 @@ void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpa
+   gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+ 
+   if(node.getHint("icon").defined())
+-    inserticon(string("lshw-") + node.getHint("icon").asString(), "", buffer, iter, textview);
++    inserticon(string("lshw-") + node.getHint("icon").asString(), "", buffer, iter, pixbufs);
+ 
+   if(node.getHint("bus.icon").defined())
+-    inserticon(string("lshw-") + node.getHint("bus.icon").asString(), "", buffer, iter, textview);
++    inserticon(string("lshw-") + node.getHint("bus.icon").asString(), "", buffer, iter, pixbufs);
+ 
+   if(node.getHint("logo").defined())
+-    inserticon(string("lshw-") + node.getHint("logo").asString(), "", buffer, iter, textview);
++    inserticon(string("lshw-") + node.getHint("logo").asString(), "", buffer, iter, pixbufs);
+ 
+   gtk_text_buffer_insert (buffer, &iter, "\n\n", -1);
+ 
+@@ -218,10 +215,10 @@ void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpa
+   gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+ 
+   if(!node.claimed())
+-    inserticon(LSHW_STOCK_DISABLED, _("this device hasn't been claimed\n"), buffer, iter, textview);
++    inserticon(LSHW_STOCK_DISABLED, _("this device hasn't been claimed\n"), buffer, iter, pixbufs);
+ 
+   if(!node.enabled())
+-    inserticon(LSHW_STOCK_DISABLED, _("this device has been disabled\n"), buffer, iter, textview);
++    inserticon(LSHW_STOCK_DISABLED, _("this device has been disabled\n"), buffer, iter, pixbufs);
+ 
+   (void) &id;                                     // avoid "id defined but not used" warning
+ }
+diff --git a/src/gui/print-gui.h b/src/gui/print-gui.h
+index 055f7cdf3087..d41946161f02 100644
+--- a/src/gui/print-gui.h
++++ b/src/gui/print-gui.h
+@@ -4,7 +4,7 @@
+ #include "hw.h"
+ #include <gtk/gtk.h>
+ 
+-void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpath);
++void printmarkup(const hwNode & node, GtkTextView *textview, const string & hwpath, GHashTable *pixbufs);
+ 
+ string gethwpath(hwNode & node, hwNode & base);
+ #endif
+diff --git a/src/gui/stock.c b/src/gui/stock.c
+index 46dfbe7173b5..9e7c3664427a 100644
+--- a/src/gui/stock.c
++++ b/src/gui/stock.c
+@@ -16,6 +16,7 @@ GtkWidget *description = NULL;
+ GtkWidget *go_up_button = NULL;
+ GtkWidget *save_button = NULL;
+ GtkWidget *statusbar = NULL;
++GHashTable *pixbufs = NULL;
+ 
+ static struct StockIcon
+ {
+@@ -87,7 +88,6 @@ void
+ lshw_gtk_stock_init(void)
+ {
+   static int stock_initted = 0;
+-  GtkIconFactory *icon_factory;
+   int i;
+ 
+   if (stock_initted)
+@@ -95,15 +95,12 @@ lshw_gtk_stock_init(void)
+ 
+   stock_initted = 1;
+ 
+-/* Setup the icon factory. */
+-  icon_factory = gtk_icon_factory_new();
+-
+-  gtk_icon_factory_add_default(icon_factory);
++/* Setup the icons hash table. */
++  pixbufs = g_hash_table_new(g_str_hash, g_str_equal);
+ 
+   for (i = 0; i < G_N_ELEMENTS(stock_icons); i++)
+   {
+     GdkPixbuf *pixbuf;
+-    GtkIconSet *iconset;
+     gchar *filename;
+ 
+       filename = find_file(stock_icons[i].filename, "artwork");
+@@ -111,23 +108,15 @@ lshw_gtk_stock_init(void)
+       if (filename == NULL)
+         continue;
+ 
+-      pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
++      pixbuf = gdk_pixbuf_new_from_file_at_size(filename, LSHW_DEFAULT_ICON_SIZE, LSHW_DEFAULT_ICON_SIZE, NULL);
+       g_free(filename);
+ 
+       if(pixbuf)	/* we managed to load something */
+       {
+-        iconset = gtk_icon_set_new_from_pixbuf(pixbuf);
+-        g_object_unref(G_OBJECT(pixbuf));
+-        gtk_icon_factory_add(icon_factory, stock_icons[i].name, iconset);
+-        gtk_icon_set_unref(iconset);
++        g_hash_table_insert(pixbufs, (char*)stock_icons[i].name, pixbuf);
+       }
+   }
+ 
+-/* register logo icon size */
+-  gtk_icon_size_register(LSHW_ICON_SIZE_LOGO, LSHW_DEFAULT_ICON_SIZE, LSHW_DEFAULT_ICON_SIZE);
+-
+-  g_object_unref(G_OBJECT(icon_factory));
+-
+   (void) &id;                                     /* avoid "id defined but not used" warning */
+ }
+ 
+@@ -168,10 +157,7 @@ void lshw_ui_init(void)
+   gtk_builder_connect_signals( builder, mainwindow );
+   g_object_unref( G_OBJECT( builder ) );
+ 
+-  icon = gtk_widget_render_icon(GTK_WIDGET(mainwindow),
+-    "lshw-logo",
+-    GTK_ICON_SIZE_DIALOG,
+-    NULL);
++  icon = g_hash_table_lookup(pixbufs, LSHW_STOCK_LOGO);
+   if(GDK_IS_PIXBUF(icon))
+   {
+     gtk_window_set_icon(GTK_WINDOW(mainwindow), icon);
+diff --git a/src/gui/stock.h b/src/gui/stock.h
+index a0fef5b882b2..58f788e5b573 100644
+--- a/src/gui/stock.h
++++ b/src/gui/stock.h
+@@ -43,7 +43,6 @@
+ /**
+  * For getting the icon size for the logo
+  */
+-#define LSHW_ICON_SIZE_LOGO        "lshw-icon-size-logo"
+ #define LSHW_DEFAULT_ICON_SIZE        40
+ 
+ void lshw_gtk_stock_init(void);
+-- 
+2.17.1
+
diff --git a/SOURCES/0007-Replace-the-last-GtkStock-in-overwrite-dialog.patch b/SOURCES/0007-Replace-the-last-GtkStock-in-overwrite-dialog.patch
new file mode 100644
index 0000000..dec5759
--- /dev/null
+++ b/SOURCES/0007-Replace-the-last-GtkStock-in-overwrite-dialog.patch
@@ -0,0 +1,29 @@
+From 8ff4b056e8fd371dca868f8967b36c6e9a4590ab Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 05:06:38 +0200
+Subject: [PATCH 07/18] Replace the last GtkStock in overwrite dialog
+
+Also add a mnemonic for better keyboard access to the overwrite button.
+
+---
+ src/gui/engine.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/gui/engine.cc b/src/gui/engine.cc
+index c66279e5f498..ff0607490673 100644
+--- a/src/gui/engine.cc
++++ b/src/gui/engine.cc
+@@ -556,8 +556,8 @@ void save_as(GtkWidget *mainwindow)
+                                   "A file named <i><tt>%s</tt></i> already exists in folder <tt>%s</tt>.\n\nDo you want to overwrite it?",
+                                   basename(buffer1), dirname(buffer2));
+         gtk_dialog_add_buttons(GTK_DIALOG(dialog), 
+-				  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+-				  "Overwrite", GTK_RESPONSE_ACCEPT,
++				  "_Cancel", GTK_RESPONSE_CANCEL,
++				  "_Overwrite", GTK_RESPONSE_ACCEPT,
+                                   NULL);
+         proceed = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT);
+         gtk_widget_destroy (dialog);
+-- 
+2.17.1
+
diff --git a/SOURCES/0008-Remove-deprecated-widgets.patch b/SOURCES/0008-Remove-deprecated-widgets.patch
new file mode 100644
index 0000000..daa477f
--- /dev/null
+++ b/SOURCES/0008-Remove-deprecated-widgets.patch
@@ -0,0 +1,48 @@
+From 0a290c29faa083767698d77b3454ca08fe2a71eb Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 05:18:25 +0200
+Subject: [PATCH 08/18] Remove deprecated widgets
+
+---
+ src/gui/gtk-lshw.ui | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 25ab1ad03349..5f21da08e8e1 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -114,9 +114,10 @@
+     <signal name="delete-event" handler="gtk_main_quit" swapped="no"/>
+     <signal name="map" handler="on_lshw_map" after="yes" swapped="no"/>
+     <child>
+-      <object class="GtkVBox" id="vbox1">
++      <object class="GtkBox" id="main-box">
+         <property name="visible">True</property>
+         <property name="can_focus">False</property>
++        <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+         <child>
+           <object class="GtkMenuBar" id="menubar1">
+             <property name="visible">True</property>
+@@ -292,15 +293,17 @@
+           </packing>
+         </child>
+         <child>
+-          <object class="GtkHPaned" id="hpaned1">
++          <object class="GtkPaned" id="paned">
+             <property name="visible">True</property>
+             <property name="can_focus">True</property>
++            <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+             <child>
+-              <object class="GtkHBox" id="hbox3">
++              <object class="GtkBox" id="tree-box">
+                 <property name="width_request">350</property>
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+                 <property name="homogeneous">True</property>
++                <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+                 <child>
+                   <object class="GtkScrolledWindow" id="scrolledwindow2">
+                     <property name="visible">True</property>
+-- 
+2.17.1
+
diff --git a/SOURCES/0009-Remove-deprecated-use_action_appearance-property.patch b/SOURCES/0009-Remove-deprecated-use_action_appearance-property.patch
new file mode 100644
index 0000000..76a26e1
--- /dev/null
+++ b/SOURCES/0009-Remove-deprecated-use_action_appearance-property.patch
@@ -0,0 +1,128 @@
+From 6cf78e942827dd01b91607704c7bfad9a1a1541d Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 06:45:43 +0200
+Subject: [PATCH 09/18] Remove deprecated use_action_appearance property
+
+---
+ src/gui/gtk-lshw.ui | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 5f21da08e8e1..1656f80ddd53 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -27,7 +27,6 @@
+                 <property name="can_focus">True</property>
+                 <property name="can_default">True</property>
+                 <property name="receives_default">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="use_stock">True</property>
+                 <signal name="activate" handler="on_aboutclose_activate" swapped="no"/>
+                 <signal name="clicked" handler="on_aboutclose_activate" swapped="no"/>
+@@ -73,7 +72,6 @@
+             <property name="can_focus">True</property>
+             <property name="receives_default">True</property>
+             <property name="has_tooltip">True</property>
+-            <property name="use_action_appearance">False</property>
+             <property name="relief">none</property>
+             <property name="uri">http://www.ezix.org/</property>
+           </object>
+@@ -126,7 +124,6 @@
+               <object class="GtkMenuItem" id="menuitem1">
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="label" translatable="yes">_File</property>
+                 <property name="use_underline">True</property>
+                 <child type="submenu">
+@@ -138,7 +135,6 @@
+                         <property name="label">gtk-save</property>
+                         <property name="visible">True</property>
+                         <property name="can_focus">False</property>
+-                        <property name="use_action_appearance">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_save_activate" swapped="no"/>
+@@ -148,7 +144,6 @@
+                       <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
+                         <property name="visible">True</property>
+                         <property name="can_focus">False</property>
+-                        <property name="use_action_appearance">False</property>
+                       </object>
+                     </child>
+                     <child>
+@@ -156,7 +151,6 @@
+                         <property name="label">gtk-quit</property>
+                         <property name="visible">True</property>
+                         <property name="can_focus">False</property>
+-                        <property name="use_action_appearance">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="gtk_main_quit" swapped="no"/>
+@@ -170,7 +164,6 @@
+               <object class="GtkMenuItem" id="menuitem3">
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="label" translatable="yes">_View</property>
+                 <property name="use_underline">True</property>
+                 <child type="submenu">
+@@ -182,7 +175,6 @@
+                         <property name="label">gtk-refresh</property>
+                         <property name="visible">True</property>
+                         <property name="can_focus">False</property>
+-                        <property name="use_action_appearance">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="refresh_display" swapped="no"/>
+@@ -196,7 +188,6 @@
+               <object class="GtkMenuItem" id="menuitem4">
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="label" translatable="yes">_Help</property>
+                 <property name="use_underline">True</property>
+                 <child type="submenu">
+@@ -208,7 +199,6 @@
+                         <property name="label">gtk-about</property>
+                         <property name="visible">True</property>
+                         <property name="can_focus">False</property>
+-                        <property name="use_action_appearance">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+                         <signal name="activate" handler="on_about1_activate" swapped="no"/>
+@@ -235,7 +225,6 @@
+                 <property name="visible">True</property>
+                 <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="stock_id">gtk-go-up</property>
+                 <signal name="clicked" handler="go_up" swapped="no"/>
+               </object>
+@@ -249,7 +238,6 @@
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+                 <property name="tooltip_text" translatable="yes">Rescan the hardware</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="stock_id">gtk-refresh</property>
+                 <signal name="clicked" handler="refresh_display" swapped="no"/>
+               </object>
+@@ -263,7 +251,6 @@
+                 <property name="visible">True</property>
+                 <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="stock_id">gtk-save</property>
+                 <signal name="clicked" handler="on_savebutton_clicked" swapped="no"/>
+               </object>
+@@ -276,7 +263,6 @@
+               <object class="GtkToolButton" id="quitbutton">
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+-                <property name="use_action_appearance">False</property>
+                 <property name="stock_id">gtk-quit</property>
+                 <signal name="clicked" handler="gtk_main_quit" swapped="no"/>
+               </object>
+-- 
+2.17.1
+
diff --git a/SOURCES/0010-Move-to-GtkApplication.patch b/SOURCES/0010-Move-to-GtkApplication.patch
new file mode 100644
index 0000000..21550d0
--- /dev/null
+++ b/SOURCES/0010-Move-to-GtkApplication.patch
@@ -0,0 +1,99 @@
+From 5fd82e398ba94766f0981f97988c8f14ab4297c5 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 05:53:57 +0200
+Subject: [PATCH 10/18] Move to GtkApplication
+
+This will eventually let us use GActions to build our menus and buttons.
+
+---
+ src/gui/gtk-lshw.c  | 36 ++++++++++++++++++++++--------------
+ src/gui/gtk-lshw.ui |  3 +--
+ 2 files changed, 23 insertions(+), 16 deletions(-)
+
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index 9ac525c715d8..6c0f0bbdf77f 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -11,17 +11,10 @@ static char *id = "@(#) $Id$";
+ 
+ extern GtkWidget *mainwindow;
+ 
+-int
+-main (int argc, char *argv[])
++static void
++activate (GApplication *app,
++          gpointer      user_data)
+ {
+-#ifndef NONLS
+-  bindtextdomain (PACKAGE, LOCALEDIR);
+-  bind_textdomain_codeset (PACKAGE, "UTF-8");
+-  textdomain (PACKAGE);
+-#endif
+-
+-  gtk_init (&argc, &argv);
+-
+   if(geteuid() != 0)
+   {
+     bool proceed = false;
+@@ -39,19 +32,34 @@ main (int argc, char *argv[])
+     gtk_widget_destroy (dialog);
+ 
+     if(!proceed)
+-      return -1;
++      return;
+   }
+ 
+   lshw_gtk_stock_init();
+   lshw_ui_init();
+ 
+   if(!mainwindow)
+-    return(1);
++    return;
+ 
+   gtk_widget_show(mainwindow);
+-  gtk_main ();
++  gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(mainwindow));
++}
++
++int
++main (int argc, char *argv[])
++{
++#ifndef NONLS
++  bindtextdomain (PACKAGE, LOCALEDIR);
++  bind_textdomain_codeset (PACKAGE, "UTF-8");
++  textdomain (PACKAGE);
++#endif
++
++  GtkApplication *app = gtk_application_new ("org.ezix.gtk-lshw", G_APPLICATION_FLAGS_NONE);
++  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
++  int status = g_application_run (G_APPLICATION (app), argc, argv);
++  g_object_unref (app);
+ 
+   (void) &id;                                     // avoid warning "id defined but not used"
+ 
+-  return 0;
++  return status;
+ }
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 1656f80ddd53..7504c76d1a1b 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -102,14 +102,13 @@
+       <action-widget response="-7">closebutton1</action-widget>
+     </action-widgets>
+   </object>
+-  <object class="GtkWindow" id="mainwindow">
++  <object class="GtkApplicationWindow" id="mainwindow">
+     <property name="visible">True</property>
+     <property name="can_focus">False</property>
+     <property name="title" translatable="yes">lshw</property>
+     <property name="default_width">700</property>
+     <property name="default_height">480</property>
+     <property name="startup_id">org.ezix.gtk-lshw</property>
+-    <signal name="delete-event" handler="gtk_main_quit" swapped="no"/>
+     <signal name="map" handler="on_lshw_map" after="yes" swapped="no"/>
+     <child>
+       <object class="GtkBox" id="main-box">
+-- 
+2.17.1
+
diff --git a/SOURCES/0011-Replace-signals-with-GSimpleActions.patch b/SOURCES/0011-Replace-signals-with-GSimpleActions.patch
new file mode 100644
index 0000000..39183df
--- /dev/null
+++ b/SOURCES/0011-Replace-signals-with-GSimpleActions.patch
@@ -0,0 +1,279 @@
+From d1690196a9007568bfce3847841ea2b509eb3150 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Fri, 10 Jul 2020 06:28:06 +0200
+Subject: [PATCH 11/18] Replace signals with GSimpleActions
+
+This unifies actions pertaining to the application.
+
+---
+ src/gui/callbacks.c | 62 ++++++++++++++++++++++-----------------------
+ src/gui/callbacks.h | 35 ++++++++++++++++---------
+ src/gui/gtk-lshw.c  | 14 ++++++++++
+ src/gui/gtk-lshw.ui | 16 ++++++------
+ 4 files changed, 76 insertions(+), 51 deletions(-)
+
+diff --git a/src/gui/callbacks.c b/src/gui/callbacks.c
+index f8aa0cb0f968..eec3e5571741 100644
+--- a/src/gui/callbacks.c
++++ b/src/gui/callbacks.c
+@@ -17,17 +17,36 @@ static char *id = "@(#) $Id$";
+ 
+ G_MODULE_EXPORT
+ void
+-refresh_display                        (GtkMenuItem     *menuitem,
+-gpointer         user_data)
++on_go_up_activated                     (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
++{
++  go_back(mainwindow);
++}
++
++G_MODULE_EXPORT
++void
++on_refresh_activated                   (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
+ {
+   refresh(mainwindow);
+ }
+ 
++G_MODULE_EXPORT
++void
++on_save_activated                      (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
++{
++  save_as(mainwindow);
++}
+ 
+ G_MODULE_EXPORT
+ void
+-on_about1_activate                     (GtkMenuItem     *menuitem,
+-gpointer         user_data)
++on_about_activated                     (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
+ {
+   if(GTK_IS_WIDGET(about))
+   {
+@@ -35,6 +54,14 @@ gpointer         user_data)
+   }
+ }
+ 
++G_MODULE_EXPORT
++void
++on_quit_activated                      (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
++{
++  g_application_quit(G_APPLICATION(app));
++}
+ 
+ G_MODULE_EXPORT
+ void
+@@ -147,15 +174,6 @@ gpointer         user_data)
+ }
+ 
+ 
+-G_MODULE_EXPORT
+-void
+-go_up                                  (GtkToolButton   *toolbutton,
+-gpointer         user_data)
+-{
+-  go_back(mainwindow);
+-}
+-
+-
+ G_MODULE_EXPORT
+ void
+ on_lshw_map                            (GtkWidget       *widget,
+@@ -163,21 +181,3 @@ gpointer         user_data)
+ {
+   refresh(mainwindow);
+ }
+-
+-G_MODULE_EXPORT
+-void
+-on_save_activate                       (GtkMenuItem     *menuitem,
+-                                        gpointer         user_data)
+-{
+-  save_as(mainwindow);
+-}
+-
+-
+-G_MODULE_EXPORT
+-void
+-on_savebutton_clicked                  (GtkToolButton   *toolbutton,
+-                                        gpointer         user_data)
+-{
+-  on_save_activate(NULL, NULL);
+-}
+-
+diff --git a/src/gui/callbacks.h b/src/gui/callbacks.h
+index cc856e45ddb4..b9b9141c0eb7 100644
+--- a/src/gui/callbacks.h
++++ b/src/gui/callbacks.h
+@@ -1,8 +1,29 @@
+ #include <gtk/gtk.h>
+ 
+-void refresh_display (GtkMenuItem * menuitem, gpointer user_data);
++void
++on_go_up_activated                     (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app);
++
++void
++on_refresh_activated                   (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app);
+ 
+-void on_about1_activate (GtkMenuItem * menuitem, gpointer user_data);
++void
++on_save_activated                      (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app);
++
++void
++on_about_activated                     (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app);
++
++void
++on_quit_activated                      (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app);
+ 
+ void on_aboutclose_activate (GtkButton * button, gpointer user_data);
+ 
+@@ -35,14 +56,4 @@ void on_treeview2_cursor_changed (GtkTreeView * treeview, gpointer user_data);
+ 
+ void on_treeview3_cursor_changed (GtkTreeView * treeview, gpointer user_data);
+ 
+-void go_up (GtkToolButton * toolbutton, gpointer user_data);
+-
+ void on_lshw_map (GtkWidget * widget, gpointer user_data);
+-
+-void
+-on_save_activate                       (GtkMenuItem     *menuitem,
+-                                        gpointer         user_data);
+-
+-void
+-on_savebutton_clicked                  (GtkToolButton   *toolbutton,
+-                                        gpointer         user_data);
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index 6c0f0bbdf77f..0dc3aff6d322 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -6,11 +6,21 @@
+ #include "config.h"
+ #include "stock.h"
+ #include "engine.h"
++#include "callbacks.h"
+ 
+ static char *id = "@(#) $Id$";
+ 
+ extern GtkWidget *mainwindow;
+ 
++static GActionEntry app_entries[] =
++{
++  { "go_up",   on_go_up_activated,   NULL, NULL, NULL },
++  { "refresh", on_refresh_activated, NULL, NULL, NULL },
++  { "save",    on_save_activated,    NULL, NULL, NULL },
++  { "about",   on_about_activated,   NULL, NULL, NULL },
++  { "quit",    on_quit_activated,    NULL, NULL, NULL }
++};
++
+ static void
+ activate (GApplication *app,
+           gpointer      user_data)
+@@ -35,6 +45,10 @@ activate (GApplication *app,
+       return;
+   }
+ 
++  g_action_map_add_action_entries (G_ACTION_MAP (app),
++                                   app_entries, G_N_ELEMENTS (app_entries),
++                                   app);
++
+   lshw_gtk_stock_init();
+   lshw_ui_init();
+ 
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 7504c76d1a1b..d24e05c3aa20 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -136,7 +136,7 @@
+                         <property name="can_focus">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+-                        <signal name="activate" handler="on_save_activate" swapped="no"/>
++                        <property name="action_name">app.save</property>
+                       </object>
+                     </child>
+                     <child>
+@@ -152,7 +152,7 @@
+                         <property name="can_focus">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+-                        <signal name="activate" handler="gtk_main_quit" swapped="no"/>
++                        <property name="action_name">app.quit</property>
+                       </object>
+                     </child>
+                   </object>
+@@ -176,7 +176,7 @@
+                         <property name="can_focus">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+-                        <signal name="activate" handler="refresh_display" swapped="no"/>
++                        <property name="action_name">app.refresh</property>
+                       </object>
+                     </child>
+                   </object>
+@@ -200,7 +200,7 @@
+                         <property name="can_focus">False</property>
+                         <property name="use_underline">True</property>
+                         <property name="use_stock">True</property>
+-                        <signal name="activate" handler="on_about1_activate" swapped="no"/>
++                        <property name="action_name">app.about</property>
+                       </object>
+                     </child>
+                   </object>
+@@ -225,7 +225,7 @@
+                 <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+                 <property name="stock_id">gtk-go-up</property>
+-                <signal name="clicked" handler="go_up" swapped="no"/>
++                <property name="action_name">app.go_up</property>
+               </object>
+               <packing>
+                 <property name="expand">False</property>
+@@ -238,7 +238,7 @@
+                 <property name="can_focus">False</property>
+                 <property name="tooltip_text" translatable="yes">Rescan the hardware</property>
+                 <property name="stock_id">gtk-refresh</property>
+-                <signal name="clicked" handler="refresh_display" swapped="no"/>
++                <property name="action_name">app.refresh</property>
+               </object>
+               <packing>
+                 <property name="expand">False</property>
+@@ -251,7 +251,7 @@
+                 <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+                 <property name="stock_id">gtk-save</property>
+-                <signal name="clicked" handler="on_savebutton_clicked" swapped="no"/>
++                <property name="action_name">app.save</property>
+               </object>
+               <packing>
+                 <property name="expand">False</property>
+@@ -263,7 +263,7 @@
+                 <property name="visible">True</property>
+                 <property name="can_focus">False</property>
+                 <property name="stock_id">gtk-quit</property>
+-                <signal name="clicked" handler="gtk_main_quit" swapped="no"/>
++                <property name="action_name">app.quit</property>
+               </object>
+               <packing>
+                 <property name="expand">False</property>
+-- 
+2.17.1
+
diff --git a/SOURCES/0012-Enable-Disable-GSimpleAction-instead-of-button-sensi.patch b/SOURCES/0012-Enable-Disable-GSimpleAction-instead-of-button-sensi.patch
new file mode 100644
index 0000000..4733ba2
--- /dev/null
+++ b/SOURCES/0012-Enable-Disable-GSimpleAction-instead-of-button-sensi.patch
@@ -0,0 +1,154 @@
+From a116b319adf51d4eafcb264de027647244340708 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Wed, 15 Jul 2020 17:32:45 +0200
+Subject: [PATCH 12/18] Enable/Disable GSimpleAction instead of button
+ sensitivity
+
+This also fixes the Save menu item not having been disabled properly.
+
+---
+ src/gui/engine.cc   | 24 +++++++-----------------
+ src/gui/gtk-lshw.c  |  7 +++++++
+ src/gui/gtk-lshw.ui |  2 --
+ src/gui/stock.c     |  4 ----
+ 4 files changed, 14 insertions(+), 23 deletions(-)
+
+diff --git a/src/gui/engine.cc b/src/gui/engine.cc
+index ff0607490673..2962ec80d81a 100644
+--- a/src/gui/engine.cc
++++ b/src/gui/engine.cc
+@@ -37,10 +37,10 @@ static hwNode *selected3 = NULL;
+ extern GtkWidget *mainwindow;
+ extern GtkWidget *list1, *list2, *list3;
+ extern GtkWidget *description;
+-extern GtkWidget *go_up_button;
+-extern GtkWidget *save_button;
+ extern GtkWidget *statusbar;
+ extern GHashTable *pixbufs;
++extern GSimpleAction *go_up_action;
++extern GSimpleAction *save_action;
+ 
+ enum
+ {
+@@ -251,14 +251,11 @@ void refresh(GtkWidget *mainwindow)
+ {
+   hwNode computer("computer", hw::system);
+   static bool lock = false;
+-  //GtkWidget * menu = lookup_widget(mainwindow, "menu");
+-  //GtkWidget * save_menuitem = lookup_widget(menu, "save");
+ 
+   if(lock) return;
+ 
+   lock = true;
+-  gtk_widget_set_sensitive(save_button, FALSE);
+-  //gtk_widget_set_sensitive(save_menuitem, FALSE);
++  g_simple_action_set_enabled(save_action, FALSE);
+ 
+   populate_sublist(list1, NULL);
+   populate_sublist(list2, NULL);
+@@ -273,9 +270,8 @@ void refresh(GtkWidget *mainwindow)
+   status(NULL);
+   displayed = container.addChild(computer);
+ 
+-  gtk_widget_set_sensitive(go_up_button, FALSE);
+-  gtk_widget_set_sensitive(save_button, TRUE);
+-  //gtk_widget_set_sensitive(save_menuitem, TRUE);
++  g_simple_action_set_enabled(go_up_action, FALSE);
++  g_simple_action_set_enabled(save_action, TRUE);
+ 
+   selected1 = NULL;
+   selected2 = NULL;
+@@ -379,10 +375,7 @@ void browse(unsigned list, GtkTreeView *treeview)
+       break;
+   }
+ 
+-  if(selected1 && (find_parent(selected1, &container)!= &container))
+-    gtk_widget_set_sensitive(go_up_button, 1);
+-  else
+-    gtk_widget_set_sensitive(go_up_button, 0);
++  g_simple_action_set_enabled(go_up_action, selected1 && (find_parent(selected1, &container)!= &container));
+ 
+   (void) &::id;                                   // avoid warning "id defined but not used"
+ }
+@@ -404,10 +397,7 @@ void go_back(GtkWidget *mainwindow)
+       displayed = find_parent(displayed, &container);
+   }
+ 
+-  if(selected1 && (find_parent(selected1, &container)!= &container))
+-    gtk_widget_set_sensitive(go_up_button, 1);
+-  else
+-    gtk_widget_set_sensitive(go_up_button, 0);
++  g_simple_action_set_enabled(go_up_action, selected1 && (find_parent(selected1, &container)!= &container));
+ 
+   display(mainwindow);
+ }
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index 0dc3aff6d322..7b91ec5e4f01 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -11,6 +11,8 @@
+ static char *id = "@(#) $Id$";
+ 
+ extern GtkWidget *mainwindow;
++GSimpleAction *go_up_action;
++GSimpleAction *save_action;
+ 
+ static GActionEntry app_entries[] =
+ {
+@@ -48,6 +50,11 @@ activate (GApplication *app,
+   g_action_map_add_action_entries (G_ACTION_MAP (app),
+                                    app_entries, G_N_ELEMENTS (app_entries),
+                                    app);
++  go_up_action = G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (app), "go_up"));
++  save_action = G_SIMPLE_ACTION (g_action_map_lookup_action (G_ACTION_MAP (app), "save"));
++
++  g_simple_action_set_enabled(go_up_action, FALSE);
++  g_simple_action_set_enabled(save_action, FALSE);
+ 
+   lshw_gtk_stock_init();
+   lshw_ui_init();
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index d24e05c3aa20..76fcd19379f2 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -222,7 +222,6 @@
+             <child>
+               <object class="GtkToolButton" id="upbutton">
+                 <property name="visible">True</property>
+-                <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+                 <property name="stock_id">gtk-go-up</property>
+                 <property name="action_name">app.go_up</property>
+@@ -248,7 +247,6 @@
+             <child>
+               <object class="GtkToolButton" id="savebutton">
+                 <property name="visible">True</property>
+-                <property name="sensitive">False</property>
+                 <property name="can_focus">False</property>
+                 <property name="stock_id">gtk-save</property>
+                 <property name="action_name">app.save</property>
+diff --git a/src/gui/stock.c b/src/gui/stock.c
+index 9e7c3664427a..fa18f9ed7f85 100644
+--- a/src/gui/stock.c
++++ b/src/gui/stock.c
+@@ -13,8 +13,6 @@ GtkWidget *list1 = NULL;
+ GtkWidget *list2 = NULL;
+ GtkWidget *list3 = NULL;
+ GtkWidget *description = NULL;
+-GtkWidget *go_up_button = NULL;
+-GtkWidget *save_button = NULL;
+ GtkWidget *statusbar = NULL;
+ GHashTable *pixbufs = NULL;
+ 
+@@ -151,8 +149,6 @@ void lshw_ui_init(void)
+   list2 = GTK_WIDGET(gtk_builder_get_object( builder, "treeview2"));
+   list3 = GTK_WIDGET(gtk_builder_get_object( builder, "treeview3"));
+   description = GTK_WIDGET(gtk_builder_get_object( builder, "description"));
+-  go_up_button = GTK_WIDGET(gtk_builder_get_object( builder, "upbutton"));
+-  save_button = GTK_WIDGET(gtk_builder_get_object( builder, "savebutton"));
+   statusbar = GTK_WIDGET(gtk_builder_get_object( builder, "statusbar"));
+   gtk_builder_connect_signals( builder, mainwindow );
+   g_object_unref( G_OBJECT( builder ) );
+-- 
+2.17.1
+
diff --git a/SOURCES/0013-Move-from-GtkMenuBar-to-GMenu.patch b/SOURCES/0013-Move-from-GtkMenuBar-to-GMenu.patch
new file mode 100644
index 0000000..6acf57d
--- /dev/null
+++ b/SOURCES/0013-Move-from-GtkMenuBar-to-GMenu.patch
@@ -0,0 +1,240 @@
+From bc5046d9917fe9cf84dd899f90aef5b90b7d4b04 Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Wed, 15 Jul 2020 16:54:27 +0200
+Subject: [PATCH 13/18] Move from GtkMenuBar to GMenu
+
+This moves forward with gtk4 support, while also allowing a global menu
+for environments which use one, such as GNOME.
+
+I also added shortcuts so that users can press ^Q, ^R and ^S to quit,
+refresh and save.
+
+---
+ src/gui/gtk-lshw.c  |   2 +-
+ src/gui/gtk-lshw.ui | 138 ++++++++++++--------------------------------
+ src/gui/stock.c     |   6 +-
+ src/gui/stock.h     |   4 +-
+ 4 files changed, 47 insertions(+), 103 deletions(-)
+
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index 7b91ec5e4f01..d3e531c4ceb3 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -57,7 +57,7 @@ activate (GApplication *app,
+   g_simple_action_set_enabled(save_action, FALSE);
+ 
+   lshw_gtk_stock_init();
+-  lshw_ui_init();
++  lshw_ui_init(GTK_APPLICATION(app));
+ 
+   if(!mainwindow)
+     return;
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index 76fcd19379f2..cf9d678f00d9 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -103,7 +103,6 @@
+     </action-widgets>
+   </object>
+   <object class="GtkApplicationWindow" id="mainwindow">
+-    <property name="visible">True</property>
+     <property name="can_focus">False</property>
+     <property name="title" translatable="yes">lshw</property>
+     <property name="default_width">700</property>
+@@ -115,105 +114,6 @@
+         <property name="visible">True</property>
+         <property name="can_focus">False</property>
+         <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+-        <child>
+-          <object class="GtkMenuBar" id="menubar1">
+-            <property name="visible">True</property>
+-            <property name="can_focus">False</property>
+-            <child>
+-              <object class="GtkMenuItem" id="menuitem1">
+-                <property name="visible">True</property>
+-                <property name="can_focus">False</property>
+-                <property name="label" translatable="yes">_File</property>
+-                <property name="use_underline">True</property>
+-                <child type="submenu">
+-                  <object class="GtkMenu" id="menu1">
+-                    <property name="visible">True</property>
+-                    <property name="can_focus">False</property>
+-                    <child>
+-                      <object class="GtkImageMenuItem" id="savemenu">
+-                        <property name="label">gtk-save</property>
+-                        <property name="visible">True</property>
+-                        <property name="can_focus">False</property>
+-                        <property name="use_underline">True</property>
+-                        <property name="use_stock">True</property>
+-                        <property name="action_name">app.save</property>
+-                      </object>
+-                    </child>
+-                    <child>
+-                      <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
+-                        <property name="visible">True</property>
+-                        <property name="can_focus">False</property>
+-                      </object>
+-                    </child>
+-                    <child>
+-                      <object class="GtkImageMenuItem" id="imagemenuitem5">
+-                        <property name="label">gtk-quit</property>
+-                        <property name="visible">True</property>
+-                        <property name="can_focus">False</property>
+-                        <property name="use_underline">True</property>
+-                        <property name="use_stock">True</property>
+-                        <property name="action_name">app.quit</property>
+-                      </object>
+-                    </child>
+-                  </object>
+-                </child>
+-              </object>
+-            </child>
+-            <child>
+-              <object class="GtkMenuItem" id="menuitem3">
+-                <property name="visible">True</property>
+-                <property name="can_focus">False</property>
+-                <property name="label" translatable="yes">_View</property>
+-                <property name="use_underline">True</property>
+-                <child type="submenu">
+-                  <object class="GtkMenu" id="menu2">
+-                    <property name="visible">True</property>
+-                    <property name="can_focus">False</property>
+-                    <child>
+-                      <object class="GtkImageMenuItem" id="refresh1">
+-                        <property name="label">gtk-refresh</property>
+-                        <property name="visible">True</property>
+-                        <property name="can_focus">False</property>
+-                        <property name="use_underline">True</property>
+-                        <property name="use_stock">True</property>
+-                        <property name="action_name">app.refresh</property>
+-                      </object>
+-                    </child>
+-                  </object>
+-                </child>
+-              </object>
+-            </child>
+-            <child>
+-              <object class="GtkMenuItem" id="menuitem4">
+-                <property name="visible">True</property>
+-                <property name="can_focus">False</property>
+-                <property name="label" translatable="yes">_Help</property>
+-                <property name="use_underline">True</property>
+-                <child type="submenu">
+-                  <object class="GtkMenu" id="menu3">
+-                    <property name="visible">True</property>
+-                    <property name="can_focus">False</property>
+-                    <child>
+-                      <object class="GtkImageMenuItem" id="imagemenuitem10">
+-                        <property name="label">gtk-about</property>
+-                        <property name="visible">True</property>
+-                        <property name="can_focus">False</property>
+-                        <property name="use_underline">True</property>
+-                        <property name="use_stock">True</property>
+-                        <property name="action_name">app.about</property>
+-                      </object>
+-                    </child>
+-                  </object>
+-                </child>
+-              </object>
+-            </child>
+-          </object>
+-          <packing>
+-            <property name="expand">False</property>
+-            <property name="fill">True</property>
+-            <property name="position">0</property>
+-          </packing>
+-        </child>
+         <child>
+           <object class="GtkToolbar" id="toolbar1">
+             <property name="visible">True</property>
+@@ -423,4 +323,42 @@
+       </object>
+     </child>
+   </object>
++  <menu id="menubar">
++    <submenu>
++      <attribute name="label" translatable="yes">_File</attribute>
++      <section>
++        <item>
++          <attribute name="label" translatable="yes">_Save</attribute>
++          <attribute name="action">app.save</attribute>
++          <attribute name="accel">&lt;Control&gt;s</attribute>
++        </item>
++      </section>
++      <section>
++        <item>
++          <attribute name="label" translatable="yes">_Quit</attribute>
++          <attribute name="action">app.quit</attribute>
++          <attribute name="accel">&lt;Control&gt;q</attribute>
++        </item>
++      </section>
++    </submenu>
++    <submenu>
++      <attribute name="label" translatable="yes">_View</attribute>
++      <section>
++        <item>
++          <attribute name="label" translatable="yes">_Refresh</attribute>
++          <attribute name="action">app.refresh</attribute>
++          <attribute name="accel">&lt;Control&gt;r</attribute>
++        </item>
++      </section>
++    </submenu>
++    <submenu>
++      <attribute name="label" translatable="yes">_Help</attribute>
++      <section>
++        <item>
++          <attribute name="label" translatable="yes">_About</attribute>
++          <attribute name="action">app.about</attribute>
++        </item>
++      </section>
++    </submenu>
++  </menu>
+ </interface>
+diff --git a/src/gui/stock.c b/src/gui/stock.c
+index fa18f9ed7f85..ce0b42abea58 100644
+--- a/src/gui/stock.c
++++ b/src/gui/stock.c
+@@ -14,6 +14,7 @@ GtkWidget *list2 = NULL;
+ GtkWidget *list3 = NULL;
+ GtkWidget *description = NULL;
+ GtkWidget *statusbar = NULL;
++GMenuModel *menubar = NULL;
+ GHashTable *pixbufs = NULL;
+ 
+ static struct StockIcon
+@@ -118,7 +119,7 @@ lshw_gtk_stock_init(void)
+   (void) &id;                                     /* avoid "id defined but not used" warning */
+ }
+ 
+-void lshw_ui_init(void)
++void lshw_ui_init(GtkApplication *app)
+ {
+   GError *error = NULL;
+   GtkBuilder *builder = NULL;
+@@ -151,6 +152,9 @@ void lshw_ui_init(void)
+   description = GTK_WIDGET(gtk_builder_get_object( builder, "description"));
+   statusbar = GTK_WIDGET(gtk_builder_get_object( builder, "statusbar"));
+   gtk_builder_connect_signals( builder, mainwindow );
++  menubar = G_MENU_MODEL( gtk_builder_get_object( builder, "menubar"));
++  gtk_window_set_application( GTK_WINDOW( mainwindow ), app );
++  gtk_application_set_menubar( app, menubar );
+   g_object_unref( G_OBJECT( builder ) );
+ 
+   icon = g_hash_table_lookup(pixbufs, LSHW_STOCK_LOGO);
+diff --git a/src/gui/stock.h b/src/gui/stock.h
+index 58f788e5b573..1c732dfb541e 100644
+--- a/src/gui/stock.h
++++ b/src/gui/stock.h
+@@ -45,6 +45,8 @@
+  */
+ #define LSHW_DEFAULT_ICON_SIZE        40
+ 
++typedef struct _GtkApplication GtkApplication;
++
+ void lshw_gtk_stock_init(void);
+-void lshw_ui_init(void);
++void lshw_ui_init(GtkApplication *);
+ #endif                                            /* _STOCK_H_ */
+-- 
+2.17.1
+
diff --git a/SOURCES/0014-Replace-the-about-GtkDialog-with-a-GtkAboutDialog.patch b/SOURCES/0014-Replace-the-about-GtkDialog-with-a-GtkAboutDialog.patch
new file mode 100644
index 0000000..4e42e90
--- /dev/null
+++ b/SOURCES/0014-Replace-the-about-GtkDialog-with-a-GtkAboutDialog.patch
@@ -0,0 +1,252 @@
+From e96f82ce459a6d503f70d6c7b0f762bf0d133edf Mon Sep 17 00:00:00 2001
+From: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
+Date: Sat, 1 Aug 2020 15:03:23 +0200
+Subject: [PATCH 14/18] Replace the about GtkDialog with a GtkAboutDialog
+
+This reduces the amount of code needed for this feature, and integrates
+better with the rest of the system.
+---
+ src/gui/callbacks.c |  46 ++++++--------------
+ src/gui/callbacks.h |   4 --
+ src/gui/gtk-lshw.ui | 101 --------------------------------------------
+ src/gui/stock.c     |   2 -
+ 4 files changed, 12 insertions(+), 141 deletions(-)
+
+diff --git a/src/gui/callbacks.c b/src/gui/callbacks.c
+index eec3e5571741..b108777fe11f 100644
+--- a/src/gui/callbacks.c
++++ b/src/gui/callbacks.c
+@@ -10,7 +10,6 @@
+ #include "engine.h"
+ #include <string.h>
+ 
+-extern GtkWidget *about;
+ extern GtkWidget *mainwindow;
+ 
+ static char *id = "@(#) $Id$";
+@@ -42,18 +41,6 @@ on_save_activated                      (GSimpleAction   *action,
+   save_as(mainwindow);
+ }
+ 
+-G_MODULE_EXPORT
+-void
+-on_about_activated                     (GSimpleAction   *action,
+-                                        GVariant        *parameter,
+-                                        gpointer         app)
+-{
+-  if(GTK_IS_WIDGET(about))
+-  {
+-    gtk_widget_show(about);
+-  }
+-}
+-
+ G_MODULE_EXPORT
+ void
+ on_quit_activated                      (GSimpleAction   *action,
+@@ -65,25 +52,20 @@ on_quit_activated                      (GSimpleAction   *action,
+ 
+ G_MODULE_EXPORT
+ void
+-on_aboutclose_activate          (GtkButton       *button,
+-gpointer         user_data)
++on_about_activated                     (GSimpleAction   *action,
++                                        GVariant        *parameter,
++                                        gpointer         app)
+ {
+-  if(GTK_IS_WIDGET(about))
+-  {
+-    gtk_widget_hide(about);
+-  }
+-}
+-
++  gtk_show_about_dialog(GTK_WINDOW(mainwindow),
++                        "program-name", "GTK+ frontend for lshw",
++                        "website", "https://www.ezix.org/",
++                        "copyright", "© 2004-2011 Lyonel Vincent\n© 2020 Emmanuel Gil Peyrot",
++                        "version", getpackageversion(),
++                        "license-type", GTK_LICENSE_GPL_2_0,
++                        NULL);
+ 
+-G_MODULE_EXPORT
+-void
+-on_version_realize                     (GtkWidget       *widget,
+-gpointer         user_data)
+-{
+   const char *latest = checkupdates();
+ 
+-  gtk_label_set_text(GTK_LABEL(widget), getpackageversion());
+-
+   if(latest)
+   {
+     if(strcmp(latest, getpackageversion()) != 0)
+@@ -100,18 +82,14 @@ gpointer         user_data)
+                                   latest);
+ 
+         gtk_window_set_title(GTK_WINDOW(dialog), "Update available");
+-        /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
+-        g_signal_connect_swapped (dialog, "response",
+-                           G_CALLBACK (gtk_widget_destroy),
+-                           dialog);
+       }
+ 
+-      gtk_widget_show(dialog);
++      gtk_dialog_run(GTK_DIALOG(dialog));
++      gtk_widget_destroy(dialog);
+     }
+   }
+ }
+ 
+-
+ G_MODULE_EXPORT
+ void
+ on_treeview1_row_activated             (GtkTreeView     *treeview,
+diff --git a/src/gui/callbacks.h b/src/gui/callbacks.h
+index b9b9141c0eb7..e7636efdcae5 100644
+--- a/src/gui/callbacks.h
++++ b/src/gui/callbacks.h
+@@ -25,10 +25,6 @@ on_quit_activated                      (GSimpleAction   *action,
+                                         GVariant        *parameter,
+                                         gpointer         app);
+ 
+-void on_aboutclose_activate (GtkButton * button, gpointer user_data);
+-
+-void on_version_realize (GtkWidget * widget, gpointer user_data);
+-
+ void
+ on_treeview1_row_activated (GtkTreeView * treeview,
+ 			    GtkTreePath * path,
+diff --git a/src/gui/gtk-lshw.ui b/src/gui/gtk-lshw.ui
+index b61bedf501ee..57817fd58b39 100644
+--- a/src/gui/gtk-lshw.ui
++++ b/src/gui/gtk-lshw.ui
+@@ -1,107 +1,6 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <interface>
+   <requires lib="gtk+" version="3.22"/>
+-  <object class="GtkDialog" id="aboutlshw">
+-    <property name="can_focus">False</property>
+-    <property name="title" translatable="yes">About</property>
+-    <property name="resizable">False</property>
+-    <property name="window_position">center-on-parent</property>
+-    <property name="destroy_with_parent">True</property>
+-    <property name="type_hint">dialog</property>
+-    <property name="skip_taskbar_hint">True</property>
+-    <property name="skip_pager_hint">True</property>
+-    <child internal-child="vbox">
+-      <object class="GtkBox" id="dialog-vbox1">
+-        <property name="visible">True</property>
+-        <property name="can_focus">False</property>
+-        <property name="orientation">vertical</property>
+-        <child internal-child="action_area">
+-          <object class="GtkButtonBox" id="dialog-action_area1">
+-            <property name="visible">True</property>
+-            <property name="can_focus">False</property>
+-            <property name="layout_style">end</property>
+-            <child>
+-              <object class="GtkButton" id="closebutton1">
+-                <property name="label">gtk-close</property>
+-                <property name="visible">True</property>
+-                <property name="can_focus">True</property>
+-                <property name="can_default">True</property>
+-                <property name="receives_default">False</property>
+-                <property name="use_stock">True</property>
+-                <signal name="activate" handler="on_aboutclose_activate" swapped="no"/>
+-                <signal name="clicked" handler="on_aboutclose_activate" swapped="no"/>
+-              </object>
+-              <packing>
+-                <property name="expand">False</property>
+-                <property name="fill">True</property>
+-                <property name="position">0</property>
+-              </packing>
+-            </child>
+-          </object>
+-          <packing>
+-            <property name="expand">False</property>
+-            <property name="fill">True</property>
+-            <property name="pack_type">end</property>
+-            <property name="position">0</property>
+-          </packing>
+-        </child>
+-        <child>
+-          <object class="GtkLabel" id="aboutext">
+-            <property name="visible">True</property>
+-            <property name="can_focus">False</property>
+-            <property name="xpad">20</property>
+-            <property name="ypad">20</property>
+-            <property name="label" translatable="yes">&lt;big&gt;&lt;b&gt;GTK+ front-end for &lt;tt&gt;lshw&lt;/tt&gt;&lt;/b&gt;&lt;/big&gt;
+-
+-© 2004-2011 Lyonel Vincent
+-&lt;tt&gt;lyonel@ezix.org&lt;/tt&gt;</property>
+-            <property name="use_markup">True</property>
+-            <property name="justify">center</property>
+-            <property name="mnemonic_widget">closebutton1</property>
+-          </object>
+-          <packing>
+-            <property name="expand">False</property>
+-            <property name="fill">False</property>
+-            <property name="position">1</property>
+-          </packing>
+-        </child>
+-        <child>
+-          <object class="GtkLinkButton" id="linkbutton1">
+-            <property name="label" translatable="yes">http://www.ezix.org/</property>
+-            <property name="visible">True</property>
+-            <property name="can_focus">True</property>
+-            <property name="receives_default">True</property>
+-            <property name="has_tooltip">True</property>
+-            <property name="relief">none</property>
+-            <property name="uri">http://www.ezix.org/</property>
+-          </object>
+-          <packing>
+-            <property name="expand">False</property>
+-            <property name="fill">True</property>
+-            <property name="position">2</property>
+-          </packing>
+-        </child>
+-        <child>
+-          <object class="GtkLabel" id="version">
+-            <property name="visible">True</property>
+-            <property name="can_focus">False</property>
+-            <property name="label" translatable="yes">VERSION</property>
+-            <property name="justify">center</property>
+-            <property name="mnemonic_widget">closebutton1</property>
+-            <signal name="realize" handler="on_version_realize" swapped="no"/>
+-          </object>
+-          <packing>
+-            <property name="expand">False</property>
+-            <property name="fill">False</property>
+-            <property name="position">3</property>
+-          </packing>
+-        </child>
+-      </object>
+-    </child>
+-    <action-widgets>
+-      <action-widget response="-7">closebutton1</action-widget>
+-    </action-widgets>
+-  </object>
+   <object class="GtkApplicationWindow" id="mainwindow">
+     <property name="can_focus">False</property>
+     <property name="title" translatable="yes">lshw</property>
+diff --git a/src/gui/stock.c b/src/gui/stock.c
+index 7b98c642d43f..db2e98189662 100644
+--- a/src/gui/stock.c
++++ b/src/gui/stock.c
+@@ -9,7 +9,6 @@ static char *id = "@(#) $Id$";
+ #define UIFILE "gtk-lshw.ui"
+ 
+ GtkWidget *mainwindow = NULL;
+-GtkWidget *about = NULL;
+ GtkWidget *list1 = NULL;
+ GtkWidget *list2 = NULL;
+ GtkWidget *list3 = NULL;
+@@ -146,7 +145,6 @@ void lshw_ui_init(GtkApplication *app)
+   g_free(uiname);
+ 
+   mainwindow = GTK_WIDGET( gtk_builder_get_object( builder, "mainwindow" ) );
+-  about = GTK_WIDGET( gtk_builder_get_object( builder, "aboutlshw" ) );
+   list1 = GTK_WIDGET(gtk_builder_get_object( builder, "treeview1"));
+   list2 = GTK_WIDGET(gtk_builder_get_object( builder, "treeview2"));
+   list3 = GTK_WIDGET(gtk_builder_get_object( builder, "treeview3"));
+-- 
+2.17.1
+
diff --git a/SOURCES/0015-Update-docs-TODO.patch b/SOURCES/0015-Update-docs-TODO.patch
new file mode 100644
index 0000000..2bc6614
--- /dev/null
+++ b/SOURCES/0015-Update-docs-TODO.patch
@@ -0,0 +1,22 @@
+From 60c906d385b933fb6f5f0f2b14bfc9ea6de43a99 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Fri, 21 Aug 2020 11:38:20 +0200
+Subject: [PATCH 15/18] Update 'docs/TODO'
+
+---
+ docs/TODO | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/docs/TODO b/docs/TODO
+index 1e74710cb37b..ff0f288e2333 100644
+--- a/docs/TODO
++++ b/docs/TODO
+@@ -7,3 +7,5 @@
+  * use businfo to find CPUs instead of hardcoding cpu:n form
+  * use sysfs for PCMCIA access
+  * use MPTABLE for reporting of CPUs
++
++report SSD/rotational devices: /sys/block/DEV/queue/rotational
+-- 
+2.17.1
+
diff --git a/SOURCES/0016-Update-docs-TODO.patch b/SOURCES/0016-Update-docs-TODO.patch
new file mode 100644
index 0000000..f6b8b3e
--- /dev/null
+++ b/SOURCES/0016-Update-docs-TODO.patch
@@ -0,0 +1,22 @@
+From 358e65f92dec01f13b632d1d13fb8c76e1d50ca4 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Wed, 26 Aug 2020 23:36:59 +0200
+Subject: [PATCH 16/18] Update 'docs/TODO'
+
+---
+ docs/TODO | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/docs/TODO b/docs/TODO
+index ff0f288e2333..0b337826dc86 100644
+--- a/docs/TODO
++++ b/docs/TODO
+@@ -9,3 +9,4 @@
+  * use MPTABLE for reporting of CPUs
+ 
+ report SSD/rotational devices: /sys/block/DEV/queue/rotational
++better handle containers
+\ No newline at end of file
+-- 
+2.17.1
+
diff --git a/SOURCES/0017-update-man-page.patch b/SOURCES/0017-update-man-page.patch
new file mode 100644
index 0000000..1c4ddc2
--- /dev/null
+++ b/SOURCES/0017-update-man-page.patch
@@ -0,0 +1,77 @@
+From 2c235e6bf21e30b8e2da4d20f358df1e540a5b69 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Thu, 15 Oct 2020 14:11:58 +0200
+Subject: [PATCH 17/18] update man page
+
+add `-notime` option
+
+---
+ src/lshw.1    | 9 ++++++---
+ src/lshw.sgml | 5 +++++
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/src/lshw.1 b/src/lshw.1
+index 79c36197c32d..ae6fa34cea50 100644
+--- a/src/lshw.1
++++ b/src/lshw.1
+@@ -1,5 +1,5 @@
+ .\" auto-generated by docbook2man-spec from docbook-utils package
+-.TH "LSHW" "1" "28 January 2018" "$Rev$" ""
++.TH "LSHW" "1" "15 October 2020" "$Rev$" ""
+ .SH NAME
+ lshw \- list hardware
+ .SH SYNOPSIS
+@@ -10,7 +10,7 @@ lshw \- list hardware
+ .sp
+ \fBlshw\fR [ \fB-X\fR ] 
+ .sp
+-\fBlshw\fR [ \fB [ -html ]  [ -short ]  [ -xml ]  [ -json ]  [ -businfo ] \fR ]  [ \fB-dump \fIfilename\fB\fR ]  [ \fB-class \fIclass\fB\fR\fI...\fR ]  [ \fB-disable \fItest\fB\fR\fI...\fR ]  [ \fB-enable \fItest\fB\fR\fI...\fR ]  [ \fB-sanitize\fR ]  [ \fB-numeric\fR ]  [ \fB-quiet\fR ] 
++\fBlshw\fR [ \fB [ -html ]  [ -short ]  [ -xml ]  [ -json ]  [ -businfo ] \fR ]  [ \fB-dump \fIfilename\fB\fR ]  [ \fB-class \fIclass\fB\fR\fI...\fR ]  [ \fB-disable \fItest\fB\fR\fI...\fR ]  [ \fB-enable \fItest\fB\fR\fI...\fR ]  [ \fB-sanitize\fR ]  [ \fB-numeric\fR ]  [ \fB-quiet\fR ]  [ \fB-notime\fR ] 
+ .SH "DESCRIPTION"
+ .PP
+ 
+@@ -53,7 +53,7 @@ Outputs the device tree showing hardware paths, very much like the output of HP-
+ Outputs the device list showing bus information, detailing SCSI, USB, IDE and PCI addresses.
+ .TP
+ \fB-dump \fIfilename\fB\fR
+-Display output and dump collected information into a file (SQLite database).
++Dump collected information into a file (SQLite database).
+ .TP
+ \fB-class \fIclass\fB\fR
+ Only show the given class of hardware. \fIclass\fR can be found using \fBlshw -short\fR or \fBlshw -businfo\fR\&.
+@@ -74,6 +74,9 @@ Remove potentially sensitive information from output (IP addresses, serial numbe
+ .TP
+ \fB-numeric\fR
+ Also display numeric IDs (for PCI and USB devices).
++.TP
++\fB-notime\fR
++Exclude volatile attributes (timestamps) from output.
+ .SH "BUGS"
+ .PP
+ \fBlshw\fR currently does not detect 
+diff --git a/src/lshw.sgml b/src/lshw.sgml
+index 8c1c49e0898b..5e92cbfd4665 100644
+--- a/src/lshw.sgml
++++ b/src/lshw.sgml
+@@ -43,6 +43,7 @@ list hardware
+ 	<arg choice="opt"><option>-sanitize</option></arg>
+ 	<arg choice="opt"><option>-numeric</option></arg>
+ 	<arg choice="opt"><option>-quiet</option></arg>
++	<arg choice="opt"><option>-notime</option></arg>
+    </cmdsynopsis>
+ </refsynopsisdiv>
+ 
+@@ -126,6 +127,10 @@ Remove potentially sensitive information from output (IP addresses, serial numbe
+ <listitem><para>
+ Also display numeric IDs (for PCI and USB devices).
+ </para></listitem></varlistentry>
++<varlistentry><term>-notime</term>
++<listitem><para>
++Exclude volatile attributes (timestamps) from output.
++</para></listitem></varlistentry>
+ </variablelist>
+ </para>
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/0018-fix-man-page-after-previous-update.patch b/SOURCES/0018-fix-man-page-after-previous-update.patch
new file mode 100644
index 0000000..2ba2c84
--- /dev/null
+++ b/SOURCES/0018-fix-man-page-after-previous-update.patch
@@ -0,0 +1,41 @@
+From 56f1de9d1e4d6ff92d98530c0d3d91b353a311b9 Mon Sep 17 00:00:00 2001
+From: Lyonel Vincent <lyonel@ezix.org>
+Date: Thu, 15 Oct 2020 14:22:05 +0200
+Subject: [PATCH 18/18] fix man page after previous update
+
+SGML source was not in sync with man page
+
+---
+ src/lshw.1    | 2 +-
+ src/lshw.sgml | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/lshw.1 b/src/lshw.1
+index ae6fa34cea50..74b0e42afcad 100644
+--- a/src/lshw.1
++++ b/src/lshw.1
+@@ -53,7 +53,7 @@ Outputs the device tree showing hardware paths, very much like the output of HP-
+ Outputs the device list showing bus information, detailing SCSI, USB, IDE and PCI addresses.
+ .TP
+ \fB-dump \fIfilename\fB\fR
+-Dump collected information into a file (SQLite database).
++Display output and dump collected information into a file (SQLite database).
+ .TP
+ \fB-class \fIclass\fB\fR
+ Only show the given class of hardware. \fIclass\fR can be found using \fBlshw -short\fR or \fBlshw -businfo\fR\&.
+diff --git a/src/lshw.sgml b/src/lshw.sgml
+index 5e92cbfd4665..d190279e96d5 100644
+--- a/src/lshw.sgml
++++ b/src/lshw.sgml
+@@ -101,7 +101,7 @@ Outputs the device list showing bus information, detailing <productname>SCSI</pr
+ </para></listitem></varlistentry>
+ <varlistentry><term>-dump <replaceable class="parameter">filename</replaceable></term>
+ <listitem><para>
+-Dump collected information into a file (SQLite database).
++Display output and dump collected information into a file (SQLite database).
+ </para></listitem></varlistentry>
+ <varlistentry><term>-class <replaceable class="parameter">class</replaceable></term>
+ <listitem><para>
+-- 
+2.17.1
+
diff --git a/SOURCES/rhelonly-cleanup-remove-unused-support.c-support.h-generated-.patch b/SOURCES/rhelonly-cleanup-remove-unused-support.c-support.h-generated-.patch
new file mode 100644
index 0000000..3fbba0f
--- /dev/null
+++ b/SOURCES/rhelonly-cleanup-remove-unused-support.c-support.h-generated-.patch
@@ -0,0 +1,263 @@
+From 9093e083aa78aee6b85345e8fd15424549d01cac Mon Sep 17 00:00:00 2001
+From: Lianbo Jiang <lijiang@redhat.com>
+Date: Thu, 3 Dec 2020 10:58:33 +0800
+Subject: [PATCH] cleanup: remove unused support.c/support.h generated by Glade
+
+The support.c and support.h are automatically generated by Glade, and these
+files are not used any more, so let's remove the redundant files and make a
+cleanup, which can also make ninja-build happy.
+
+Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
+---
+ src/gui/callbacks.c |   1 -
+ src/gui/engine.cc   |   5 --
+ src/gui/gtk-lshw.c  |   1 -
+ src/gui/support.c   | 144 --------------------------------------------
+ src/gui/support.h   |  44 --------------
+ 5 files changed, 195 deletions(-)
+ delete mode 100644 src/gui/support.c
+ delete mode 100644 src/gui/support.h
+
+diff --git a/src/gui/callbacks.c b/src/gui/callbacks.c
+index b108777fe11f..6b88c82e6098 100644
+--- a/src/gui/callbacks.c
++++ b/src/gui/callbacks.c
+@@ -5,7 +5,6 @@
+ #include <gtk/gtk.h>
+ 
+ #include "callbacks.h"
+-#include "support.h"
+ #include "version.h"
+ #include "engine.h"
+ #include <string.h>
+diff --git a/src/gui/engine.cc b/src/gui/engine.cc
+index 2962ec80d81a..b537ef11db23 100644
+--- a/src/gui/engine.cc
++++ b/src/gui/engine.cc
+@@ -15,11 +15,6 @@
+ 
+ static const char *id = "@(#) $Id$";
+ 
+-extern "C"
+-{
+-#include "support.h"
+-};
+-
+ #define AUTOMATIC "automatic file format"
+ #define LSHW_XML "lshw XML format (.lshw, .xml)"
+ #define PLAIN_TEXT "plain text document (.text, .txt)"
+diff --git a/src/gui/gtk-lshw.c b/src/gui/gtk-lshw.c
+index d3e531c4ceb3..090484317c6e 100644
+--- a/src/gui/gtk-lshw.c
++++ b/src/gui/gtk-lshw.c
+@@ -2,7 +2,6 @@
+ #include <unistd.h>
+ #include <gtk/gtk.h>
+ 
+-#include "support.h"
+ #include "config.h"
+ #include "stock.h"
+ #include "engine.h"
+diff --git a/src/gui/support.c b/src/gui/support.c
+deleted file mode 100644
+index 7dc3c78cb605..000000000000
+--- a/src/gui/support.c
++++ /dev/null
+@@ -1,144 +0,0 @@
+-/*
+- * DO NOT EDIT THIS FILE - it is generated by Glade.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#  include <config.h>
+-#endif
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <stdio.h>
+-
+-#include <gtk/gtk.h>
+-
+-#include "support.h"
+-
+-GtkWidget*
+-lookup_widget                          (GtkWidget       *widget,
+-                                        const gchar     *widget_name)
+-{
+-  GtkWidget *parent, *found_widget;
+-
+-  for (;;)
+-    {
+-      if (GTK_IS_MENU (widget))
+-        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+-      else
+-        parent = widget->parent;
+-      if (!parent)
+-        parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
+-      if (parent == NULL)
+-        break;
+-      widget = parent;
+-    }
+-
+-  found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
+-                                                 widget_name);
+-  if (!found_widget)
+-    g_warning ("Widget not found: %s", widget_name);
+-  return found_widget;
+-}
+-
+-static GList *pixmaps_directories = NULL;
+-
+-/* Use this function to set the directory containing installed pixmaps. */
+-void
+-add_pixmap_directory                   (const gchar     *directory)
+-{
+-  pixmaps_directories = g_list_prepend (pixmaps_directories,
+-                                        g_strdup (directory));
+-}
+-
+-/* This is an internally used function to find pixmap files. */
+-static gchar*
+-find_pixmap_file                       (const gchar     *filename)
+-{
+-  GList *elem;
+-
+-  /* We step through each of the pixmaps directory to find it. */
+-  elem = pixmaps_directories;
+-  while (elem)
+-    {
+-      gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
+-                                         G_DIR_SEPARATOR_S, filename);
+-      if (g_file_test (pathname, G_FILE_TEST_EXISTS))
+-        return pathname;
+-      g_free (pathname);
+-      elem = elem->next;
+-    }
+-  return NULL;
+-}
+-
+-/* This is an internally used function to create pixmaps. */
+-GtkWidget*
+-create_pixmap                          (GtkWidget       *widget,
+-                                        const gchar     *filename)
+-{
+-  gchar *pathname = NULL;
+-  GtkWidget *pixmap;
+-
+-  if (!filename || !filename[0])
+-      return gtk_image_new ();
+-
+-  pathname = find_pixmap_file (filename);
+-
+-  if (!pathname)
+-    {
+-      g_warning ("Couldn't find pixmap file: %s", filename);
+-      return gtk_image_new ();
+-    }
+-
+-  pixmap = gtk_image_new_from_file (pathname);
+-  g_free (pathname);
+-  return pixmap;
+-}
+-
+-/* This is an internally used function to create pixmaps. */
+-GdkPixbuf*
+-create_pixbuf                          (const gchar     *filename)
+-{
+-  gchar *pathname = NULL;
+-  GdkPixbuf *pixbuf;
+-  GError *error = NULL;
+-
+-  if (!filename || !filename[0])
+-      return NULL;
+-
+-  pathname = find_pixmap_file (filename);
+-
+-  if (!pathname)
+-    {
+-      g_warning ("Couldn't find pixmap file: %s", filename);
+-      return NULL;
+-    }
+-
+-  pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
+-  if (!pixbuf)
+-    {
+-      fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
+-               pathname, error->message);
+-      g_error_free (error);
+-    }
+-  g_free (pathname);
+-  return pixbuf;
+-}
+-
+-/* This is used to set ATK action descriptions. */
+-void
+-glade_set_atk_action_description       (AtkAction       *action,
+-                                        const gchar     *action_name,
+-                                        const gchar     *description)
+-{
+-  gint n_actions, i;
+-
+-  n_actions = atk_action_get_n_actions (action);
+-  for (i = 0; i < n_actions; i++)
+-    {
+-      if (!strcmp (atk_action_get_name (action, i), action_name))
+-        atk_action_set_description (action, i, description);
+-    }
+-}
+-
+diff --git a/src/gui/support.h b/src/gui/support.h
+deleted file mode 100644
+index 2dea079c2a42..000000000000
+--- a/src/gui/support.h
++++ /dev/null
+@@ -1,44 +0,0 @@
+-/*
+- * DO NOT EDIT THIS FILE - it is generated by Glade.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#  include <config.h>
+-#endif
+-
+-#include <gtk/gtk.h>
+-
+-/*
+- * Public Functions.
+- */
+-
+-/*
+- * This function returns a widget in a component created by Glade.
+- * Call it with the toplevel widget in the component (i.e. a window/dialog),
+- * or alternatively any widget in the component, and the name of the widget
+- * you want returned.
+- */
+-GtkWidget*  lookup_widget              (GtkWidget       *widget,
+-                                        const gchar     *widget_name);
+-
+-
+-/* Use this function to set the directory containing installed pixmaps. */
+-void        add_pixmap_directory       (const gchar     *directory);
+-
+-
+-/*
+- * Private Functions.
+- */
+-
+-/* This is used to create the pixmaps used in the interface. */
+-GtkWidget*  create_pixmap              (GtkWidget       *widget,
+-                                        const gchar     *filename);
+-
+-/* This is used to create the pixbufs used in the interface. */
+-GdkPixbuf*  create_pixbuf              (const gchar     *filename);
+-
+-/* This is used to set ATK action descriptions. */
+-void        glade_set_atk_action_description (AtkAction       *action,
+-                                              const gchar     *action_name,
+-                                              const gchar     *description);
+-
+-- 
+2.17.1
+
diff --git a/SPECS/lshw.spec b/SPECS/lshw.spec
index ff10c0c..10fe40c 100644
--- a/SPECS/lshw.spec
+++ b/SPECS/lshw.spec
@@ -1,7 +1,7 @@
 Summary:       Hardware lister
 Name:          lshw
 Version:       B.02.19.2
-Release:       2%{?dist}
+Release:       5%{?dist}
 License:       GPLv2
 Group:         Applications/System
 URL:           http://ezix.org/project/wiki/HardwareLiSter
@@ -27,13 +27,34 @@ Patch18:       0014-devtree-Add-capabilites-to-the-OPAL-Firmware.patch
 Patch19:       0015-fix-issue-with-logical-names-being-truncated-dev-sda.patch
 Patch20:       0016-code-clean-up-for-read-3.patch
 Patch21:       0017-report-product-model-on-Power-systems.patch
+Patch22:       0001-Fix-few-memory-leaks.patch
+Patch23:       0002-Build-against-gtk3-instead-of-gtk2.patch
+Patch24:       0003-Remove-deprecated-stock-messages.patch
+Patch25:       0004-Remove-hack-which-is-apparently-not-useful-anymore.patch
+Patch26:       0005-Use-GtkFileChooserNative-instead-of-GtkFileChooserDi.patch
+Patch27:       0006-Replace-deprecated-GtkIconFactory-with-GHashTable.patch
+Patch28:       0007-Replace-the-last-GtkStock-in-overwrite-dialog.patch
+Patch29:       0008-Remove-deprecated-widgets.patch
+Patch30:       0009-Remove-deprecated-use_action_appearance-property.patch
+Patch31:       0010-Move-to-GtkApplication.patch
+Patch32:       0011-Replace-signals-with-GSimpleActions.patch
+Patch33:       0012-Enable-Disable-GSimpleAction-instead-of-button-sensi.patch
+Patch34:       0013-Move-from-GtkMenuBar-to-GMenu.patch
+Patch35:       0014-Replace-the-about-GtkDialog-with-a-GtkAboutDialog.patch
+Patch36:       0015-Update-docs-TODO.patch
+Patch37:       0016-Update-docs-TODO.patch
+Patch38:       0017-update-man-page.patch
+Patch39:       0018-fix-man-page-after-previous-update.patch
+Patch40:       rhelonly-cleanup-remove-unused-support.c-support.h-generated-.patch
+Patch41:       0001-Report-correct-memory-size-on-SMBIOS-2.7.patch
+Patch42:       0001-devtree-Add-UUID-property.patch
 
 BuildRequires: cmake
 BuildRequires: desktop-file-utils
 BuildRequires: gcc
 BuildRequires: gcc-c++
 BuildRequires: gettext
-BuildRequires: gtk2-devel >= 2.4
+BuildRequires: gtk3-devel >= 3.22
 BuildRequires: libappstream-glib
 BuildRequires: ninja-build
 BuildRequires: python3-devel
@@ -53,6 +74,7 @@ Information can be output in plain text, XML or HTML.
 Summary:       Graphical hardware lister
 Group:         Applications/System
 Requires:      polkit
+Requires:      gtk3 >= 3.22
 Requires:      %{name} = %{version}-%{release}
 %description   gui
 Graphical frontend for the hardware lister (lshw) tool. If desired,
@@ -82,6 +104,27 @@ format.
 %patch19 -p1
 %patch20 -p1
 %patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
+%patch40 -p1
+%patch41 -p1
+%patch42 -p1
 
 %build
 mkdir build && pushd build
@@ -129,6 +172,18 @@ src/lshw -json \
 %{_datadir}/polkit-1/actions/org.ezix.lshw.gui.policy
 
 %changelog
+* Tue Feb 02 2021 Lianbo Jiang <lijiang@redhat.com> - B.02.19.2-5
+- Fix the wrong memory information in azure m or mv2 series
+- Add UUID property to PowerVM LPAR
+
+* Wed Dec 16 2020 Lianbo Jiang <lijiang@redhat.com> - B.02.19.2-4
+- Fix the gtk3 dependency for lshw-gui instead of lshw
+- Resolves: rhbz#1905816
+
+* Thu Dec 03 2020 Lianbo Jiang <lijiang@redhat.com> - B.02.19.2-3
+- Update to upstream master 56f1de9d1e4d
+- Resolves: rhbz#1844426
+
 * Wed May 27 2020 Lianbo Jiang <lijiang@redhat.com> - B.02.19.2-2
 - Update to upstream master 3775782808e8