Use libcomsic-applet in status-area, network, graphics

This commit is contained in:
Ian Douglas Scott 2022-07-05 16:21:23 -07:00
parent aac43de65d
commit 765e3af815
13 changed files with 154 additions and 330 deletions

3
Cargo.lock generated
View file

@ -368,6 +368,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"cosmic-panel-config", "cosmic-panel-config",
"gtk4", "gtk4",
"libcosmic-applet",
"once_cell", "once_cell",
"relm4-macros", "relm4-macros",
"tokio", "tokio",
@ -383,6 +384,7 @@ dependencies = [
"futures-util", "futures-util",
"gtk4", "gtk4",
"itertools", "itertools",
"libcosmic-applet",
"libcosmic-widgets", "libcosmic-widgets",
"once_cell", "once_cell",
"relm4-macros", "relm4-macros",
@ -431,6 +433,7 @@ dependencies = [
"cosmic-panel-config", "cosmic-panel-config",
"futures", "futures",
"gtk4", "gtk4",
"libcosmic-applet",
"once_cell", "once_cell",
"serde", "serde",
"zbus", "zbus",

View file

@ -7,6 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
gtk4 = { git = "https://github.com/gtk-rs/gtk4-rs", features = ["v4_2"] } gtk4 = { git = "https://github.com/gtk-rs/gtk4-rs", features = ["v4_2"] }
libcosmic-applet = { path = "../../libcosmic-applet" }
once_cell = "1.9.0" once_cell = "1.9.0"
relm4-macros = { git = "https://github.com/Relm4/Relm4.git", branch = "next" } relm4-macros = { git = "https://github.com/Relm4/Relm4.git", branch = "next" }
tokio = { version = "1.16.1", features = ["full"] } tokio = { version = "1.16.1", features = ["full"] }

View file

@ -10,29 +10,16 @@ pub mod graphics;
pub mod mode_box; pub mod mode_box;
use self::{dbus::PowerDaemonProxy, graphics::Graphics, mode_box::ModeSelection}; use self::{dbus::PowerDaemonProxy, graphics::Graphics, mode_box::ModeSelection};
use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{ use gtk4::{
gdk::Display,
gio::ApplicationFlags,
glib::{self, clone, MainContext, PRIORITY_DEFAULT}, glib::{self, clone, MainContext, PRIORITY_DEFAULT},
prelude::*, prelude::*,
Align, CssProvider, Label, ListBox, ListBoxRow, Orientation, Overlay, Separator, Spinner, Align, Label, ListBox, ListBoxRow, Orientation, Overlay, Separator, Spinner,
StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION,
}; };
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().expect("failed to build tokio runtime")); static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().expect("failed to build tokio runtime"));
fn main() {
let application = gtk4::Application::new(
Some("com.system76.cosmic.applets.graphics"),
ApplicationFlags::default(),
);
application.connect_activate(build_ui);
application.run();
}
async fn get_current_graphics() -> zbus::Result<Graphics> { async fn get_current_graphics() -> zbus::Result<Graphics> {
let connection = zbus::Connection::system().await?; let connection = zbus::Connection::system().await?;
let proxy = PowerDaemonProxy::new(&connection).await?; let proxy = PowerDaemonProxy::new(&connection).await?;
@ -53,7 +40,9 @@ fn row_clicked(_: &ListBox, row: &ListBoxRow) {
selector.emit_activate(); selector.emit_activate();
} }
fn build_ui(application: &gtk4::Application) { fn main() {
gtk4::init().unwrap();
let provider = gtk4::CssProvider::new(); let provider = gtk4::CssProvider::new();
provider.load_from_data(include_bytes!("style.css")); provider.load_from_data(include_bytes!("style.css"));
gtk4::StyleContext::add_provider_for_display( gtk4::StyleContext::add_provider_for_display(
@ -62,141 +51,119 @@ fn build_ui(application: &gtk4::Application) {
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION, gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
); );
let window = gtk4::ApplicationWindow::builder()
.application(application)
.title("COSMIC Graphics Applet")
.decorated(false)
.resizable(false)
.width_request(1)
.height_request(1)
.css_classes(vec!["root_window".to_string()])
.build();
let config = CosmicPanelConfig::load_from_env().unwrap_or_default();
let popover = gtk4::builders::PopoverBuilder::new()
.autohide(true)
.has_arrow(false)
.build();
let button = gtk4::Button::new();
button.add_css_class("panel_icon");
button.connect_clicked(glib::clone!(@weak popover => move |_| {
popover.show();
}));
// TODO cleanup
let image = gtk4::Image::from_icon_name("input-gaming");
image.add_css_class("panel_icon");
image.set_pixel_size(config.get_applet_icon_size().try_into().unwrap());
button.set_child(Some(&image));
let current_graphics = RT let current_graphics = RT
.block_on(get_current_graphics()) .block_on(get_current_graphics())
.expect("failed to connect to system76-power"); .expect("failed to connect to system76-power");
view! {
icon_box = gtk4::Box {
set_orientation: Orientation::Vertical,
set_spacing: 0,
add_css_class: "icon_box",
}
}
let (tx, rx) = MainContext::channel::<bool>(PRIORITY_DEFAULT); let (tx, rx) = MainContext::channel::<bool>(PRIORITY_DEFAULT);
view! { view! {
main_overlay = Overlay { window = libcosmic_applet::AppletWindow {
add_overlay: loading_box = &gtk4::Box { set_title: Some("COSMIC Graphics Applet"),
append: loading_explain_box = &gtk4::Box {
set_orientation: Orientation::Vertical,
set_halign: Align::Center,
set_valign: Align::Center,
append: loading_spinner = &Spinner {
set_halign: Align::Center,
},
append: loading_explain = &Label {
set_label: "Please wait while your graphics mode is set...",
set_halign: Align::Center,
},
},
set_halign: Align::Center,
set_valign: Align::Center,
set_hexpand: true,
set_vexpand: true,
set_visible: false,
add_css_class: "loading-overlay",
},
#[wrap(Some)] #[wrap(Some)]
set_child: main_box = &gtk4::Box { set_child = &libcosmic_applet::AppletButton {
set_orientation: Orientation::Vertical, set_button_icon_name: "input-gaming",
set_spacing: 10, #[wrap(Some)]
set_margin_top: 20, set_popover_child: main_overlay = &Overlay {
set_margin_bottom: 20, add_overlay: loading_box = &gtk4::Box {
set_margin_start: 24, append: loading_explain_box = &gtk4::Box {
set_margin_end: 24, set_orientation: Orientation::Vertical,
append: mode_label = &Label { set_halign: Align::Center,
set_text: "Graphics Mode" set_valign: Align::Center,
}, append: loading_spinner = &Spinner {
append: separator = &Separator { set_halign: Align::Center,
set_orientation: Orientation::Horizontal },
}, append: loading_explain = &Label {
append: graphics_modes_list = &ListBox { set_label: "Please wait while your graphics mode is set...",
connect_row_activated: row_clicked, set_halign: Align::Center,
append: integrated_selector = &ModeSelection { },
set_title: "Integrated Graphics", },
set_description: "Disables external displays. Requires Restart.", set_halign: Align::Center,
set_active: (current_graphics == Graphics::Integrated), set_valign: Align::Center,
connect_toggled: clone!(@strong tx => move |_| { set_hexpand: true,
tx.send(true).expect("failed to send to main context"); set_vexpand: true,
let tx = tx.clone(); set_visible: false,
RT.spawn(async move { add_css_class: "loading-overlay",
set_graphics(Graphics::Integrated).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: nvidia_selector = &ModeSelection {
set_title: "NVIDIA Graphics",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Nvidia),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Nvidia).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: hybrid_selector = &ModeSelection {
set_title: "Hybrid Graphics",
set_description: "Requires Restart.",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Hybrid),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Hybrid).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: compute_selector = &ModeSelection {
set_title: "Compute Graphics",
set_description: "Disables external displays. Requires Restart.",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Compute),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Compute).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
}, },
#[wrap(Some)]
set_child: main_box = &gtk4::Box {
set_orientation: Orientation::Vertical,
set_spacing: 10,
set_margin_top: 20,
set_margin_bottom: 20,
set_margin_start: 24,
set_margin_end: 24,
append: mode_label = &Label {
set_text: "Graphics Mode"
},
append: separator = &Separator {
set_orientation: Orientation::Horizontal
},
append: graphics_modes_list = &ListBox {
connect_row_activated: row_clicked,
append: integrated_selector = &ModeSelection {
set_title: "Integrated Graphics",
set_description: "Disables external displays. Requires Restart.",
set_active: (current_graphics == Graphics::Integrated),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Integrated).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: nvidia_selector = &ModeSelection {
set_title: "NVIDIA Graphics",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Nvidia),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Nvidia).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: hybrid_selector = &ModeSelection {
set_title: "Hybrid Graphics",
set_description: "Requires Restart.",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Hybrid),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Hybrid).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
append: compute_selector = &ModeSelection {
set_title: "Compute Graphics",
set_description: "Disables external displays. Requires Restart.",
set_group: Some(&integrated_selector),
set_active: (current_graphics == Graphics::Compute),
connect_toggled: clone!(@strong tx => move |_| {
tx.send(true).expect("failed to send to main context");
let tx = tx.clone();
RT.spawn(async move {
set_graphics(Graphics::Compute).await.expect("failed to set graphics mode");
tx.send(false).expect("failed to send to main context");
});
})
},
}
}
} }
} }
} }
} }
rx.attach( rx.attach(
None, None,
clone!(@weak loading_box, @weak loading_spinner => @default-return Continue(true), move |val| { clone!(@weak loading_box, @weak loading_spinner => @default-return Continue(true), move |val| {
@ -205,11 +172,9 @@ fn build_ui(application: &gtk4::Application) {
Continue(true) Continue(true)
}), }),
); );
popover.set_child(Some(&main_overlay));
icon_box.append(&button);
icon_box.append(&popover);
window.set_child(Some(&icon_box));
window.show(); window.show();
let main_loop = glib::MainLoop::new(None, false);
main_loop.run();
} }

View file

@ -2,32 +2,3 @@
background-color: #2f2f2f; background-color: #2f2f2f;
opacity: 0.85; opacity: 0.85;
} }
image.panel_icon {
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
button.panel_icon {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: transparent;
background: transparent;
outline-color: transparent;
}
button.panel_icon:hover {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: rgba(255, 255, 255, 0.1);
outline-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.1);
}
window.root_window {
background: transparent;
}

