mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-17 23:01:04 +02:00
refactor: replace channel macros with ext trait methods
This commit is contained in:
parent
d5744f597c
commit
f929aef2d9
50 changed files with 658 additions and 476 deletions
|
@ -1,8 +1,9 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::compositor::BindModeUpdate;
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, module_update, send_async, spawn};
|
||||
use crate::{module_impl, spawn};
|
||||
use color_eyre::Result;
|
||||
use gtk::Label;
|
||||
use gtk::prelude::*;
|
||||
|
@ -49,7 +50,7 @@ impl Module<Label> for Bindmode {
|
|||
let mut rx = client.subscribe()?;
|
||||
spawn(async move {
|
||||
while let Ok(ev) = rx.recv().await {
|
||||
module_update!(tx, ev);
|
||||
tx.send_update(ev).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -80,7 +81,7 @@ impl Module<Label> for Bindmode {
|
|||
label.set_label_escaped(&mode.name);
|
||||
};
|
||||
|
||||
glib_recv!(context.subscribe(), on_mode);
|
||||
context.subscribe().recv_glib(on_mode);
|
||||
}
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::config::CommonConfig;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, spawn, try_send};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{module_impl, spawn};
|
||||
use cairo::{Format, ImageSurface};
|
||||
use glib::Propagation;
|
||||
use glib::translate::ToGlibPtr;
|
||||
|
@ -87,7 +88,7 @@ impl Module<gtk::Box> for CairoModule {
|
|||
debug!("{event:?}");
|
||||
|
||||
if event.paths.first().is_some_and(|p| p == &path) {
|
||||
try_send!(tx, ModuleUpdateEvent::Update(()));
|
||||
tx.send_update_spawn(());
|
||||
}
|
||||
}
|
||||
Err(e) => error!("Error occurred when watching stylesheet: {:?}", e),
|
||||
|
@ -191,22 +192,20 @@ impl Module<gtk::Box> for CairoModule {
|
|||
}
|
||||
});
|
||||
|
||||
glib_recv!(context.subscribe(), _ev => {
|
||||
context.subscribe().recv_glib(move |_ev| {
|
||||
let res = fs::read_to_string(&self.path)
|
||||
.map(|s| s.replace("function draw", format!("function __draw_{id}").as_str()));
|
||||
|
||||
match res {
|
||||
Ok(script) => {
|
||||
match lua.load(&script).exec() {
|
||||
Ok(()) => {},
|
||||
Err(Error::SyntaxError { message, ..}) => {
|
||||
let message = message.split_once("]:").expect("to exist").1;
|
||||
error!("[lua syntax error] {}:{message}", self.path.display());
|
||||
},
|
||||
Err(err) => error!("lua error: {err:?}")
|
||||
Ok(script) => match lua.load(&script).exec() {
|
||||
Ok(()) => {}
|
||||
Err(Error::SyntaxError { message, .. }) => {
|
||||
let message = message.split_once("]:").expect("to exist").1;
|
||||
error!("[lua syntax error] {}:{message}", self.path.display());
|
||||
}
|
||||
Err(err) => error!("lua error: {err:?}"),
|
||||
},
|
||||
Err(err) => error!("{err:?}")
|
||||
Err(err) => error!("{err:?}"),
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::clipboard::{self, ClipboardEvent};
|
||||
use crate::clients::wayland::{ClipboardItem, ClipboardValue};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
|
@ -7,7 +8,7 @@ use crate::image::IconButton;
|
|||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
};
|
||||
use crate::{glib_recv, module_impl, spawn, try_send};
|
||||
use crate::{module_impl, spawn};
|
||||
use glib::Propagation;
|
||||
use gtk::gdk_pixbuf::Pixbuf;
|
||||
use gtk::gio::{Cancellable, MemoryInputStream};
|
||||
|
@ -109,18 +110,16 @@ impl Module<Button> for ClipboardModule {
|
|||
match event {
|
||||
ClipboardEvent::Add(item) => {
|
||||
let msg = match item.value.as_ref() {
|
||||
ClipboardValue::Other => {
|
||||
ModuleUpdateEvent::Update(ControllerEvent::Deactivate)
|
||||
}
|
||||
_ => ModuleUpdateEvent::Update(ControllerEvent::Add(item.id, item)),
|
||||
ClipboardValue::Other => ControllerEvent::Deactivate,
|
||||
_ => ControllerEvent::Add(item.id, item),
|
||||
};
|
||||
try_send!(tx, msg);
|
||||
tx.send_update_spawn(msg);
|
||||
}
|
||||
ClipboardEvent::Remove(id) => {
|
||||
try_send!(tx, ModuleUpdateEvent::Update(ControllerEvent::Remove(id)));
|
||||
tx.send_update_spawn(ControllerEvent::Remove(id));
|
||||
}
|
||||
ClipboardEvent::Activate(id) => {
|
||||
try_send!(tx, ModuleUpdateEvent::Update(ControllerEvent::Activate(id)));
|
||||
tx.send_update_spawn(ControllerEvent::Activate(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +155,7 @@ impl Module<Button> for ClipboardModule {
|
|||
|
||||
let tx = context.tx.clone();
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
tx.send_spawn(ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
});
|
||||
|
||||
let rx = context.subscribe();
|
||||
|
@ -189,7 +188,7 @@ impl Module<Button> for ClipboardModule {
|
|||
|
||||
{
|
||||
let hidden_option = hidden_option.clone();
|
||||
glib_recv!(rx, event => {
|
||||
rx.recv_glib(move |event| {
|
||||
match event {
|
||||
ControllerEvent::Add(id, item) => {
|
||||
debug!("Adding new value with ID {}", id);
|
||||
|
@ -231,7 +230,7 @@ impl Module<Button> for ClipboardModule {
|
|||
button.style_context().add_class("image");
|
||||
|
||||
button
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
error!("{err:?}");
|
||||
return;
|
||||
|
@ -260,7 +259,7 @@ impl Module<Button> for ClipboardModule {
|
|||
.expect("Failed to get id from button name");
|
||||
|
||||
debug!("Copying item with id: {id}");
|
||||
try_send!(tx, UIEvent::Copy(id));
|
||||
tx.send_spawn(UIEvent::Copy(id));
|
||||
}
|
||||
|
||||
Propagation::Stop
|
||||
|
@ -282,7 +281,7 @@ impl Module<Button> for ClipboardModule {
|
|||
.expect("Failed to get id from button name");
|
||||
|
||||
debug!("Removing item with id: {id}");
|
||||
try_send!(tx, UIEvent::Remove(id));
|
||||
tx.send_spawn(UIEvent::Remove(id));
|
||||
|
||||
entries.remove(&row);
|
||||
});
|
||||
|
|
|
@ -8,12 +8,13 @@ use serde::Deserialize;
|
|||
use tokio::sync::{broadcast, mpsc};
|
||||
use tokio::time::sleep;
|
||||
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn, try_send};
|
||||
use crate::{module_impl, spawn};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -107,7 +108,7 @@ impl Module<Button> for ClockModule {
|
|||
spawn(async move {
|
||||
loop {
|
||||
let date = Local::now();
|
||||
send_async!(tx, ModuleUpdateEvent::Update(date));
|
||||
tx.send_update(date).await;
|
||||
sleep(tokio::time::Duration::from_millis(500)).await;
|
||||
}
|
||||
});
|
||||
|
@ -131,14 +132,14 @@ impl Module<Button> for ClockModule {
|
|||
|
||||
let tx = context.tx.clone();
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
tx.send_spawn(ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
});
|
||||
|
||||
let format = self.format.clone();
|
||||
let locale = Locale::try_from(self.locale.as_str()).unwrap_or(Locale::POSIX);
|
||||
|
||||
let rx = context.subscribe();
|
||||
glib_recv!(rx, date => {
|
||||
rx.recv_glib(move |date| {
|
||||
let date_string = format!("{}", date.format_localized(&format, locale));
|
||||
label.set_label(&date_string);
|
||||
});
|
||||
|
@ -179,7 +180,7 @@ impl Module<Button> for ClockModule {
|
|||
let format = self.format_popup;
|
||||
let locale = Locale::try_from(self.locale.as_str()).unwrap_or(Locale::POSIX);
|
||||
|
||||
glib_recv!(rx, date => {
|
||||
rx.recv_glib(move |date| {
|
||||
let date_string = format!("{}", date.format_localized(&format, locale));
|
||||
clock.set_label(&date_string);
|
||||
});
|
||||
|
|
|
@ -3,11 +3,12 @@ use gtk::{Button, Label};
|
|||
use serde::Deserialize;
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
|
||||
use crate::build;
|
||||
use crate::channels::AsyncSenderExt;
|
||||
use crate::config::LayoutConfig;
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::PopupButton;
|
||||
use crate::{build, try_send};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -81,14 +82,11 @@ impl CustomWidget for ButtonWidget {
|
|||
let tx = context.tx.clone();
|
||||
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(
|
||||
tx,
|
||||
ExecEvent {
|
||||
cmd: exec.clone(),
|
||||
args: None,
|
||||
id: button.try_popup_id().unwrap_or(usize::MAX), // may not be a popup button
|
||||
}
|
||||
);
|
||||
tx.send_spawn(ExecEvent {
|
||||
cmd: exec.clone(),
|
||||
args: None,
|
||||
id: button.try_popup_id().unwrap_or(usize::MAX), // may not be a popup button
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use self::r#box::BoxWidget;
|
|||
use self::image::ImageWidget;
|
||||
use self::label::LabelWidget;
|
||||
use self::slider::SliderWidget;
|
||||
use crate::channels::AsyncSenderExt;
|
||||
use crate::config::{CommonConfig, ModuleConfig};
|
||||
use crate::modules::custom::button::ButtonWidget;
|
||||
use crate::modules::custom::progress::ProgressWidget;
|
||||
|
@ -17,7 +18,7 @@ use crate::modules::{
|
|||
ModuleUpdateEvent, PopupButton, PopupModuleFactory, WidgetContext, wrap_widget,
|
||||
};
|
||||
use crate::script::Script;
|
||||
use crate::{module_impl, send_async, spawn};
|
||||
use crate::{module_impl, spawn};
|
||||
use color_eyre::Result;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, IconTheme, Orientation};
|
||||
|
@ -205,11 +206,12 @@ impl Module<gtk::Box> for CustomModule {
|
|||
let args = event.args.unwrap_or_default();
|
||||
script.run_as_oneshot(Some(&args));
|
||||
} else if event.cmd == "popup:toggle" {
|
||||
send_async!(tx, ModuleUpdateEvent::TogglePopup(event.id));
|
||||
tx.send_expect(ModuleUpdateEvent::TogglePopup(event.id))
|
||||
.await;
|
||||
} else if event.cmd == "popup:open" {
|
||||
send_async!(tx, ModuleUpdateEvent::OpenPopup(event.id));
|
||||
tx.send_expect(ModuleUpdateEvent::OpenPopup(event.id)).await;
|
||||
} else if event.cmd == "popup:close" {
|
||||
send_async!(tx, ModuleUpdateEvent::ClosePopup);
|
||||
tx.send_expect(ModuleUpdateEvent::ClosePopup).await;
|
||||
} else {
|
||||
error!("Received invalid command: '{}'", event.cmd);
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ use serde::Deserialize;
|
|||
use tokio::sync::mpsc;
|
||||
use tracing::error;
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext};
|
||||
use crate::channels::{AsyncSenderExt, MpscReceiverExt};
|
||||
use crate::config::ModuleOrientation;
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::modules::custom::set_length;
|
||||
use crate::script::{OutputStream, Script, ScriptInput};
|
||||
use crate::{build, glib_recv_mpsc, spawn, try_send};
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext};
|
||||
use crate::{build, spawn};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -87,7 +87,7 @@ impl CustomWidget for ProgressWidget {
|
|||
script
|
||||
.run(None, move |stream, _success| match stream {
|
||||
OutputStream::Stdout(out) => match out.parse::<f64>() {
|
||||
Ok(value) => try_send!(tx, value),
|
||||
Ok(value) => tx.send_spawn(value),
|
||||
Err(err) => error!("{err:?}"),
|
||||
},
|
||||
OutputStream::Stderr(err) => error!("{err:?}"),
|
||||
|
@ -95,7 +95,7 @@ impl CustomWidget for ProgressWidget {
|
|||
.await;
|
||||
});
|
||||
|
||||
glib_recv_mpsc!(rx, value => progress.set_fraction(value / self.max));
|
||||
rx.recv_glib(move |value| progress.set_fraction(value / self.max));
|
||||
}
|
||||
|
||||
if let Some(text) = self.label {
|
||||
|
|
|
@ -8,12 +8,12 @@ use serde::Deserialize;
|
|||
use tokio::sync::mpsc;
|
||||
use tracing::error;
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext, ExecEvent};
|
||||
use crate::channels::{AsyncSenderExt, MpscReceiverExt};
|
||||
use crate::config::ModuleOrientation;
|
||||
use crate::modules::custom::set_length;
|
||||
use crate::script::{OutputStream, Script, ScriptInput};
|
||||
use crate::{build, glib_recv_mpsc, spawn, try_send};
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext, ExecEvent};
|
||||
use crate::{build, spawn};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -134,14 +134,11 @@ impl CustomWidget for SliderWidget {
|
|||
let val = val.clamp(min, max);
|
||||
|
||||
if val != prev_value.get() {
|
||||
try_send!(
|
||||
tx,
|
||||
ExecEvent {
|
||||
cmd: on_change.clone(),
|
||||
args: Some(vec![val.to_string()]),
|
||||
id: usize::MAX // ignored
|
||||
}
|
||||
);
|
||||
tx.send_spawn(ExecEvent {
|
||||
cmd: on_change.clone(),
|
||||
args: Some(vec![val.to_string()]),
|
||||
id: usize::MAX, // ignored
|
||||
});
|
||||
|
||||
prev_value.set(val);
|
||||
}
|
||||
|
@ -160,7 +157,7 @@ impl CustomWidget for SliderWidget {
|
|||
script
|
||||
.run(None, move |stream, _success| match stream {
|
||||
OutputStream::Stdout(out) => match out.parse() {
|
||||
Ok(value) => try_send!(tx, value),
|
||||
Ok(value) => tx.send_spawn(value),
|
||||
Err(err) => error!("{err:?}"),
|
||||
},
|
||||
OutputStream::Stderr(err) => error!("{err:?}"),
|
||||
|
@ -168,7 +165,7 @@ impl CustomWidget for SliderWidget {
|
|||
.await;
|
||||
});
|
||||
|
||||
glib_recv_mpsc!(rx, value => scale.set_value(value));
|
||||
rx.recv_glib(move |value| scale.set_value(value));
|
||||
}
|
||||
|
||||
scale
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::wayland::{self, ToplevelEvent};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::image::ImageProvider;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn, try_send};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{module_impl, spawn};
|
||||
use color_eyre::Result;
|
||||
use gtk::Label;
|
||||
use gtk::prelude::*;
|
||||
|
@ -90,10 +91,8 @@ impl Module<gtk::Box> for FocusedModule {
|
|||
if let Some(focused) = focused {
|
||||
current = Some(focused.id);
|
||||
|
||||
try_send!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(Some((focused.title.clone(), focused.app_id)))
|
||||
);
|
||||
tx.send_update(Some((focused.title.clone(), focused.app_id)))
|
||||
.await;
|
||||
};
|
||||
|
||||
while let Ok(event) = wlrx.recv().await {
|
||||
|
@ -104,24 +103,19 @@ impl Module<gtk::Box> for FocusedModule {
|
|||
|
||||
current = Some(info.id);
|
||||
|
||||
send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(Some((
|
||||
info.title.clone(),
|
||||
info.app_id.clone()
|
||||
)))
|
||||
);
|
||||
tx.send_update(Some((info.title.clone(), info.app_id)))
|
||||
.await;
|
||||
} else if info.id == current.unwrap_or_default() {
|
||||
debug!("Clearing focus");
|
||||
current = None;
|
||||
send_async!(tx, ModuleUpdateEvent::Update(None));
|
||||
tx.send_update(None).await;
|
||||
}
|
||||
}
|
||||
ToplevelEvent::Remove(info) => {
|
||||
if info.focused {
|
||||
debug!("Clearing focus");
|
||||
current = None;
|
||||
send_async!(tx, ModuleUpdateEvent::Update(None));
|
||||
tx.send_update(None).await;
|
||||
}
|
||||
}
|
||||
ToplevelEvent::New(_) => {}
|
||||
|
@ -162,10 +156,9 @@ impl Module<gtk::Box> for FocusedModule {
|
|||
let icon_overrides = info.icon_overrides.clone();
|
||||
let icon_theme = info.icon_theme.clone();
|
||||
|
||||
glib_recv!(context.subscribe(), data => {
|
||||
context.subscribe().recv_glib(move |data| {
|
||||
if let Some((name, mut id)) = data {
|
||||
if self.show_icon {
|
||||
|
||||
if let Some(icon) = icon_overrides.get(&id) {
|
||||
id = icon.clone();
|
||||
}
|
||||
|
|
|
@ -8,12 +8,13 @@ use tokio::sync::mpsc;
|
|||
use tracing::{debug, trace};
|
||||
|
||||
use super::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::compositor::{self, KeyboardLayoutUpdate};
|
||||
use crate::clients::libinput::{Event, Key, KeyEvent};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::{IconButton, IconLabel};
|
||||
use crate::{glib_recv, module_impl, module_update, send_async, spawn, try_send};
|
||||
use crate::{module_impl, spawn};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -196,11 +197,11 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
key,
|
||||
state: client.get_state(key),
|
||||
};
|
||||
module_update!(tx, KeyboardUpdate::Key(event));
|
||||
tx.send_update(KeyboardUpdate::Key(event)).await;
|
||||
}
|
||||
}
|
||||
Event::Key(ev) => {
|
||||
module_update!(tx, KeyboardUpdate::Key(ev));
|
||||
tx.send_update(KeyboardUpdate::Key(ev)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +220,7 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
match srx.recv().await {
|
||||
Ok(payload) => {
|
||||
debug!("Received update: {payload:?}");
|
||||
module_update!(tx, KeyboardUpdate::Layout(payload));
|
||||
tx.send_update(KeyboardUpdate::Layout(payload)).await;
|
||||
}
|
||||
Err(tokio::sync::broadcast::error::RecvError::Lagged(count)) => {
|
||||
tracing::warn!(
|
||||
|
@ -297,7 +298,7 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
{
|
||||
let tx = context.controller_tx.clone();
|
||||
layout_button.connect_clicked(move |_| {
|
||||
try_send!(tx, ());
|
||||
tx.send_spawn(());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -334,7 +335,7 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
}
|
||||
};
|
||||
|
||||
glib_recv!(context.subscribe(), handle_event);
|
||||
context.subscribe().recv_glib(handle_event);
|
||||
Ok(ModuleParts::new(container, None))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, try_send};
|
||||
use crate::module_impl;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use color_eyre::Result;
|
||||
use gtk::Label;
|
||||
use serde::Deserialize;
|
||||
|
@ -57,7 +58,7 @@ impl Module<Label> for LabelModule {
|
|||
) -> Result<()> {
|
||||
let tx = context.tx.clone();
|
||||
dynamic_string(&self.label, move |string| {
|
||||
try_send!(tx, ModuleUpdateEvent::Update(string));
|
||||
tx.send_update_spawn(string);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
@ -80,7 +81,9 @@ impl Module<Label> for LabelModule {
|
|||
|
||||
{
|
||||
let label = label.clone();
|
||||
glib_recv!(context.subscribe(), string => label.set_label_escaped(&string));
|
||||
context
|
||||
.subscribe()
|
||||
.recv_glib(move |string| label.set_label_escaped(&string));
|
||||
}
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use super::open_state::OpenState;
|
||||
use crate::channels::AsyncSenderExt;
|
||||
use crate::clients::wayland::ToplevelInfo;
|
||||
use crate::config::{BarPosition, TruncateMode};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::image::ImageProvider;
|
||||
use crate::modules::ModuleUpdateEvent;
|
||||
use crate::modules::launcher::{ItemEvent, LauncherUpdate};
|
||||
use crate::{read_lock, try_send};
|
||||
use crate::read_lock;
|
||||
use glib::Propagation;
|
||||
use gtk::gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY};
|
||||
use gtk::prelude::*;
|
||||
|
@ -226,15 +227,15 @@ impl ItemButton {
|
|||
let menu_state = read_lock!(menu_state);
|
||||
|
||||
if style_context.has_class("focused") && menu_state.num_windows == 1 {
|
||||
try_send!(tx, ItemEvent::MinimizeItem(app_id.clone()));
|
||||
tx.send_spawn(ItemEvent::MinimizeItem(app_id.clone()));
|
||||
} else {
|
||||
try_send!(tx, ItemEvent::FocusItem(app_id.clone()));
|
||||
tx.send_spawn(ItemEvent::FocusItem(app_id.clone()));
|
||||
}
|
||||
} else {
|
||||
try_send!(tx, ItemEvent::OpenItem(app_id.clone()));
|
||||
tx.send_spawn(ItemEvent::OpenItem(app_id.clone()));
|
||||
}
|
||||
} else if event.button() == BUTTON_MIDDLE {
|
||||
try_send!(tx, ItemEvent::OpenItem(app_id.clone()));
|
||||
tx.send_spawn(ItemEvent::OpenItem(app_id.clone()));
|
||||
}
|
||||
|
||||
Propagation::Proceed
|
||||
|
@ -250,17 +251,12 @@ impl ItemButton {
|
|||
let menu_state = read_lock!(menu_state);
|
||||
|
||||
if menu_state.num_windows > 1 {
|
||||
try_send!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(LauncherUpdate::Hover(app_id.clone(),))
|
||||
);
|
||||
|
||||
try_send!(
|
||||
tx,
|
||||
ModuleUpdateEvent::OpenPopupAt(button.geometry(bar_position.orientation()))
|
||||
);
|
||||
tx.send_update_spawn(LauncherUpdate::Hover(app_id.clone()));
|
||||
tx.send_spawn(ModuleUpdateEvent::OpenPopupAt(
|
||||
button.geometry(bar_position.orientation()),
|
||||
));
|
||||
} else {
|
||||
try_send!(tx, ModuleUpdateEvent::ClosePopup);
|
||||
tx.send_spawn(ModuleUpdateEvent::ClosePopup);
|
||||
}
|
||||
|
||||
Propagation::Proceed
|
||||
|
@ -285,7 +281,7 @@ impl ItemButton {
|
|||
};
|
||||
|
||||
if close {
|
||||
try_send!(tx, ModuleUpdateEvent::ClosePopup);
|
||||
tx.send_spawn(ModuleUpdateEvent::ClosePopup);
|
||||
}
|
||||
|
||||
Propagation::Proceed
|
||||
|
|
|
@ -5,13 +5,14 @@ mod pagination;
|
|||
use self::item::{AppearanceOptions, Item, ItemButton, Window};
|
||||
use self::open_state::OpenState;
|
||||
use super::{Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::wayland::{self, ToplevelEvent};
|
||||
use crate::config::{CommonConfig, EllipsizeMode, LayoutConfig, TruncateMode};
|
||||
use crate::desktop_file::find_desktop_file;
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::launcher::item::ImageTextButton;
|
||||
use crate::modules::launcher::pagination::{IconContext, Pagination};
|
||||
use crate::{arc_mut, glib_recv, lock, module_impl, send_async, spawn, try_send, write_lock};
|
||||
use crate::{arc_mut, lock, module_impl, spawn, write_lock};
|
||||
use color_eyre::{Help, Report};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, Orientation};
|
||||
|
@ -271,10 +272,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
let items = lock!(items);
|
||||
let items = items.iter();
|
||||
for (_, item) in items {
|
||||
try_send!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(LauncherUpdate::AddItem(item.clone()))
|
||||
);
|
||||
tx.send_update_spawn(LauncherUpdate::AddItem(item.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,7 +408,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
},
|
||||
);
|
||||
} else {
|
||||
send_async!(tx, ModuleUpdateEvent::ClosePopup);
|
||||
tx.send_expect(ModuleUpdateEvent::ClosePopup).await;
|
||||
|
||||
let minimize_window = matches!(event, ItemEvent::MinimizeItem(_));
|
||||
|
||||
|
@ -494,7 +492,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
let tx = context.tx.clone();
|
||||
let rx = context.subscribe();
|
||||
|
||||
let mut handle_event = move |event: LauncherUpdate| {
|
||||
let handle_event = move |event: LauncherUpdate| {
|
||||
// all widgets show by default
|
||||
// so check if pagination should be shown
|
||||
// to ensure correct state on init.
|
||||
|
@ -598,7 +596,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
};
|
||||
};
|
||||
|
||||
glib_recv!(rx, handle_event);
|
||||
rx.recv_glib(handle_event);
|
||||
}
|
||||
|
||||
let rx = context.subscribe();
|
||||
|
@ -632,7 +630,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
|
||||
{
|
||||
let container = container.clone();
|
||||
glib_recv!(rx, event => {
|
||||
rx.recv_glib(move |event| {
|
||||
match event {
|
||||
LauncherUpdate::AddItem(item) => {
|
||||
let app_id = item.app_id.clone();
|
||||
|
@ -651,7 +649,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
{
|
||||
let tx = controller_tx.clone();
|
||||
button.connect_clicked(move |_| {
|
||||
try_send!(tx, ItemEvent::FocusWindow(win.id));
|
||||
tx.send_spawn(ItemEvent::FocusWindow(win.id));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -677,7 +675,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
{
|
||||
let tx = controller_tx.clone();
|
||||
button.connect_clicked(move |_button| {
|
||||
try_send!(tx, ItemEvent::FocusWindow(win.id));
|
||||
tx.send_spawn(ItemEvent::FocusWindow(win.id));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,12 @@ use gtk::{Application, Button, EventBox, IconTheme, Orientation, Revealer, Widge
|
|||
use tokio::sync::{broadcast, mpsc};
|
||||
use tracing::debug;
|
||||
|
||||
use crate::Ironbar;
|
||||
use crate::channels::{MpscReceiverExt, SyncSenderExt};
|
||||
use crate::clients::{ClientResult, ProvidesClient, ProvidesFallibleClient};
|
||||
use crate::config::{BarPosition, CommonConfig, TransitionType};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, WidgetGeometry};
|
||||
use crate::popup::Popup;
|
||||
use crate::{Ironbar, glib_recv_mpsc, send};
|
||||
|
||||
#[cfg(feature = "bindmode")]
|
||||
pub mod bindmode;
|
||||
|
@ -391,37 +392,41 @@ impl ModuleFactory for BarModuleFactory {
|
|||
TSend: Debug + Clone + Send + 'static,
|
||||
{
|
||||
let popup = self.popup.clone();
|
||||
glib_recv_mpsc!(rx, ev => {
|
||||
match ev {
|
||||
ModuleUpdateEvent::Update(update) => {
|
||||
send!(tx, update);
|
||||
}
|
||||
ModuleUpdateEvent::TogglePopup(button_id) if !disable_popup => {
|
||||
debug!("Toggling popup for {} [#{}] (button id: {button_id})", name, id);
|
||||
if popup.visible() && popup.current_widget().unwrap_or_default() == id {
|
||||
popup.hide();
|
||||
} else {
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
}
|
||||
ModuleUpdateEvent::OpenPopup(button_id) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}] (button id: {button_id})", name, id);
|
||||
rx.recv_glib(move |ev| match ev {
|
||||
ModuleUpdateEvent::Update(update) => {
|
||||
tx.send_expect(update);
|
||||
}
|
||||
ModuleUpdateEvent::TogglePopup(button_id) if !disable_popup => {
|
||||
debug!(
|
||||
"Toggling popup for {} [#{}] (button id: {button_id})",
|
||||
name, id
|
||||
);
|
||||
if popup.visible() && popup.current_widget().unwrap_or_default() == id {
|
||||
popup.hide();
|
||||
} else {
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
#[cfg(feature = "launcher")]
|
||||
ModuleUpdateEvent::OpenPopupAt(geometry) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}]", name, id);
|
||||
|
||||
popup.hide();
|
||||
popup.show_at(id, geometry);
|
||||
}
|
||||
ModuleUpdateEvent::ClosePopup if !disable_popup => {
|
||||
debug!("Closing popup for {} [#{}]", name, id);
|
||||
popup.hide();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
ModuleUpdateEvent::OpenPopup(button_id) if !disable_popup => {
|
||||
debug!(
|
||||
"Opening popup for {} [#{}] (button id: {button_id})",
|
||||
name, id
|
||||
);
|
||||
popup.hide();
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
#[cfg(feature = "launcher")]
|
||||
ModuleUpdateEvent::OpenPopupAt(geometry) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}]", name, id);
|
||||
|
||||
popup.hide();
|
||||
popup.show_at(id, geometry);
|
||||
}
|
||||
ModuleUpdateEvent::ClosePopup if !disable_popup => {
|
||||
debug!("Closing popup for {} [#{}]", name, id);
|
||||
popup.hide();
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -464,37 +469,42 @@ impl ModuleFactory for PopupModuleFactory {
|
|||
{
|
||||
let popup = self.popup.clone();
|
||||
let button_id = self.button_id;
|
||||
glib_recv_mpsc!(rx, ev => {
|
||||
match ev {
|
||||
ModuleUpdateEvent::Update(update) => {
|
||||
send!(tx, update);
|
||||
}
|
||||
ModuleUpdateEvent::TogglePopup(_) if !disable_popup => {
|
||||
debug!("Toggling popup for {} [#{}] (button id: {button_id})", name, id);
|
||||
if popup.visible() && popup.current_widget().unwrap_or_default() == id {
|
||||
popup.hide();
|
||||
} else {
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
}
|
||||
ModuleUpdateEvent::OpenPopup(_) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}] (button id: {button_id})", name, id);
|
||||
|
||||
rx.recv_glib(move |ev| match ev {
|
||||
ModuleUpdateEvent::Update(update) => {
|
||||
tx.send_expect(update);
|
||||
}
|
||||
ModuleUpdateEvent::TogglePopup(_) if !disable_popup => {
|
||||
debug!(
|
||||
"Toggling popup for {} [#{}] (button id: {button_id})",
|
||||
name, id
|
||||
);
|
||||
if popup.visible() && popup.current_widget().unwrap_or_default() == id {
|
||||
popup.hide();
|
||||
} else {
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
#[cfg(feature = "launcher")]
|
||||
ModuleUpdateEvent::OpenPopupAt(geometry) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}]", name, id);
|
||||
|
||||
popup.hide();
|
||||
popup.show_at(id, geometry);
|
||||
}
|
||||
ModuleUpdateEvent::ClosePopup if !disable_popup => {
|
||||
debug!("Closing popup for {} [#{}]", name, id);
|
||||
popup.hide();
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
ModuleUpdateEvent::OpenPopup(_) if !disable_popup => {
|
||||
debug!(
|
||||
"Opening popup for {} [#{}] (button id: {button_id})",
|
||||
name, id
|
||||
);
|
||||
popup.hide();
|
||||
popup.show(id, button_id);
|
||||
}
|
||||
#[cfg(feature = "launcher")]
|
||||
ModuleUpdateEvent::OpenPopupAt(geometry) if !disable_popup => {
|
||||
debug!("Opening popup for {} [#{}]", name, id);
|
||||
|
||||
popup.hide();
|
||||
popup.show_at(id, geometry);
|
||||
}
|
||||
ModuleUpdateEvent::ClosePopup if !disable_popup => {
|
||||
debug!("Closing popup for {} [#{}]", name, id);
|
||||
popup.hide();
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@ use regex::Regex;
|
|||
use tokio::sync::{broadcast, mpsc};
|
||||
use tracing::error;
|
||||
|
||||
pub use self::config::MusicModule;
|
||||
use self::config::PlayerType;
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::Clients;
|
||||
use crate::clients::music::{
|
||||
self, MusicClient, PlayerState, PlayerUpdate, ProgressTick, Status, Track,
|
||||
|
@ -22,10 +25,7 @@ use crate::modules::PopupButton;
|
|||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext,
|
||||
};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn, try_send};
|
||||
|
||||
pub use self::config::MusicModule;
|
||||
use self::config::PlayerType;
|
||||
use crate::{module_impl, spawn};
|
||||
|
||||
mod config;
|
||||
|
||||
|
@ -136,24 +136,14 @@ impl Module<Button> for MusicModule {
|
|||
display_string,
|
||||
};
|
||||
|
||||
send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(ControllerEvent::Update(Some(
|
||||
update
|
||||
)))
|
||||
);
|
||||
tx.send_update(ControllerEvent::Update(Some(update))).await;
|
||||
}
|
||||
None => send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(ControllerEvent::Update(None))
|
||||
),
|
||||
None => tx.send_update(ControllerEvent::Update(None)).await,
|
||||
},
|
||||
PlayerUpdate::ProgressTick(progress_tick) => send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(ControllerEvent::UpdateProgress(
|
||||
progress_tick
|
||||
))
|
||||
),
|
||||
PlayerUpdate::ProgressTick(progress_tick) => {
|
||||
tx.send_update(ControllerEvent::UpdateProgress(progress_tick))
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +211,7 @@ impl Module<Button> for MusicModule {
|
|||
let tx = context.tx.clone();
|
||||
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
tx.send_spawn(ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -231,9 +221,9 @@ impl Module<Button> for MusicModule {
|
|||
let tx = context.tx.clone();
|
||||
let rx = context.subscribe();
|
||||
|
||||
glib_recv!(rx, event => {
|
||||
rx.recv_glib(move |event| {
|
||||
let ControllerEvent::Update(mut event) = event else {
|
||||
continue;
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(event) = event.take() {
|
||||
|
@ -262,7 +252,7 @@ impl Module<Button> for MusicModule {
|
|||
}
|
||||
} else {
|
||||
button.hide();
|
||||
try_send!(tx, ModuleUpdateEvent::ClosePopup);
|
||||
tx.send_spawn(ModuleUpdateEvent::ClosePopup);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -350,27 +340,27 @@ impl Module<Button> for MusicModule {
|
|||
|
||||
let tx_prev = tx.clone();
|
||||
btn_prev.connect_clicked(move |_| {
|
||||
try_send!(tx_prev, PlayerCommand::Previous);
|
||||
tx_prev.send_spawn(PlayerCommand::Previous);
|
||||
});
|
||||
|
||||
let tx_play = tx.clone();
|
||||
btn_play.connect_clicked(move |_| {
|
||||
try_send!(tx_play, PlayerCommand::Play);
|
||||
tx_play.send_spawn(PlayerCommand::Play);
|
||||
});
|
||||
|
||||
let tx_pause = tx.clone();
|
||||
btn_pause.connect_clicked(move |_| {
|
||||
try_send!(tx_pause, PlayerCommand::Pause);
|
||||
tx_pause.send_spawn(PlayerCommand::Pause);
|
||||
});
|
||||
|
||||
let tx_next = tx.clone();
|
||||
btn_next.connect_clicked(move |_| {
|
||||
try_send!(tx_next, PlayerCommand::Next);
|
||||
tx_next.send_spawn(PlayerCommand::Next);
|
||||
});
|
||||
|
||||
let tx_vol = tx.clone();
|
||||
volume_slider.connect_change_value(move |_, _, val| {
|
||||
try_send!(tx_vol, PlayerCommand::Volume(val as u8));
|
||||
tx_vol.send_spawn(PlayerCommand::Volume(val as u8));
|
||||
Propagation::Proceed
|
||||
});
|
||||
|
||||
|
@ -404,7 +394,7 @@ impl Module<Button> for MusicModule {
|
|||
let drag_lock = drag_lock.clone();
|
||||
progress.connect_button_release_event(move |scale, _| {
|
||||
let value = scale.value();
|
||||
try_send!(tx, PlayerCommand::Seek(Duration::from_secs_f64(value)));
|
||||
tx.send_spawn(PlayerCommand::Seek(Duration::from_secs_f64(value)));
|
||||
|
||||
drag_lock.set(false);
|
||||
Propagation::Proceed
|
||||
|
@ -418,7 +408,7 @@ impl Module<Button> for MusicModule {
|
|||
let image_size = self.cover_image_size;
|
||||
|
||||
let mut prev_cover = None;
|
||||
glib_recv!(rx, event => {
|
||||
rx.recv_glib(move |event| {
|
||||
match event {
|
||||
ControllerEvent::Update(Some(update)) => {
|
||||
// only update art when album changes
|
||||
|
|
|
@ -6,12 +6,13 @@ use gtk::{Box as GtkBox, Image};
|
|||
use serde::Deserialize;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::networkmanager::{Client, ClientState};
|
||||
use crate::config::CommonConfig;
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::ImageProvider;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{module_impl, spawn};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
|
@ -41,11 +42,11 @@ impl Module<GtkBox> for NetworkManagerModule {
|
|||
) -> Result<()> {
|
||||
let client = context.try_client::<Client>()?;
|
||||
let mut client_signal = client.subscribe().to_stream();
|
||||
let widget_transmitter = context.tx.clone();
|
||||
let tx = context.tx.clone();
|
||||
|
||||
spawn(async move {
|
||||
while let Some(state) = client_signal.next().await {
|
||||
send_async!(widget_transmitter, ModuleUpdateEvent::Update(state));
|
||||
tx.send_update(state).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -68,8 +69,7 @@ impl Module<GtkBox> for NetworkManagerModule {
|
|||
ImageProvider::parse(initial_icon_name, &icon_theme, false, self.icon_size)
|
||||
.map(|provider| provider.load_into_image(&icon));
|
||||
|
||||
let widget_receiver = context.subscribe();
|
||||
glib_recv!(widget_receiver, state => {
|
||||
context.subscribe().recv_glib(move |state| {
|
||||
let icon_name = match state {
|
||||
ClientState::WiredConnected => "network-wired-symbolic",
|
||||
ClientState::WifiConnected => "network-wireless-symbolic",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::swaync;
|
||||
use crate::config::CommonConfig;
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn, try_send};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{module_impl, spawn};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Align, Button, Label, Overlay};
|
||||
use serde::Deserialize;
|
||||
|
@ -153,12 +154,12 @@ impl Module<Overlay> for NotificationsModule {
|
|||
let initial_state = client.state().await;
|
||||
|
||||
match initial_state {
|
||||
Ok(ev) => send_async!(tx, ModuleUpdateEvent::Update(ev)),
|
||||
Ok(ev) => tx.send_update(ev).await,
|
||||
Err(err) => error!("{err:?}"),
|
||||
};
|
||||
|
||||
while let Ok(ev) = rx.recv().await {
|
||||
send_async!(tx, ModuleUpdateEvent::Update(ev));
|
||||
tx.send_update(ev).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -200,13 +201,13 @@ impl Module<Overlay> for NotificationsModule {
|
|||
|
||||
let ctx = context.controller_tx.clone();
|
||||
button.connect_clicked(move |_| {
|
||||
try_send!(ctx, UiEvent::ToggleVisibility);
|
||||
ctx.send_spawn(UiEvent::ToggleVisibility);
|
||||
});
|
||||
|
||||
{
|
||||
let button = button.clone();
|
||||
|
||||
glib_recv!(context.subscribe(), ev => {
|
||||
context.subscribe().recv_glib(move |ev| {
|
||||
let icon = self.icons.icon(ev);
|
||||
button.set_label(icon);
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::script::{OutputStream, Script, ScriptMode};
|
||||
use crate::{glib_recv, module_impl, spawn, try_send};
|
||||
use crate::{module_impl, spawn};
|
||||
use color_eyre::{Help, Report, Result};
|
||||
use gtk::Label;
|
||||
use serde::Deserialize;
|
||||
|
@ -83,7 +84,7 @@ impl Module<Label> for ScriptModule {
|
|||
spawn(async move {
|
||||
script.run(None, move |out, _| match out {
|
||||
OutputStream::Stdout(stdout) => {
|
||||
try_send!(tx, ModuleUpdateEvent::Update(stdout));
|
||||
tx.send_update_spawn(stdout);
|
||||
},
|
||||
OutputStream::Stderr(stderr) => {
|
||||
error!("{:?}", Report::msg(stderr)
|
||||
|
@ -111,7 +112,9 @@ impl Module<Label> for ScriptModule {
|
|||
|
||||
{
|
||||
let label = label.clone();
|
||||
glib_recv!(context.subscribe(), s => label.set_label_escaped(&s));
|
||||
context
|
||||
.subscribe()
|
||||
.recv_glib(move |s| label.set_label_escaped(&s));
|
||||
}
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
|
|
@ -2,12 +2,13 @@ mod parser;
|
|||
mod renderer;
|
||||
mod token;
|
||||
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::sysinfo::TokenType;
|
||||
use crate::config::{CommonConfig, LayoutConfig, ModuleOrientation};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::sysinfo::token::Part;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{clients, glib_recv, module_impl, send_async, spawn, try_send};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{clients, module_impl, spawn};
|
||||
use color_eyre::Result;
|
||||
use gtk::Label;
|
||||
use gtk::prelude::*;
|
||||
|
@ -216,7 +217,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
|||
|
||||
for (i, token_set) in format_tokens.iter().enumerate() {
|
||||
let rendered = Part::render_all(token_set, &client, interval);
|
||||
try_send!(context.tx, ModuleUpdateEvent::Update((i, rendered)));
|
||||
context.tx.send_update_spawn((i, rendered));
|
||||
}
|
||||
|
||||
let (refresh_tx, mut refresh_rx) = mpsc::channel(16);
|
||||
|
@ -226,7 +227,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
|||
let tx = refresh_tx.clone();
|
||||
spawn(async move {
|
||||
loop {
|
||||
send_async!(tx, $refresh_type);
|
||||
tx.send_expect($refresh_type).await;
|
||||
sleep(Duration::from_secs(interval.$func())).await;
|
||||
}
|
||||
});
|
||||
|
@ -266,7 +267,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
|||
|
||||
if is_affected {
|
||||
let rendered = Part::render_all(token_set, &client, interval);
|
||||
send_async!(tx, ModuleUpdateEvent::Update((i, rendered)));
|
||||
tx.send_update((i, rendered)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +303,7 @@ impl Module<gtk::Box> for SysInfoModule {
|
|||
labels.push(label);
|
||||
}
|
||||
|
||||
glib_recv!(context.subscribe(), data => {
|
||||
context.subscribe().recv_glib(move |data| {
|
||||
let label = &labels[data.0];
|
||||
label.set_label_escaped(&data.1);
|
||||
});
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
mod icon;
|
||||
mod interface;
|
||||
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::tray;
|
||||
use crate::config::{CommonConfig, ModuleOrientation};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, lock, module_impl, send_async, spawn};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{lock, module_impl, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{IconTheme, Orientation};
|
||||
|
@ -74,21 +75,16 @@ impl Module<gtk::Box> for TrayModule {
|
|||
// listen to tray updates
|
||||
spawn(async move {
|
||||
for (key, (item, menu)) in initial_items {
|
||||
send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(Event::Add(key.clone(), item.into()))
|
||||
);
|
||||
tx.send_update(Event::Add(key.clone(), item.into())).await;
|
||||
|
||||
if let Some(menu) = menu.clone() {
|
||||
send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(Event::Update(key, UpdateEvent::Menu(menu)))
|
||||
);
|
||||
tx.send_update(Event::Update(key, UpdateEvent::Menu(menu)))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
while let Ok(message) = tray_rx.recv().await {
|
||||
send_async!(tx, ModuleUpdateEvent::Update(message));
|
||||
tx.send_update(message).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -127,9 +123,16 @@ impl Module<gtk::Box> for TrayModule {
|
|||
let icon_theme = info.icon_theme.clone();
|
||||
|
||||
// listen for UI updates
|
||||
glib_recv!(context.subscribe(), update =>
|
||||
on_update(update, &container, &mut menus, &icon_theme, self.icon_size, self.prefer_theme_icons)
|
||||
);
|
||||
context.subscribe().recv_glib(move |update| {
|
||||
on_update(
|
||||
update,
|
||||
&container,
|
||||
&mut menus,
|
||||
&icon_theme,
|
||||
self.icon_size,
|
||||
self.prefer_theme_icons,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
|
|
@ -7,6 +7,7 @@ use tokio::sync::{broadcast, mpsc};
|
|||
use zbus;
|
||||
use zbus::fdo::PropertiesProxy;
|
||||
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::upower::BatteryState;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
|
@ -15,7 +16,7 @@ use crate::modules::PopupButton;
|
|||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext,
|
||||
};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn, try_send};
|
||||
use crate::{module_impl, spawn};
|
||||
|
||||
const DAY: i64 = 24 * 60 * 60;
|
||||
const HOUR: i64 = 60 * 60;
|
||||
|
@ -116,7 +117,7 @@ impl Module<Button> for UpowerModule {
|
|||
time_to_empty,
|
||||
};
|
||||
|
||||
send_async!(tx, ModuleUpdateEvent::Update(properties.clone()));
|
||||
tx.send_update(properties.clone()).await;
|
||||
|
||||
while let Some(signal) = prop_changed_stream.next().await {
|
||||
let args = signal.args().expect("Invalid signal arguments");
|
||||
|
@ -156,7 +157,7 @@ impl Module<Button> for UpowerModule {
|
|||
}
|
||||
}
|
||||
|
||||
send_async!(tx, ModuleUpdateEvent::Update(properties.clone()));
|
||||
tx.send_update(properties.clone()).await;
|
||||
}
|
||||
|
||||
Result::<()>::Ok(())
|
||||
|
@ -195,22 +196,23 @@ impl Module<Button> for UpowerModule {
|
|||
|
||||
let tx = context.tx.clone();
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
tx.send_spawn(ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
});
|
||||
|
||||
let format = self.format.clone();
|
||||
|
||||
let rx = context.subscribe();
|
||||
glib_recv!(rx, properties => {
|
||||
rx.recv_glib(move |properties| {
|
||||
let state = properties.state;
|
||||
let is_charging = state == BatteryState::Charging || state == BatteryState::PendingCharge;
|
||||
let is_charging =
|
||||
state == BatteryState::Charging || state == BatteryState::PendingCharge;
|
||||
let time_remaining = if is_charging {
|
||||
seconds_to_string(properties.time_to_full)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
seconds_to_string(properties.time_to_empty)
|
||||
};
|
||||
let format = format.replace("{percentage}", &properties.percentage.to_string())
|
||||
let format = format
|
||||
.replace("{percentage}", &properties.percentage.to_string())
|
||||
.replace("{time_remaining}", &time_remaining)
|
||||
.replace("{state}", battery_state_to_string(state));
|
||||
|
||||
|
@ -218,7 +220,7 @@ impl Module<Button> for UpowerModule {
|
|||
icon_name.push_str(&properties.icon_name);
|
||||
|
||||
ImageProvider::parse(&icon_name, &icon_theme, false, self.icon_size)
|
||||
.map(|provider| provider.load_into_image(&icon));
|
||||
.map(|provider| provider.load_into_image(&icon));
|
||||
|
||||
label.set_label_escaped(&format);
|
||||
});
|
||||
|
@ -249,7 +251,7 @@ impl Module<Button> for UpowerModule {
|
|||
label.add_class("upower-details");
|
||||
container.add(&label);
|
||||
|
||||
glib_recv!(rx, properties => {
|
||||
rx.recv_glib(move |properties| {
|
||||
let state = properties.state;
|
||||
let format = match state {
|
||||
BatteryState::Charging | BatteryState::PendingCharge => {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::volume::{self, Event};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
};
|
||||
use crate::{glib_recv, lock, module_impl, send_async, spawn, try_send};
|
||||
use crate::{lock, module_impl, spawn};
|
||||
use glib::Propagation;
|
||||
use gtk::pango::EllipsizeMode;
|
||||
use gtk::prelude::*;
|
||||
|
@ -171,20 +172,17 @@ impl Module<Button> for VolumeModule {
|
|||
trace!("initial inputs: {inputs:?}");
|
||||
|
||||
for sink in sinks {
|
||||
send_async!(tx, ModuleUpdateEvent::Update(Event::AddSink(sink)));
|
||||
tx.send_update(Event::AddSink(sink)).await;
|
||||
}
|
||||
|
||||
for input in inputs {
|
||||
send_async!(
|
||||
tx,
|
||||
ModuleUpdateEvent::Update(Event::AddInput(input.clone()))
|
||||
);
|
||||
tx.send_update(Event::AddInput(input)).await;
|
||||
}
|
||||
|
||||
// recv loop
|
||||
while let Ok(event) = rx.recv().await {
|
||||
trace!("received event: {event:?}");
|
||||
send_async!(tx, ModuleUpdateEvent::Update(event));
|
||||
tx.send_update(event).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -226,7 +224,7 @@ impl Module<Button> for VolumeModule {
|
|||
let tx = context.tx.clone();
|
||||
|
||||
button.connect_clicked(move |button| {
|
||||
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
tx.send_spawn(ModuleUpdateEvent::TogglePopup(button.popup_id()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -236,18 +234,23 @@ impl Module<Button> for VolumeModule {
|
|||
|
||||
let format = self.format.clone();
|
||||
|
||||
glib_recv!(rx, event => {
|
||||
match event {
|
||||
Event::AddSink(sink) | Event::UpdateSink(sink) if sink.active => {
|
||||
let label = format
|
||||
.replace("{icon}", if sink.muted { &icons.muted } else { icons.volume_icon(sink.volume) })
|
||||
.replace("{percentage}", &sink.volume.to_string())
|
||||
.replace("{name}", &sink.description);
|
||||
rx.recv_glib(move |event| match event {
|
||||
Event::AddSink(sink) | Event::UpdateSink(sink) if sink.active => {
|
||||
let label = format
|
||||
.replace(
|
||||
"{icon}",
|
||||
if sink.muted {
|
||||
&icons.muted
|
||||
} else {
|
||||
icons.volume_icon(sink.volume)
|
||||
},
|
||||
)
|
||||
.replace("{percentage}", &sink.volume.to_string())
|
||||
.replace("{name}", &sink.description);
|
||||
|
||||
button_label.set_label_escaped(&label);
|
||||
},
|
||||
_ => {}
|
||||
button_label.set_label_escaped(&label);
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -302,7 +305,7 @@ impl Module<Button> for VolumeModule {
|
|||
let tx = tx.clone();
|
||||
sink_selector.connect_changed(move |selector| {
|
||||
if let Some(name) = selector.active_id() {
|
||||
try_send!(tx, Update::SinkChange(name.into()));
|
||||
tx.send_spawn(Update::SinkChange(name.into()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -329,7 +332,7 @@ impl Module<Button> for VolumeModule {
|
|||
if let Some(sink) = selector.active_id() {
|
||||
// GTK will send values outside min/max range
|
||||
let val = scale.value().clamp(0.0, self.max_volume);
|
||||
try_send!(tx, Update::SinkVolume(sink.into(), val));
|
||||
tx.send_spawn(Update::SinkVolume(sink.into(), val));
|
||||
}
|
||||
|
||||
Propagation::Proceed
|
||||
|
@ -347,7 +350,7 @@ impl Module<Button> for VolumeModule {
|
|||
btn_mute.connect_toggled(move |btn| {
|
||||
if let Some(sink) = selector.active_id() {
|
||||
let muted = btn.is_active();
|
||||
try_send!(tx, Update::SinkMute(sink.into(), muted));
|
||||
tx.send_spawn(Update::SinkMute(sink.into(), muted));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -361,7 +364,7 @@ impl Module<Button> for VolumeModule {
|
|||
|
||||
let mut sinks = vec![];
|
||||
|
||||
glib_recv!(rx, event => {
|
||||
rx.recv_glib(move |event| {
|
||||
match event {
|
||||
Event::AddSink(info) => {
|
||||
sink_selector.append(Some(&info.name), &info.description);
|
||||
|
@ -371,7 +374,11 @@ impl Module<Button> for VolumeModule {
|
|||
slider.set_value(info.volume);
|
||||
|
||||
btn_mute.set_active(info.muted);
|
||||
btn_mute.set_label(if info.muted { &self.icons.muted } else { self.icons.volume_icon(info.volume) });
|
||||
btn_mute.set_label(if info.muted {
|
||||
&self.icons.muted
|
||||
} else {
|
||||
self.icons.volume_icon(info.volume)
|
||||
});
|
||||
}
|
||||
|
||||
sinks.push(info);
|
||||
|
@ -383,7 +390,11 @@ impl Module<Button> for VolumeModule {
|
|||
slider.set_value(info.volume);
|
||||
|
||||
btn_mute.set_active(info.muted);
|
||||
btn_mute.set_label(if info.muted { &self.icons.muted } else { self.icons.volume_icon(info.volume) });
|
||||
btn_mute.set_label(if info.muted {
|
||||
&self.icons.muted
|
||||
} else {
|
||||
self.icons.volume_icon(info.volume)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -413,7 +424,7 @@ impl Module<Button> for VolumeModule {
|
|||
slider.connect_button_release_event(move |scale, _| {
|
||||
// GTK will send values outside min/max range
|
||||
let val = scale.value().clamp(0.0, self.max_volume);
|
||||
try_send!(tx, Update::InputVolume(index, val));
|
||||
tx.send_spawn(Update::InputVolume(index, val));
|
||||
|
||||
Propagation::Proceed
|
||||
});
|
||||
|
@ -423,13 +434,17 @@ impl Module<Button> for VolumeModule {
|
|||
btn_mute.add_class("btn-mute");
|
||||
|
||||
btn_mute.set_active(info.muted);
|
||||
btn_mute.set_label(if info.muted { &self.icons.muted } else { self.icons.volume_icon(info.volume) });
|
||||
btn_mute.set_label(if info.muted {
|
||||
&self.icons.muted
|
||||
} else {
|
||||
self.icons.volume_icon(info.volume)
|
||||
});
|
||||
|
||||
{
|
||||
let tx = tx.clone();
|
||||
btn_mute.connect_toggled(move |btn| {
|
||||
let muted = btn.is_active();
|
||||
try_send!(tx, Update::InputMute(index, muted));
|
||||
tx.send_spawn(Update::InputMute(index, muted));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -440,19 +455,26 @@ impl Module<Button> for VolumeModule {
|
|||
|
||||
input_container.add(&item_container);
|
||||
|
||||
inputs.insert(info.index, InputUi {
|
||||
container: item_container,
|
||||
label,
|
||||
slider,
|
||||
btn_mute
|
||||
});
|
||||
inputs.insert(
|
||||
info.index,
|
||||
InputUi {
|
||||
container: item_container,
|
||||
label,
|
||||
slider,
|
||||
btn_mute,
|
||||
},
|
||||
);
|
||||
}
|
||||
Event::UpdateInput(info) => {
|
||||
if let Some(ui) = inputs.get(&info.index) {
|
||||
ui.label.set_label(&info.name);
|
||||
ui.slider.set_value(info.volume);
|
||||
ui.slider.set_sensitive(info.can_set_volume);
|
||||
ui.btn_mute.set_label(if info.muted { &self.icons.muted } else { self.icons.volume_icon(info.volume) });
|
||||
ui.btn_mute.set_label(if info.muted {
|
||||
&self.icons.muted
|
||||
} else {
|
||||
self.icons.volume_icon(info.volume)
|
||||
});
|
||||
}
|
||||
}
|
||||
Event::RemoveInput(index) => {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use super::open_state::OpenState;
|
||||
use crate::channels::AsyncSenderExt;
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::IconButton;
|
||||
use crate::modules::workspaces::WorkspaceItemContext;
|
||||
use crate::try_send;
|
||||
use gtk::Button as GtkButton;
|
||||
use gtk::prelude::*;
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl Button {
|
|||
let tx = context.tx.clone();
|
||||
|
||||
button.connect_clicked(move |_item| {
|
||||
try_send!(tx, id);
|
||||
tx.send_spawn(id);
|
||||
});
|
||||
|
||||
let btn = Self {
|
||||
|
|
|
@ -3,12 +3,13 @@ mod button_map;
|
|||
mod open_state;
|
||||
|
||||
use self::button::Button;
|
||||
use crate::channels::{AsyncSenderExt, BroadcastReceiverExt};
|
||||
use crate::clients::compositor::{Workspace, WorkspaceClient, WorkspaceUpdate};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::modules::workspaces::button_map::{ButtonMap, Identifier};
|
||||
use crate::modules::workspaces::open_state::OpenState;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{glib_recv, module_impl, send_async, spawn};
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::{module_impl, spawn};
|
||||
use color_eyre::{Report, Result};
|
||||
use gtk::IconTheme;
|
||||
use gtk::prelude::*;
|
||||
|
@ -208,7 +209,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
|||
|
||||
while let Ok(payload) = srx.recv().await {
|
||||
debug!("Received update: {payload:?}");
|
||||
send_async!(tx, ModuleUpdateEvent::Update(payload));
|
||||
tx.send_update(payload).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -317,7 +318,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
|||
}
|
||||
|
||||
let name_map = self.name_map;
|
||||
let mut handle_event = move |event: WorkspaceUpdate| match event {
|
||||
let handle_event = move |event: WorkspaceUpdate| match event {
|
||||
WorkspaceUpdate::Init(workspaces) => {
|
||||
if has_initialized {
|
||||
return;
|
||||
|
@ -403,7 +404,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
|||
WorkspaceUpdate::Unknown => warn!("received unknown type workspace event"),
|
||||
};
|
||||
|
||||
glib_recv!(context.subscribe(), handle_event);
|
||||
context.subscribe().recv_glib(handle_event);
|
||||
}
|
||||
|
||||
Ok(ModuleParts {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue