Skip to content

Commit

Permalink
fix(bar): pass reconnect event to bar
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alex-ds13 committed Jan 22, 2025
1 parent 0093d82 commit 45ffb89
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 134 deletions.
65 changes: 49 additions & 16 deletions komorebi-bar/src/bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ use crate::render::RenderConfig;
use crate::render::RenderExt;
use crate::widget::BarWidget;
use crate::widget::WidgetConfig;
use crate::KomorebiEvent;
use crate::BAR_HEIGHT;
use crate::DEFAULT_PADDING;
use crate::MAX_LABEL_WIDTH;
use crate::MONITOR_LEFT;
use crate::MONITOR_RIGHT;
use crate::MONITOR_TOP;
use crossbeam_channel::Receiver;
use crossbeam_channel::TryRecvError;
use eframe::egui::Align;
use eframe::egui::Align2;
use eframe::egui::Area;
Expand Down Expand Up @@ -63,7 +65,7 @@ pub struct Komobar {
pub left_widgets: Vec<Box<dyn BarWidget>>,
pub center_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 bg_color: Rc<RefCell<Color32>>,
pub bg_color_with_alpha: Rc<RefCell<Color32>>,
Expand Down Expand Up @@ -504,7 +506,7 @@ impl Komobar {

pub fn new(
cc: &eframe::CreationContext<'_>,
rx_gui: Receiver<komorebi_client::Notification>,
rx_gui: Receiver<KomorebiEvent>,
rx_config: Receiver<KomobarConfig>,
config: Arc<KomobarConfig>,
) -> Self {
Expand Down Expand Up @@ -632,20 +634,51 @@ impl eframe::App for Komobar {
);
}

if let Some(komorebi_notification_state) = &self.komorebi_notification_state {
komorebi_notification_state
.borrow_mut()
.handle_notification(
ctx,
self.monitor_index,
self.rx_gui.clone(),
self.bg_color.clone(),
self.bg_color_with_alpha.clone(),
self.config.transparency_alpha,
self.config.grouping,
self.config.theme,
self.render_config.clone(),
);
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 {
komorebi_notification_state
.borrow_mut()
.handle_notification(
ctx,
self.monitor_index,
notification,
self.bg_color.clone(),
self.bg_color_with_alpha.clone(),
self.config.transparency_alpha,
self.config.grouping,
self.config.theme,
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 {
Expand Down
177 changes: 80 additions & 97 deletions komorebi-bar/src/komorebi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use crate::widget::BarWidget;
use crate::ICON_CACHE;
use crate::MAX_LABEL_WIDTH;
use crate::MONITOR_INDEX;
use crossbeam_channel::Receiver;
use crossbeam_channel::TryRecvError;
use eframe::egui::vec2;
use eframe::egui::Color32;
use eframe::egui::ColorImage;
Expand Down Expand Up @@ -496,127 +494,112 @@ impl KomorebiNotificationState {
&mut self,
ctx: &Context,
monitor_index: usize,
rx_gui: Receiver<komorebi_client::Notification>,
notification: komorebi_client::Notification,
bg_color: Rc<RefCell<Color32>>,
bg_color_with_alpha: Rc<RefCell<Color32>>,
transparency_alpha: Option<u8>,
grouping: Option<Grouping>,
default_theme: Option<KomobarTheme>,
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 {
NotificationEvent::WindowManager(_) => {}
NotificationEvent::Socket(message) => match message {
SocketMessage::ReloadStaticConfiguration(path) => {
if let Ok(config) = komorebi_client::StaticConfig::read(&path) {
if let Some(theme) = config.theme {
apply_theme(
ctx,
KomobarTheme::from(theme),
bg_color.clone(),
bg_color_with_alpha.clone(),
transparency_alpha,
grouping,
render_config,
);
tracing::info!("applied theme from updated komorebi.json");
} else if let Some(default_theme) = default_theme {
apply_theme(
ctx,
default_theme,
bg_color.clone(),
bg_color_with_alpha.clone(),
transparency_alpha,
grouping,
render_config,
);
tracing::info!("removed theme from updated komorebi.json and applied default theme");
} else {
tracing::warn!("theme was removed from updated komorebi.json but there was no default theme to apply");
}
}
}
SocketMessage::Theme(theme) => {
match notification.event {
NotificationEvent::WindowManager(_) => {}
NotificationEvent::Socket(message) => match message {
SocketMessage::ReloadStaticConfiguration(path) => {
if let Ok(config) = komorebi_client::StaticConfig::read(&path) {
if let Some(theme) = config.theme {
apply_theme(
ctx,
KomobarTheme::from(theme),
bg_color,
bg_color.clone(),
bg_color_with_alpha.clone(),
transparency_alpha,
grouping,
render_config,
);
tracing::info!("applied theme from komorebi socket message");
tracing::info!("applied theme from updated komorebi.json");
} else if let Some(default_theme) = default_theme {
apply_theme(
ctx,
default_theme,
bg_color.clone(),
bg_color_with_alpha.clone(),
transparency_alpha,
grouping,
render_config,
);
tracing::info!("removed theme from updated komorebi.json and applied default theme");
} else {
tracing::warn!("theme was removed from updated komorebi.json but there was no default theme to apply");
}
_ => {}
},
}
}
SocketMessage::Theme(theme) => {
apply_theme(
ctx,
KomobarTheme::from(theme),
bg_color,
bg_color_with_alpha.clone(),
transparency_alpha,
grouping,
render_config,
);
tracing::info!("applied theme from komorebi socket message");
}
_ => {}
},
}

self.monitor_index = monitor_index;

self.mouse_follows_focus = notification.state.mouse_follows_focus;

let monitor = &notification.state.monitors.elements()[monitor_index];
self.work_area_offset =
notification.state.monitors.elements()[monitor_index].work_area_offset();
self.monitor_index = monitor_index;

let focused_workspace_idx = monitor.focused_workspace_idx();
self.mouse_follows_focus = notification.state.mouse_follows_focus;

let mut workspaces = vec![];
self.selected_workspace = monitor.workspaces()[focused_workspace_idx]
.name()
.to_owned()
.unwrap_or_else(|| format!("{}", focused_workspace_idx + 1));
let monitor = &notification.state.monitors.elements()[monitor_index];
self.work_area_offset =
notification.state.monitors.elements()[monitor_index].work_area_offset();

for (i, ws) in monitor.workspaces().iter().enumerate() {
let should_show = if self.hide_empty_workspaces {
focused_workspace_idx == i || !ws.containers().is_empty()
} else {
true
};
let focused_workspace_idx = monitor.focused_workspace_idx();

if should_show {
workspaces.push((
ws.name().to_owned().unwrap_or_else(|| format!("{}", i + 1)),
ws.into(),
));
}
}
let mut workspaces = vec![];
self.selected_workspace = monitor.workspaces()[focused_workspace_idx]
.name()
.to_owned()
.unwrap_or_else(|| format!("{}", focused_workspace_idx + 1));

self.workspaces = workspaces;

if monitor.workspaces()[focused_workspace_idx]
.monocle_container()
.is_some()
{
self.layout = KomorebiLayout::Monocle;
} else if !*monitor.workspaces()[focused_workspace_idx].tile() {
self.layout = KomorebiLayout::Floating;
} else if notification.state.is_paused {
self.layout = KomorebiLayout::Paused;
} else {
self.layout = match monitor.workspaces()[focused_workspace_idx].layout() {
komorebi_client::Layout::Default(layout) => {
KomorebiLayout::Default(*layout)
}
komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom,
};
}
for (i, ws) in monitor.workspaces().iter().enumerate() {
let should_show = if self.hide_empty_workspaces {
focused_workspace_idx == i || !ws.containers().is_empty()
} else {
true
};

self.focused_container_information =
(&monitor.workspaces()[focused_workspace_idx]).into();
if should_show {
workspaces.push((
ws.name().to_owned().unwrap_or_else(|| format!("{}", i + 1)),
ws.into(),
));
}
}

self.workspaces = workspaces;

if monitor.workspaces()[focused_workspace_idx]
.monocle_container()
.is_some()
{
self.layout = KomorebiLayout::Monocle;
} else if !*monitor.workspaces()[focused_workspace_idx].tile() {
self.layout = KomorebiLayout::Floating;
} else if notification.state.is_paused {
self.layout = KomorebiLayout::Paused;
} else {
self.layout = match monitor.workspaces()[focused_workspace_idx].layout() {
komorebi_client::Layout::Default(layout) => KomorebiLayout::Default(*layout),
komorebi_client::Layout::Custom(_) => KomorebiLayout::Custom,
};
}

self.focused_container_information = (&monitor.workspaces()[focused_workspace_idx]).into();
}
}

Expand Down
32 changes: 11 additions & 21 deletions komorebi-bar/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ fn process_hwnd() -> Option<isize> {
}
}

pub enum KomorebiEvent {
Notification(komorebi_client::Notification),
Reconnect,
}

fn main() -> color_eyre::Result<()> {
unsafe { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) }?;

Expand Down Expand Up @@ -333,8 +338,6 @@ fn main() -> color_eyre::Result<()> {
"komorebi-bar",
native_options,
Box::new(|cc| {
let config_cl = config_arc.clone();

let ctx_repainter = cc.egui_ctx.clone();
std::thread::spawn(move || loop {
std::thread::sleep(Duration::from_secs(1));
Expand Down Expand Up @@ -377,25 +380,12 @@ fn main() -> color_eyre::Result<()> {

tracing::info!("reconnected to komorebi");

let (monitor_index, work_area_offset) = match &config_cl.monitor {
MonitorConfigOrIndex::MonitorConfig(monitor_config) => {
(monitor_config.index, monitor_config.work_area_offset)
}
MonitorConfigOrIndex::Index(idx) => (*idx, None),
};

if let Some(rect) = &work_area_offset {
while komorebi_client::send_message(
&SocketMessage::MonitorWorkAreaOffset(
monitor_index,
*rect,
),
)
.is_err()
{
std::thread::sleep(Duration::from_secs(1));
}
if let Err(error) = tx_gui.send(KomorebiEvent::Reconnect) {
tracing::error!("could not send komorebi reconnect event to gui thread: {error}")
}

ctx_komorebi.request_repaint();
continue;
}

match String::from_utf8(buffer) {
Expand All @@ -406,7 +396,7 @@ fn main() -> color_eyre::Result<()> {
Ok(notification) => {
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}")
}

Expand Down

0 comments on commit 45ffb89

Please sign in to comment.