Merge lp:~sjakthol/software-properties/fix-1073728 into lp:software-properties

Proposed by Sami Jaktholm
Status: Merged
Merged at revision: 845
Proposed branch: lp:~sjakthol/software-properties/fix-1073728
Merge into: lp:software-properties
Diff against target: 126 lines (+47/-6)
1 file modified
softwareproperties/gtk/SoftwarePropertiesGtk.py (+47/-6)
To merge this branch: bzr merge lp:~sjakthol/software-properties/fix-1073728
Reviewer Review Type Date Requested Status
Ubuntu Core Development Team Pending
Review via email: mp+165737@code.launchpad.net

Commit message

-gtk: Open APT cache and detect drivers in a background thread asynchronously
      when user opens the Additional Drivers tab. This speeds up the startup
      considerably.

      Fixes LP: #1073728.

Description of the change

Here this dropped the startup time from 6.5 seconds to 0.3 seconds.

To post a comment you must log in.
Revision history for this message
Adolfo Jayme Barrientos (fitojb) wrote :

While I can't review your code, I just wanted to say thank you, Sami :-)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'softwareproperties/gtk/SoftwarePropertiesGtk.py'
--- softwareproperties/gtk/SoftwarePropertiesGtk.py 2013-04-30 15:06:14 +0000
+++ softwareproperties/gtk/SoftwarePropertiesGtk.py 2013-05-25 08:22:25 +0000
@@ -34,8 +34,10 @@
34from aptdaemon import client34from aptdaemon import client
35from aptdaemon.errors import NotAuthorizedError, TransactionFailed35from aptdaemon.errors import NotAuthorizedError, TransactionFailed
36import logging36import logging
37import threading
38import sys
3739
38from gi.repository import GObject, Gdk, Gtk, Gio40from gi.repository import GObject, Gdk, Gtk, Gio, GLib
3941
40from .SimpleGtkbuilderApp import SimpleGtkbuilderApp42from .SimpleGtkbuilderApp import SimpleGtkbuilderApp
41from .DialogAdd import DialogAdd43from .DialogAdd import DialogAdd
@@ -51,6 +53,9 @@
5153
52from UbuntuDrivers import detect54from UbuntuDrivers import detect
5355
56if GLib.pyglib_version < (3, 9, 1):
57 GLib.threads_init()
58
54(LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3)59(LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3)
5560
56(61(
@@ -119,8 +124,6 @@
119 self.window_main.set_transient_for(toplevel)124 self.window_main.set_transient_for(toplevel)
120 except:125 except:
121 pass126 pass
122 if options and options.open_tab:
123 self.notebook_main.set_current_page(int(options.open_tab))
124127
125 # gsettings128 # gsettings
126 all_schemas = Gio.Settings.list_schemas()129 all_schemas = Gio.Settings.list_schemas()
@@ -154,7 +157,7 @@
154 # used to store the handlers of callbacks157 # used to store the handlers of callbacks
155 self.handlers = {}158 self.handlers = {}
156159
157 self.apt_cache = apt.Cache()160 self.apt_cache = {}
158 self.apt_client = client.AptClient()161 self.apt_client = client.AptClient()
159162
160 # Put some life into the user interface:163 # Put some life into the user interface:
@@ -173,9 +176,14 @@
173 self.show_distro()176 self.show_distro()
174 # Setup and show the Additonal Drivers tab177 # Setup and show the Additonal Drivers tab
175 self.init_drivers()178 self.init_drivers()
176 self.show_drivers()
177179
180 # Connect to switch-page before setting initial tab. Otherwise the
181 # first switch goes unnoticed.
178 self.notebook_main.connect("switch-page", self.on_main_notebook_page_switched)182 self.notebook_main.connect("switch-page", self.on_main_notebook_page_switched)
183
184 if options and options.open_tab:
185 self.notebook_main.set_current_page(int(options.open_tab))
186
179 # Show the import/replace sources.list dialog if a file different187 # Show the import/replace sources.list dialog if a file different
180 # to the default sources.list was specified188 # to the default sources.list was specified
181 # NOTE: If the file path points to the default sources.list the user189 # NOTE: If the file path points to the default sources.list the user
@@ -192,6 +200,8 @@
192 # On the additional drivers page, don't show the backend revert button.200 # On the additional drivers page, don't show the backend revert button.
193 if page == self.vbox_drivers:201 if page == self.vbox_drivers:
194 self.button_revert.set_visible(False)202 self.button_revert.set_visible(False)
203 if not self.detect_called:
204 GLib.idle_add(lambda: threading.Thread(target=self.detect_drivers).start())
195 else:205 else:
196 self.button_revert.set_visible(True)206 self.button_revert.set_visible(True)
197207
@@ -1105,11 +1115,18 @@
1105 self.box_driver_action.pack_end(self.button_driver_restart, False, False, 0)1115 self.box_driver_action.pack_end(self.button_driver_restart, False, False, 0)
1106 self.box_driver_action.pack_end(self.button_driver_cancel, False, False, 0)1116 self.box_driver_action.pack_end(self.button_driver_cancel, False, False, 0)
11071117
1118 props = {"halign":Gtk.Align.CENTER, "valign":Gtk.Align.CENTER,
1119 "vexpand":True, "visible":True}
1120 self.label_driver_detail = Gtk.Label(_("Searching for available "
1121 "drivers..."), **props)
1122 self.box_driver_detail.add(self.label_driver_detail)
1123
1108 self.progress_bar = Gtk.ProgressBar()1124 self.progress_bar = Gtk.ProgressBar()
1109 self.box_driver_action.pack_end(self.progress_bar, False, False, 0)1125 self.box_driver_action.pack_end(self.progress_bar, False, False, 0)
1110 self.progress_bar.set_visible(False)1126 self.progress_bar.set_visible(False)
11111127
1112 self.devices = detect.system_device_drivers()1128 self.devices = {}
1129 self.detect_called = False
1113 self.driver_changes = []1130 self.driver_changes = []
1114 self.orig_selection = {}1131 self.orig_selection = {}
1115 # HACK: the case where the selection is actually "Do not use"; is a little1132 # HACK: the case where the selection is actually "Do not use"; is a little
@@ -1121,6 +1138,24 @@
1121 self.nonfree_drivers = 01138 self.nonfree_drivers = 0
1122 self.ui_building = False1139 self.ui_building = False
11231140
1141 def detect_drivers(self):
1142 # WARNING: This is run in a separate thread.
1143 self.detect_called = True
1144 try:
1145 self.apt_cache = apt.Cache()
1146 self.devices = detect.system_device_drivers(self.apt_cache)
1147 except:
1148 # Catch all exceptions and feed them to apport.
1149 GLib.idle_add(self.label_driver_detail.set_text,
1150 _("An error occured while searching for drivers."))
1151
1152 # For apport to catch this exception. See
1153 # http://bugs.python.org/issue1230540
1154 sys.excepthook(*sys.exc_info())
1155 return
1156
1157 GLib.idle_add(self.show_drivers)
1158
1124 def on_driver_selection_changed(self, button, modalias, pkg_name=None):1159 def on_driver_selection_changed(self, button, modalias, pkg_name=None):
1125 if self.ui_building:1160 if self.ui_building:
1126 return1161 return
@@ -1274,6 +1309,12 @@
1274 return (overall_status, icon, returned_drivers)1309 return (overall_status, icon, returned_drivers)
12751310
1276 def show_drivers(self):1311 def show_drivers(self):
1312 if not self.devices:
1313 # No drivers found.
1314 self.label_driver_detail.set_text(_("No additional drivers available."))
1315 return
1316 else:
1317 self.box_driver_detail.remove(self.label_driver_detail)
1277 self.ui_building = True1318 self.ui_building = True
1278 self.dynamic_device_status = {}1319 self.dynamic_device_status = {}
1279 for device in sorted(self.devices.keys()):1320 for device in sorted(self.devices.keys()):

Subscribers

People subscribed via source and target branches

to status/vote changes: