Skip to content

Commit fbd2e9a

Browse files
authored
RKFill: add airplane mode property (#438)
1 parent 5af6c03 commit fbd2e9a

File tree

3 files changed

+75
-33
lines changed

3 files changed

+75
-33
lines changed

data/network.metainfo.xml.in

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@
2828
<update_contact>contact_at_elementary.io</update_contact>
2929

3030
<releases>
31+
<release version="8.2.0" date="2025-08-12" urgency="medium">
32+
<description>
33+
<p>Minor updates</p>
34+
<ul>
35+
<li>Updated translations</li>
36+
</ul>
37+
</description>
38+
<issues>
39+
<issue url="https://github.com/elementary/switchboard-plug-network/issues/346">Airplane mode switch does not change when mode changed with wingpanel</issue>
40+
<issue url="https://github.com/elementary/switchboard-plug-network/issues/360">Airplane mode seems to disable wired network, too</issue>
41+
</issues>
42+
</release>
43+
3144
<release version="8.1.0" date="2025-02-12" urgency="medium">
3245
<description>
3346
<p>Minor updates</p>

src/MainView.vala

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class Network.MainView : Gtk.Box {
2727
private Gtk.ListBox device_list;
2828
private Gtk.Stack content;
2929
private NM.Device current_device = null;
30+
private RFKillManager rfkill;
3031
private VPNPage vpn_page;
3132

3233
construct {
@@ -61,28 +62,17 @@ public class Network.MainView : Gtk.Box {
6162
device_list.append (proxy);
6263
device_list.append (vpn);
6364

64-
var label = new Gtk.Label (_("Airplane Mode"));
65-
66-
var airplane_switch = new Gtk.Switch () {
65+
var airplane_switch = new Granite.SwitchModelButton (_("Airplane Mode")) {
66+
hexpand = true,
6767
valign = CENTER
6868
};
6969

7070
var footer = new Gtk.ActionBar ();
71-
footer.pack_start (label);
72-
footer.pack_end (airplane_switch);
73-
74-
var airplane_mode = new Granite.Placeholder (
75-
_("Airplane Mode Is Enabled")) {
76-
description = _("While in Airplane Mode your device's Internet access and any wireless and ethernet connections, will be suspended.\n\n") +
77-
_("You will be unable to browse the web or use applications that require a network connection or Internet access.\n") +
78-
_("Applications and other functions that do not require the Internet will be unaffected."),
79-
icon = new ThemedIcon ("airplane-mode")
80-
};
71+
footer.pack_start (airplane_switch);
8172

8273
content = new Gtk.Stack () {
8374
hexpand = true
8475
};
85-
content.add_named (airplane_mode, "airplane-mode-info");
8676
content.add_child (vpn_page);
8777
content.add_child (proxy.page);
8878

@@ -141,24 +131,9 @@ public class Network.MainView : Gtk.Box {
141131
update_networking_state ();
142132
nm_client.notify["networking-enabled"].connect (update_networking_state);
143133

144-
airplane_switch.notify["active"].connect (() => {
145-
nm_client.dbus_call.begin (
146-
NM.DBUS_PATH, NM.DBUS_INTERFACE, "Enable",
147-
new GLib.Variant.tuple ({!airplane_switch.active}),
148-
null, -1, null,
149-
(obj, res) => {
150-
try {
151-
nm_client.dbus_call.end (res);
152-
} catch (Error e) {
153-
warning (e.message);
154-
}
155-
}
156-
);
157-
});
158-
159-
if (!airplane_switch.active && !nm_client.networking_enabled) {
160-
airplane_switch.activate ();
161-
}
134+
rfkill = new RFKillManager ();
135+
rfkill.open ();
136+
rfkill.bind_property ("airplane-mode", airplane_switch, "active", BIDIRECTIONAL | SYNC_CREATE);
162137
}
163138

164139
private void device_removed_cb (NM.Device device) {
@@ -339,7 +314,6 @@ public class Network.MainView : Gtk.Box {
339314
device_list.sensitive = false;
340315
current_device = null;
341316
device_list.select_row (null);
342-
content.set_visible_child_name ("airplane-mode-info");
343317
}
344318
}
345319

src/rfkill.vala

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,60 @@ public class RFKillManager : Object {
8080
return devices;
8181
}
8282

83+
/*
84+
* Toggle Airplane Mode
85+
*
86+
* Modern mobile platforms don't disable Bluetooth, we skip it too
87+
*
88+
* Setting airplane mode from here does all software lock, whereas setting
89+
* from a key press does all hardware lock. We need one of these two things—
90+
* all devices to be locked somehow—to consider it Airplane Mode
91+
*/
92+
public bool airplane_mode {
93+
get {
94+
var all_hardware_locked = true;
95+
var all_software_locked = true;
96+
97+
foreach (unowned var device in get_devices ()) {
98+
if (device.device_type == BLUETOOTH) {
99+
continue;
100+
}
101+
102+
if (!device.software_lock) {
103+
all_software_locked = false;
104+
}
105+
106+
if (!device.hardware_lock) {
107+
all_hardware_locked = false;
108+
}
109+
}
110+
111+
return all_hardware_locked || all_software_locked;
112+
}
113+
114+
set {
115+
set_software_lock (WLAN, value);
116+
set_software_lock (UWB, value);
117+
set_software_lock (WIMAX, value);
118+
set_software_lock (WMAN, value);
119+
120+
/*
121+
* Some hardware keys still turn off bluetooth so we iterate over
122+
* devices to check if bluetooth was hardware locked and unlock it
123+
* but we don't want to toggle it back on if it was manually disabled
124+
* in software
125+
*/
126+
if (!value) {
127+
foreach (unowned var device in get_devices ()) {
128+
if (device.device_type == BLUETOOTH && device.hardware_lock) {
129+
set_software_lock (BLUETOOTH, false);
130+
break;
131+
}
132+
}
133+
}
134+
}
135+
}
136+
83137
public void set_software_lock (RFKillDeviceType type, bool lock_enabled) {
84138
var event = RFKillEvent ();
85139
event.type = type;
@@ -117,6 +171,7 @@ public class RFKillManager : Object {
117171
device._hardware_lock = event.hard != 0;
118172
device.changed ();
119173
device_changed (device);
174+
notify_property ("airplane-mode");
120175
}
121176
break;
122177
}

0 commit comments

Comments
 (0)