diff --git a/src/Widgets/WifiInterface.vala b/src/Widgets/WifiInterface.vala index 660610a..8772323 100644 --- a/src/Widgets/WifiInterface.vala +++ b/src/Widgets/WifiInterface.vala @@ -60,7 +60,7 @@ public class Network.WifiInterface : Network.AbstractWifiInterface { public override void update () { base.update (); - wifi_item.set_sensitive (!hardware_locked); + wifi_item.sensitive = !hardware_locked; wifi_item.active = !locked; active_ap = wifi_device.get_active_access_point (); @@ -77,24 +77,25 @@ public class Network.WifiInterface : Network.AbstractWifiInterface { protected override void wifi_activate_cb (WifiMenuItem i) { var connections = nm_client.get_connections (); var device_connections = wifi_device.filter_connections (connections); - var ap_connections = i.ap.filter_connections (device_connections); + var ap = i.get_nearest_ap (); + var ap_connections = ap.filter_connections (device_connections); bool already_connected = ap_connections.length > 0; if (already_connected) { nm_client.activate_connection_async.begin (ap_connections.get (0), wifi_device, - i.ap.get_path (), + ap.get_path (), null, null); } else { - debug ("Trying to connect to %s", NM.Utils.ssid_to_utf8 (i.ap.get_ssid ().get_data ())); + debug ("Trying to connect to %s", NM.Utils.ssid_to_utf8 (ap.ssid.get_data ())); - if (i.ap.get_wpa_flags () == NM.@80211ApSecurityFlags.NONE) { + if (ap.wpa_flags == NM.@80211ApSecurityFlags.NONE) { debug ("Directly, as it is an insecure network."); nm_client.add_and_activate_connection_async.begin (NM.SimpleConnection.new (), device, - i.ap.get_path (), + ap.get_path (), null, null); } else { diff --git a/src/common/Widgets/AbstractWifiInterface.vala b/src/common/Widgets/AbstractWifiInterface.vala index 83efbee..132068e 100644 --- a/src/common/Widgets/AbstractWifiInterface.vala +++ b/src/common/Widgets/AbstractWifiInterface.vala @@ -17,327 +17,333 @@ */ public abstract class Network.AbstractWifiInterface : Network.WidgetNMInterface { - protected RFKillManager rfkill; - public NM.DeviceWifi? wifi_device; - protected NM.AccessPoint? active_ap; - protected Gtk.ListBox wifi_list; - protected NM.Client nm_client; - protected WifiMenuItem? active_wifi_item { get; set; } - protected WifiMenuItem? blank_item = null; - protected Gtk.Stack placeholder; - - protected bool locked; - protected bool software_locked; - protected bool hardware_locked; - - uint timeout_scan = 0; - - public void init_wifi_interface (NM.Client nm_client, NM.Device? _device) { - this.nm_client = nm_client; - device = _device; - wifi_device = (NM.DeviceWifi)device; - blank_item = new WifiMenuItem.blank (); - active_wifi_item = null; - - var no_aps_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); - no_aps_box.visible = true; - no_aps_box.valign = Gtk.Align.CENTER; - - var no_aps = construct_placeholder_label (_("No Access Points Available"), true); - - no_aps_box.add (no_aps); - - var wireless_off_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - wireless_off_box.visible = true; - wireless_off_box.valign = Gtk.Align.CENTER; - - var spinner = new Gtk.Spinner (); - spinner.visible = true; - spinner.halign = spinner.valign = Gtk.Align.CENTER; - spinner.start (); - - var scanning_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 5); - var scanning = construct_placeholder_label (_("Scanning for Access Points…"), true); - - scanning_box.add (scanning); - scanning_box.add (spinner); - scanning_box.visible = true; - scanning_box.valign = Gtk.Align.CENTER; - - placeholder.add_named (no_aps_box, "no-aps"); - placeholder.add_named (wireless_off_box, "wireless-off"); - placeholder.add_named (scanning_box, "scanning"); - placeholder.visible_child_name = "no-aps"; - - /* Monitor killswitch status */ - rfkill = new RFKillManager (); - rfkill.open (); - rfkill.device_added.connect (update); - rfkill.device_changed.connect (update); - rfkill.device_deleted.connect (update); - - wifi_device.notify["active-access-point"].connect (update); - wifi_device.access_point_added.connect (access_point_added_cb); - wifi_device.access_point_removed.connect (access_point_removed_cb); - wifi_device.state_changed.connect (update); - - var aps = wifi_device.get_access_points (); - if (aps != null && aps.length > 0) { - aps.foreach (access_point_added_cb); - } - - update (); - } - - construct { - placeholder = new Gtk.Stack (); - placeholder.visible = true; - - wifi_list = new Gtk.ListBox (); - wifi_list.set_sort_func (sort_func); - wifi_list.set_placeholder (placeholder); - } - - public override void update_name (int count) { - if (count <= 1) { - display_title = _("Wireless"); - } - else { - display_title = device.get_description (); - } - } - - protected Gtk.Label construct_placeholder_label (string text, bool title) { - var label = new Gtk.Label (text); - label.visible = true; - label.use_markup = true; - label.wrap = true; - label.wrap_mode = Pango.WrapMode.WORD_CHAR; - label.max_width_chars = 30; - label.justify = Gtk.Justification.CENTER; - - return label; - } - - void access_point_added_cb (Object ap_) { - NM.AccessPoint ap = (NM.AccessPoint)ap_; - WifiMenuItem? previous_wifi_item = blank_item; - unowned GLib.Bytes ap_ssid = ap.ssid; - - bool found = false; - - foreach (weak Gtk.Widget w in wifi_list.get_children ()) { - var menu_item = (WifiMenuItem) w; - - var menu_ssid = menu_item.ssid; - if (menu_ssid != null && ap.ssid != null && ap.ssid.compare (menu_ssid) == 0) { - found = true; - menu_item.add_ap (ap); - break; - } - - previous_wifi_item = menu_item; - } - - /* Sometimes network manager sends a (fake?) AP without a valid ssid. */ - if (!found && ap_ssid != null) { - var item = new WifiMenuItem (ap, previous_wifi_item); - - previous_wifi_item = item; - item.set_visible (true); - item.user_action.connect (wifi_activate_cb); - - wifi_list.add (item); - wifi_list.show_all (); - - update (); - } - - } - - void update_active_ap () { - debug ("Update active AP"); - - active_ap = wifi_device.get_active_access_point (); - - if (active_wifi_item != null) { - if (active_wifi_item.state == Network.State.CONNECTING_WIFI) { - active_wifi_item.state = Network.State.DISCONNECTED; - } - active_wifi_item = null; - } - - if (active_ap == null) { - debug ("No active AP"); - blank_item.set_active (true); - } else { - unowned GLib.Bytes active_ap_ssid = active_ap.ssid; - debug ("Active ap: %s", NM.Utils.ssid_to_utf8 (active_ap_ssid.get_data ())); - - bool found = false; - foreach (weak Gtk.Widget w in wifi_list.get_children ()) { - var menu_item = (WifiMenuItem) w; - - if (active_ap_ssid.compare (menu_item.ssid) == 0) { - found = true; - menu_item.set_active (true); - active_wifi_item = menu_item; - active_wifi_item.state = state; - } - } - - /* This can happen at start, when the access point list is populated. */ - if (!found) { - debug ("Active AP not added"); - } - } - } - - private void access_point_removed_cb (Object ap_) { - NM.AccessPoint ap = (NM.AccessPoint)ap_; - if (ap.ssid == null) { - update (); - return; - } - - WifiMenuItem found_item = null; - - foreach (weak Gtk.Widget w in wifi_list.get_children ()) { - var menu_item = (WifiMenuItem) w; - - assert (menu_item != null); - - if (ap.ssid.compare (menu_item.ssid) == 0) { - found_item = menu_item; - break; - } - } - - if (found_item == null) { - critical ("Couldn't remove an access point which has not been added."); - } else { - if (!found_item.remove_ap (ap)) { - found_item.destroy (); - } - } - - update (); - } - - private Network.State strength_to_state (uint8 strength) { - if (strength < 30) { - return Network.State.CONNECTED_WIFI_WEAK; - } else if (strength < 55) { - return Network.State.CONNECTED_WIFI_OK; - } else if (strength < 80) { - return Network.State.CONNECTED_WIFI_GOOD; - } else { - return Network.State.CONNECTED_WIFI_EXCELLENT; - } - } - - public override void update () { - switch (wifi_device.state) { - case NM.DeviceState.UNKNOWN: - case NM.DeviceState.UNMANAGED: - case NM.DeviceState.FAILED: - state = State.FAILED_WIFI; - if (active_wifi_item != null) { - active_wifi_item.state = state; - } - cancel_scan (); - break; - - case NM.DeviceState.DEACTIVATING: - case NM.DeviceState.UNAVAILABLE: - cancel_scan (); - placeholder.visible_child_name = "wireless-off"; - state = State.DISCONNECTED; - break; - case NM.DeviceState.DISCONNECTED: - set_scan_placeholder (); - state = State.DISCONNECTED; - break; - - case NM.DeviceState.PREPARE: - case NM.DeviceState.CONFIG: - case NM.DeviceState.NEED_AUTH: - case NM.DeviceState.IP_CONFIG: - case NM.DeviceState.IP_CHECK: - case NM.DeviceState.SECONDARIES: - set_scan_placeholder (); - state = State.CONNECTING_WIFI; - break; - - case NM.DeviceState.ACTIVATED: - set_scan_placeholder (); - - /* That can happen if active_ap has not been added yet, at startup. */ - if (active_ap != null) { - state = strength_to_state (active_ap.get_strength ()); - } else { - state = State.CONNECTED_WIFI_WEAK; - } - break; - } - - debug ("New network state: %s", state.to_string ()); - - /* Wifi */ - software_locked = false; - hardware_locked = false; - foreach (var device in rfkill.get_devices ()) { - if (device.device_type != RFKillDeviceType.WLAN) { - continue; - } - - if (device.software_lock) { - software_locked = true; - } - - if (device.hardware_lock) { - hardware_locked = true; - } - } - - locked = hardware_locked || software_locked; - - update_active_ap (); - - base.update (); - } - - void cancel_scan () { - if (timeout_scan > 0) { - Source.remove (timeout_scan); - timeout_scan = 0; - } - } - - void set_scan_placeholder () { - // this state is the previous state (because this method is called before putting the new state) - if (state == State.DISCONNECTED) { - placeholder.visible_child_name = "scanning"; - cancel_scan (); - wifi_device.request_scan_async.begin (null, null); - timeout_scan = Timeout.add (5000, () => { - timeout_scan = 0; - placeholder.visible_child_name = "no-aps"; - return false; - }); - } - } - - protected abstract void wifi_activate_cb (WifiMenuItem i); - - private int sort_func (Gtk.ListBoxRow r1, Gtk.ListBoxRow r2) { - if (r1 == null || r2 == null) { - return 0; - } - - var w1 = (WifiMenuItem)r1; - var w2 = (WifiMenuItem)r2; - - return w2.strength - w1.strength; - } + protected RFKillManager rfkill; + public NM.DeviceWifi? wifi_device; + protected NM.AccessPoint? active_ap; + + protected Gtk.ListBox wifi_list; + + protected NM.Client nm_client; + + protected WifiMenuItem? active_wifi_item { get; set; } + protected WifiMenuItem? blank_item = null; + protected Gtk.Stack placeholder; + + protected bool locked; + protected bool software_locked; + protected bool hardware_locked; + + uint timeout_scan = 0; + + public void init_wifi_interface (NM.Client nm_client, NM.Device? _device) { + this.nm_client = nm_client; + device = _device; + wifi_device = (NM.DeviceWifi)device; + blank_item = new WifiMenuItem.blank (); + active_wifi_item = null; + + var no_aps_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); + no_aps_box.visible = true; + no_aps_box.valign = Gtk.Align.CENTER; + + var no_aps = construct_placeholder_label (_("No Access Points Available"), true); + + no_aps_box.add (no_aps); + + var wireless_off_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + wireless_off_box.visible = true; + wireless_off_box.valign = Gtk.Align.CENTER; + + var spinner = new Gtk.Spinner (); + spinner.visible = true; + spinner.halign = spinner.valign = Gtk.Align.CENTER; + spinner.start (); + + var scanning_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 5); + var scanning = construct_placeholder_label (_("Scanning for Access Points…"), true); + + scanning_box.add (scanning); + scanning_box.add (spinner); + scanning_box.visible = true; + scanning_box.valign = Gtk.Align.CENTER; + + placeholder.add_named (no_aps_box, "no-aps"); + placeholder.add_named (wireless_off_box, "wireless-off"); + placeholder.add_named (scanning_box, "scanning"); + placeholder.visible_child_name = "no-aps"; + + /* Monitor killswitch status */ + rfkill = new RFKillManager (); + rfkill.open (); + rfkill.device_added.connect (update); + rfkill.device_changed.connect (update); + rfkill.device_deleted.connect (update); + + wifi_device.notify["active-access-point"].connect (update); + wifi_device.access_point_added.connect (access_point_added_cb); + wifi_device.access_point_removed.connect (access_point_removed_cb); + wifi_device.state_changed.connect (update); + + var aps = wifi_device.get_access_points (); + if (aps != null && aps.length > 0) { + aps.foreach(access_point_added_cb); + } + + update(); + } + + construct { + placeholder = new Gtk.Stack (); + placeholder.visible = true; + + wifi_list = new Gtk.ListBox (); + wifi_list.set_sort_func (sort_func); + wifi_list.set_placeholder (placeholder); + + map.connect (() => wifi_list.invalidate_sort ()); + } + + public override void update_name (int count) { + if (count <= 1) { + display_title = _("Wireless"); + } + else { + display_title = device.get_description (); + } + } + + protected Gtk.Label construct_placeholder_label (string text, bool title) { + var label = new Gtk.Label (text); + label.visible = true; + label.use_markup = true; + label.wrap = true; + label.wrap_mode = Pango.WrapMode.WORD_CHAR; + label.max_width_chars = 30; + label.justify = Gtk.Justification.CENTER; + + return label; + } + + void access_point_added_cb (Object ap_) { + NM.AccessPoint ap = (NM.AccessPoint)ap_; + WifiMenuItem? previous_wifi_item = blank_item; + + if (ap.ssid == null) { + debug ("NULL AP SSID"); + return; + } + + bool found = false; + foreach (weak Gtk.Widget w in wifi_list.get_children ()) { + var menu_item = (WifiMenuItem) w; + + var menu_ssid = menu_item.ssid; + if (menu_ssid != null && ap.ssid.compare (menu_ssid) == 0) { + found = true; + menu_item.add_ap (ap); + break; + } + + previous_wifi_item = menu_item; + } + + /* Sometimes network manager sends a (fake?) AP without a valid ssid. */ + if (!found && ap.ssid != null) { + var item = new WifiMenuItem (ap, previous_wifi_item); + item.user_action.connect (wifi_activate_cb); + + previous_wifi_item = item; + wifi_list.add (item); + + update (); + } + + } + + void update_active_ap () { + debug("Update active AP"); + + active_ap = wifi_device.active_access_point; + + if (active_wifi_item != null) { + if(active_wifi_item.state == Network.State.CONNECTING_WIFI) { + active_wifi_item.state = Network.State.DISCONNECTED; + } + active_wifi_item = null; + } + + if (active_ap == null) { + debug("No active AP"); + blank_item.set_active (true); + return; + } + + var ssid = active_ap.ssid; + if (ssid == null) { + debug ("NULL active AP SSID"); + blank_item.set_active (true); + return; + } + + debug ("Active ap: %s", NM.Utils.ssid_to_utf8 (ssid.get_data ())); + + bool found = false; + foreach (weak Gtk.Widget w in wifi_list.get_children ()) { + var menu_item = (WifiMenuItem) w; + if (menu_item.ssid == null) + continue; + + if (ssid.compare (menu_item.ssid) == 0) { + found = true; + menu_item.set_active (true); + active_wifi_item = menu_item; + active_wifi_item.state = state; + } + } + + /* This can happen at start, when the access point list is populated. */ + if (!found) { + debug ("Active AP not added"); + } + } + + void access_point_removed_cb (Object ap_) { + NM.AccessPoint ap = (NM.AccessPoint)ap_; + + WifiMenuItem found_item = null; + + foreach (weak Gtk.Widget w in wifi_list.get_children ()) { + var menu_item = (WifiMenuItem) w; + if (menu_item.ssid == null) + continue; + + if (ap.ssid.compare (menu_item.ssid) == 0) { + found_item = menu_item; + break; + } + } + + if(found_item == null) { + critical("Couldn't remove an access point which has not been added."); + return; + } else { + if(!found_item.remove_ap(ap)) { + found_item.destroy (); + } + } + + update (); + } + + Network.State strength_to_state (uint8 strength) { + if(strength < 30) + return Network.State.CONNECTED_WIFI_WEAK; + else if(strength < 55) + return Network.State.CONNECTED_WIFI_OK; + else if(strength < 80) + return Network.State.CONNECTED_WIFI_GOOD; + else + return Network.State.CONNECTED_WIFI_EXCELLENT; + } + + public override void update () { + switch (wifi_device.state) { + case NM.DeviceState.UNKNOWN: + case NM.DeviceState.UNMANAGED: + case NM.DeviceState.FAILED: + state = State.FAILED_WIFI; + if(active_wifi_item != null) { + active_wifi_item.state = state; + } + cancel_scan (); + break; + + case NM.DeviceState.DEACTIVATING: + case NM.DeviceState.UNAVAILABLE: + cancel_scan (); + placeholder.visible_child_name = "wireless-off"; + state = State.DISCONNECTED; + break; + case NM.DeviceState.DISCONNECTED: + set_scan_placeholder (); + state = State.DISCONNECTED; + break; + + case NM.DeviceState.PREPARE: + case NM.DeviceState.CONFIG: + case NM.DeviceState.NEED_AUTH: + case NM.DeviceState.IP_CONFIG: + case NM.DeviceState.IP_CHECK: + case NM.DeviceState.SECONDARIES: + set_scan_placeholder (); + state = State.CONNECTING_WIFI; + break; + + case NM.DeviceState.ACTIVATED: + set_scan_placeholder (); + + /* That can happen if active_ap has not been added yet, at startup. */ + if (active_ap != null) { + state = strength_to_state(active_ap.get_strength()); + } else { + state = State.CONNECTED_WIFI_WEAK; + } + break; + } + + debug("New network state: %s", state.to_string ()); + + /* Wifi */ + software_locked = false; + hardware_locked = false; + foreach (var device in rfkill.get_devices ()) { + if (device.device_type != RFKillDeviceType.WLAN) + continue; + + if (device.software_lock) + software_locked = true; + if (device.hardware_lock) + hardware_locked = true; + } + + locked = hardware_locked || software_locked; + + update_active_ap (); + + base.update (); + } + + void cancel_scan () { + if (timeout_scan > 0) { + Source.remove (timeout_scan); + timeout_scan = 0; + } + } + + void set_scan_placeholder () { + // this state is the previous state (because this method is called before putting the new state) + if (state == State.DISCONNECTED) { + placeholder.visible_child_name = "scanning"; + cancel_scan (); + wifi_device.request_scan_async.begin (null, null); + timeout_scan = Timeout.add(5000, () => { + timeout_scan = 0; + placeholder.visible_child_name = "no-aps"; + return false; + }); + } + } + + protected abstract void wifi_activate_cb (WifiMenuItem i); + + private int sort_func (Gtk.ListBoxRow r1, Gtk.ListBoxRow r2) { + if (r1 == null || r2 == null) { + return 0; + } + + var w1 = (WifiMenuItem)r1; + var w2 = (WifiMenuItem)r2; + + return w2.strength - w1.strength; + } } diff --git a/src/common/Widgets/WifiMenuItem.vala b/src/common/Widgets/WifiMenuItem.vala index 3fd142c..8c5b397 100644 --- a/src/common/Widgets/WifiMenuItem.vala +++ b/src/common/Widgets/WifiMenuItem.vala @@ -16,44 +16,28 @@ */ public class Network.WifiMenuItem : Gtk.ListBoxRow { - private List _ap; public signal void user_action (); - public GLib.Bytes ssid { - get { - return _tmp_ap.get_ssid (); - } - } - - public Network.State state { get; set; default=Network.State.DISCONNECTED; } - - public uint8 strength { - get { - uint8 strength = 0; - foreach (var ap in _ap) { - strength = uint8.max (strength, ap.get_strength ()); - } - return strength; - } - } + public Network.State state { get; set; default = Network.State.DISCONNECTED; } + public GLib.Bytes ssid { get; construct; } + public uint8 strength { get; private set; default = 0; } - public NM.AccessPoint ap { get { return _tmp_ap; } } - NM.AccessPoint _tmp_ap; + private Gee.LinkedList all_aps; Gtk.RadioButton radio_button; Gtk.Image img_strength; Gtk.Image lock_img; Gtk.Image error_img; Gtk.Spinner spinner; + uint refresh_source = 0; + + construct { + all_aps = new Gee.LinkedList (); + get_style_context ().add_class ("menuitem"); - public WifiMenuItem (NM.AccessPoint ap, WifiMenuItem? previous = null) { radio_button = new Gtk.RadioButton (null); radio_button.hexpand = true; radio_button.margin_start = 6; - if (previous != null) { - radio_button.set_group (previous.get_group ()); - } - img_strength = new Gtk.Image (); img_strength.icon_size = Gtk.IconSize.MENU; img_strength.margin_end = 6; @@ -62,12 +46,12 @@ public class Network.WifiMenuItem : Gtk.ListBoxRow { /* TODO: investigate this, it has not been tested yet. */ error_img = new Gtk.Image.from_icon_name ("process-error-symbolic", Gtk.IconSize.MENU); - error_img.set_tooltip_text (_("This wireless network could not be connected to.")); + error_img.tooltip_text = _("This wireless network could not be connected to."); - spinner = new Gtk.Spinner (); + spinner = new Gtk.Spinner(); spinner.start (); spinner.visible = false; - spinner.no_show_all = !spinner.visible; + spinner.no_show_all = true; var grid = new Gtk.Grid (); grid.column_spacing = 6; @@ -77,66 +61,110 @@ public class Network.WifiMenuItem : Gtk.ListBoxRow { grid.add (lock_img); grid.add (img_strength); - _ap = new List (); - - /* Adding the access point triggers update */ - add_ap (ap); + add (grid); notify["state"].connect (update); radio_button.notify["active"].connect (update); - - radio_button.button_release_event.connect ((b, ev) => { + button_release_event.connect (() => { activate (); }); + activate.connect (() => { user_action (); - return false; }); - add (grid); + map.connect (() => start_refresh ()); + unmap.connect (() => stop_refresh ()); + } - this.get_style_context ().add_class ("menuitem"); + public WifiMenuItem (NM.AccessPoint ap, WifiMenuItem? previous = null) { + Object (ssid: ap.ssid); + add_ap (ap); + + if (previous != null) { + radio_button.set_group (previous.radio_button.get_group ()); + } + + show_all (); } /** * Only used for an item which is not displayed: hacky way to have no radio button selected. **/ public WifiMenuItem.blank () { - radio_button = new Gtk.RadioButton (null); + get_child ().destroy (); + } + + public void set_active (bool active) { + radio_button.active = active; + } + + public void add_ap (NM.AccessPoint ap) { + lock (all_aps) { + all_aps.add (ap); + } + + update (); } - void update_tmp_ap () { - uint8 strength = 0; - foreach (var ap in _ap) { - _tmp_ap = strength > ap.get_strength () ? _tmp_ap : ap; - strength = uint8.max (strength, ap.get_strength ()); + public bool remove_ap (NM.AccessPoint ap) { + lock (all_aps) { + all_aps.remove (ap); + return !all_aps.is_empty; } } - public void set_active (bool active) { - radio_button.set_active (active); + public NM.AccessPoint get_nearest_ap () { + lock (all_aps) { + NM.AccessPoint ap = all_aps.first (); + foreach (var iter_ap in all_aps) { + if (ap.strength < iter_ap.strength) { + ap = iter_ap; + } + } + + return ap; + } } - unowned SList get_group () { - return radio_button.get_group (); + private void start_refresh () { + lock (refresh_source) { + if (refresh_source > 0) { + GLib.Source.remove (refresh_source); + } + + refresh_source = GLib.Timeout.add_seconds (5, () => { + update (); + return GLib.Source.CONTINUE; + }); + } + } + + private void stop_refresh () { + lock (refresh_source) { + GLib.Source.remove (refresh_source); + refresh_source = 0; + } } private void update () { - radio_button.label = NM.Utils.ssid_to_utf8 (ap.get_ssid ().get_data ()); + radio_button.label = NM.Utils.ssid_to_utf8 (ssid.get_data ()); - img_strength.icon_name = get_strength_symbolic_icon (); - img_strength.show_all (); + NM.AccessPoint ap = null; + lock (all_aps) { + ap = all_aps.first (); + } - var flags = ap.get_wpa_flags (); + NM.@80211ApSecurityFlags flags = ap.wpa_flags; var is_secured = false; - if ((flags & NM.@80211ApSecurityFlags.GROUP_WEP40) != 0) { + if (NM.@80211ApSecurityFlags.GROUP_WEP40 in flags) { is_secured = true; tooltip_text = _("This network uses 40/64-bit WEP encryption"); - } else if ((flags & NM.@80211ApSecurityFlags.GROUP_WEP104) != 0) { + } else if (NM.@80211ApSecurityFlags.GROUP_WEP104 in flags) { is_secured = true; tooltip_text = _("This network uses 104/128-bit WEP encryption"); - } else if ((flags & NM.@80211ApSecurityFlags.KEY_MGMT_PSK) != 0) { + } else if (NM.@80211ApSecurityFlags.KEY_MGMT_PSK in flags) { is_secured = true; tooltip_text = _("This network uses WPA encryption"); - } else if (flags != NM.@80211ApSecurityFlags.NONE || ap.get_rsn_flags () != NM.@80211ApSecurityFlags.NONE) { + } else if (flags != NM.@80211ApSecurityFlags.NONE || ap.rsn_flags != NM.@80211ApSecurityFlags.NONE) { is_secured = true; tooltip_text = _("This network uses encryption"); } else { @@ -150,38 +178,42 @@ public class Network.WifiMenuItem : Gtk.ListBoxRow { hide_item (spinner); switch (state) { - case State.FAILED_WIFI: - show_item (error_img); - break; - case State.CONNECTING_WIFI: - show_item (spinner); - if (!radio_button.active) { - critical ("An access point is being connected but not active."); + case State.FAILED_WIFI: + show_item (error_img); + break; + case State.CONNECTING_WIFI: + show_item (spinner); + if (!radio_button.active) { + critical ("An access point is being connected but not active."); + } + break; + } + + // Recalculate global strength + uint8 next_strength = 0; + lock (all_aps) { + foreach (var iter_ap in all_aps) { + next_strength = uint8.max (next_strength, iter_ap.strength); } - break; } + + strength = next_strength; + img_strength.icon_name = get_strength_symbolic_icon (); } - void show_item (Gtk.Widget w) { + private void show_item (Gtk.Widget w) { w.visible = true; w.no_show_all = !w.visible; } - void hide_item (Gtk.Widget w) { + private void hide_item (Gtk.Widget w) { w.visible = false; w.no_show_all = !w.visible; w.hide (); } - public void add_ap (NM.AccessPoint ap) { - _ap.append (ap); - update_tmp_ap (); - - update (); - } - - private const string BASE_ICON_NAME = "network-wireless-signal-"; - private const string SYMBOLIC = "-symbolic"; + const string BASE_ICON_NAME = "network-wireless-signal-"; + const string SYMBOLIC = "-symbolic"; private unowned string get_strength_symbolic_icon () { if (strength < 30) { return BASE_ICON_NAME + "weak" + SYMBOLIC; @@ -193,10 +225,4 @@ public class Network.WifiMenuItem : Gtk.ListBoxRow { return BASE_ICON_NAME + "excellent" + SYMBOLIC; } } - - public bool remove_ap (NM.AccessPoint ap) { - _ap.remove (ap); - update_tmp_ap (); - return _ap.length () > 0; - } }