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
1=== modified file 'softwareproperties/gtk/SoftwarePropertiesGtk.py'
2--- softwareproperties/gtk/SoftwarePropertiesGtk.py 2013-04-30 15:06:14 +0000
3+++ softwareproperties/gtk/SoftwarePropertiesGtk.py 2013-05-25 08:22:25 +0000
4@@ -34,8 +34,10 @@
5 from aptdaemon import client
6 from aptdaemon.errors import NotAuthorizedError, TransactionFailed
7 import logging
8+import threading
9+import sys
10
11-from gi.repository import GObject, Gdk, Gtk, Gio
12+from gi.repository import GObject, Gdk, Gtk, Gio, GLib
13
14 from .SimpleGtkbuilderApp import SimpleGtkbuilderApp
15 from .DialogAdd import DialogAdd
16@@ -51,6 +53,9 @@
17
18 from UbuntuDrivers import detect
19
20+if GLib.pyglib_version < (3, 9, 1):
21+ GLib.threads_init()
22+
23 (LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3)
24
25 (
26@@ -119,8 +124,6 @@
27 self.window_main.set_transient_for(toplevel)
28 except:
29 pass
30- if options and options.open_tab:
31- self.notebook_main.set_current_page(int(options.open_tab))
32
33 # gsettings
34 all_schemas = Gio.Settings.list_schemas()
35@@ -154,7 +157,7 @@
36 # used to store the handlers of callbacks
37 self.handlers = {}
38
39- self.apt_cache = apt.Cache()
40+ self.apt_cache = {}
41 self.apt_client = client.AptClient()
42
43 # Put some life into the user interface:
44@@ -173,9 +176,14 @@
45 self.show_distro()
46 # Setup and show the Additonal Drivers tab
47 self.init_drivers()
48- self.show_drivers()
49
50+ # Connect to switch-page before setting initial tab. Otherwise the
51+ # first switch goes unnoticed.
52 self.notebook_main.connect("switch-page", self.on_main_notebook_page_switched)
53+
54+ if options and options.open_tab:
55+ self.notebook_main.set_current_page(int(options.open_tab))
56+
57 # Show the import/replace sources.list dialog if a file different
58 # to the default sources.list was specified
59 # NOTE: If the file path points to the default sources.list the user
60@@ -192,6 +200,8 @@
61 # On the additional drivers page, don't show the backend revert button.
62 if page == self.vbox_drivers:
63 self.button_revert.set_visible(False)
64+ if not self.detect_called:
65+ GLib.idle_add(lambda: threading.Thread(target=self.detect_drivers).start())
66 else:
67 self.button_revert.set_visible(True)
68
69@@ -1105,11 +1115,18 @@
70 self.box_driver_action.pack_end(self.button_driver_restart, False, False, 0)
71 self.box_driver_action.pack_end(self.button_driver_cancel, False, False, 0)
72
73+ props = {"halign":Gtk.Align.CENTER, "valign":Gtk.Align.CENTER,
74+ "vexpand":True, "visible":True}
75+ self.label_driver_detail = Gtk.Label(_("Searching for available "
76+ "drivers..."), **props)
77+ self.box_driver_detail.add(self.label_driver_detail)
78+
79 self.progress_bar = Gtk.ProgressBar()
80 self.box_driver_action.pack_end(self.progress_bar, False, False, 0)
81 self.progress_bar.set_visible(False)
82
83- self.devices = detect.system_device_drivers()
84+ self.devices = {}
85+ self.detect_called = False
86 self.driver_changes = []
87 self.orig_selection = {}
88 # HACK: the case where the selection is actually "Do not use"; is a little
89@@ -1121,6 +1138,24 @@
90 self.nonfree_drivers = 0
91 self.ui_building = False
92
93+ def detect_drivers(self):
94+ # WARNING: This is run in a separate thread.
95+ self.detect_called = True
96+ try:
97+ self.apt_cache = apt.Cache()
98+ self.devices = detect.system_device_drivers(self.apt_cache)
99+ except:
100+ # Catch all exceptions and feed them to apport.
101+ GLib.idle_add(self.label_driver_detail.set_text,
102+ _("An error occured while searching for drivers."))
103+
104+ # For apport to catch this exception. See
105+ # http://bugs.python.org/issue1230540
106+ sys.excepthook(*sys.exc_info())
107+ return
108+
109+ GLib.idle_add(self.show_drivers)
110+
111 def on_driver_selection_changed(self, button, modalias, pkg_name=None):
112 if self.ui_building:
113 return
114@@ -1274,6 +1309,12 @@
115 return (overall_status, icon, returned_drivers)
116
117 def show_drivers(self):
118+ if not self.devices:
119+ # No drivers found.
120+ self.label_driver_detail.set_text(_("No additional drivers available."))
121+ return
122+ else:
123+ self.box_driver_detail.remove(self.label_driver_detail)
124 self.ui_building = True
125 self.dynamic_device_status = {}
126 for device in sorted(self.devices.keys()):

Subscribers

People subscribed via source and target branches

to status/vote changes: