fix(bar): pass reconnect event to bar

This commit changes the `rx_gui` from receiving just a notification from
komorebi to now receive a new type `KomorebiEvent` which can be either a
`KomorebiEvent::Notification(komorebi_client::Notification)` or a
`KomorebiEvent::Reconnect`.

The `Reconnect` is sent after losing connection with komorebi and then
reconnecting again.

Now on the bar `update` we check for this `rx_gui` if we get a
notification we pass that to the
`KomorebiNotificationState::handle_notification` function just like
before (except now it takes a notification directly instead of taking
the `rx_gui` and checking for some message on the channel).

If instead we get a `Reconnect` we send a `MonitorWorkAreaOffset` socket
message to komorebi to update the work area offset.
This commit is contained in:
alex-ds13
2025-01-22 22:51:14 +00:00
committed by LGUG2Z
parent 3e1fc6123a
commit d7fcbb7d00
3 changed files with 144 additions and 138 deletions
+36 -3
View File
@@ -13,6 +13,7 @@ use crate::render::RenderConfig;
use crate::render::RenderExt; use crate::render::RenderExt;
use crate::widget::BarWidget; use crate::widget::BarWidget;
use crate::widget::WidgetConfig; use crate::widget::WidgetConfig;
use crate::KomorebiEvent;
use crate::BAR_HEIGHT; use crate::BAR_HEIGHT;
use crate::DEFAULT_PADDING; use crate::DEFAULT_PADDING;
use crate::MAX_LABEL_WIDTH; use crate::MAX_LABEL_WIDTH;
@@ -20,6 +21,7 @@ use crate::MONITOR_LEFT;
use crate::MONITOR_RIGHT; use crate::MONITOR_RIGHT;
use crate::MONITOR_TOP; use crate::MONITOR_TOP;
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
use crossbeam_channel::TryRecvError;
use eframe::egui::Align; use eframe::egui::Align;
use eframe::egui::Align2; use eframe::egui::Align2;
use eframe::egui::Area; use eframe::egui::Area;
@@ -63,7 +65,7 @@ pub struct Komobar {
pub left_widgets: Vec<Box<dyn BarWidget>>, pub left_widgets: Vec<Box<dyn BarWidget>>,
pub center_widgets: Vec<Box<dyn BarWidget>>, pub center_widgets: Vec<Box<dyn BarWidget>>,
pub right_widgets: Vec<Box<dyn BarWidget>>, pub right_widgets: Vec<Box<dyn BarWidget>>,
pub rx_gui: Receiver<komorebi_client::Notification>, pub rx_gui: Receiver<KomorebiEvent>,
pub rx_config: Receiver<KomobarConfig>, pub rx_config: Receiver<KomobarConfig>,
pub bg_color: Rc<RefCell<Color32>>, pub bg_color: Rc<RefCell<Color32>>,
pub bg_color_with_alpha: Rc<RefCell<Color32>>, pub bg_color_with_alpha: Rc<RefCell<Color32>>,
@@ -504,7 +506,7 @@ impl Komobar {
pub fn new( pub fn new(
cc: &eframe::CreationContext<'_>, cc: &eframe::CreationContext<'_>,
rx_gui: Receiver<komorebi_client::Notification>, rx_gui: Receiver<KomorebiEvent>,
rx_config: Receiver<KomobarConfig>, rx_config: Receiver<KomobarConfig>,
config: Arc<KomobarConfig>, config: Arc<KomobarConfig>,
) -> Self { ) -> Self {
@@ -632,13 +634,23 @@ impl eframe::App for Komobar {
); );
} }
match self.rx_gui.try_recv() {
Err(error) => match error {
TryRecvError::Empty => {}
TryRecvError::Disconnected => {
tracing::error!(
"failed to receive komorebi notification on gui thread: {error}"
);
}
},
Ok(KomorebiEvent::Notification(notification)) => {
if let Some(komorebi_notification_state) = &self.komorebi_notification_state { if let Some(komorebi_notification_state) = &self.komorebi_notification_state {
komorebi_notification_state komorebi_notification_state
.borrow_mut() .borrow_mut()
.handle_notification( .handle_notification(
ctx, ctx,
self.monitor_index, self.monitor_index,
self.rx_gui.clone(), notification,
self.bg_color.clone(), self.bg_color.clone(),
self.bg_color_with_alpha.clone(), self.bg_color_with_alpha.clone(),
self.config.transparency_alpha, self.config.transparency_alpha,
@@ -647,6 +659,27 @@ impl eframe::App for Komobar {
self.render_config.clone(), self.render_config.clone(),
); );
} }
}
Ok(KomorebiEvent::Reconnect) => {
if let Err(error) =
komorebi_client::send_message(&SocketMessage::MonitorWorkAreaOffset(
self.monitor_index,
self.work_area_offset,
))
{
tracing::error!(
"error applying work area offset to monitor '{}': {}",
self.monitor_index,
error,
);
} else {
tracing::info!(
"work area offset applied to monitor: {}",
self.monitor_index
);
}
}
}
if !self.applied_theme_on_first_frame { if !self.applied_theme_on_first_frame {
self.try_apply_theme(&self.config.clone(), ctx); self.try_apply_theme(&self.config.clone(), ctx);
+3 -20
View File
@@ -10,8 +10,6 @@ use crate::widget::BarWidget;
use crate::ICON_CACHE; use crate::ICON_CACHE;
use crate::MAX_LABEL_WIDTH; use crate::MAX_LABEL_WIDTH;
use crate::MONITOR_INDEX; use crate::MONITOR_INDEX;
use crossbeam_channel::Receiver;
use crossbeam_channel::TryRecvError;
use eframe::egui::vec2; use eframe::egui::vec2;
use eframe::egui::Color32; use eframe::egui::Color32;
use eframe::egui::ColorImage; use eframe::egui::ColorImage;
@@ -496,7 +494,7 @@ impl KomorebiNotificationState {
&mut self, &mut self,
ctx: &Context, ctx: &Context,
monitor_index: usize, monitor_index: usize,
rx_gui: Receiver<komorebi_client::Notification>, notification: komorebi_client::Notification,
bg_color: Rc<RefCell<Color32>>, bg_color: Rc<RefCell<Color32>>,
bg_color_with_alpha: Rc<RefCell<Color32>>, bg_color_with_alpha: Rc<RefCell<Color32>>,
transparency_alpha: Option<u8>, transparency_alpha: Option<u8>,
@@ -504,16 +502,6 @@ impl KomorebiNotificationState {
default_theme: Option<KomobarTheme>, default_theme: Option<KomobarTheme>,
render_config: Rc<RefCell<RenderConfig>>, render_config: Rc<RefCell<RenderConfig>>,
) { ) {
match rx_gui.try_recv() {
Err(error) => match error {
TryRecvError::Empty => {}
TryRecvError::Disconnected => {
tracing::error!(
"failed to receive komorebi notification on gui thread: {error}"
);
}
},
Ok(notification) => {
match notification.event { match notification.event {
NotificationEvent::WindowManager(_) => {} NotificationEvent::WindowManager(_) => {}
NotificationEvent::Socket(message) => match message { NotificationEvent::Socket(message) => match message {
@@ -606,17 +594,12 @@ impl KomorebiNotificationState {
self.layout = KomorebiLayout::Paused; self.layout = KomorebiLayout::Paused;
} else { } else {
self.layout = match monitor.workspaces()[focused_workspace_idx].layout() { self.layout = match monitor.workspaces()[focused_workspace_idx].layout() {
komorebi_client::Layout::Default(layout) => { komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(*layout),
KomorebiLayout::Default(*layout)
}
komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom, komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom,
}; };
} }
self.focused_container_information = self.focused_container_information = (&monitor.workspaces()[focused_workspace_idx]).into();
(&monitor.workspaces()[focused_workspace_idx]).into();
}
}
} }
} }
+10 -20
View File
@@ -115,6 +115,11 @@ fn process_hwnd() -> Option<isize> {
} }
} }
pub enum KomorebiEvent {
Notification(komorebi_client::Notification),
Reconnect,
}
fn main() -> color_eyre::Result<()> { fn main() -> color_eyre::Result<()> {
unsafe { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }?; unsafe { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }?;
@@ -333,8 +338,6 @@ fn main() -> color_eyre::Result<()> {
"komorebi-bar", "komorebi-bar",
native_options, native_options,
Box::new(|cc| { Box::new(|cc| {
let config_cl = config_arc.clone();
let ctx_repainter = cc.egui_ctx.clone(); let ctx_repainter = cc.egui_ctx.clone();
std::thread::spawn(move || loop { std::thread::spawn(move || loop {
std::thread::sleep(Duration::from_secs(1)); std::thread::sleep(Duration::from_secs(1));
@@ -377,25 +380,12 @@ fn main() -> color_eyre::Result<()> {
tracing::info!("reconnected to komorebi"); tracing::info!("reconnected to komorebi");
let (monitor_index, work_area_offset) = match &config_cl.monitor { if let Err(error) = tx_gui.send(KomorebiEvent::Reconnect) {
MonitorConfigOrIndex::MonitorConfig(monitor_config) => { tracing::error!("could not send komorebi reconnect event to gui thread: {error}")
(monitor_config.index, monitor_config.work_area_offset)
} }
MonitorConfigOrIndex::Index(idx) => (*idx, None),
};
if let Some(rect) = &work_area_offset { ctx_komorebi.request_repaint();
while komorebi_client::send_message( continue;
&SocketMessage::MonitorWorkAreaOffset(
monitor_index,
*rect,
),
)
.is_err()
{
std::thread::sleep(Duration::from_secs(1));
}
}
} }
match String::from_utf8(buffer) { match String::from_utf8(buffer) {
@@ -406,7 +396,7 @@ fn main() -> color_eyre::Result<()> {
Ok(notification) => { Ok(notification) => {
tracing::debug!("received notification from komorebi"); tracing::debug!("received notification from komorebi");
if let Err(error) = tx_gui.send(notification) { if let Err(error) = tx_gui.send(KomorebiEvent::Notification(notification)) {
tracing::error!("could not send komorebi notification update to gui thread: {error}") tracing::error!("could not send komorebi notification update to gui thread: {error}")
} }