From ba3bc2afc2f3d4baec8b001ac9cc93e309c8b39a Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Tue, 16 Dec 2008 00:48:47 -0500 Subject: [PATCH] Only show valid wpa_supplicant drivers in the GUI. Don't needlessly created PreferenceDialog objects. Use dbus signals to alert the UI that the daemon is back up, instead of polling. --- wicd/backends/be-external.py | 4 + wicd/backends/be-ioctl.py | 4 + wicd/gui.py | 29 +++--- wicd/networking.py | 5 + wicd/prefs.py | 178 +++++++++++++++++++---------------- wicd/wicd-client.py | 24 ++--- wicd/wicd-daemon.py | 13 ++- wicd/wnettools.py | 10 ++ 8 files changed, 149 insertions(+), 118 deletions(-) diff --git a/wicd/backends/be-external.py b/wicd/backends/be-external.py index 024e0fa..801574d 100644 --- a/wicd/backends/be-external.py +++ b/wicd/backends/be-external.py @@ -98,6 +98,10 @@ def GetWiredInterfaces(*args, **kargs): """ Call the wnettools GetWiredInterfaces method. """ return wnettools.GetWiredInterfaces(*args, **kargs) +def IsValidWpaSuppDriver(*args, **kargs): + """ Call the wnettools IsValidWpaSuppDrive method. """ + return wnettools.IsValidWpaSuppDriver(*args, **kargs) + def NeedsExternalCalls(*args, **kargs): """ Return True, since this backend using iwconfig/ifconfig. """ return True diff --git a/wicd/backends/be-ioctl.py b/wicd/backends/be-ioctl.py index 18c1a94..b8d22ec 100644 --- a/wicd/backends/be-ioctl.py +++ b/wicd/backends/be-ioctl.py @@ -102,6 +102,10 @@ def GetWiredInterfaces(*args, **kargs): """ Call the wnettools GetWiredInterfaces method. """ return wnettools.GetWiredInterfaces(*args, **kargs) +def IsValidWpaSuppDriver(*args, **kargs): + """ Call the wnettools IsValidWpaSuppDrive method. """ + return wnettools.IsValidWpaSuppDriver(*args, **kargs) + def get_iw_ioctl_result(iface, call): """ Makes the given ioctl call and returns the results. diff --git a/wicd/gui.py b/wicd/gui.py index 261ed1b..7d9bbe7 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -85,21 +85,7 @@ def handle_no_dbus(from_tray=False): if from_tray: return False print "Wicd daemon is shutting down!" error(None, "The wicd daemon has shut down, the UI will not function properly until it is restarted.") - _wait_for_dbus() return False - -@misc.threaded -def _wait_for_dbus(): - global DBUS_AVAIL - while True: - time.sleep(10) - print "Trying to reconnect.." - if not setup_dbus(force=False): - print "Failed to reconnect to the daemon." - else: - print "Successfully reconnected to the daemon." - DBUS_AVAIL = True - return def error(parent, message): """ Shows an error dialog """ @@ -284,6 +270,7 @@ class appGui(object): self.first_dialog_load = True self.is_visible = True self.pulse_active = False + self.pref = None self.standalone = standalone self.wpadrivercombo = None self.connecting = False @@ -305,6 +292,8 @@ class appGui(object): if standalone: bus.add_signal_receiver(handle_no_dbus, "DaemonClosing", "org.wicd.daemon") + bus.add_signal_receiver(lambda: setup_dbus(force=False), + "DaemonStarting", "org.wicd.daemon") try: gobject.timeout_add_seconds(1, self.update_statusbar) except: @@ -384,10 +373,14 @@ class appGui(object): def settings_dialog(self, widget, event=None): """ Displays a general settings dialog. """ - pref = PreferencesDialog(self.wTree, dbusmanager.get_dbus_ifaces()) - if pref.run() == 1: - pref.save_results() - pref.hide() + if not self.pref: + self.pref = PreferencesDialog(self.wTree, + dbusmanager.get_dbus_ifaces()) + else: + self.pref.load_preferences_diag() + if self.pref.run() == 1: + self.pref.save_results() + self.pref.hide() def connect_hidden(self, widget): """ Prompts the user for a hidden network, then scans for it. """ diff --git a/wicd/networking.py b/wicd/networking.py index 11adcbf..b20be29 100644 --- a/wicd/networking.py +++ b/wicd/networking.py @@ -528,6 +528,11 @@ class Wireless(Controller): """ Get the out of iwconfig. """ return self.wiface.GetIwconfig() + def GetWpaSupplicantDrivers(self, drivers): + """ Returns all valid wpa_supplicant drivers in a list. """ + return [driver for driver in drivers if + BACKEND.IsValidWpaSuppDriver(driver)] + def IsUp(self): """ Calls the IsUp method for the wireless interface. diff --git a/wicd/prefs.py b/wicd/prefs.py index 23f18db..95a517f 100644 --- a/wicd/prefs.py +++ b/wicd/prefs.py @@ -27,6 +27,8 @@ handles recieving/sendings the settings from/to the daemon. import gtk import gobject import pango +import os +import gtk.glade from wicd import misc from wicd import wpath @@ -54,87 +56,28 @@ class PreferencesDialog(object): wireless = dbus['wireless'] wired = dbus['wired'] self.wTree = wTree + self.wpadrivers = None self.prep_settings_diag() - self.build_preferences_diag() + self.load_preferences_diag() - def build_preferences_diag(self): - """ Builds the preferences dialog window. """ - def build_combobox(lbl): - """ Sets up a ComboBox using the given widget name. """ - liststore = gtk.ListStore(gobject.TYPE_STRING) - combobox = self.wTree.get_widget(lbl) - combobox.clear() - combobox.set_model(liststore) - cell = gtk.CellRendererText() - combobox.pack_start(cell, True) - combobox.add_attribute(cell, 'text', 0) - return combobox + def load_preferences_diag(self): + """ Loads data into the preferences Dialog. """ - def setup_label(name, lbl=""): - """ Sets up a label for the given widget name. """ - widget = self.wTree.get_widget(name) - if lbl: - widget.set_label(language[lbl]) - return widget - - self.dialog = self.wTree.get_widget("pref_dialog") - self.dialog.set_title(language['preferences']) - if os.path.exists(os.path.join(wpath.images, "wicd.png")): - self.dialog.set_icon_from_file(os.path.join(wpath.images, "wicd.png")) - size = daemon.ReadWindowSize("pref") - width = size[0] - height = size[1] - if width > -1 and height > -1: - self.dialog.resize(int(width), int(height)) - else: - self.dialog.resize(gtk.gdk.screen_width() / 3, - gtk.gdk.screen_height() / 2) - - self.wiredcheckbox = setup_label("pref_always_check", - 'wired_always_on') self.wiredcheckbox.set_active(daemon.GetAlwaysShowWiredInterface()) - self.reconnectcheckbox = setup_label("pref_auto_check", - 'auto_reconnect') self.reconnectcheckbox.set_active(daemon.GetAutoReconnect()) - self.debugmodecheckbox = setup_label("pref_debug_check", - 'use_debug_mode') self.debugmodecheckbox.set_active(daemon.GetDebugMode()) - self.displaytypecheckbox = setup_label("pref_dbm_check", - 'display_type_dialog') self.displaytypecheckbox.set_active(daemon.GetSignalDisplayType()) - self.usedefaultradiobutton = setup_label("pref_use_def_radio", - 'use_default_profile') - self.showlistradiobutton = setup_label("pref_prompt_radio", - 'show_wired_list') - self.lastusedradiobutton = setup_label("pref_use_last_radio", - 'use_last_used_profile') - # DHCP Clients - self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config") - self.dhclientradio = self.wTree.get_widget("dhclient_radio") - self.pumpradio = self.wTree.get_widget("pump_radio") - self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio") dhcp_list = [self.dhcpautoradio, self.dhclientradio, self.dhcpcdradio, self.pumpradio] - dhcp_method = daemon.GetDHCPClient() dhcp_list[dhcp_method].set_active(True) - # Wired Link Detection Apps - self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config') - self.linkautoradio = setup_label("link_auto_radio") - self.ethtoolradio = setup_label("ethtool_radio") - self.miitoolradio = setup_label("miitool_radio") wired_link_list = [self.linkautoradio, self.ethtoolradio, self.miitoolradio] wired_link_method = daemon.GetLinkDetectionTool() wired_link_list[wired_link_method].set_active(True) - - # Route Flushing Apps - self.flushautoradio = setup_label("flush_auto_radio", - 'wicd_auto_config') - self.ipflushradio = setup_label("ip_flush_radio") - self.routeflushradio = setup_label("route_flush_radio") + flush_list = [self.flushautoradio, self.ipflushradio, self.routeflushradio] flush_method = daemon.GetFlushTool() @@ -148,16 +91,9 @@ class PreferencesDialog(object): elif auto_conn_meth == 3: self.lastusedradiobutton.set_active(True) - self.entryWirelessInterface = self.wTree.get_widget("pref_wifi_entry") self.entryWirelessInterface.set_text(daemon.GetWirelessInterface()) - - self.entryWiredInterface = self.wTree.get_widget("pref_wired_entry") self.entryWiredInterface.set_text(daemon.GetWiredInterface()) - # Replacement for the combo box hack - self.wpadrivercombo = build_combobox("pref_wpa_combobox") - self.wpadrivers = ["wext", "hostap", "madwifi", "atmel", "ndiswrapper", - "ipw", "ralink legacy"] found = False def_driver = daemon.GetWPADriver() for i, x in enumerate(self.wpadrivers): @@ -175,14 +111,6 @@ class PreferencesDialog(object): # Use wext as default, since normally it is the correct driver. self.wpadrivercombo.set_active(0) - # Set up global DNS stuff - self.useGlobalDNSCheckbox = setup_label("pref_global_check", - 'use_global_dns') - self.searchDomEntry = self.wTree.get_widget("pref_search_dom_entry") - self.dns1Entry = self.wTree.get_widget("pref_dns1_entry") - self.dns2Entry = self.wTree.get_widget("pref_dns2_entry") - self.dns3Entry = self.wTree.get_widget("pref_dns3_entry") - self.useGlobalDNSCheckbox.connect("toggled", checkboxTextboxToggle, (self.dns1Entry, self.dns2Entry, self.dns3Entry, self.searchDomEntry)) @@ -201,7 +129,6 @@ class PreferencesDialog(object): self.dns3Entry.set_sensitive(False) # Load backend combobox - self.backendcombo = build_combobox("pref_backend_combobox") self.backends = daemon.GetBackendList() # "" is included as a hack for DBus limitations, so we remove it. self.backends.remove("") @@ -229,9 +156,12 @@ class PreferencesDialog(object): """ Hides the preferences dialog window. """ self.dialog.hide() + def destroy(self): + self.dialog.destroy() + def show_all(self): """ Shows the preferences dialog window. """ - self.show_all() + self.dialog.show() def save_results(self): """ Pushes the selected settings to the daemon. """ @@ -290,6 +220,24 @@ class PreferencesDialog(object): def prep_settings_diag(self): """ Set up anything that doesn't have to be persisted later. """ + def build_combobox(lbl): + """ Sets up a ComboBox using the given widget name. """ + liststore = gtk.ListStore(gobject.TYPE_STRING) + combobox = self.wTree.get_widget(lbl) + combobox.clear() + combobox.set_model(liststore) + cell = gtk.CellRendererText() + combobox.pack_start(cell, True) + combobox.add_attribute(cell, 'text', 0) + return combobox + + def setup_label(name, lbl=""): + """ Sets up a label for the given widget name. """ + widget = self.wTree.get_widget(name) + if lbl: + widget.set_label(language[lbl]) + return widget + # External Programs tab self.wTree.get_widget("gen_settings_label").set_label(language["gen_settings"]) self.wTree.get_widget("ext_prog_label").set_label(language["ext_programs"]) @@ -312,3 +260,71 @@ class PreferencesDialog(object): self.set_label("pref_wifi_label", "%s:" % language['wireless_interface']) self.set_label("pref_wired_label", "%s:" % language['wired_interface']) self.set_label("pref_driver_label", "%s:" % language['wpa_supplicant_driver']) + + self.dialog = self.wTree.get_widget("pref_dialog") + self.dialog.set_title(language['preferences']) + if os.path.exists(os.path.join(wpath.images, "wicd.png")): + self.dialog.set_icon_from_file(os.path.join(wpath.images, "wicd.png")) + size = daemon.ReadWindowSize("pref") + width = size[0] + height = size[1] + if width > -1 and height > -1: + self.dialog.resize(int(width), int(height)) + else: + self.dialog.resize(gtk.gdk.screen_width() / 3, + gtk.gdk.screen_height() / 2) + + self.wiredcheckbox = setup_label("pref_always_check", + 'wired_always_on') + + self.reconnectcheckbox = setup_label("pref_auto_check", + 'auto_reconnect') + self.debugmodecheckbox = setup_label("pref_debug_check", + 'use_debug_mode') + self.displaytypecheckbox = setup_label("pref_dbm_check", + 'display_type_dialog') + self.usedefaultradiobutton = setup_label("pref_use_def_radio", + 'use_default_profile') + self.showlistradiobutton = setup_label("pref_prompt_radio", + 'show_wired_list') + self.lastusedradiobutton = setup_label("pref_use_last_radio", + 'use_last_used_profile') + + + # DHCP Clients + self.dhcpautoradio = setup_label("dhcp_auto_radio", "wicd_auto_config") + self.dhclientradio = self.wTree.get_widget("dhclient_radio") + self.pumpradio = self.wTree.get_widget("pump_radio") + self.dhcpcdradio = self.wTree.get_widget("dhcpcd_radio") + + # Wired Link Detection Apps + self.linkautoradio = setup_label("link_auto_radio", 'wicd_auto_config') + self.linkautoradio = setup_label("link_auto_radio") + self.ethtoolradio = setup_label("ethtool_radio") + self.miitoolradio = setup_label("miitool_radio") + + # Route Flushing Apps + self.flushautoradio = setup_label("flush_auto_radio", + 'wicd_auto_config') + self.ipflushradio = setup_label("ip_flush_radio") + self.routeflushradio = setup_label("route_flush_radio") + + # Replacement for the combo box hack + self.wpadrivercombo = build_combobox("pref_wpa_combobox") + self.wpadrivers = ["wext", "hostap", "madwifi", "atmel", + "ndiswrapper", "ipw"] + self.wpadrivers = wireless.GetWpaSupplicantDrivers(self.wpadrivers) + self.wpadrivers.append("ralink_legacy") + + self.entryWirelessInterface = self.wTree.get_widget("pref_wifi_entry") + self.entryWiredInterface = self.wTree.get_widget("pref_wired_entry") + + # Set up global DNS stuff + self.useGlobalDNSCheckbox = setup_label("pref_global_check", + 'use_global_dns') + self.searchDomEntry = self.wTree.get_widget("pref_search_dom_entry") + self.dns1Entry = self.wTree.get_widget("pref_dns1_entry") + self.dns2Entry = self.wTree.get_widget("pref_dns2_entry") + self.dns3Entry = self.wTree.get_widget("pref_dns3_entry") + + self.backendcombo = build_combobox("pref_backend_combobox") \ No newline at end of file diff --git a/wicd/wicd-client.py b/wicd/wicd-client.py index 96d484c..37528ae 100755 --- a/wicd/wicd-client.py +++ b/wicd/wicd-client.py @@ -642,7 +642,7 @@ Arguments: def setup_dbus(force=True): global bus, daemon, wireless, wired, DBUS_AVAIL - + print "Connecting to daemon..." try: dbusmanager.connect_to_dbus() except DBusException: @@ -653,7 +653,7 @@ def setup_dbus(force=True): dbusmanager.connect_to_dbus() except DBusException: gui.error(None, "Could not connect to wicd's D-Bus interface. " + - "Check the wicd log for error messages.") + "Check the wicd log for error messages.") return False else: return False @@ -664,6 +664,7 @@ def setup_dbus(force=True): wireless = dbus_ifaces['wireless'] wired = dbus_ifaces['wired'] DBUS_AVAIL = True + print "Connected." return True @@ -674,23 +675,8 @@ def handle_no_dbus(): print "Wicd daemon is shutting down!" gui.error(None, "The wicd daemon has shut down, the UI will not function " + "properly until it is restarted.") - _wait_for_dbus() return False -@misc.threaded -def _wait_for_dbus(): - global DBUS_AVAIL - while True: - time.sleep(10) - print "Trying to reconnect.." - if not setup_dbus(force=False): - print "Failed to reconnect to the daemon." - else: - print "Successfully reconnected to the daemon." - gui.setup_dbus(force=False) - DBUS_AVAIL = True - return - def main(argv): """ The main frontend program. @@ -750,7 +736,9 @@ def main(argv): 'SendStartScanSignal', 'org.wicd.daemon.wireless') bus.add_signal_receiver(lambda: handle_no_dbus() or tray_icon.icon_info.set_not_connected_state(), "DaemonClosing", 'org.wicd.daemon') - print 'Done.' + bus.add_signal_receiver(lambda: setup_dbus(force=False), "DaemonStarting", + "org.wicd.daemon") + print 'Done loading.' mainloop = gobject.MainLoop() mainloop.run() diff --git a/wicd/wicd-daemon.py b/wicd/wicd-daemon.py index 5d3ee1b..4b2e8c5 100644 --- a/wicd/wicd-daemon.py +++ b/wicd/wicd-daemon.py @@ -113,7 +113,8 @@ class WicdDaemon(dbus.service.Object): self.wired.wiface = self.wifi.wiface signal.signal(signal.SIGTERM, self.DaemonClosing) - + self.DaemonStarting() + # Scan since we just got started if auto_connect: print "autoconnecting if needed...", str(self.GetWirelessInterface()) @@ -705,6 +706,11 @@ class WicdDaemon(dbus.service.Object): print 'calling wired profile chooser' self.SetNeedWiredProfileChooser(True) + @dbus.service.signal(dbus_interface="org.wicd.daemon", signature='') + def DaemonStarting(self): + """ Emits a signa indicating the daemon is starting. """ + pass + @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='') def DaemonClosing(self): """ Emits a signal indicating the daemon will be closing. """ @@ -1122,6 +1128,11 @@ class WirelessDaemon(dbus.service.Object): essid_key = "essid:" + str(self.LastScan[networkid]) self.config.remove_section(essid_key) + @dbus.service.method('org.wicd.daemon.wireless') + def GetWpaSupplicantDrivers(self, drivers): + """ Returns all valid wpa_supplicant drivers in a given list. """ + return self.wifi.GetWpaSupplicantDrivers(drivers) + @dbus.service.method('org.wicd.daemon.wireless') def ReloadConfig(self): """ Reloads the active config file. """ diff --git a/wicd/wnettools.py b/wicd/wnettools.py index 8bb4f64..0a0b9c2 100644 --- a/wicd/wnettools.py +++ b/wicd/wnettools.py @@ -131,6 +131,16 @@ def NeedsExternalCalls(): """ Returns True if the backend needs to use an external program. """ raise NotImplementedError + +def IsValidWpaSuppDriver(driver): + """ Returns True if given string is a valid wpa_supplicant driver. """ + output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iwlan9", + "-c/etc/zzzzzzzz.confzzz"]) + if re.match("Unsupported driver", output): + return False + else: + return True + class BaseInterface(object): """ Control a network interface. """