Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions data/Indicator.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,31 @@
* SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io)
*/

network .image-button.toggle {
network .image-button.toggle,
settings-toggle .image-button.toggle {
border-radius: 1em;
}

network .image-button {
network .image-button,
settings-toggle .image-button {
border: none;
box-shadow: none;
min-height: 2.1666rem; /* 26px */
min-width: 2.1666rem; /* 26px */
}

network .image-button {
network .image-button,
settings-toggle .image-button {
background: alpha(@text_color, 0.1);
}

network .image-button:checked {
network.image-button:checked,
settings-toggle .image-button:checked {
background: @selected_bg_color;
color: @selected_fg_color;
}

network .image-button:disabled {
network .image-button:disabled,
settings-toggle .image-button:disabled {
background: @insensitive_bg_color;
}
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ shared_module(
'src/Widgets/EtherInterface.vala',
'src/Widgets/ModemInterface.vala',
'src/Widgets/PopoverWidget.vala',
'src/Widgets/SettingsToggle.vala',
'src/Widgets/VpnInterface.vala',
'src/Widgets/VpnMenuItem.vala',
'src/Widgets/WidgetNMInterface.vala',
Expand Down
35 changes: 24 additions & 11 deletions src/Indicator.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class Network.Indicator : Wingpanel.Indicator {
NetworkMonitor network_monitor;

private Gtk.GestureMultiPress gesture_click;
private SimpleAction airplane_action;

public bool is_in_session { get; set; default = false; }

Expand Down Expand Up @@ -60,20 +61,30 @@ public class Network.Indicator : Wingpanel.Indicator {
};

gesture_click.pressed.connect (() => {
popover_widget.nm_client.dbus_call.begin (
NM.DBUS_PATH, NM.DBUS_INTERFACE,
"Enable", new Variant.tuple ({new Variant.boolean (!popover_widget.nm_client.networking_get_enabled ())}),
null, -1, null, (obj, res) => {
try {
((NM.Client) obj).dbus_set_property.end (res);
} catch (Error e) {
warning ("Error setting airplane mode: %s", e.message);
}
}
);
airplane_action.activate (null);
});
}

airplane_action = new SimpleAction.stateful ("airplane-mode", null, new Variant.boolean (popover_widget.nm_client.networking_get_enabled ()));
airplane_action.activate.connect (() => {
popover_widget.nm_client.dbus_call.begin (
NM.DBUS_PATH, NM.DBUS_INTERFACE,
"Enable", new Variant.tuple ({new Variant.boolean (!popover_widget.nm_client.networking_get_enabled ())}),
null, -1, null, (obj, res) => {
try {
((NM.Client) obj).dbus_set_property.end (res);
} catch (Error e) {
warning ("Error setting airplane mode: %s", e.message);
}
}
);
});

var action_group = new SimpleActionGroup ();
action_group.add_action (airplane_action);

popover_widget.insert_action_group ("network", action_group);

update_tooltip ();
on_state_changed ();
start_monitor ();
Expand All @@ -93,6 +104,8 @@ public class Network.Indicator : Wingpanel.Indicator {

display_widget.update_state (popover_widget.state, popover_widget.secure, popover_widget.extra_info);

airplane_action.set_state (new Variant.boolean (!popover_widget.nm_client.networking_get_enabled ()));

update_tooltip ();
}

Expand Down
66 changes: 32 additions & 34 deletions src/Widgets/EtherInterface.vala
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,26 @@
*/

public class Network.EtherInterface : Network.WidgetNMInterface {
private Gtk.ToggleButton ethernet_item;
private SettingsToggle ethernet_item;
private SimpleAction toggle_ethernet_action;

public EtherInterface (NM.Client nm_client, NM.Device? _device) {
device = _device;

ethernet_item = new Gtk.ToggleButton () {
halign = Gtk.Align.CENTER,
image = new Gtk.Image.from_icon_name ("panel-network-wired-connected-symbolic", Gtk.IconSize.MENU)
ethernet_item = new SettingsToggle () {
action_name = "ethernet.toggle",
icon_name = "panel-network-wired-connected-symbolic",
settings_uri = "settings://network",
text = display_title
};

var label = new Gtk.Label (display_title) {
ellipsize = Pango.EllipsizeMode.MIDDLE,
max_width_chars = 16
};
label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL);

hexpand = true;
orientation = Gtk.Orientation.VERTICAL;
spacing = 3;
add (ethernet_item);
add (label);

bind_property ("display-title", label, "label");
bind_property ("display-title", ethernet_item, "text");

ethernet_item.toggled.connect (() => {
debug ("update");
if (ethernet_item.active && device.get_state () == NM.DeviceState.DISCONNECTED) {
toggle_ethernet_action = new SimpleAction.stateful ("toggle", null, new Variant.boolean (true));
toggle_ethernet_action.activate.connect (() => {
if (device.get_state () == NM.DeviceState.DISCONNECTED) {
var connection = NM.SimpleConnection.new ();
var remote_array = device.get_available_connections ();
if (remote_array == null) {
Expand All @@ -52,13 +45,18 @@ public class Network.EtherInterface : Network.WidgetNMInterface {
connection.set_path (remote_array.get (0).get_path ());
nm_client.activate_connection_async.begin (connection, device, null, null, null);
}
} else if (!ethernet_item.active && device.get_state () == NM.DeviceState.ACTIVATED) {
} else if (device.get_state () == NM.DeviceState.ACTIVATED) {
device.disconnect_async.begin (null, () => { debug ("Successfully disconnected."); });
}
});

update ();
device.state_changed.connect (update);

var action_group = new SimpleActionGroup ();
action_group.add_action (toggle_ethernet_action);

insert_action_group ("ethernet", action_group);
}

private void update () {
Expand All @@ -67,23 +65,23 @@ public class Network.EtherInterface : Network.WidgetNMInterface {
case NM.DeviceState.UNMANAGED:
case NM.DeviceState.DEACTIVATING:
case NM.DeviceState.FAILED:
sensitive = false;
ethernet_item.active = false;
toggle_ethernet_action.set_state (new Variant.boolean (false));
toggle_ethernet_action.set_enabled (false);
state = State.FAILED;
((Gtk.Image ) ethernet_item.image).icon_name = "panel-network-wired-error-symbolic";
ethernet_item.icon_name = "panel-network-wired-error-symbolic";
break;

case NM.DeviceState.UNAVAILABLE:
sensitive = false;
ethernet_item.active = false;
toggle_ethernet_action.set_state (new Variant.boolean (false));
toggle_ethernet_action.set_enabled (false);
state = State.WIRED_UNPLUGGED;
((Gtk.Image ) ethernet_item.image).icon_name = "panel-network-wired-no-route-symbolic";
ethernet_item.icon_name = "panel-network-wired-no-route-symbolic";
break;
case NM.DeviceState.DISCONNECTED:
sensitive = true;
ethernet_item.active = false;
toggle_ethernet_action.set_state (new Variant.boolean (false));
toggle_ethernet_action.set_enabled (true);
state = State.WIRED_UNPLUGGED;
((Gtk.Image ) ethernet_item.image).icon_name = "panel-network-wired-offline-symbolic";
ethernet_item.icon_name = "panel-network-wired-offline-symbolic";
break;

case NM.DeviceState.PREPARE:
Expand All @@ -92,17 +90,17 @@ public class Network.EtherInterface : Network.WidgetNMInterface {
case NM.DeviceState.IP_CONFIG:
case NM.DeviceState.IP_CHECK:
case NM.DeviceState.SECONDARIES:
sensitive = true;
ethernet_item.active = true;
toggle_ethernet_action.set_enabled (true);
toggle_ethernet_action.set_state (new Variant.boolean (true));
state = State.CONNECTING_WIRED;
((Gtk.Image ) ethernet_item.image).icon_name = "panel-network-wired-acquiring-symbolic";
ethernet_item.icon_name = "panel-network-wired-acquiring-symbolic";
break;

case NM.DeviceState.ACTIVATED:
sensitive = true;
ethernet_item.active = true;
toggle_ethernet_action.set_enabled (true);
toggle_ethernet_action.set_state (new Variant.boolean (true));
state = State.CONNECTED_WIRED;
((Gtk.Image ) ethernet_item.image).icon_name = "panel-network-wired-connected-symbolic-symbolic";
ethernet_item.icon_name = "panel-network-wired-connected-symbolic-symbolic";
break;
}
}
Expand Down
35 changes: 6 additions & 29 deletions src/Widgets/PopoverWidget.vala
Original file line number Diff line number Diff line change
Expand Up @@ -56,43 +56,20 @@ public class Network.Widgets.PopoverWidget : Gtk.Box {
}

if (is_in_session) {
var airplane_toggle = new Gtk.ToggleButton () {
halign = Gtk.Align.CENTER,
image = new Gtk.Image.from_icon_name ("airplane-mode-symbolic", Gtk.IconSize.MENU)
var airplane_toggle = new SettingsToggle () {
action_name = "network.airplane-mode",
icon_name = "airplane-mode-symbolic",
settings_uri = "settings://network",
text = _("Airplane Mode")
};

var airplane_label = new Gtk.Label (_("Airplane Mode"));
airplane_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL);

var airplane_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 3);
airplane_box.add (airplane_toggle);
airplane_box.add (airplane_label);

var airplane_child = new Gtk.FlowBoxChild () {
// Prevent weird double focus border
can_focus = false,
child = airplane_box
child = airplane_toggle
};

other_box.add (airplane_child);

airplane_toggle.toggled.connect (() => {
nm_client.dbus_call.begin (
NM.DBUS_PATH, NM.DBUS_INTERFACE,
"Enable", new Variant.tuple ({new Variant.boolean (!airplane_toggle.active)}),
null, -1, null, (obj, res) => {
try {
((NM.Client) obj).dbus_set_property.end (res);
} catch (Error e) {
warning ("Error setting airplane mode: %s", e.message);
}
}
);
});

if (!airplane_toggle.active && !nm_client.networking_get_enabled ()) {
airplane_toggle.activate ();
}
}

var other_sep = new Gtk.Separator (Gtk.Orientation.HORIZONTAL) {
Expand Down
59 changes: 59 additions & 0 deletions src/Widgets/SettingsToggle.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io)
*/

public class Network.SettingsToggle : Gtk.Box {
public string action_name { get; set; }
public string icon_name { get; set; }
public string text { get; set; }
public string settings_uri { get; set; default = "settings://"; }

private Gtk.GestureMultiPress middle_click_gesture;

class construct {
set_css_name ("settings-toggle");
}

construct {
var image = new Gtk.Image ();

var button = new Gtk.ToggleButton () {
halign = CENTER,
image = image
};

var label = new Gtk.Label (null) {
ellipsize = MIDDLE,
justify = CENTER,
lines = 2,
max_width_chars = 13,
mnemonic_widget = button
};
label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL);

halign = CENTER;
orientation = VERTICAL;
spacing = 3;
add (button);
add (label);

bind_property ("action-name", button, "action-name");
bind_property ("icon-name", image, "icon-name");
bind_property ("text", label, "label");

middle_click_gesture = new Gtk.GestureMultiPress (this) {
button = Gdk.BUTTON_MIDDLE
};
middle_click_gesture.pressed.connect (() => {
try {
AppInfo.launch_default_for_uri (settings_uri, null);

var popover = (Gtk.Popover) get_ancestor (typeof (Gtk.Popover));
popover.popdown ();
} catch (Error e) {
critical ("Failed to open system settings: %s", e.message);
}
});
}
}
Loading