2012-07-20 12:05:10 +01:00
|
|
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011-2012 Richard Hughes <richard@hughsie.com>
|
|
|
|
*
|
|
|
|
* Licensed under the GNU General Public License Version 2
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <glib-object.h>
|
|
|
|
#include <glib/gi18n.h>
|
|
|
|
|
|
|
|
#include <netinet/ether.h>
|
|
|
|
|
2016-04-29 16:05:54 +02:00
|
|
|
#include <NetworkManager.h>
|
2015-06-23 16:55:10 +02:00
|
|
|
#include <polkit/polkit.h>
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-09-17 12:15:11 +00:00
|
|
|
#include "cc-wifi-hotspot-dialog.h"
|
2018-04-06 13:38:40 +02:00
|
|
|
#include "hostname-helper.h"
|
2012-07-20 12:05:10 +01:00
|
|
|
#include "network-dialogs.h"
|
|
|
|
#include "panel-common.h"
|
2019-12-02 14:52:25 +05:30
|
|
|
#include "cc-list-row.h"
|
2022-08-05 15:42:45 +02:00
|
|
|
#include "cc-qr-code-dialog.h"
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2012-12-09 19:38:32 -05:00
|
|
|
#include "connection-editor/net-connection-editor.h"
|
2012-07-20 12:05:10 +01:00
|
|
|
#include "net-device-wifi.h"
|
|
|
|
|
2018-12-15 17:54:13 +01:00
|
|
|
#include "cc-wifi-connection-list.h"
|
2018-12-13 18:04:01 +01:00
|
|
|
#include "cc-wifi-connection-row.h"
|
2018-02-20 17:09:35 +01:00
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
#define PERIODIC_WIFI_SCAN_TIMEOUT 15
|
2012-12-09 01:26:03 -05:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
static void nm_device_wifi_refresh_ui (NetDeviceWifi *self);
|
|
|
|
static void show_wifi_list (NetDeviceWifi *self);
|
|
|
|
static void show_hotspot_ui (NetDeviceWifi *self);
|
2023-08-30 18:37:53 +02:00
|
|
|
static void nm_client_on_permission_change (NetDeviceWifi *self);
|
2018-12-15 17:54:13 +01:00
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2018-10-31 20:40:00 -03:00
|
|
|
struct _NetDeviceWifi
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2021-11-29 10:37:01 -03:00
|
|
|
AdwBin parent;
|
2018-10-31 20:40:00 -03:00
|
|
|
|
2023-03-28 12:38:34 +05:30
|
|
|
AdwWindowTitle *wifi_headerbar_title;
|
2023-03-23 16:42:20 -04:00
|
|
|
AdwPreferencesGroup *details_box;
|
2019-10-15 12:25:48 +13:00
|
|
|
GtkSwitch *device_off_switch;
|
|
|
|
GtkBox *header_box;
|
2021-11-29 10:37:01 -03:00
|
|
|
GtkPopover *header_button_popover;
|
2019-10-24 14:08:18 +13:00
|
|
|
GtkBox *hotspot_box;
|
2019-12-02 14:52:25 +05:30
|
|
|
CcListRow *hotspot_name_row;
|
|
|
|
CcListRow *hotspot_security_row;
|
|
|
|
CcListRow *hotspot_password_row;
|
2019-10-15 12:25:48 +13:00
|
|
|
GtkBox *listbox_box;
|
2021-11-29 10:37:01 -03:00
|
|
|
GtkStack *stack;
|
2023-12-14 03:10:32 +01:00
|
|
|
AdwPreferencesGroup *saved_networks_box;
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
CcWifiConnectionList *saved_networks_list;
|
2023-12-13 23:31:11 +01:00
|
|
|
GtkWindow *saved_networks_dialog;
|
|
|
|
AdwToastOverlay *saved_networks_toast_overlay;
|
2023-10-25 10:39:36 +02:00
|
|
|
AdwToast *saved_networks_undo_toast;
|
2023-03-23 16:42:20 -04:00
|
|
|
|
2023-12-14 00:24:09 +01:00
|
|
|
AdwSwitchRow *device_enable_row;
|
|
|
|
CcListRow *saved_network_row;
|
|
|
|
CcListRow *connect_hidden_row;
|
|
|
|
CcListRow *hotspot_row;
|
2019-10-15 12:25:48 +13:00
|
|
|
|
2019-10-23 12:08:54 +13:00
|
|
|
CcPanel *panel;
|
2019-10-23 14:45:52 +13:00
|
|
|
NMClient *client;
|
2019-10-24 13:04:14 +13:00
|
|
|
NMDevice *device;
|
2012-07-20 12:05:10 +01:00
|
|
|
gboolean updating_device;
|
2012-07-27 14:12:18 +01:00
|
|
|
gchar *selected_ssid_title;
|
|
|
|
gchar *selected_connection_id;
|
2012-09-08 16:58:14 -04:00
|
|
|
gchar *selected_ap_id;
|
2019-09-17 12:15:11 +00:00
|
|
|
CcWifiHotspotDialog *hotspot_dialog;
|
2019-06-14 13:58:46 -03:00
|
|
|
|
|
|
|
gint64 last_scan;
|
|
|
|
gboolean scanning;
|
|
|
|
|
|
|
|
guint monitor_scanning_id;
|
2018-02-20 17:09:35 +01:00
|
|
|
guint scan_id;
|
|
|
|
GCancellable *cancellable;
|
2012-07-20 12:05:10 +01:00
|
|
|
};
|
|
|
|
|
2019-06-14 13:58:46 -03:00
|
|
|
enum {
|
|
|
|
PROP_0,
|
|
|
|
PROP_SCANNING,
|
|
|
|
PROP_LAST,
|
|
|
|
};
|
|
|
|
|
2021-11-29 10:37:01 -03:00
|
|
|
G_DEFINE_TYPE (NetDeviceWifi, net_device_wifi, ADW_TYPE_BIN)
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2018-02-20 17:09:35 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
disable_scan_timeout (NetDeviceWifi *self)
|
2018-02-20 17:09:35 +01:00
|
|
|
{
|
|
|
|
g_debug ("Disabling periodic Wi-Fi scan");
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->monitor_scanning_id > 0) {
|
|
|
|
g_source_remove (self->monitor_scanning_id);
|
|
|
|
self->monitor_scanning_id = 0;
|
2019-06-14 13:58:46 -03:00
|
|
|
}
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->scan_id > 0) {
|
|
|
|
g_source_remove (self->scan_id);
|
|
|
|
self->scan_id = 0;
|
2018-02-20 17:09:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
wireless_enabled_toggled (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
|
|
|
gboolean enabled;
|
|
|
|
|
2019-10-23 14:45:52 +13:00
|
|
|
enabled = nm_client_wireless_get_enabled (self->client);
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
self->updating_device = TRUE;
|
2023-03-23 16:42:20 -04:00
|
|
|
g_object_set (self->device_enable_row, "active", enabled, NULL);
|
2023-08-30 18:37:53 +02:00
|
|
|
if (!enabled) {
|
2019-10-18 11:47:17 +13:00
|
|
|
disable_scan_timeout (self);
|
2023-08-30 18:37:53 +02:00
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->hotspot_row), FALSE);
|
|
|
|
} else {
|
|
|
|
nm_client_on_permission_change(self);
|
|
|
|
}
|
2022-05-30 23:38:07 +02:00
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->connect_hidden_row), enabled);
|
2019-10-18 11:47:17 +13:00
|
|
|
self->updating_device = FALSE;
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static NMConnection *
|
2019-10-18 11:47:17 +13:00
|
|
|
find_connection_for_device (NetDeviceWifi *self,
|
2012-07-20 12:05:10 +01:00
|
|
|
NMDevice *device)
|
|
|
|
{
|
2019-10-23 14:45:52 +13:00
|
|
|
return net_device_get_find_connection (self->client, device);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2012-08-07 10:19:18 -04:00
|
|
|
connection_is_shared (NMConnection *c)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2016-04-29 16:05:54 +02:00
|
|
|
NMSettingIPConfig *s_ip4;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (c);
|
2016-04-29 16:05:54 +02:00
|
|
|
if (g_strcmp0 (nm_setting_ip_config_get_method (s_ip4),
|
2012-07-20 12:05:10 +01:00
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-08-07 10:19:18 -04:00
|
|
|
static gboolean
|
2019-10-18 11:47:17 +13:00
|
|
|
device_is_hotspot (NetDeviceWifi *self)
|
2012-08-07 10:19:18 -04:00
|
|
|
{
|
|
|
|
NMConnection *c;
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
if (nm_device_get_active_connection (self->device) == NULL)
|
2014-09-03 12:32:49 -05:00
|
|
|
return FALSE;
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
c = find_connection_for_device (self, self->device);
|
2012-08-07 10:19:18 -04:00
|
|
|
if (c == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return connection_is_shared (c);
|
|
|
|
}
|
|
|
|
|
2016-04-29 16:05:54 +02:00
|
|
|
static GBytes *
|
2019-10-18 11:47:17 +13:00
|
|
|
device_get_hotspot_ssid (NetDeviceWifi *self,
|
2012-07-20 12:05:10 +01:00
|
|
|
NMDevice *device)
|
|
|
|
{
|
|
|
|
NMConnection *c;
|
|
|
|
NMSettingWireless *sw;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
c = find_connection_for_device (self, device);
|
2017-04-27 18:20:48 +02:00
|
|
|
if (c == NULL)
|
|
|
|
return NULL;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
sw = nm_connection_get_setting_wireless (c);
|
|
|
|
return nm_setting_wireless_get_ssid (sw);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-04-29 16:05:54 +02:00
|
|
|
get_secrets_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
2012-07-20 12:05:10 +01:00
|
|
|
gpointer data)
|
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self = data;
|
2020-11-17 11:19:01 +13:00
|
|
|
g_autoptr(GVariant) secrets = NULL;
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2016-04-29 16:05:54 +02:00
|
|
|
secrets = nm_remote_connection_get_secrets_finish (NM_REMOTE_CONNECTION (source_object), res, &error);
|
|
|
|
if (!secrets) {
|
2017-03-10 17:41:48 +01:00
|
|
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
|
g_warning ("Could not get secrets: %s", error->message);
|
2016-04-29 16:05:54 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2016-04-29 16:05:54 +02:00
|
|
|
nm_connection_update_secrets (NM_CONNECTION (source_object),
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
|
2012-07-20 12:05:10 +01:00
|
|
|
secrets, NULL);
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
nm_device_wifi_refresh_ui (self);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
device_get_hotspot_security_details (NetDeviceWifi *self,
|
2012-07-20 12:05:10 +01:00
|
|
|
NMDevice *device,
|
|
|
|
gchar **secret,
|
|
|
|
gchar **security)
|
|
|
|
{
|
|
|
|
NMConnection *c;
|
|
|
|
NMSettingWirelessSecurity *sws;
|
|
|
|
const gchar *key_mgmt;
|
|
|
|
const gchar *tmp_secret;
|
|
|
|
const gchar *tmp_security;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
c = find_connection_for_device (self, device);
|
2012-07-30 09:49:40 +01:00
|
|
|
if (c == NULL)
|
2012-07-20 12:05:10 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
sws = nm_connection_get_setting_wireless_security (c);
|
2016-04-29 16:05:54 +02:00
|
|
|
if (sws == NULL)
|
2012-07-20 12:05:10 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
tmp_secret = NULL;
|
2012-08-28 23:17:22 +09:00
|
|
|
tmp_security = C_("Wifi security", "None");
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2012-10-23 16:35:30 -05:00
|
|
|
/* Key management values:
|
2023-11-07 15:19:48 +01:00
|
|
|
* "none" = WEP or no password protection
|
2012-10-23 16:35:30 -05:00
|
|
|
* "wpa-psk" = WPAv2 Ad-Hoc mode (eg IBSS RSN) and AP-mode WPA v1 and v2
|
|
|
|
*/
|
2012-07-20 12:05:10 +01:00
|
|
|
key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws);
|
|
|
|
if (strcmp (key_mgmt, "none") == 0) {
|
|
|
|
tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0);
|
|
|
|
tmp_security = _("WEP");
|
|
|
|
}
|
2023-11-07 15:19:48 +01:00
|
|
|
else if (strcmp (key_mgmt, "wpa-psk") == 0) {
|
2012-07-20 12:05:10 +01:00
|
|
|
tmp_secret = nm_setting_wireless_security_get_psk (sws);
|
|
|
|
tmp_security = _("WPA");
|
|
|
|
} else {
|
|
|
|
g_warning ("unhandled security key-mgmt: %s", key_mgmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we don't have secrets, request them from NM and bail.
|
|
|
|
* We'll refresh the UI when secrets arrive.
|
|
|
|
*/
|
|
|
|
if (tmp_secret == NULL) {
|
2016-04-29 16:05:54 +02:00
|
|
|
nm_remote_connection_get_secrets_async ((NMRemoteConnection*)c,
|
|
|
|
NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
|
2019-10-23 13:51:47 +13:00
|
|
|
self->cancellable,
|
2016-04-29 16:05:54 +02:00
|
|
|
get_secrets_cb,
|
2019-10-18 11:47:17 +13:00
|
|
|
self);
|
2012-07-20 12:05:10 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-07-30 09:49:40 +01:00
|
|
|
if (secret)
|
2012-07-20 12:05:10 +01:00
|
|
|
*secret = g_strdup (tmp_secret);
|
2012-07-30 09:49:40 +01:00
|
|
|
if (security)
|
2012-07-20 12:05:10 +01:00
|
|
|
*security = g_strdup (tmp_security);
|
|
|
|
}
|
|
|
|
|
2012-07-30 09:53:38 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
nm_device_wifi_refresh_hotspot (NetDeviceWifi *self)
|
2012-07-30 09:53:38 +01:00
|
|
|
{
|
2016-04-29 16:05:54 +02:00
|
|
|
GBytes *ssid;
|
2019-09-12 11:40:48 +12:00
|
|
|
g_autofree gchar *hotspot_secret = NULL;
|
|
|
|
g_autofree gchar *hotspot_security = NULL;
|
|
|
|
g_autofree gchar *hotspot_ssid = NULL;
|
2012-07-30 09:53:38 +01:00
|
|
|
|
|
|
|
/* refresh hotspot ui */
|
2019-10-24 13:04:14 +13:00
|
|
|
ssid = device_get_hotspot_ssid (self, self->device);
|
2012-07-30 09:53:38 +01:00
|
|
|
if (ssid)
|
2016-04-29 16:05:54 +02:00
|
|
|
hotspot_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
|
2019-10-18 11:47:17 +13:00
|
|
|
device_get_hotspot_security_details (self,
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device,
|
2012-07-30 09:53:38 +01:00
|
|
|
&hotspot_secret,
|
|
|
|
&hotspot_security);
|
|
|
|
|
2017-04-29 14:10:59 +02:00
|
|
|
g_debug ("Refreshing hotspot labels to name: '%s', security key: '%s', security: '%s'",
|
|
|
|
hotspot_ssid, hotspot_secret, hotspot_security);
|
|
|
|
|
2019-12-02 14:52:25 +05:30
|
|
|
cc_list_row_set_secondary_label (self->hotspot_name_row, hotspot_ssid);
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->hotspot_name_row), hotspot_ssid != NULL);
|
2019-10-18 14:28:46 +13:00
|
|
|
|
2019-12-02 14:52:25 +05:30
|
|
|
cc_list_row_set_secondary_label (self->hotspot_password_row, hotspot_secret);
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->hotspot_password_row), hotspot_secret != NULL);
|
2019-10-18 14:28:46 +13:00
|
|
|
|
2019-12-02 14:52:25 +05:30
|
|
|
cc_list_row_set_secondary_label (self->hotspot_security_row, hotspot_security);
|
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->hotspot_security_row), hotspot_security != NULL);
|
2012-07-30 09:53:38 +01:00
|
|
|
}
|
|
|
|
|
2019-06-14 13:58:46 -03:00
|
|
|
static void
|
|
|
|
set_scanning (NetDeviceWifi *self,
|
|
|
|
gboolean scanning,
|
|
|
|
gint64 last_scan)
|
|
|
|
{
|
|
|
|
gboolean scanning_changed = self->scanning != scanning;
|
|
|
|
|
|
|
|
self->scanning = scanning;
|
|
|
|
self->last_scan = last_scan;
|
|
|
|
|
|
|
|
if (scanning_changed)
|
|
|
|
g_object_notify (G_OBJECT (self), "scanning");
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
update_scanning (gpointer user_data)
|
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self = user_data;
|
2019-06-14 13:58:46 -03:00
|
|
|
gint64 last_scan;
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
last_scan = nm_device_wifi_get_last_scan (NM_DEVICE_WIFI (self->device));
|
2019-06-14 13:58:46 -03:00
|
|
|
|
|
|
|
/* The last_scan property is updated after the device finished scanning,
|
|
|
|
* so notify about it and stop monitoring for changes.
|
|
|
|
*/
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->last_scan != last_scan) {
|
|
|
|
set_scanning (self, FALSE, last_scan);
|
|
|
|
self->monitor_scanning_id = 0;
|
2019-06-14 13:58:46 -03:00
|
|
|
return G_SOURCE_REMOVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2018-02-20 17:09:35 +01:00
|
|
|
static gboolean
|
|
|
|
request_scan (gpointer user_data)
|
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self = user_data;
|
2018-02-20 17:09:35 +01:00
|
|
|
|
|
|
|
g_debug ("Periodic Wi-Fi scan requested");
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
set_scanning (self, TRUE,
|
2019-10-24 13:04:14 +13:00
|
|
|
nm_device_wifi_get_last_scan (NM_DEVICE_WIFI (self->device)));
|
2019-06-14 13:58:46 -03:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->monitor_scanning_id == 0) {
|
|
|
|
self->monitor_scanning_id = g_timeout_add (1500, update_scanning,
|
|
|
|
self);
|
2019-06-14 13:58:46 -03:00
|
|
|
}
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (self->device),
|
2019-10-18 11:47:17 +13:00
|
|
|
self->cancellable, NULL, NULL);
|
2018-02-20 17:09:35 +01:00
|
|
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
nm_device_wifi_refresh_ui (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2019-10-01 12:50:30 +13:00
|
|
|
g_autofree gchar *status = NULL;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (device_is_hotspot (self)) {
|
|
|
|
nm_device_wifi_refresh_hotspot (self);
|
|
|
|
show_hotspot_ui (self);
|
|
|
|
disable_scan_timeout (self);
|
2012-09-08 16:58:14 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->scan_id == 0 &&
|
2019-10-23 14:45:52 +13:00
|
|
|
nm_client_wireless_get_enabled (self->client)) {
|
2019-10-18 11:47:17 +13:00
|
|
|
self->scan_id = g_timeout_add_seconds (PERIODIC_WIFI_SCAN_TIMEOUT,
|
|
|
|
request_scan, self);
|
|
|
|
request_scan (self);
|
2018-02-20 17:09:35 +01:00
|
|
|
}
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
/* keep this in sync with the signal handler setup in cc_network_panel_init */
|
2019-10-18 11:47:17 +13:00
|
|
|
wireless_enabled_toggled (self);
|
2012-09-08 16:58:14 -04:00
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
status = panel_device_status_to_localized_string (self->device, NULL);
|
2023-03-28 12:38:34 +05:30
|
|
|
adw_window_title_set_subtitle (self->wifi_headerbar_title, status);
|
2012-07-26 13:38:55 +01:00
|
|
|
/* update list of APs */
|
2019-10-18 11:47:17 +13:00
|
|
|
show_wifi_list (self);
|
2023-11-08 16:14:55 +01:00
|
|
|
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->saved_network_row), !cc_wifi_connection_list_is_empty (self->saved_networks_list));
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-24 20:29:35 +13:00
|
|
|
device_off_switch_changed_cb (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
|
|
|
gboolean active;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->updating_device)
|
2012-07-20 12:05:10 +01:00
|
|
|
return;
|
|
|
|
|
2023-06-30 11:51:36 +02:00
|
|
|
active = adw_switch_row_get_active (self->device_enable_row);
|
2022-05-31 15:44:42 +12:00
|
|
|
nm_client_dbus_set_property (self->client,
|
|
|
|
NM_DBUS_PATH,
|
|
|
|
NM_DBUS_INTERFACE,
|
|
|
|
"WirelessEnabled",
|
|
|
|
g_variant_new_boolean (active),
|
|
|
|
-1,
|
|
|
|
NULL, NULL, NULL);
|
2018-02-20 17:09:35 +01:00
|
|
|
if (!active)
|
2019-10-18 11:47:17 +13:00
|
|
|
disable_scan_timeout (self);
|
2022-05-30 23:38:07 +02:00
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->connect_hidden_row), active);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2022-05-30 23:38:07 +02:00
|
|
|
connect_hidden (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2021-11-29 10:37:01 -03:00
|
|
|
GtkNative *native = gtk_widget_get_native (GTK_WIDGET (self));
|
|
|
|
cc_network_panel_connect_to_hidden_network (GTK_WIDGET (native), self->client);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-04-29 16:05:54 +02:00
|
|
|
connection_add_activate_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2016-04-29 16:05:54 +02:00
|
|
|
NMActiveConnection *conn;
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2016-04-29 16:05:54 +02:00
|
|
|
|
|
|
|
conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error);
|
|
|
|
if (!conn) {
|
2017-03-10 17:41:48 +01:00
|
|
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
nm_device_wifi_refresh_ui (user_data);
|
|
|
|
/* failed to activate */
|
|
|
|
g_warning ("Failed to add and activate connection '%d': %s",
|
|
|
|
error->code,
|
|
|
|
error->message);
|
|
|
|
}
|
2016-04-29 16:05:54 +02:00
|
|
|
return;
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-07 16:57:20 +02:00
|
|
|
static void
|
2016-04-29 16:05:54 +02:00
|
|
|
connection_activate_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
2012-07-20 12:05:10 +01:00
|
|
|
gpointer user_data)
|
|
|
|
{
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2016-04-29 16:05:54 +02:00
|
|
|
|
|
|
|
if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) {
|
2017-03-10 17:41:48 +01:00
|
|
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
|
|
nm_device_wifi_refresh_ui (user_data);
|
|
|
|
/* failed to activate */
|
|
|
|
g_debug ("Failed to add and activate connection '%d': %s",
|
|
|
|
error->code,
|
|
|
|
error->message);
|
|
|
|
}
|
2016-04-29 16:05:54 +02:00
|
|
|
return;
|
|
|
|
}
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
2012-10-02 14:55:59 +02:00
|
|
|
static gboolean
|
|
|
|
is_8021x (NMDevice *device,
|
|
|
|
const char *ap_object_path)
|
|
|
|
{
|
|
|
|
NM80211ApSecurityFlags wpa_flags, rsn_flags;
|
|
|
|
NMAccessPoint *ap;
|
|
|
|
|
|
|
|
ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device),
|
|
|
|
ap_object_path);
|
|
|
|
if (!ap)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
rsn_flags = nm_access_point_get_rsn_flags (ap);
|
|
|
|
if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
wpa_flags = nm_access_point_get_wpa_flags (ap);
|
|
|
|
if (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
wireless_try_to_connect (NetDeviceWifi *self,
|
2016-06-03 12:08:31 -05:00
|
|
|
GBytes *ssid,
|
2012-09-08 16:58:14 -04:00
|
|
|
const gchar *ap_object_path)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2016-06-03 12:08:31 -05:00
|
|
|
const gchar *ssid_target;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
if (self->updating_device)
|
2019-09-12 11:53:42 +12:00
|
|
|
return;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2012-09-08 16:58:14 -04:00
|
|
|
if (ap_object_path == NULL || ap_object_path[0] == 0)
|
2019-09-12 11:53:42 +12:00
|
|
|
return;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2016-06-03 12:08:31 -05:00
|
|
|
ssid_target = nm_utils_escape_ssid ((gpointer) g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid));
|
2012-07-20 12:05:10 +01:00
|
|
|
g_debug ("try to connect to WIFI network %s [%s]",
|
2012-09-08 16:58:14 -04:00
|
|
|
ssid_target, ap_object_path);
|
2012-07-26 13:38:55 +01:00
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
/* activate the connection */
|
2019-10-24 13:04:14 +13:00
|
|
|
if (!is_8021x (self->device, ap_object_path)) {
|
2019-09-12 11:53:42 +12:00
|
|
|
g_autoptr(GPermission) permission = NULL;
|
2015-06-23 16:55:10 +02:00
|
|
|
gboolean allowed_to_share = FALSE;
|
2019-09-12 11:53:42 +12:00
|
|
|
g_autoptr(NMConnection) partial = NULL;
|
2015-06-23 16:55:10 +02:00
|
|
|
|
|
|
|
permission = polkit_permission_new_sync ("org.freedesktop.NetworkManager.settings.modify.system",
|
|
|
|
NULL, NULL, NULL);
|
2019-09-12 11:53:42 +12:00
|
|
|
if (permission)
|
2015-06-23 16:55:10 +02:00
|
|
|
allowed_to_share = g_permission_get_allowed (permission);
|
|
|
|
|
|
|
|
if (!allowed_to_share) {
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
s_con = (NMSettingConnection *)nm_setting_connection_new ();
|
|
|
|
nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL);
|
2016-04-29 16:05:54 +02:00
|
|
|
partial = nm_simple_connection_new ();
|
2015-06-23 16:55:10 +02:00
|
|
|
nm_connection_add_setting (partial, NM_SETTING (s_con));
|
|
|
|
}
|
|
|
|
|
2012-10-02 14:55:59 +02:00
|
|
|
g_debug ("no existing connection found for %s, creating and activating one", ssid_target);
|
2019-10-23 14:45:52 +13:00
|
|
|
nm_client_add_and_activate_connection_async (self->client,
|
2016-04-29 16:05:54 +02:00
|
|
|
partial,
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device,
|
2016-04-29 16:05:54 +02:00
|
|
|
ap_object_path,
|
2019-10-23 13:51:47 +13:00
|
|
|
self->cancellable,
|
2016-04-29 16:05:54 +02:00
|
|
|
connection_add_activate_cb,
|
2019-10-18 11:47:17 +13:00
|
|
|
self);
|
2012-10-02 14:55:59 +02:00
|
|
|
} else {
|
2019-09-12 11:53:42 +12:00
|
|
|
g_autoptr(GVariantBuilder) builder = NULL;
|
2013-10-07 15:34:06 +08:00
|
|
|
GVariant *parameters;
|
2012-10-02 14:55:59 +02:00
|
|
|
|
|
|
|
g_debug ("no existing connection found for %s, creating", ssid_target);
|
2013-10-07 15:34:06 +08:00
|
|
|
builder = g_variant_builder_new (G_VARIANT_TYPE ("av"));
|
|
|
|
g_variant_builder_add (builder, "v", g_variant_new_string ("connect-8021x-wifi"));
|
2019-10-24 13:04:14 +13:00
|
|
|
g_variant_builder_add (builder, "v", g_variant_new_string (nm_object_get_path (NM_OBJECT (self->device))));
|
2013-10-07 15:34:06 +08:00
|
|
|
g_variant_builder_add (builder, "v", g_variant_new_string (ap_object_path));
|
|
|
|
parameters = g_variant_new ("av", builder);
|
2012-10-02 14:55:59 +02:00
|
|
|
|
2019-10-23 12:08:54 +13:00
|
|
|
g_object_set (self->panel, "parameters", parameters, NULL);
|
2012-10-02 14:55:59 +02:00
|
|
|
}
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gchar *
|
|
|
|
get_hostname (void)
|
|
|
|
{
|
2019-09-12 11:53:42 +12:00
|
|
|
g_autoptr(GDBusConnection) bus = NULL;
|
|
|
|
g_autoptr(GVariant) res = NULL;
|
|
|
|
g_autoptr(GVariant) inner = NULL;
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
|
2013-08-19 18:08:12 +02:00
|
|
|
if (bus == NULL) {
|
2012-07-20 12:05:10 +01:00
|
|
|
g_warning ("Failed to get system bus connection: %s", error->message);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
res = g_dbus_connection_call_sync (bus,
|
|
|
|
"org.freedesktop.hostname1",
|
|
|
|
"/org/freedesktop/hostname1",
|
|
|
|
"org.freedesktop.DBus.Properties",
|
|
|
|
"Get",
|
|
|
|
g_variant_new ("(ss)",
|
|
|
|
"org.freedesktop.hostname1",
|
|
|
|
"PrettyHostname"),
|
|
|
|
(GVariantType*)"(v)",
|
|
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
|
|
-1,
|
|
|
|
NULL,
|
|
|
|
&error);
|
|
|
|
|
2019-09-12 11:53:42 +12:00
|
|
|
if (res == NULL) {
|
2012-07-20 12:05:10 +01:00
|
|
|
g_warning ("Getting pretty hostname failed: %s", error->message);
|
2019-09-12 11:53:42 +12:00
|
|
|
return NULL;
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
2019-09-12 11:53:42 +12:00
|
|
|
g_variant_get (res, "(v)", &inner);
|
|
|
|
return g_variant_dup_string (inner, NULL);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
is_hotspot_connection (NMConnection *connection)
|
|
|
|
{
|
|
|
|
NMSettingConnection *sc;
|
|
|
|
NMSettingWireless *sw;
|
2016-04-29 16:05:54 +02:00
|
|
|
NMSettingIPConfig *sip;
|
|
|
|
NMSetting *setting;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
sc = nm_connection_get_setting_connection (connection);
|
|
|
|
if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
sw = nm_connection_get_setting_wireless (connection);
|
2012-10-23 16:35:30 -05:00
|
|
|
if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0 &&
|
|
|
|
g_strcmp0 (nm_setting_wireless_get_mode (sw), "ap") != 0) {
|
2012-07-20 12:05:10 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
2016-04-29 16:05:54 +02:00
|
|
|
setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME);
|
|
|
|
if (!setting)
|
2012-07-20 12:05:10 +01:00
|
|
|
return FALSE;
|
2016-04-29 16:05:54 +02:00
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
sip = nm_connection_get_setting_ip4_config (connection);
|
2016-04-29 16:05:54 +02:00
|
|
|
if (g_strcmp0 (nm_setting_ip_config_get_method (sip), "shared") != 0) {
|
2012-07-20 12:05:10 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
show_hotspot_ui (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2012-07-30 09:53:38 +01:00
|
|
|
/* show hotspot tab */
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->hotspot_box));
|
2012-08-07 09:19:23 +01:00
|
|
|
}
|
2012-07-30 09:53:38 +01:00
|
|
|
|
2012-08-07 09:19:23 +01:00
|
|
|
static void
|
2016-04-29 16:05:54 +02:00
|
|
|
activate_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
2012-08-07 09:19:23 +01:00
|
|
|
{
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2016-04-29 16:05:54 +02:00
|
|
|
|
|
|
|
if (nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error) == NULL) {
|
2012-08-07 09:19:23 +01:00
|
|
|
g_warning ("Failed to add new connection: (%d) %s",
|
|
|
|
error->code,
|
|
|
|
error->message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* show hotspot tab */
|
2016-04-29 16:05:54 +02:00
|
|
|
nm_device_wifi_refresh_ui (user_data);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2016-04-29 16:05:54 +02:00
|
|
|
activate_new_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2016-04-29 16:05:54 +02:00
|
|
|
NMActiveConnection *conn;
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2016-04-29 16:05:54 +02:00
|
|
|
|
|
|
|
conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object),
|
|
|
|
res, &error);
|
|
|
|
if (!conn) {
|
|
|
|
g_warning ("Failed to add new connection: (%d) %s",
|
|
|
|
error->code,
|
|
|
|
error->message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* show hotspot tab */
|
|
|
|
nm_device_wifi_refresh_ui (user_data);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
2017-03-10 14:24:19 +01:00
|
|
|
static NMConnection *
|
2019-10-18 11:47:17 +13:00
|
|
|
net_device_wifi_get_hotspot_connection (NetDeviceWifi *self)
|
2017-03-10 14:24:19 +01:00
|
|
|
{
|
|
|
|
GSList *connections, *l;
|
|
|
|
NMConnection *c = NULL;
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
connections = net_device_get_valid_connections (self->client, self->device);
|
2017-03-10 14:24:19 +01:00
|
|
|
for (l = connections; l; l = l->next) {
|
|
|
|
NMConnection *tmp = l->data;
|
|
|
|
if (is_hotspot_connection (tmp)) {
|
|
|
|
c = tmp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2017-03-10 14:25:33 +01:00
|
|
|
static void
|
|
|
|
overwrite_ssid_cb (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2017-03-10 14:25:33 +01:00
|
|
|
NMRemoteConnection *connection;
|
|
|
|
NMConnection *c;
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self;
|
2017-03-10 14:25:33 +01:00
|
|
|
|
|
|
|
connection = NM_REMOTE_CONNECTION (source_object);
|
|
|
|
|
|
|
|
if (!nm_remote_connection_commit_changes_finish (connection, res, &error)) {
|
|
|
|
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
|
|
g_warning ("Failed to save hotspot's settings to disk: %s",
|
|
|
|
error->message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
self = user_data;
|
|
|
|
c = net_device_wifi_get_hotspot_connection (self);
|
2017-03-10 14:25:33 +01:00
|
|
|
|
|
|
|
g_debug ("activate existing hotspot connection\n");
|
2019-10-23 14:45:52 +13:00
|
|
|
nm_client_activate_connection_async (self->client,
|
2017-03-10 14:25:33 +01:00
|
|
|
c,
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device,
|
2017-03-10 14:25:33 +01:00
|
|
|
NULL,
|
2019-10-23 13:51:47 +13:00
|
|
|
self->cancellable,
|
2017-03-10 14:25:33 +01:00
|
|
|
activate_cb,
|
2019-10-18 11:47:17 +13:00
|
|
|
self);
|
2017-03-10 14:25:33 +01:00
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2023-12-14 00:24:09 +01:00
|
|
|
on_wifi_hotspot_dialog_response_cb (GtkDialog *dialog,
|
2021-11-29 10:37:01 -03:00
|
|
|
gint response,
|
|
|
|
NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2019-09-17 12:15:11 +00:00
|
|
|
if (response == GTK_RESPONSE_APPLY) {
|
|
|
|
NMConnection *connection;
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
connection = cc_wifi_hotspot_dialog_get_connection (self->hotspot_dialog);
|
2019-09-17 12:15:11 +00:00
|
|
|
if (NM_IS_REMOTE_CONNECTION (connection))
|
|
|
|
nm_remote_connection_commit_changes_async (NM_REMOTE_CONNECTION (connection),
|
|
|
|
TRUE,
|
2019-10-23 13:51:47 +13:00
|
|
|
self->cancellable,
|
2019-09-17 12:15:11 +00:00
|
|
|
overwrite_ssid_cb,
|
2019-10-18 11:47:17 +13:00
|
|
|
self);
|
2019-09-17 12:15:11 +00:00
|
|
|
else
|
2019-10-23 14:45:52 +13:00
|
|
|
nm_client_add_and_activate_connection_async (self->client,
|
2019-09-17 12:15:11 +00:00
|
|
|
connection,
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device,
|
2019-09-17 12:15:11 +00:00
|
|
|
NULL,
|
2019-10-23 13:51:47 +13:00
|
|
|
self->cancellable,
|
2019-09-17 12:15:11 +00:00
|
|
|
activate_new_cb,
|
2019-10-18 11:47:17 +13:00
|
|
|
self);
|
2019-09-17 12:15:11 +00:00
|
|
|
}
|
|
|
|
|
2023-01-08 20:25:50 +02:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->hotspot_dialog), FALSE);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
2021-11-29 10:37:01 -03:00
|
|
|
static void
|
2022-05-30 23:38:07 +02:00
|
|
|
start_hotspot (NetDeviceWifi *self)
|
2021-11-29 10:37:01 -03:00
|
|
|
{
|
|
|
|
GtkNative *native;
|
|
|
|
NMConnection *c;
|
|
|
|
g_autofree gchar *hostname = NULL;
|
|
|
|
g_autofree gchar *ssid = NULL;
|
|
|
|
|
|
|
|
native = gtk_widget_get_native (GTK_WIDGET (self));
|
|
|
|
|
2024-01-06 00:40:06 +01:00
|
|
|
if (!self->hotspot_dialog) {
|
2021-11-29 10:37:01 -03:00
|
|
|
self->hotspot_dialog = cc_wifi_hotspot_dialog_new (GTK_WINDOW (native));
|
2024-01-06 00:40:06 +01:00
|
|
|
g_object_ref_sink (self->hotspot_dialog);
|
|
|
|
}
|
2021-11-29 10:37:01 -03:00
|
|
|
cc_wifi_hotspot_dialog_set_device (self->hotspot_dialog, NM_DEVICE_WIFI (self->device));
|
|
|
|
hostname = get_hostname ();
|
|
|
|
ssid = pretty_hostname_to_ssid (hostname);
|
|
|
|
cc_wifi_hotspot_dialog_set_hostname (self->hotspot_dialog, ssid);
|
|
|
|
c = net_device_wifi_get_hotspot_connection (self);
|
|
|
|
if (c)
|
|
|
|
cc_wifi_hotspot_dialog_set_connection (self->hotspot_dialog, c);
|
|
|
|
|
2023-12-14 00:24:09 +01:00
|
|
|
g_signal_connect_after (self->hotspot_dialog, "response", G_CALLBACK (on_wifi_hotspot_dialog_response_cb), self);
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_window_present (GTK_WINDOW (self->hotspot_dialog));
|
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
stop_shared_connection (NetDeviceWifi *self)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
|
|
|
const GPtrArray *connections;
|
|
|
|
const GPtrArray *devices;
|
|
|
|
gint i;
|
|
|
|
NMActiveConnection *c;
|
2014-09-02 19:08:46 +02:00
|
|
|
gboolean found = FALSE;
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-23 14:45:52 +13:00
|
|
|
connections = nm_client_get_active_connections (self->client);
|
2013-09-11 16:12:49 +02:00
|
|
|
for (i = 0; connections && i < connections->len; i++) {
|
2012-07-20 12:05:10 +01:00
|
|
|
c = (NMActiveConnection *)connections->pdata[i];
|
|
|
|
|
|
|
|
devices = nm_active_connection_get_devices (c);
|
2019-10-24 13:04:14 +13:00
|
|
|
if (devices && devices->pdata[0] == self->device) {
|
2022-05-31 15:38:39 +12:00
|
|
|
nm_client_deactivate_connection_async (self->client, c, NULL, NULL, NULL);
|
2014-09-02 19:08:46 +02:00
|
|
|
found = TRUE;
|
2012-07-20 12:05:10 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-02 19:08:46 +02:00
|
|
|
if (!found) {
|
|
|
|
g_warning ("Could not stop hotspot connection as no connection attached to the device could be found.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-10-18 11:47:17 +13:00
|
|
|
nm_device_wifi_refresh_ui (self);
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
|
|
|
|
2012-07-26 13:38:55 +01:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
show_wifi_list (NetDeviceWifi *self)
|
2012-07-26 13:38:55 +01:00
|
|
|
{
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->listbox_box));
|
2012-07-26 13:38:55 +01:00
|
|
|
}
|
|
|
|
|
2023-07-31 11:02:54 +04:00
|
|
|
static void
|
|
|
|
net_device_wifi_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
NetDeviceWifi *self = NET_DEVICE_WIFI (object);
|
|
|
|
|
|
|
|
if (self->hotspot_dialog) {
|
2023-10-05 19:21:39 +02:00
|
|
|
gtk_window_destroy (GTK_WINDOW (self->hotspot_dialog));
|
2024-01-06 00:40:06 +01:00
|
|
|
g_object_unref (self->hotspot_dialog);
|
2023-07-31 11:02:54 +04:00
|
|
|
self->hotspot_dialog = NULL;
|
|
|
|
}
|
|
|
|
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
g_clear_pointer (&self->saved_networks_dialog, gtk_window_destroy);
|
|
|
|
|
2023-07-31 11:02:54 +04:00
|
|
|
G_OBJECT_CLASS (net_device_wifi_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
|
|
|
net_device_wifi_finalize (GObject *object)
|
|
|
|
{
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self = NET_DEVICE_WIFI (object);
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-23 09:38:55 +13:00
|
|
|
g_cancellable_cancel (self->cancellable);
|
|
|
|
g_clear_object (&self->cancellable);
|
2019-10-18 11:47:17 +13:00
|
|
|
disable_scan_timeout (self);
|
2018-02-20 17:09:35 +01:00
|
|
|
|
2019-10-23 14:45:52 +13:00
|
|
|
g_clear_object (&self->client);
|
2019-10-24 13:04:14 +13:00
|
|
|
g_clear_object (&self->device);
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
g_clear_object (&self->saved_networks_list);
|
2019-10-23 09:38:55 +13:00
|
|
|
g_clear_pointer (&self->selected_ssid_title, g_free);
|
|
|
|
g_clear_pointer (&self->selected_connection_id, g_free);
|
|
|
|
g_clear_pointer (&self->selected_ap_id, g_free);
|
2012-07-20 12:05:10 +01:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (net_device_wifi_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2019-06-14 13:58:46 -03:00
|
|
|
static void
|
|
|
|
net_device_wifi_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
NetDeviceWifi *self = NET_DEVICE_WIFI (object);
|
|
|
|
|
|
|
|
switch (prop_id) {
|
|
|
|
case PROP_SCANNING:
|
|
|
|
g_value_set_boolean (value, self->scanning);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-08 23:29:15 -04:00
|
|
|
static void
|
2018-12-15 17:54:13 +01:00
|
|
|
really_forgotten (GObject *source_object,
|
|
|
|
GAsyncResult *res,
|
|
|
|
gpointer user_data)
|
2012-12-08 23:10:51 -05:00
|
|
|
{
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
g_autoptr(NetDeviceWifi) self = NET_DEVICE_WIFI (user_data);
|
2023-11-10 12:37:02 +01:00
|
|
|
g_autoptr(CcWifiConnectionList) list = NULL;
|
2019-09-12 10:54:37 +12:00
|
|
|
g_autoptr(GError) error = NULL;
|
2012-12-08 23:10:51 -05:00
|
|
|
|
2023-11-10 12:37:02 +01:00
|
|
|
list = CC_WIFI_CONNECTION_LIST (g_object_get_data (G_OBJECT (self), "list"));
|
2018-12-15 17:54:13 +01:00
|
|
|
cc_wifi_connection_list_thaw (list);
|
|
|
|
|
2019-09-12 11:53:42 +12:00
|
|
|
if (!nm_remote_connection_delete_finish (NM_REMOTE_CONNECTION (source_object), res, &error))
|
2012-12-08 23:10:51 -05:00
|
|
|
g_warning ("failed to delete connection %s: %s",
|
2016-04-29 16:05:54 +02:00
|
|
|
nm_object_get_path (NM_OBJECT (source_object)),
|
2012-12-08 23:10:51 -05:00
|
|
|
error->message);
|
2023-11-10 12:37:02 +01:00
|
|
|
|
|
|
|
if (cc_wifi_connection_list_is_empty (list)) {
|
2023-12-13 23:31:11 +01:00
|
|
|
gtk_window_close (self->saved_networks_dialog);
|
2023-11-10 12:37:02 +01:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (self->saved_network_row), FALSE);
|
|
|
|
}
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-10-25 10:39:36 +02:00
|
|
|
really_forget (AdwToast *toast, CcWifiConnectionRow *row)
|
2012-12-08 23:10:51 -05:00
|
|
|
{
|
|
|
|
NMRemoteConnection *connection;
|
2023-03-23 18:52:41 -04:00
|
|
|
CcWifiConnectionList *list;
|
2019-10-18 11:47:17 +13:00
|
|
|
NetDeviceWifi *self;
|
2012-12-08 23:10:51 -05:00
|
|
|
|
2023-03-23 18:52:41 -04:00
|
|
|
self = NET_DEVICE_WIFI (g_object_get_data (G_OBJECT (row), "net"));
|
2023-10-25 10:39:36 +02:00
|
|
|
if (self->saved_networks_undo_toast == NULL)
|
|
|
|
return;
|
|
|
|
|
2023-03-23 18:52:41 -04:00
|
|
|
list = CC_WIFI_CONNECTION_LIST (g_object_get_data (G_OBJECT (row), "list"));
|
|
|
|
connection = NM_REMOTE_CONNECTION (cc_wifi_connection_row_get_connection (row));
|
|
|
|
|
2023-11-10 12:37:02 +01:00
|
|
|
g_object_set_data (G_OBJECT (self), "list", g_object_ref (list));
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
nm_remote_connection_delete_async (connection, self->cancellable, really_forgotten, g_object_ref (self));
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-10-25 10:39:36 +02:00
|
|
|
on_saved_networks_forget_undo (AdwToast *toast, CcWifiConnectionRow *row)
|
2012-09-08 23:29:15 -04:00
|
|
|
{
|
2023-10-25 10:39:36 +02:00
|
|
|
NetDeviceWifi *self;
|
2023-12-14 01:18:36 +01:00
|
|
|
CcWifiConnectionList *list;
|
2012-12-08 23:10:51 -05:00
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
self = NET_DEVICE_WIFI (g_object_get_data (G_OBJECT (row), "net"));
|
|
|
|
self->saved_networks_undo_toast = NULL;
|
2023-02-27 01:10:13 +05:30
|
|
|
|
2023-12-14 01:18:36 +01:00
|
|
|
list = CC_WIFI_CONNECTION_LIST (g_object_get_data (G_OBJECT (row), "list"));
|
|
|
|
cc_wifi_connection_list_thaw (list);
|
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (row), TRUE);
|
|
|
|
}
|
2023-02-27 01:10:13 +05:30
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
static void
|
|
|
|
forget_selected (NetDeviceWifi *self, CcWifiConnectionRow *row, CcWifiConnectionList *list)
|
|
|
|
{
|
|
|
|
g_autofree gchar *message = NULL;
|
2023-02-27 01:10:13 +05:30
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
gtk_widget_set_visible (GTK_WIDGET (row), FALSE);
|
2023-12-14 01:18:36 +01:00
|
|
|
cc_wifi_connection_list_freeze (list);
|
2023-02-27 01:10:13 +05:30
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
message = g_strdup_printf (_("Network “%s” has been deleted"),
|
|
|
|
adw_preferences_row_get_title (ADW_PREFERENCES_ROW (row)));
|
|
|
|
self->saved_networks_undo_toast = adw_toast_new (message);
|
|
|
|
adw_toast_set_use_markup (self->saved_networks_undo_toast, FALSE);
|
|
|
|
adw_toast_set_button_label (self->saved_networks_undo_toast, _("_Undo"));
|
2023-02-27 01:10:13 +05:30
|
|
|
|
2023-03-23 18:52:41 -04:00
|
|
|
g_object_set_data (G_OBJECT (row), "net", self);
|
|
|
|
g_object_set_data (G_OBJECT (row), "list", list);
|
|
|
|
|
2023-10-25 10:39:36 +02:00
|
|
|
g_signal_connect (self->saved_networks_undo_toast, "button-clicked", G_CALLBACK (on_saved_networks_forget_undo), row);
|
|
|
|
g_signal_connect (self->saved_networks_undo_toast, "dismissed", G_CALLBACK (really_forget), row);
|
|
|
|
|
2023-12-13 23:31:11 +01:00
|
|
|
adw_toast_overlay_add_toast (self->saved_networks_toast_overlay, self->saved_networks_undo_toast);
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
static gint
|
|
|
|
history_sort (gconstpointer a, gconstpointer b, gpointer data)
|
|
|
|
{
|
|
|
|
guint64 ta, tb;
|
|
|
|
NMConnection *ca, *cb;
|
|
|
|
NMSettingConnection *sc;
|
2012-12-08 23:10:51 -05:00
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
ca = cc_wifi_connection_row_get_connection (CC_WIFI_CONNECTION_ROW ((gpointer) a));
|
|
|
|
cb = cc_wifi_connection_row_get_connection (CC_WIFI_CONNECTION_ROW ((gpointer) b));
|
2012-12-09 02:00:58 -05:00
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
if (ca) {
|
|
|
|
sc = nm_connection_get_setting_connection (ca);
|
|
|
|
ta = nm_setting_connection_get_timestamp (sc);
|
2012-12-08 23:10:51 -05:00
|
|
|
} else {
|
2018-12-13 18:04:01 +01:00
|
|
|
ta = 0;
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
if (cb) {
|
|
|
|
sc = nm_connection_get_setting_connection (cb);
|
|
|
|
tb = nm_setting_connection_get_timestamp (sc);
|
2012-12-08 23:10:51 -05:00
|
|
|
} else {
|
2018-12-13 18:04:01 +01:00
|
|
|
tb = 0;
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ta > tb) return -1;
|
|
|
|
if (tb > ta) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
ap_sort (gconstpointer a, gconstpointer b, gpointer data)
|
|
|
|
{
|
2020-11-06 13:53:01 +13:00
|
|
|
NetDeviceWifi *self = data;
|
|
|
|
CcWifiConnectionRow *a_row = CC_WIFI_CONNECTION_ROW ((gpointer) a);
|
|
|
|
CcWifiConnectionRow *b_row = CC_WIFI_CONNECTION_ROW ((gpointer) b);
|
|
|
|
NMActiveConnection *active_connection;
|
|
|
|
gboolean a_configured, b_configured;
|
2018-12-13 18:04:01 +01:00
|
|
|
NMAccessPoint *apa, *apb;
|
2012-12-08 23:10:51 -05:00
|
|
|
guint sa, sb;
|
|
|
|
|
2020-11-06 13:53:01 +13:00
|
|
|
/* Show the connected AP first */
|
|
|
|
active_connection = nm_device_get_active_connection (NM_DEVICE (self->device));
|
|
|
|
if (active_connection != NULL) {
|
|
|
|
NMConnection *connection = NM_CONNECTION (nm_active_connection_get_connection (active_connection));
|
|
|
|
if (connection == cc_wifi_connection_row_get_connection (a_row))
|
|
|
|
return -1;
|
|
|
|
else if (connection == cc_wifi_connection_row_get_connection (b_row))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show configured networks before non-configured */
|
|
|
|
a_configured = cc_wifi_connection_row_get_connection (a_row) != NULL;
|
|
|
|
b_configured = cc_wifi_connection_row_get_connection (b_row) != NULL;
|
|
|
|
if (a_configured != b_configured) {
|
|
|
|
if (a_configured) return -1;
|
|
|
|
if (b_configured) return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show higher strength networks above lower strength ones */
|
|
|
|
|
|
|
|
apa = cc_wifi_connection_row_best_access_point (a_row);
|
|
|
|
apb = cc_wifi_connection_row_best_access_point (b_row);
|
2018-12-13 18:04:01 +01:00
|
|
|
|
|
|
|
if (apa)
|
|
|
|
sa = nm_access_point_get_strength (apa);
|
|
|
|
else
|
|
|
|
sa = 0;
|
|
|
|
|
|
|
|
if (apb)
|
|
|
|
sb = nm_access_point_get_strength (apb);
|
|
|
|
else
|
|
|
|
sb = 0;
|
|
|
|
|
2012-12-08 23:10:51 -05:00
|
|
|
if (sa > sb) return -1;
|
|
|
|
if (sb > sa) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2012-12-09 19:38:32 -05:00
|
|
|
|
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
show_details_for_row (NetDeviceWifi *self, CcWifiConnectionRow *row, CcWifiConnectionList *list)
|
2012-12-09 19:38:32 -05:00
|
|
|
{
|
|
|
|
NMConnection *connection;
|
|
|
|
NMAccessPoint *ap;
|
|
|
|
NetConnectionEditor *editor;
|
|
|
|
|
2018-12-13 18:04:01 +01:00
|
|
|
connection = cc_wifi_connection_row_get_connection (row);
|
2018-12-15 17:47:25 +01:00
|
|
|
ap = cc_wifi_connection_row_best_access_point (row);
|
2012-12-09 19:38:32 -05:00
|
|
|
|
2020-11-19 11:17:22 +13:00
|
|
|
editor = net_connection_editor_new (connection, self->device, ap, self->client);
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (editor), GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (row))));
|
2020-11-19 11:43:16 +13:00
|
|
|
gtk_window_present (GTK_WINDOW (editor));
|
2012-12-09 19:38:32 -05:00
|
|
|
}
|
|
|
|
|
2022-08-05 15:42:45 +02:00
|
|
|
static void
|
|
|
|
show_qr_code_for_row (NetDeviceWifi *self, CcWifiConnectionRow *row, CcWifiConnectionList *list)
|
|
|
|
{
|
|
|
|
NMConnection *connection;
|
|
|
|
GtkNative *native;
|
|
|
|
GtkWidget *dialog;
|
|
|
|
|
|
|
|
connection = cc_wifi_connection_row_get_connection (row);
|
|
|
|
|
|
|
|
// getting a new "local" connection, since we don't want to populate the secrets of the original connection
|
|
|
|
connection = NM_CONNECTION (nm_client_get_connection_by_id (self->client, nm_connection_get_id (connection)));
|
|
|
|
|
|
|
|
dialog = cc_qr_code_dialog_new (connection);
|
|
|
|
native = gtk_widget_get_native (GTK_WIDGET (self));
|
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (native));
|
|
|
|
gtk_window_present (GTK_WINDOW (dialog));
|
|
|
|
}
|
|
|
|
|
2023-12-14 01:23:28 +01:00
|
|
|
static void
|
|
|
|
on_show_saved_network (NetDeviceWifi *self)
|
|
|
|
{
|
2023-12-13 23:31:11 +01:00
|
|
|
gtk_window_set_transient_for (self->saved_networks_dialog,
|
2023-10-25 10:39:36 +02:00
|
|
|
GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))));
|
2023-12-13 23:31:11 +01:00
|
|
|
gtk_window_present (self->saved_networks_dialog);
|
2023-03-23 16:42:20 -04:00
|
|
|
}
|
2022-05-30 23:38:07 +02:00
|
|
|
|
2023-03-23 16:42:20 -04:00
|
|
|
static void
|
|
|
|
on_connect_hidden_network (NetDeviceWifi *self)
|
|
|
|
{
|
|
|
|
connect_hidden (self);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_wifi_hotspot_network (NetDeviceWifi *self)
|
|
|
|
{
|
|
|
|
start_hotspot (self);
|
2022-05-30 23:38:07 +02:00
|
|
|
}
|
|
|
|
|
2012-12-08 23:10:51 -05:00
|
|
|
static void
|
2019-10-18 11:47:17 +13:00
|
|
|
ap_activated (NetDeviceWifi *self, GtkListBoxRow *row)
|
2012-12-08 23:10:51 -05:00
|
|
|
{
|
2018-12-15 17:54:13 +01:00
|
|
|
CcWifiConnectionRow *c_row;
|
2012-12-08 23:10:51 -05:00
|
|
|
NMConnection *connection;
|
|
|
|
NMAccessPoint *ap;
|
|
|
|
|
2018-12-15 17:54:13 +01:00
|
|
|
/* The mockups want a row to connecto hidden networks; this could
|
|
|
|
* be handeled here. */
|
|
|
|
if (!CC_IS_WIFI_CONNECTION_ROW (row))
|
|
|
|
return;
|
|
|
|
|
|
|
|
c_row = CC_WIFI_CONNECTION_ROW (row);
|
2015-01-13 14:26:19 +01:00
|
|
|
|
2018-12-15 17:54:13 +01:00
|
|
|
connection = cc_wifi_connection_row_get_connection (c_row);
|
|
|
|
ap = cc_wifi_connection_row_best_access_point (c_row);
|
2012-12-08 23:10:51 -05:00
|
|
|
|
|
|
|
if (ap != NULL) {
|
|
|
|
if (connection != NULL) {
|
2019-10-23 14:45:52 +13:00
|
|
|
nm_client_activate_connection_async (self->client,
|
2016-04-29 16:05:54 +02:00
|
|
|
connection,
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device, NULL, self->cancellable,
|
2019-10-18 11:47:17 +13:00
|
|
|
connection_activate_cb, self);
|
2012-12-08 23:10:51 -05:00
|
|
|
} else {
|
2016-04-29 16:05:54 +02:00
|
|
|
GBytes *ssid;
|
2012-12-08 23:10:51 -05:00
|
|
|
const gchar *object_path;
|
2013-10-07 12:37:45 +02:00
|
|
|
|
2012-12-08 23:10:51 -05:00
|
|
|
ssid = nm_access_point_get_ssid (ap);
|
|
|
|
object_path = nm_object_get_path (NM_OBJECT (ap));
|
2019-10-18 11:47:17 +13:00
|
|
|
wireless_try_to_connect (self, ssid, object_path);
|
2012-12-08 23:10:51 -05:00
|
|
|
}
|
|
|
|
}
|
2012-09-08 23:29:15 -04:00
|
|
|
}
|
|
|
|
|
2012-07-20 12:05:10 +01:00
|
|
|
static void
|
2019-10-24 20:29:35 +13:00
|
|
|
net_device_wifi_class_init (NetDeviceWifiClass *klass)
|
2012-07-20 12:05:10 +01:00
|
|
|
{
|
2019-10-24 20:29:35 +13:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
2019-10-18 11:47:17 +13:00
|
|
|
|
2023-07-31 11:02:54 +04:00
|
|
|
object_class->dispose = net_device_wifi_dispose;
|
2019-10-24 20:29:35 +13:00
|
|
|
object_class->finalize = net_device_wifi_finalize;
|
|
|
|
object_class->get_property = net_device_wifi_get_property;
|
2018-02-20 17:09:35 +01:00
|
|
|
|
2019-10-24 20:29:35 +13:00
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
PROP_SCANNING,
|
|
|
|
g_param_spec_boolean ("scanning",
|
|
|
|
"Scanning",
|
|
|
|
"Whether the device is scanning for access points",
|
|
|
|
FALSE,
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
2012-07-20 12:05:10 +01:00
|
|
|
|
2019-10-24 20:29:35 +13:00
|
|
|
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/network/network-wifi.ui");
|
2012-09-30 21:14:36 -04:00
|
|
|
|
2023-03-28 12:38:34 +05:30
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, wifi_headerbar_title);
|
2023-03-23 16:42:20 -04:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, device_enable_row);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, saved_network_row);
|
2022-05-30 23:38:07 +02:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, connect_hidden_row);
|
2023-03-23 16:42:20 -04:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, hotspot_row);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, details_box);
|
2019-10-24 20:29:35 +13:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, hotspot_box);
|
2019-12-02 14:52:25 +05:30
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, hotspot_name_row);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, hotspot_security_row);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, hotspot_password_row);
|
2019-10-24 20:29:35 +13:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, listbox_box);
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, stack);
|
2023-10-25 10:39:36 +02:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, saved_networks_dialog);
|
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, saved_networks_toast_overlay);
|
2023-12-14 03:10:32 +01:00
|
|
|
gtk_widget_class_bind_template_child (widget_class, NetDeviceWifi, saved_networks_box);
|
2012-09-30 21:14:36 -04:00
|
|
|
|
2019-10-24 20:29:35 +13:00
|
|
|
gtk_widget_class_bind_template_callback (widget_class, device_off_switch_changed_cb);
|
2023-03-23 16:42:20 -04:00
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_show_saved_network);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_connect_hidden_network);
|
|
|
|
gtk_widget_class_bind_template_callback (widget_class, on_wifi_hotspot_network);
|
2019-10-24 20:29:35 +13:00
|
|
|
}
|
2012-12-08 23:10:51 -05:00
|
|
|
|
2019-10-24 20:29:35 +13:00
|
|
|
static void
|
|
|
|
net_device_wifi_init (NetDeviceWifi *self)
|
|
|
|
{
|
|
|
|
gtk_widget_init_template (GTK_WIDGET (self));
|
|
|
|
|
|
|
|
self->cancellable = g_cancellable_new ();
|
2012-07-20 12:05:10 +01:00
|
|
|
}
|
2019-10-23 14:45:52 +13:00
|
|
|
|
2020-06-17 08:53:47 -04:00
|
|
|
|
2020-09-16 14:33:51 +02:00
|
|
|
static void
|
2020-06-17 08:53:47 -04:00
|
|
|
nm_client_on_permission_change (NetDeviceWifi *self) {
|
|
|
|
NMClientPermissionResult perm;
|
|
|
|
NMDeviceWifiCapabilities caps;
|
|
|
|
|
|
|
|
if (nm_client_get_permissions_state (self->client) != NM_TERNARY_TRUE) {
|
|
|
|
/* permissions aren't ready yet */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* only enable the button if the user can create a hotspot */
|
|
|
|
perm = nm_client_get_permission_result (self->client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN);
|
|
|
|
caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (self->device));
|
|
|
|
if (perm != NM_CLIENT_PERMISSION_RESULT_YES &&
|
|
|
|
perm != NM_CLIENT_PERMISSION_RESULT_AUTH) {
|
2023-03-23 16:42:20 -04:00
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->hotspot_row), _("System policy prohibits use as a Hotspot"));
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->hotspot_row), FALSE);
|
2020-06-17 08:53:47 -04:00
|
|
|
} else if (!(caps & (NM_WIFI_DEVICE_CAP_AP | NM_WIFI_DEVICE_CAP_ADHOC))) {
|
2023-03-23 16:42:20 -04:00
|
|
|
gtk_widget_set_tooltip_text (GTK_WIDGET (self->hotspot_row), _("Wireless device does not support Hotspot mode"));
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->hotspot_row), FALSE);
|
2023-08-30 18:37:53 +02:00
|
|
|
} else {
|
|
|
|
gtk_widget_set_sensitive (GTK_WIDGET (self->hotspot_row), nm_client_wireless_get_enabled (self->client));
|
|
|
|
}
|
2020-06-17 08:53:47 -04:00
|
|
|
}
|
|
|
|
|
2019-10-23 14:45:52 +13:00
|
|
|
NetDeviceWifi *
|
|
|
|
net_device_wifi_new (CcPanel *panel, NMClient *client, NMDevice *device)
|
|
|
|
{
|
|
|
|
NetDeviceWifi *self;
|
2021-11-29 10:37:01 -03:00
|
|
|
GtkListBox *listbox;
|
2023-12-14 03:10:32 +01:00
|
|
|
CcWifiConnectionList *list;
|
2019-10-23 14:45:52 +13:00
|
|
|
|
2019-10-24 14:08:18 +13:00
|
|
|
self = g_object_new (net_device_wifi_get_type (), NULL);
|
2019-10-23 14:45:52 +13:00
|
|
|
self->panel = panel;
|
|
|
|
self->client = g_object_ref (client);
|
2019-10-24 13:04:14 +13:00
|
|
|
self->device = g_object_ref (device);
|
2019-10-23 14:45:52 +13:00
|
|
|
|
|
|
|
g_signal_connect_object (client, "notify::wireless-enabled",
|
|
|
|
G_CALLBACK (wireless_enabled_toggled), self, G_CONNECT_SWAPPED);
|
|
|
|
|
2019-10-24 13:48:25 +13:00
|
|
|
g_signal_connect_object (device, "state-changed", G_CALLBACK (nm_device_wifi_refresh_ui), self, G_CONNECT_SWAPPED);
|
2019-10-24 12:13:40 +13:00
|
|
|
|
2023-12-14 03:10:32 +01:00
|
|
|
/* Set up the main Visible Networks list */
|
|
|
|
list = cc_wifi_connection_list_new (client, NM_DEVICE_WIFI (device), TRUE, TRUE, FALSE, FALSE);
|
|
|
|
gtk_box_append (self->listbox_box, GTK_WIDGET (list));
|
2019-10-23 14:45:52 +13:00
|
|
|
|
2023-12-14 03:10:32 +01:00
|
|
|
listbox = cc_wifi_connection_list_get_list_box (list);
|
2021-11-29 10:37:01 -03:00
|
|
|
gtk_list_box_set_sort_func (listbox, (GtkListBoxSortFunc)ap_sort, self, NULL);
|
2019-10-23 14:45:52 +13:00
|
|
|
|
2021-11-29 10:37:01 -03:00
|
|
|
g_signal_connect_object (listbox, "row-activated",
|
2019-11-22 16:21:43 +13:00
|
|
|
G_CALLBACK (ap_activated), self, G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (list, "configure",
|
|
|
|
G_CALLBACK (show_details_for_row), self, G_CONNECT_SWAPPED);
|
2022-08-05 15:42:45 +02:00
|
|
|
g_signal_connect_object (list, "show-qr-code",
|
|
|
|
G_CALLBACK (show_qr_code_for_row), self, G_CONNECT_SWAPPED);
|
2020-06-17 08:53:47 -04:00
|
|
|
g_signal_connect_object (client, "notify",
|
|
|
|
G_CALLBACK(nm_client_on_permission_change), self, G_CONNECT_SWAPPED);
|
2023-12-14 03:10:32 +01:00
|
|
|
|
|
|
|
/* Set up the Saved Networks list */
|
|
|
|
list = cc_wifi_connection_list_new (self->client, NM_DEVICE_WIFI (device), FALSE, FALSE, FALSE, TRUE);
|
wifi: Fix crash when switching to other panel after forget network
Similar to the previous crashes, if you switch panels after forgetting a
network while the toast is still alive, Settings crashes. This is
because the AdwToastOverlay is not properly disposed because the Saved
Networks dialog is also not destroyed.
However, destroying the saved networks dialog still leaves a crash,
because the overlay disposal first unreferences its child, but we still
need that for the dismissal of the waiting toasts. Therefore, we keep an
extra reference to the saved networks list.
To prevent further crashing, we cannot set "list" to NULL, because there
may be multiple async calls. Also, we have to keep a reference to self
in the async call, otherwise it does not work when you remove many
networks and then switch panels.
As an added bonus, we can now use the saved networks list inside the UI
refresh function.
2023-12-14 03:15:43 +01:00
|
|
|
self->saved_networks_list = g_object_ref_sink (list);
|
2023-12-14 03:10:32 +01:00
|
|
|
adw_preferences_group_add (self->saved_networks_box, GTK_WIDGET (list));
|
|
|
|
|
|
|
|
listbox = cc_wifi_connection_list_get_list_box (list);
|
|
|
|
gtk_list_box_set_sort_func (listbox, (GtkListBoxSortFunc)history_sort, NULL, NULL);
|
|
|
|
|
|
|
|
g_signal_connect_object (list, "configure",
|
|
|
|
G_CALLBACK (show_details_for_row), self, G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (list, "forget",
|
|
|
|
G_CALLBACK (forget_selected), self, G_CONNECT_SWAPPED);
|
|
|
|
g_signal_connect_object (list, "show_qr_code",
|
|
|
|
G_CALLBACK (show_qr_code_for_row), self, G_CONNECT_SWAPPED);
|
2019-10-23 14:45:52 +13:00
|
|
|
|
2020-06-17 08:53:47 -04:00
|
|
|
nm_client_on_permission_change(self);
|
2019-10-23 14:45:52 +13:00
|
|
|
|
|
|
|
nm_device_wifi_refresh_ui (self);
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2019-10-24 13:04:14 +13:00
|
|
|
NMDevice *
|
|
|
|
net_device_wifi_get_device (NetDeviceWifi *self)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (NET_IS_DEVICE_WIFI (self), NULL);
|
|
|
|
return self->device;
|
|
|
|
}
|
|
|
|
|
2019-10-24 13:42:25 +13:00
|
|
|
void
|
|
|
|
net_device_wifi_set_title (NetDeviceWifi *self, const gchar *title)
|
|
|
|
{
|
|
|
|
g_return_if_fail (NET_IS_DEVICE_WIFI (self));
|
2023-03-28 12:38:34 +05:30
|
|
|
adw_window_title_set_title (self->wifi_headerbar_title, title);
|
2019-10-24 13:42:25 +13:00
|
|
|
}
|
|
|
|
|
2019-10-23 14:45:52 +13:00
|
|
|
GtkWidget *
|
|
|
|
net_device_wifi_get_header_widget (NetDeviceWifi *self)
|
|
|
|
{
|
2019-10-24 13:04:14 +13:00
|
|
|
g_return_val_if_fail (NET_IS_DEVICE_WIFI (self), NULL);
|
2023-03-23 16:42:20 -04:00
|
|
|
return GTK_WIDGET (self->details_box);
|
2019-10-23 14:45:52 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget *
|
|
|
|
net_device_wifi_get_title_widget (NetDeviceWifi *self)
|
|
|
|
{
|
2019-10-24 13:04:14 +13:00
|
|
|
g_return_val_if_fail (NET_IS_DEVICE_WIFI (self), NULL);
|
2023-03-28 12:38:34 +05:30
|
|
|
return GTK_WIDGET (self->wifi_headerbar_title);
|
2019-10-23 14:45:52 +13:00
|
|
|
}
|
2019-12-02 14:52:25 +05:30
|
|
|
|
|
|
|
void
|
|
|
|
net_device_wifi_turn_off_hotspot (NetDeviceWifi *self)
|
|
|
|
{
|
|
|
|
g_return_if_fail (NET_IS_DEVICE_WIFI (self));
|
|
|
|
|
|
|
|
stop_shared_connection (self);
|
|
|
|
}
|