diff options
Diffstat (limited to 'panels')
-rw-r--r-- | panels/network/Makefile.am | 6 | ||||
-rw-r--r-- | panels/network/cc-wifi-panel.c | 631 | ||||
-rw-r--r-- | panels/network/cc-wifi-panel.h | 34 | ||||
-rw-r--r-- | panels/network/gnome-wifi-panel.desktop.in.in | 18 | ||||
-rw-r--r-- | panels/network/network.gresource.xml | 4 | ||||
-rw-r--r-- | panels/network/wifi.ui | 327 |
6 files changed, 1018 insertions, 2 deletions
diff --git a/panels/network/Makefile.am b/panels/network/Makefile.am index ed206d7d8..fb2b891b9 100644 --- a/panels/network/Makefile.am +++ b/panels/network/Makefile.am @@ -39,7 +39,9 @@ libnetwork_la_SOURCES = \ network-dialogs.c \ network-dialogs.h \ cc-network-panel.c \ - cc-network-panel.h + cc-network-panel.h \ + cc-wifi-panel.c \ + cc-wifi-panel.h libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) $(builddir)/connection-editor/libconnection-editor.la @@ -54,7 +56,7 @@ cc-network-resources.h: network.gresource.xml $(resource_files) @INTLTOOL_DESKTOP_RULE@ desktopdir = $(datadir)/applications -desktop_in_files = gnome-network-panel.desktop.in +desktop_in_files = gnome-network-panel.desktop.in gnome-wifi-panel.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) CLEANFILES = $(desktop_in_files) $(desktop_DATA) $(BUILT_SOURCES) diff --git a/panels/network/cc-wifi-panel.c b/panels/network/cc-wifi-panel.c new file mode 100644 index 000000000..89fcc3db6 --- /dev/null +++ b/panels/network/cc-wifi-panel.c @@ -0,0 +1,631 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> + * + * 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, see <http://www.gnu.org/licenses/>. + * + */ + +#include "cc-network-resources.h" +#include "cc-wifi-panel.h" +#include "net-device.h" +#include "net-device-wifi.h" +#include "network-dialogs.h" + +#include "shell/list-box-helper.h" + +#include <glib/gi18n.h> +#include <NetworkManager.h> + +typedef enum +{ + OPERATION_NULL, + OPERATION_SHOW_DEVICE, + OPERATION_CREATE_WIFI, + OPERATION_CONNECT_HIDDEN, + OPERATION_CONNECT_8021X +} CmdlineOperation; + +struct _CcWifiPanel +{ + CcPanel parent; + + /* RFKill (Airplane Mode) */ + GDBusProxy *rfkill_proxy; + GtkSwitch *rfkill_switch; + GtkWidget *rfkill_widget; + + /* Main widgets */ + GtkStack *center_stack; + GtkStack *header_stack; + GtkStack *main_stack; + GtkSizeGroup *sizegroup; + GtkStack *stack; + + NMClient *client; + + GPtrArray *devices; + + GCancellable *cancellable; + + /* Command-line arguments */ + CmdlineOperation arg_operation; + gchar *arg_device; + gchar *arg_access_point; +}; + +static void rfkill_switch_notify_activate_cb (GtkSwitch *rfkill_switch, + GParamSpec *pspec, + CcWifiPanel *self); + +static void update_devices_names (CcWifiPanel *self); + +G_DEFINE_TYPE (CcWifiPanel, cc_wifi_panel, CC_TYPE_PANEL) + +enum +{ + PROP_0, + PROP_PARAMETERS, + N_PROPS +}; + +/* Auxiliary methods */ + +static void +add_wifi_device (CcWifiPanel *self, + NMDevice *device) +{ + GtkWidget *header_widget; + NetObject *net_device; + + /* Only manage Wi-Fi devices */ + if (!NM_IS_DEVICE_WIFI (device)) + return; + + /* Create the NetDevice */ + net_device = g_object_new (NET_TYPE_DEVICE_WIFI, + "panel", self, + "removable", FALSE, + "cancellable", self->cancellable, + "client", self->client, + "nm-device", device, + "id", nm_device_get_udi (device), + NULL); + + net_object_add_to_stack (net_device, self->stack, self->sizegroup); + + /* And add to the header widgets */ + header_widget = net_device_wifi_get_header_widget (NET_DEVICE_WIFI (net_device)); + + gtk_stack_add_named (self->header_stack, header_widget, net_object_get_id (net_device)); + + /* Setup custom title properties */ + g_ptr_array_add (self->devices, net_device); + + update_devices_names (self); +} + +static void +check_main_stack_page (CcWifiPanel *self) +{ + const gchar *nm_version; + + nm_version = nm_client_get_version (self->client); + + if (!nm_version) + gtk_stack_set_visible_child_name (self->main_stack, "nm-not-running"); + else if (self->devices->len == 0) + gtk_stack_set_visible_child_name (self->main_stack, "no-wifi-devices"); + else + gtk_stack_set_visible_child_name (self->main_stack, "wifi-connections"); + +} + +static void +load_wifi_devices (CcWifiPanel *self) +{ + const GPtrArray *devices; + guint i; + + devices = nm_client_get_devices (self->client); + + /* Cold-plug existing devices */ + for (i = 0; i < devices->len; i++) + add_wifi_device (self, g_ptr_array_index (devices, i)); + + check_main_stack_page (self); +} + +static inline gboolean +get_cached_rfkill_property (CcWifiPanel *self, + const gchar *property) +{ + g_autoptr (GVariant) result; + + result = g_dbus_proxy_get_cached_property (self->rfkill_proxy, property); + return result ? g_variant_get_boolean (result) : FALSE; +} + +static void +sync_airplane_mode_switch (CcWifiPanel *self) +{ + gboolean enabled, should_show, hw_enabled; + + enabled = get_cached_rfkill_property (self, "HasAirplaneMode"); + should_show = get_cached_rfkill_property (self, "ShouldShowAirplaneMode"); + + gtk_widget_set_visible (GTK_WIDGET (self->rfkill_widget), enabled && should_show); + if (!enabled || !should_show) + return; + + enabled = get_cached_rfkill_property (self, "AirplaneMode"); + hw_enabled = get_cached_rfkill_property (self, "HardwareAirplaneMode"); + + enabled |= hw_enabled; + + if (enabled != gtk_switch_get_active (self->rfkill_switch)) + { + g_signal_handlers_block_by_func (self->rfkill_switch, + rfkill_switch_notify_activate_cb, + self); + gtk_switch_set_active (self->rfkill_switch, enabled); + g_signal_handlers_unblock_by_func (self->rfkill_switch, + rfkill_switch_notify_activate_cb, + self); + } + + gtk_widget_set_sensitive (GTK_WIDGET (self->rfkill_switch), !hw_enabled); + + check_main_stack_page (self); +} + +static void +update_devices_names (CcWifiPanel *self) +{ + guint number_of_devices = self->devices->len; + + if (number_of_devices == 1) + { + GtkWidget *title_widget; + NetObject *net_device; + + net_device = g_ptr_array_index (self->devices, 0); + title_widget = net_device_wifi_get_title_widget (NET_DEVICE_WIFI (net_device)); + + gtk_stack_add_named (self->center_stack, title_widget, "single"); + gtk_stack_set_visible_child_name (self->center_stack, "single"); + + net_object_set_title (net_device, _("Wi-Fi")); + } + else + { + GtkWidget *single_page_widget; + guint i; + + for (i = 0; i < number_of_devices; i++) + { + NetObject *object; + NMDevice *device; + + object = g_ptr_array_index (self->devices, i); + device = net_device_get_nm_device (NET_DEVICE (object)); + + net_object_set_title (object, nm_device_get_product (device)); + } + + /* Remove the widget at the "single" page */ + single_page_widget = gtk_stack_get_child_by_name (self->center_stack, "single"); + + if (single_page_widget) + { + g_object_ref (single_page_widget); + gtk_container_remove (GTK_CONTAINER (self->center_stack), single_page_widget); + } + + /* Show the stack-switcher page */ + gtk_stack_set_visible_child_name (self->center_stack, "many"); + } +} + +/* Command-line arguments */ + +static void +reset_command_line_args (CcWifiPanel *self) +{ + self->arg_operation = OPERATION_NULL; + g_clear_pointer (&self->arg_device, g_free); + g_clear_pointer (&self->arg_access_point, g_free); +} + +static gboolean +handle_argv_for_device (CcWifiPanel *self, + NetObject *net_object) +{ + GtkWidget *toplevel; + NMDevice *device; + gboolean ret; + + toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self))); + device = net_device_get_nm_device (NET_DEVICE (net_object)); + ret = FALSE; + + if (self->arg_operation == OPERATION_CREATE_WIFI) + { + cc_network_panel_create_wifi_network (toplevel, self->client); + ret = TRUE; + } + else if (self->arg_operation == OPERATION_CONNECT_HIDDEN) + { + cc_network_panel_connect_to_hidden_network (toplevel, self->client); + ret = TRUE; + } + else if (g_str_equal (nm_object_get_path (NM_OBJECT (device)), self->arg_device)) + { + if (self->arg_operation == OPERATION_CONNECT_8021X) + { + cc_network_panel_connect_to_8021x_network (toplevel, + self->client, + device, + self->arg_access_point); + ret = TRUE; + } + else if (self->arg_operation == OPERATION_SHOW_DEVICE) + { + gtk_stack_set_visible_child_name (self->stack, net_object_get_id (net_object)); + ret = TRUE; + } + } + + if (ret) + reset_command_line_args (self); + + return ret; +} + +static void +handle_argv (CcWifiPanel *self) +{ + guint i; + + if (self->arg_operation == OPERATION_NULL) + return; + + for (i = 0; i < self->devices->len; i++) + { + if (handle_argv_for_device (self, g_ptr_array_index (self->devices, i))) + break; + } +} + +static GPtrArray * +variant_av_to_string_array (GVariant *array) +{ + GVariantIter iter; + GVariant *v; + GPtrArray *strv; + gsize count; + + count = g_variant_iter_init (&iter, array); + strv = g_ptr_array_sized_new (count + 1); + + while (g_variant_iter_next (&iter, "v", &v)) + { + g_ptr_array_add (strv, (gpointer) g_variant_get_string (v, NULL)); + g_variant_unref (v); + } + + g_ptr_array_add (strv, NULL); /* NULL-terminate the strv data array */ + return strv; +} + +static gboolean +verify_argv (CcWifiPanel *self, + const char **args) +{ + switch (self->arg_operation) + { + case OPERATION_CONNECT_8021X: + case OPERATION_SHOW_DEVICE: + if (!self->arg_device) + { + g_warning ("Operation %s requires an object path", args[0]); + return FALSE; + } + default: + return TRUE; + } +} + +/* Callbacks */ + +static void +device_added_cb (NMClient *client, + NMDevice *device, + CcWifiPanel *self) +{ + add_wifi_device (self, device); + check_main_stack_page (self); +} + +static void +device_removed_cb (NMClient *client, + NMDevice *device, + CcWifiPanel *self) +{ + GtkWidget *child; + const gchar *id; + guint i; + + if (!NM_IS_DEVICE_WIFI (device)) + return; + + id = nm_device_get_udi (device); + + /* Destroy all stack pages related to this device */ + child = gtk_stack_get_child_by_name (self->stack, id); + gtk_widget_destroy (child); + + child = gtk_stack_get_child_by_name (self->header_stack, id); + gtk_widget_destroy (child); + + /* Remove from the devices list */ + for (i = 0; i < self->devices->len; i++) + { + NetObject *object = g_ptr_array_index (self->devices, 0); + + if (g_strcmp0 (net_object_get_id (object), id) == 0) + { + g_ptr_array_remove (self->devices, object); + break; + } + } + + /* Update the title widget */ + update_devices_names (self); + + /* And check which page should be visible */ + check_main_stack_page (self); +} + +static void +rfkill_proxy_acquired_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + CcWifiPanel *self = CC_WIFI_PANEL (user_data); + GError *error = NULL; + + self->rfkill_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_printerr ("Error creating rfkill proxy: %s\n", error->message); + + g_error_free (error); + return; + } + + sync_airplane_mode_switch (self); +} + +static void +rfkill_switch_notify_activate_cb (GtkSwitch *rfkill_switch, + GParamSpec *pspec, + CcWifiPanel *self) +{ + gboolean enable; + + enable = gtk_switch_get_active (rfkill_switch); + + g_dbus_proxy_call (self->rfkill_proxy, + "org.freedesktop.DBus.Properties.Set", + g_variant_new_parsed ("('org.gnome.SettingsDaemon.Rfkill'," + "'AirplaneMode', %v)", + g_variant_new_boolean (enable)), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->cancellable, + NULL, + NULL); +} + +/* Overrides */ + +static const gchar * +cc_wifi_panel_get_help_uri (CcPanel *panel) +{ + return "help:gnome-help/wifi"; +} + +static GtkWidget * +cc_wifi_panel_get_title_widget (CcPanel *panel) +{ + CcWifiPanel *self = CC_WIFI_PANEL (panel); + + return GTK_WIDGET (self->center_stack); +} + +static void +cc_wifi_panel_constructed (GObject *object) +{ + CcWifiPanel *self; + CcShell *shell; + + self = CC_WIFI_PANEL (object); + shell = cc_panel_get_shell (CC_PANEL (object)); + + G_OBJECT_CLASS (cc_wifi_panel_parent_class)->constructed (object); + + cc_shell_embed_widget_in_header (shell, GTK_WIDGET (self->header_stack)); +} + +static void +cc_wifi_panel_finalize (GObject *object) +{ + CcWifiPanel *self = (CcWifiPanel *)object; + + g_cancellable_cancel (self->cancellable); + + g_clear_object (&self->cancellable); + g_clear_object (&self->client); + g_clear_object (&self->rfkill_proxy); + + g_clear_pointer (&self->devices, g_ptr_array_unref); + + reset_command_line_args (self); + + G_OBJECT_CLASS (cc_wifi_panel_parent_class)->finalize (object); +} + +static void +cc_wifi_panel_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static void +cc_wifi_panel_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CcWifiPanel *self = CC_WIFI_PANEL (object); + GVariant *parameters; + + switch (prop_id) + { + case PROP_PARAMETERS: + reset_command_line_args (self); + + parameters = g_value_get_variant (value); + + if (parameters) + { + GPtrArray *array; + const gchar **args; + + array = variant_av_to_string_array (parameters); + args = (const gchar **) array->pdata; + + if (args[0]) + { + if (g_str_equal (args[0], "create-wifi")) + self->arg_operation = OPERATION_CREATE_WIFI; + else if (g_str_equal (args[0], "connect-hidden-wifi")) + self->arg_operation = OPERATION_CONNECT_HIDDEN; + else if (g_str_equal (args[0], "connect-8021x-wifi")) + self->arg_operation = OPERATION_CONNECT_8021X; + else if (g_str_equal (args[0], "show-device")) + self->arg_operation = OPERATION_SHOW_DEVICE; + else + self->arg_operation = OPERATION_NULL; + } + + if (args[0] && args[1]) + self->arg_device = g_strdup (args[1]); + if (args[0] && args[1] && args[2]) + self->arg_access_point = g_strdup (args[2]); + + if (!verify_argv (self, (const char **) args)) + { + reset_command_line_args (self); + g_ptr_array_unref (array); + return; + } + + g_ptr_array_unref (array); + + handle_argv (self); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +cc_wifi_panel_class_init (CcWifiPanelClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + CcPanelClass *panel_class = CC_PANEL_CLASS (klass); + + panel_class->get_help_uri = cc_wifi_panel_get_help_uri; + panel_class->get_title_widget = cc_wifi_panel_get_title_widget; + + object_class->constructed = cc_wifi_panel_constructed; + object_class->finalize = cc_wifi_panel_finalize; + object_class->get_property = cc_wifi_panel_get_property; + object_class->set_property = cc_wifi_panel_set_property; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/network/wifi.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, center_stack); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, header_stack); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, main_stack); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, rfkill_switch); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, rfkill_widget); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, sizegroup); + gtk_widget_class_bind_template_child (widget_class, CcWifiPanel, stack); + + gtk_widget_class_bind_template_callback (widget_class, rfkill_switch_notify_activate_cb); + + g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters"); +} + +static void +cc_wifi_panel_init (CcWifiPanel *self) +{ + g_resources_register (cc_network_get_resource ()); + + gtk_widget_init_template (GTK_WIDGET (self)); + + self->cancellable = g_cancellable_new (); + self->devices = g_ptr_array_new_with_free_func (g_object_unref); + + /* Load NetworkManager */ + self->client = nm_client_new (NULL, NULL); + + g_signal_connect (self->client, + "device-added", + G_CALLBACK (device_added_cb), + self); + + g_signal_connect (self->client, + "device-removed", + G_CALLBACK (device_removed_cb), + self); + + /* Load Wi-Fi devices */ + load_wifi_devices (self); + + /* Acquire Airplane Mode proxy */ + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + self->cancellable, + rfkill_proxy_acquired_cb, + self); + + /* Handle comment-line arguments after loading devices */ + handle_argv (self); +} diff --git a/panels/network/cc-wifi-panel.h b/panels/network/cc-wifi-panel.h new file mode 100644 index 000000000..43ad4bf96 --- /dev/null +++ b/panels/network/cc-wifi-panel.h @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> + * + * 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, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef CC_WIFI_PANEL_H +#define CC_WIFI_PANEL_H + +#include <shell/cc-panel.h> + +G_BEGIN_DECLS + +#define CC_TYPE_WIFI_PANEL (cc_wifi_panel_get_type()) + +G_DECLARE_FINAL_TYPE (CcWifiPanel, cc_wifi_panel, CC, WIFI_PANEL, CcPanel) + +G_END_DECLS + +#endif /* CC_WIFI_PANEL_H */ + diff --git a/panels/network/gnome-wifi-panel.desktop.in.in b/panels/network/gnome-wifi-panel.desktop.in.in new file mode 100644 index 000000000..b37e650b8 --- /dev/null +++ b/panels/network/gnome-wifi-panel.desktop.in.in @@ -0,0 +1,18 @@ +[Desktop Entry] +# Translators: Add soft hyphens to your translations so that the icon view won't clip your translations. See https://bugzilla.gnome.org/show_bug.cgi?id=647087#c13 for details +_Name=Wi-Fi +_Comment=Control how you connect to Wi-Fi networks +Exec=gnome-control-center wifi +Icon=network-wireless +Terminal=false +Type=Application +NoDisplay=true +StartupNotify=true +Categories=GNOME;GTK;Settings;HardwareSettings;X-GNOME-Settings-Panel;X-GNOME-ConnectivitySettings; +OnlyShowIn=GNOME;Unity; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-control-center +X-GNOME-Bugzilla-Component=network +X-GNOME-Bugzilla-Version=@VERSION@ +# Translators: those are keywords for the wi-fi control-center panel +_Keywords=Network;Wireless;Wi-Fi;Wifi;IP;LAN;Broadband;DNS; diff --git a/panels/network/network.gresource.xml b/panels/network/network.gresource.xml index 9dbb815fb..3532b7cae 100644 --- a/panels/network/network.gresource.xml +++ b/panels/network/network.gresource.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/org/gnome/control-center/network"> + <!-- Network panel --> <file preprocess="xml-stripblanks">network.ui</file> <file preprocess="xml-stripblanks">network-proxy.ui</file> <file preprocess="xml-stripblanks">network-vpn.ui</file> @@ -8,5 +9,8 @@ <file preprocess="xml-stripblanks">network-simple.ui</file> <file preprocess="xml-stripblanks">network-mobile.ui</file> <file preprocess="xml-stripblanks">network-ethernet.ui</file> + + <!-- Wi-Fi panel --> + <file preprocess="xml-stripblanks">wifi.ui</file> </gresource> </gresources> diff --git a/panels/network/wifi.ui b/panels/network/wifi.ui new file mode 100644 index 000000000..7252748ce --- /dev/null +++ b/panels/network/wifi.ui @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="3.20"/> + <template class="CcWifiPanel" parent="CcPanel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkStack" id="main_stack"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="homogeneous">False</property> + <property name="transition_type">crossfade</property> + + <!-- "No Wi-Fi Adapter" page --> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="expand">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="orientation">vertical</property> + <property name="margin">18</property> + <property name="spacing">18</property> + <child type="center"> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">network-wireless-no-route-symbolic</property> + <property name="pixel_size">128</property> + <style> + <class name="dim-label" /> + </style> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="wrap">True</property> + <property name="label" translatable="yes">Make sure you have a Wi-Fi adapter plugged and turned on</property> + </object> + <packing> + <property name="pack-type">end</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="wrap">True</property> + <property name="label" translatable="yes">No Wi-Fi Adapter Found</property> + <attributes> + <attribute name="scale" value="1.42" /> + </attributes> + </object> + <packing> + <property name="pack-type">end</property> + </packing> + </child> + </object> + <packing> + <property name="name">no-wifi-devices</property> + </packing> + </child> + + <!-- Wi-Fi connections and devices --> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hscrollbar-policy">never</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="shadow-type">none</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="border-width">24</property> + <property name="row-spacing">18</property> + + <!-- Empty boxes to enforce 1/3 width for the main widgets --> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + <property name="height">3</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left-attach">2</property> + <property name="top-attach">0</property> + <property name="height">3</property> + </packing> + </child> + + <!-- Airplane Mode --> + <child> + <object class="GtkFrame" id="rfkill_widget"> + <property name="visible">True</property> + <property name="vexpand">False</property> + <child> + <object class="GtkListBox"> + <property name="visible">True</property> + <property name="selection-mode">none</property> + <child> + <object class="GtkListBoxRow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="activatable">False</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="border-width">12</property> + <property name="column-spacing">12</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Airplane Mode</property> + <property name="xalign">0.0</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes">Disables Wi-Fi, Bluetooth and mobile broadband</property> + <property name="xalign">0.0</property> + <attributes> + <attribute name="scale" value="0.88"/> + </attributes> + <style> + <class name="dim-label"/> + </style> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + <child> + <object class="GtkSwitch" id="rfkill_switch"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="valign">center</property> + <signal name="notify::active" handler="rfkill_switch_notify_activate_cb" object="CcWifiPanel" swapped="no" /> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + <property name="height">2</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + + <!-- Visible Networks label & spinner --> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="hexpand">True</property> + <property name="halign">start</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="label" translatable="yes">Visible Networks</property> + <property name="xalign">0.0</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + <child> + <object class="GtkSpinner" id="spinner"> + <property name="hexpand">True</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">1</property> + </packing> + </child> + + <!-- Stack with a listbox for each Wi-Fi device --> + <child> + <object class="GtkFrame"> + <property name="visible">True</property> + <property name="valign">start</property> + <style> + <class name="view" /> + </style> + <child> + <object class="GtkStack" id="stack"> + <property name="visible">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="transition_type">crossfade</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">2</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="name">wifi-connections</property> + </packing> + </child> + + <!-- "NetworkManager Not Running" page --> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="expand">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="orientation">vertical</property> + <property name="margin">18</property> + <property name="spacing">18</property> + <child type="center"> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">face-sad-symbolic</property> + <property name="pixel_size">128</property> + <style> + <class name="dim-label" /> + </style> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="wrap">True</property> + <property name="label" translatable="yes">NetworkManager needs to be running</property> + </object> + <packing> + <property name="pack-type">end</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="wrap">True</property> + <property name="label" translatable="yes">Oops, something has gone wrong. Please contact your software vendor.</property> + <attributes> + <attribute name="scale" value="1.42" /> + </attributes> + </object> + <packing> + <property name="pack-type">end</property> + </packing> + </child> + </object> + <packing> + <property name="name">nm-not-running</property> + </packing> + </child> + </object> + </child> + </template> + + <!-- End Stack --> + <object class="GtkStack" id="header_stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + </object> + + <!-- Center Widget --> + <object class="GtkStack" id="center_stack"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">center</property> + <child> + <object class="GtkStackSwitcher"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stack">stack</property> + </object> + <packing> + <property name="name">many</property> + </packing> + </child> + </object> + + <object class="GtkSizeGroup" id="sizegroup" /> +</interface> |