mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-21 08:11:30 +02:00
feat(bar): add locked container widget, use accent colour for icons
This commit adds a new komorebi widget to indicate whether or not the focused container is locked. This commit also includes an icon colour change on the layer and layout widgets to the accent colour. The commit also renames the locked_window widget to locked_container as it is more suitable. PR: #1394
This commit is contained in:
@@ -11,7 +11,9 @@ use crate::widgets::widget::BarWidget;
|
||||
use crate::ICON_CACHE;
|
||||
use crate::MAX_LABEL_WIDTH;
|
||||
use crate::MONITOR_INDEX;
|
||||
use eframe::egui::text::LayoutJob;
|
||||
use eframe::egui::vec2;
|
||||
use eframe::egui::Align;
|
||||
use eframe::egui::Color32;
|
||||
use eframe::egui::ColorImage;
|
||||
use eframe::egui::Context;
|
||||
@@ -24,6 +26,7 @@ use eframe::egui::RichText;
|
||||
use eframe::egui::Sense;
|
||||
use eframe::egui::Stroke;
|
||||
use eframe::egui::StrokeKind;
|
||||
use eframe::egui::TextFormat;
|
||||
use eframe::egui::TextureHandle;
|
||||
use eframe::egui::TextureOptions;
|
||||
use eframe::egui::Ui;
|
||||
@@ -55,8 +58,11 @@ pub struct KomorebiConfig {
|
||||
pub layout: Option<KomorebiLayoutConfig>,
|
||||
/// Configure the Workspace Layer widget
|
||||
pub workspace_layer: Option<KomorebiWorkspaceLayerConfig>,
|
||||
/// Configure the Focused Window widget
|
||||
pub focused_window: Option<KomorebiFocusedWindowConfig>,
|
||||
/// Configure the Focused Container widget
|
||||
#[serde(alias = "focused_window")]
|
||||
pub focused_container: Option<KomorebiFocusedContainerConfig>,
|
||||
/// Configure the Locked Container widget
|
||||
pub locked_container: Option<KomorebiLockedContainerConfig>,
|
||||
/// Configure the Configuration Switcher widget
|
||||
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
|
||||
}
|
||||
@@ -96,15 +102,26 @@ pub struct KomorebiWorkspaceLayerConfig {
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct KomorebiFocusedWindowConfig {
|
||||
/// Enable the Komorebi Focused Window widget
|
||||
pub struct KomorebiFocusedContainerConfig {
|
||||
/// Enable the Komorebi Focused Container widget
|
||||
pub enable: bool,
|
||||
/// DEPRECATED: use 'display' instead (Show the icon of the currently focused window)
|
||||
/// DEPRECATED: use 'display' instead (Show the icon of the currently focused container)
|
||||
pub show_icon: Option<bool>,
|
||||
/// Display format of the currently focused window
|
||||
/// Display format of the currently focused container
|
||||
pub display: Option<DisplayFormat>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct KomorebiLockedContainerConfig {
|
||||
/// Enable the Komorebi Locked Container widget
|
||||
pub enable: bool,
|
||||
/// Display format of the current locked state
|
||||
pub display: Option<DisplayFormat>,
|
||||
/// Show the widget event if the layer is unlocked
|
||||
pub show_when_unlocked: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct KomorebiConfigurationSwitcherConfig {
|
||||
@@ -140,15 +157,19 @@ impl From<&KomorebiConfig> for Komorebi {
|
||||
.unwrap_or_default(),
|
||||
mouse_follows_focus: true,
|
||||
work_area_offset: None,
|
||||
focused_container_information: KomorebiNotificationStateContainerInformation::EMPTY,
|
||||
focused_container_information: (
|
||||
false,
|
||||
KomorebiNotificationStateContainerInformation::EMPTY,
|
||||
),
|
||||
stack_accent: None,
|
||||
monitor_index: MONITOR_INDEX.load(Ordering::SeqCst),
|
||||
monitor_usr_idx_map: HashMap::new(),
|
||||
})),
|
||||
workspaces: value.workspaces,
|
||||
layout: value.layout.clone(),
|
||||
focused_window: value.focused_window,
|
||||
focused_container: value.focused_container,
|
||||
workspace_layer: value.workspace_layer,
|
||||
locked_container: value.locked_container,
|
||||
configuration_switcher,
|
||||
}
|
||||
}
|
||||
@@ -159,8 +180,9 @@ pub struct Komorebi {
|
||||
pub komorebi_notification_state: Rc<RefCell<KomorebiNotificationState>>,
|
||||
pub workspaces: Option<KomorebiWorkspacesConfig>,
|
||||
pub layout: Option<KomorebiLayoutConfig>,
|
||||
pub focused_window: Option<KomorebiFocusedWindowConfig>,
|
||||
pub focused_container: Option<KomorebiFocusedContainerConfig>,
|
||||
pub workspace_layer: Option<KomorebiWorkspaceLayerConfig>,
|
||||
pub locked_container: Option<KomorebiLockedContainerConfig>,
|
||||
pub configuration_switcher: Option<KomorebiConfigurationSwitcherConfig>,
|
||||
}
|
||||
|
||||
@@ -337,7 +359,7 @@ impl BarWidget for Komorebi {
|
||||
if matches!(layer, WorkspaceLayer::Tiling) {
|
||||
let (response, painter) =
|
||||
ui.allocate_painter(size, Sense::hover());
|
||||
let color = ui.style().visuals.text_color();
|
||||
let color = ctx.style().visuals.selection.stroke.color;
|
||||
let stroke = Stroke::new(1.0, color);
|
||||
let mut rect = response.rect;
|
||||
let corner =
|
||||
@@ -367,7 +389,7 @@ impl BarWidget for Komorebi {
|
||||
} else {
|
||||
let (response, painter) =
|
||||
ui.allocate_painter(size, Sense::hover());
|
||||
let color = ui.style().visuals.text_color();
|
||||
let color = ctx.style().visuals.selection.stroke.color;
|
||||
let stroke = Stroke::new(1.0, color);
|
||||
let mut rect = response.rect;
|
||||
let corner =
|
||||
@@ -504,18 +526,85 @@ impl BarWidget for Komorebi {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(focused_window) = self.focused_window {
|
||||
if focused_window.enable {
|
||||
if let Some(locked_container_config) = self.locked_container {
|
||||
if locked_container_config.enable {
|
||||
let is_locked = komorebi_notification_state.focused_container_information.0;
|
||||
|
||||
if locked_container_config
|
||||
.show_when_unlocked
|
||||
.unwrap_or_default()
|
||||
|| is_locked
|
||||
{
|
||||
let titles = &komorebi_notification_state
|
||||
.focused_container_information
|
||||
.1
|
||||
.titles;
|
||||
|
||||
if !titles.is_empty() {
|
||||
let display_format = locked_container_config
|
||||
.display
|
||||
.unwrap_or(DisplayFormat::Text);
|
||||
|
||||
let mut layout_job = LayoutJob::simple(
|
||||
if display_format != DisplayFormat::Text {
|
||||
if is_locked {
|
||||
egui_phosphor::regular::LOCK_KEY.to_string()
|
||||
} else {
|
||||
egui_phosphor::regular::LOCK_SIMPLE_OPEN.to_string()
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
config.icon_font_id.clone(),
|
||||
ctx.style().visuals.selection.stroke.color,
|
||||
100.0,
|
||||
);
|
||||
|
||||
if display_format != DisplayFormat::Icon {
|
||||
layout_job.append(
|
||||
if is_locked { "Locked" } else { "Unlocked" },
|
||||
10.0,
|
||||
TextFormat {
|
||||
font_id: config.text_font_id.clone(),
|
||||
color: ctx.style().visuals.text_color(),
|
||||
valign: Align::Center,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
config.apply_on_widget(false, ui, |ui| {
|
||||
if SelectableFrame::new(false)
|
||||
.show(ui, |ui| ui.add(Label::new(layout_job).selectable(false)))
|
||||
.clicked()
|
||||
&& komorebi_client::send_batch([
|
||||
SocketMessage::FocusMonitorAtCursor,
|
||||
SocketMessage::ToggleLock,
|
||||
])
|
||||
.is_err()
|
||||
{
|
||||
tracing::error!("could not send ToggleLock");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(focused_container_config) = self.focused_container {
|
||||
if focused_container_config.enable {
|
||||
let titles = &komorebi_notification_state
|
||||
.focused_container_information
|
||||
.1
|
||||
.titles;
|
||||
|
||||
if !titles.is_empty() {
|
||||
config.apply_on_widget(false, ui, |ui| {
|
||||
let icons = &komorebi_notification_state
|
||||
.focused_container_information
|
||||
.focused_container_information.1
|
||||
.icons;
|
||||
let focused_window_idx = komorebi_notification_state
|
||||
.focused_container_information
|
||||
.focused_container_information.1
|
||||
.focused_window_idx;
|
||||
|
||||
let iter = titles.iter().zip(icons.iter());
|
||||
@@ -523,13 +612,13 @@ impl BarWidget for Komorebi {
|
||||
|
||||
for (i, (title, icon)) in iter.enumerate() {
|
||||
let selected = i == focused_window_idx && len != 1;
|
||||
let text_color = if selected { ctx.style().visuals.selection.stroke.color} else { ui.style().visuals.text_color() };
|
||||
let text_color = if selected { ctx.style().visuals.selection.stroke.color } else { ui.style().visuals.text_color() };
|
||||
|
||||
if SelectableFrame::new(selected)
|
||||
.show(ui, |ui| {
|
||||
// handle legacy setting
|
||||
let format = focused_window.display.unwrap_or(
|
||||
if focused_window.show_icon.unwrap_or(false) {
|
||||
let format = focused_container_config.display.unwrap_or(
|
||||
if focused_container_config.show_icon.unwrap_or(false) {
|
||||
DisplayFormat::IconAndText
|
||||
} else {
|
||||
DisplayFormat::Text
|
||||
@@ -632,7 +721,7 @@ pub struct KomorebiNotificationState {
|
||||
bool,
|
||||
)>,
|
||||
pub selected_workspace: String,
|
||||
pub focused_container_information: KomorebiNotificationStateContainerInformation,
|
||||
pub focused_container_information: (bool, KomorebiNotificationStateContainerInformation),
|
||||
pub layout: KomorebiLayout,
|
||||
pub hide_empty_workspaces: bool,
|
||||
pub mouse_follows_focus: bool,
|
||||
@@ -800,7 +889,12 @@ impl KomorebiNotificationState {
|
||||
};
|
||||
}
|
||||
|
||||
self.focused_container_information = (&monitor.workspaces()[focused_workspace_idx]).into();
|
||||
let focused_workspace = &monitor.workspaces()[focused_workspace_idx];
|
||||
let is_focused = focused_workspace
|
||||
.locked_containers()
|
||||
.contains(&focused_workspace.focused_container_idx());
|
||||
|
||||
self.focused_container_information = (is_focused, focused_workspace.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ impl KomorebiLayout {
|
||||
let layout_frame = SelectableFrame::new(false)
|
||||
.show(ui, |ui| {
|
||||
if let DisplayFormat::Icon | DisplayFormat::IconAndText = format {
|
||||
self.show_icon(false, font_id.clone(), ctx, ui);
|
||||
self.show_icon(true, font_id.clone(), ctx, ui);
|
||||
}
|
||||
|
||||
if let DisplayFormat::Text | DisplayFormat::IconAndText = format {
|
||||
|
||||
@@ -72,7 +72,7 @@ impl WidgetConfig {
|
||||
WidgetConfig::Komorebi(config) => {
|
||||
config.workspaces.as_ref().is_some_and(|w| w.enable)
|
||||
|| config.layout.as_ref().is_some_and(|w| w.enable)
|
||||
|| config.focused_window.as_ref().is_some_and(|w| w.enable)
|
||||
|| config.focused_container.as_ref().is_some_and(|w| w.enable)
|
||||
|| config
|
||||
.configuration_switcher
|
||||
.as_ref()
|
||||
|
||||
Reference in New Issue
Block a user