View file

@ -14,5 +14,6 @@ relm4-macros = { git = "https://github.com/Relm4/Relm4.git", branch = "next" }
slotmap = "1.0.6" slotmap = "1.0.6"
tokio = { version = "1.15.0", features = ["full"] } tokio = { version = "1.15.0", features = ["full"] }
zbus = "2.0.1" zbus = "2.0.1"
libcosmic-applet = { path = "../../libcosmic-applet" }
libcosmic-widgets = { git = "https://github.com/pop-os/libcosmic", branch = "relm4-next" } libcosmic-widgets = { git = "https://github.com/pop-os/libcosmic", branch = "relm4-next" }
cosmic-panel-config = {git = "https://github.com/pop-os/cosmic-panel", features = ["gtk4"]} cosmic-panel-config = {git = "https://github.com/pop-os/cosmic-panel", features = ["gtk4"]}

View file

@ -7,90 +7,43 @@ pub mod task;
pub mod ui; pub mod ui;
pub mod widgets; pub mod widgets;
use cosmic_panel_config::config::CosmicPanelConfig; use gtk4::{glib, prelude::*, Orientation, Separator};
use gtk4::{gio::ApplicationFlags, glib, prelude::*, Orientation, Separator};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().expect("failed to build tokio runtime")); static RT: Lazy<Runtime> = Lazy::new(|| Runtime::new().expect("failed to build tokio runtime"));
fn main() { fn main() {
let application = gtk4::Application::new( gtk4::init().unwrap();
Some("com.system76.cosmic.applets.network"),
ApplicationFlags::default(),
);
application.connect_activate(build_ui);
application.run();
}
fn build_ui(application: &gtk4::Application) {
let provider = gtk4::CssProvider::new();
provider.load_from_data(include_bytes!("style.css"));
gtk4::StyleContext::add_provider_for_display(
&gtk4::gdk::Display::default().expect("Could not connect to a display."),
&provider,
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
let window = gtk4::ApplicationWindow::builder()
.application(application)
.title("COSMIC Network Applet")
.decorated(false)
.resizable(false)
.width_request(1)
.height_request(1)
.css_classes(vec!["root_window".to_string()])
.build();
view! { view! {
main_box = gtk4::Box { window = libcosmic_applet::AppletWindow {
set_orientation: Orientation::Vertical, set_title: Some("COSMIC Network Applet"),
set_spacing: 10, #[wrap(Some)]
set_margin_top: 20, set_child: button = &libcosmic_applet::AppletButton {
set_margin_bottom: 20, set_button_icon_name: "preferences-system-network",
set_margin_start: 24, #[wrap(Some)]
set_margin_end: 24 set_popover_child: main_box = &gtk4::Box {
set_orientation: Orientation::Vertical,
set_spacing: 10,
set_margin_top: 20,
set_margin_bottom: 20,
set_margin_start: 24,
set_margin_end: 24
}
}
} }
} }
let config = CosmicPanelConfig::load_from_env().unwrap_or_default(); ui::current_networks::add_current_networks(&main_box, &button);
let popover = gtk4::builders::PopoverBuilder::new()
.autohide(true)
.has_arrow(false)
.build();
let button = gtk4::Button::new();
button.add_css_class("panel_icon");
button.connect_clicked(glib::clone!(@weak popover => move |_| {
popover.show();
}));
// TODO cleanup
let image = gtk4::Image::from_icon_name("preferences-system-network");
image.add_css_class("panel_icon");
image.set_pixel_size(config.get_applet_icon_size().try_into().unwrap());
button.set_child(Some(&image));
view! {
icon_box = gtk4::Box {
set_orientation: Orientation::Vertical,
set_spacing: 0,
add_css_class: "icon_box",
}
}
popover.set_child(Some(&main_box));
icon_box.append(&button);
icon_box.append(&popover);
ui::current_networks::add_current_networks(&main_box, &image);
main_box.append(&Separator::new(Orientation::Horizontal)); main_box.append(&Separator::new(Orientation::Horizontal));
ui::toggles::add_toggles(&main_box); ui::toggles::add_toggles(&main_box);
let available_wifi_separator = Separator::new(Orientation::Horizontal); let available_wifi_separator = Separator::new(Orientation::Horizontal);
main_box.append(&available_wifi_separator); main_box.append(&available_wifi_separator);
available_wifi_separator.hide(); available_wifi_separator.hide();
ui::available_wifi::add_available_wifi(&main_box, available_wifi_separator); ui::available_wifi::add_available_wifi(&main_box, available_wifi_separator);
window.set_child(Some(&icon_box));
window.show(); window.show();
let main_loop = glib::MainLoop::new(None, false);
main_loop.run();
} }

View file

@ -1,28 +0,0 @@
image.panel_icon {
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
button.panel_icon {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: transparent;
background: transparent;
outline-color: transparent;
}
button.panel_icon:hover {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: rgba(255, 255, 255, 0.1);
outline-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.1);
}
window.root_window {
background: transparent;
}

View file

@ -18,7 +18,7 @@ use gtk4::{
use std::{cell::RefCell, net::IpAddr, rc::Rc}; use std::{cell::RefCell, net::IpAddr, rc::Rc};
use zbus::Connection; use zbus::Connection;
pub fn add_current_networks(target: &gtk4::Box, icon_image: &gtk4::Image) { pub fn add_current_networks(target: &gtk4::Box, icon_image: &libcosmic_applet::AppletButton) {
let networks_list = ListBox::builder().show_separators(true).build(); let networks_list = ListBox::builder().show_separators(true).build();
let entries = Rc::<RefCell<Vec<ListBoxRow>>>::default(); let entries = Rc::<RefCell<Vec<ListBoxRow>>>::default();
let (tx, rx) = MainContext::channel::<Vec<ActiveConnectionInfo>>(PRIORITY_DEFAULT); let (tx, rx) = MainContext::channel::<Vec<ActiveConnectionInfo>>(PRIORITY_DEFAULT);
@ -38,7 +38,7 @@ fn display_active_connections(
connections: Vec<ActiveConnectionInfo>, connections: Vec<ActiveConnectionInfo>,
target: &ListBox, target: &ListBox,
entries: &mut Vec<ListBoxRow>, entries: &mut Vec<ListBoxRow>,
icon_image: &gtk4::Image, icon_image: &libcosmic_applet::AppletButton,
) { ) {
for old_entry in entries.drain(..) { for old_entry in entries.drain(..) {
target.remove(&old_entry); target.remove(&old_entry);
@ -51,7 +51,7 @@ fn display_active_connections(
speed, speed,
ip_addresses, ip_addresses,
} => { } => {
icon_image.set_icon_name(Some("network-wired-symbolic")); icon_image.set_button_icon_name("network-wired-symbolic");
render_wired_connection(name, speed, ip_addresses) render_wired_connection(name, speed, ip_addresses)
} }
ActiveConnectionInfo::WiFi { ActiveConnectionInfo::WiFi {
@ -62,7 +62,7 @@ fn display_active_connections(
wpa_flags, wpa_flags,
} => continue, } => continue,
ActiveConnectionInfo::Vpn { name, ip_addresses } => { ActiveConnectionInfo::Vpn { name, ip_addresses } => {
icon_image.set_icon_name(Some("network-vpn-symbolic")); icon_image.set_button_icon_name("network-vpn-symbolic");
render_vpn(name, ip_addresses) render_vpn(name, ip_addresses)
} }
}; };

View file

@ -8,6 +8,7 @@ license = "GPL-3.0-or-later"
cascade = "1" cascade = "1"
futures = "0.3" futures = "0.3"
gtk4 = { git = "https://github.com/gtk-rs/gtk4-rs" } gtk4 = { git = "https://github.com/gtk-rs/gtk4-rs" }
libcosmic-applet = { path = "../../libcosmic-applet" }
once_cell = "1.12" once_cell = "1.12"
serde = "1" serde = "1"
zbus = "2.0.1" zbus = "2.0.1"

View file

@ -1,3 +1,4 @@
use cascade::cascade;
use gtk4::{glib, prelude::*}; use gtk4::{glib, prelude::*};
mod dbus_service; mod dbus_service;
@ -14,24 +15,12 @@ fn main() {
// XXX Implement DBus service somewhere other than applet? // XXX Implement DBus service somewhere other than applet?
glib::MainContext::default().spawn_local(status_notifier_watcher::start()); glib::MainContext::default().spawn_local(status_notifier_watcher::start());
let provider = gtk4::CssProvider::new();
provider.load_from_data(include_bytes!("style.css"));
gtk4::StyleContext::add_provider_for_display(
&gtk4::gdk::Display::default().expect("Could not connect to a display."),
&provider,
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
let status_area = StatusArea::new(); let status_area = StatusArea::new();
gtk4::Window::builder() cascade! {
.decorated(false) libcosmic_applet::AppletWindow::new();
.child(&status_area) ..set_child(Some(&status_area));
.resizable(false) ..show();
.width_request(1) };
.height_request(1)
.css_classes(vec!["root_window".to_string()])
.build()
.show();
let main_loop = glib::MainLoop::new(None, false); let main_loop = glib::MainLoop::new(None, false);
main_loop.run(); main_loop.run();

View file

@ -19,7 +19,7 @@ struct Menu {
#[derive(Default)] #[derive(Default)]
pub struct StatusMenuInner { pub struct StatusMenuInner {
menu_button: DerefCell<gtk4::MenuButton>, menu_button: DerefCell<libcosmic_applet::AppletButton>,
vbox: DerefCell<gtk4::Box>, vbox: DerefCell<gtk4::Box>,
item: DerefCell<StatusNotifierItemProxy<'static>>, item: DerefCell<StatusNotifierItemProxy<'static>>,
dbus_menu: DerefCell<DBusMenuProxy<'static>>, dbus_menu: DerefCell<DBusMenuProxy<'static>>,
@ -43,17 +43,10 @@ impl ObjectImpl for StatusMenuInner {
gtk4::Box::new(gtk4::Orientation::Vertical, 0); gtk4::Box::new(gtk4::Orientation::Vertical, 0);
}; };
let popover = cascade! {
gtk4::Popover::new();
..set_child(Some(&vbox));
};
let menu_button = cascade! { let menu_button = cascade! {
gtk4::MenuButton::new(); libcosmic_applet::AppletButton::new();
..add_css_class("panel_icon");
..set_has_frame(false);
..set_parent(obj); ..set_parent(obj);
..set_popover(Some(&popover)); ..set_popover_child(Some(&vbox));
}; };
self.menu_button.set(menu_button); self.menu_button.set(menu_button);
@ -88,7 +81,7 @@ impl StatusMenu {
.await?; .await?;
let obj = glib::Object::new::<Self>(&[]).unwrap(); let obj = glib::Object::new::<Self>(&[]).unwrap();
let icon_name = item.icon_name().await?; let icon_name = item.icon_name().await?;
obj.inner().menu_button.set_icon_name(&icon_name); obj.inner().menu_button.set_button_icon_name(&icon_name);
let menu = item.menu().await?; let menu = item.menu().await?;
let menu = DBusMenuProxy::builder(&connection) let menu = DBusMenuProxy::builder(&connection)

View file

@ -1,33 +0,0 @@
.loading-overlay {
background-color: #2f2f2f;
opacity: 0.85;
}
image.panel_icon {
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
button.panel_icon {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: transparent;
background: transparent;
outline-color: transparent;
}
button.panel_icon:hover {
border-radius: 12px;
transition: 100ms;
padding: 4px;
border-color: rgba(255, 255, 255, 0.1);
outline-color: rgba(255, 255, 255, 0.1);
background: rgba(255, 255, 255, 0.1);
}
window.root_window {
background: transparent;
}

View file

@ -123,4 +123,12 @@ impl AppletButton {
pub fn set_popover_child(&self, child: Option<&impl IsA<gtk4::Widget>>) { pub fn set_popover_child(&self, child: Option<&impl IsA<gtk4::Widget>>) {
self.inner().popover.set_child(child); self.inner().popover.set_child(child);
} }
pub fn popdown(&self) {
self.inner().popover.popdown();
}
pub fn popup(&self) {
self.inner().popover.popup();
}
} }