From e738ad8c31c549668c00a81bb0c820d98338ae5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 13 Aug 2025 15:34:05 -0700 Subject: [PATCH 1/3] RKFill: add airplane mode property --- src/MainView.vala | 40 ++++++---------------------------- src/rfkill.vala | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/MainView.vala b/src/MainView.vala index 77e0cf12..29d06620 100644 --- a/src/MainView.vala +++ b/src/MainView.vala @@ -27,6 +27,7 @@ public class Network.MainView : Gtk.Box { private Gtk.ListBox device_list; private Gtk.Stack content; private NM.Device current_device = null; + private RFKillManager rfkill; private VPNPage vpn_page; construct { @@ -61,28 +62,17 @@ public class Network.MainView : Gtk.Box { device_list.append (proxy); device_list.append (vpn); - var label = new Gtk.Label (_("Airplane Mode")); - - var airplane_switch = new Gtk.Switch () { + var airplane_switch = new Granite.SwitchModelButton (("Airplane Mode")) { + hexpand = true, valign = CENTER }; var footer = new Gtk.ActionBar (); - footer.pack_start (label); - footer.pack_end (airplane_switch); - - var airplane_mode = new Granite.Placeholder ( - _("Airplane Mode Is Enabled")) { - description = _("While in Airplane Mode your device's Internet access and any wireless and ethernet connections, will be suspended.\n\n") + - _("You will be unable to browse the web or use applications that require a network connection or Internet access.\n") + - _("Applications and other functions that do not require the Internet will be unaffected."), - icon = new ThemedIcon ("airplane-mode") - }; + footer.pack_start (airplane_switch); content = new Gtk.Stack () { hexpand = true }; - content.add_named (airplane_mode, "airplane-mode-info"); content.add_child (vpn_page); content.add_child (proxy.page); @@ -141,24 +131,9 @@ public class Network.MainView : Gtk.Box { update_networking_state (); nm_client.notify["networking-enabled"].connect (update_networking_state); - airplane_switch.notify["active"].connect (() => { - nm_client.dbus_call.begin ( - NM.DBUS_PATH, NM.DBUS_INTERFACE, "Enable", - new GLib.Variant.tuple ({!airplane_switch.active}), - null, -1, null, - (obj, res) => { - try { - nm_client.dbus_call.end (res); - } catch (Error e) { - warning (e.message); - } - } - ); - }); - - if (!airplane_switch.active && !nm_client.networking_enabled) { - airplane_switch.activate (); - } + rfkill = new RFKillManager (); + rfkill.open (); + rfkill.bind_property ("airplane-mode", airplane_switch, "active", BIDIRECTIONAL | SYNC_CREATE); } private void device_removed_cb (NM.Device device) { @@ -339,7 +314,6 @@ public class Network.MainView : Gtk.Box { device_list.sensitive = false; current_device = null; device_list.select_row (null); - content.set_visible_child_name ("airplane-mode-info"); } } diff --git a/src/rfkill.vala b/src/rfkill.vala index 935892f5..cde51ffe 100644 --- a/src/rfkill.vala +++ b/src/rfkill.vala @@ -80,6 +80,60 @@ public class RFKillManager : Object { return devices; } + /* + * Toggle Airplane Mode + * + * Modern mobile platforms don't disable Bluetooth, we skip it too + * + * Setting airplane mode from here does all software lock, whereas setting + * from a key press does all hardware lock. We need one of these two things— + * all devices to be locked somehow—to consider it Airplane Mode + */ + public bool airplane_mode { + get { + var all_hardware_locked = true; + var all_software_locked = true; + + foreach (unowned var device in get_devices ()) { + if (device.device_type == BLUETOOTH) { + continue; + } + + if (!device.software_lock) { + all_software_locked = false; + } + + if (!device.hardware_lock) { + all_hardware_locked = false; + } + } + + return all_hardware_locked || all_software_locked; + } + + set { + set_software_lock (WLAN, value); + set_software_lock (UWB, value); + set_software_lock (WIMAX, value); + set_software_lock (WMAN, value); + + /* + * Some hardware keys still turn off bluetooth so we iterate over + * devices to check if bluetooth was hardware locked and unlock it + * but we don't want to toggle it back on if it was manually disabled + * in software + */ + if (!value) { + foreach (unowned var device in get_devices ()) { + if (device.device_type == BLUETOOTH && device.hardware_lock) { + set_software_lock (BLUETOOTH, false); + break; + } + } + } + } + } + public void set_software_lock (RFKillDeviceType type, bool lock_enabled) { var event = RFKillEvent (); event.type = type; @@ -117,6 +171,7 @@ public class RFKillManager : Object { device._hardware_lock = event.hard != 0; device.changed (); device_changed (device); + notify_property ("airplane-mode"); } break; } From 0a4b942d3305ea537fb2016fd83c9b7f60a23294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 13 Aug 2025 15:37:53 -0700 Subject: [PATCH 2/3] Update network.metainfo.xml.in --- data/network.metainfo.xml.in | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/data/network.metainfo.xml.in b/data/network.metainfo.xml.in index b9a591da..76e6bddf 100644 --- a/data/network.metainfo.xml.in +++ b/data/network.metainfo.xml.in @@ -28,6 +28,19 @@ contact_at_elementary.io + + +

Minor updates

+
    +
  • Updated translations
  • +
+
+ + Airplane mode switch does not change when mode changed with wingpanel + Airplane mode seems to disable wired network, too + +
+

Minor updates

From 7324f5d531af7130d67631971c75a10d779a22df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Wed, 13 Aug 2025 16:52:58 -0700 Subject: [PATCH 3/3] Update MainView.vala Co-authored-by: Ryo Nakano --- src/MainView.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MainView.vala b/src/MainView.vala index 29d06620..9cf53f2d 100644 --- a/src/MainView.vala +++ b/src/MainView.vala @@ -62,7 +62,7 @@ public class Network.MainView : Gtk.Box { device_list.append (proxy); device_list.append (vpn); - var airplane_switch = new Granite.SwitchModelButton (("Airplane Mode")) { + var airplane_switch = new Granite.SwitchModelButton (_("Airplane Mode")) { hexpand = true, valign = CENTER };