refine shell workspace indicators
This commit is contained in:
1 parent
4a6d91980c
commit
dc3ef13501
2 files changed
+89
-27
No files matched your search
@@ -28,7 +28,6 @@ pub(crate) struct ShellSnapshot {
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct OutputSnapshot {
|
||||
pub(crate) id: u64,
|
||||
pub(crate) name: String,
|
||||
pub(crate) active_workspace: u64,
|
||||
pub(crate) focused: bool,
|
||||
}
|
||||
@@ -37,7 +36,6 @@ pub(crate) struct OutputSnapshot {
|
||||
pub(crate) struct WorkspaceSnapshot {
|
||||
pub(crate) id: u64,
|
||||
pub(crate) output: Option<u64>,
|
||||
pub(crate) name: String,
|
||||
pub(crate) active: bool,
|
||||
}
|
||||
|
||||
@@ -182,13 +180,12 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
||||
ferese_shell_v1::Event::Output {
|
||||
output_hi,
|
||||
output_lo,
|
||||
name,
|
||||
name: _,
|
||||
active_workspace_hi,
|
||||
active_workspace_lo,
|
||||
focused,
|
||||
} => state.pending.outputs.push(OutputSnapshot {
|
||||
id: join_id(output_hi, output_lo),
|
||||
name,
|
||||
active_workspace: join_id(active_workspace_hi, active_workspace_lo),
|
||||
focused: focused != 0,
|
||||
}),
|
||||
@@ -197,7 +194,7 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
||||
workspace_lo,
|
||||
output_hi,
|
||||
output_lo,
|
||||
name,
|
||||
name: _,
|
||||
active,
|
||||
} => {
|
||||
let output = join_id(output_hi, output_lo);
|
||||
@@ -205,7 +202,6 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
||||
state.pending.workspaces.push(WorkspaceSnapshot {
|
||||
id: join_id(workspace_hi, workspace_lo),
|
||||
output: (output != 0).then_some(output),
|
||||
name,
|
||||
active: active != 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,6 +32,14 @@ const APP_ID: &str = "dev.ferese.Shell";
|
||||
const BAR_HEIGHT: u32 = 32;
|
||||
const BAR_MARGIN: i32 = 8;
|
||||
const EXCLUSIVE_ZONE: i32 = BAR_HEIGHT as i32;
|
||||
const BAR_TEXT_SIZE: u16 = (BAR_HEIGHT * 3 / 8) as u16;
|
||||
const BAR_ICON_SIZE: u16 = (BAR_HEIGHT / 2) as u16;
|
||||
const CONTROL_HEIGHT: f32 = BAR_HEIGHT as f32 * 0.75;
|
||||
const WORKSPACE_HIT_WIDTH: f32 = BAR_HEIGHT as f32 * 0.6875;
|
||||
const ACTIVE_MARKER_WIDTH: f32 = BAR_HEIGHT as f32 * 0.5;
|
||||
const ACTIVE_MARKER_HEIGHT: f32 = BAR_HEIGHT as f32 * 0.125;
|
||||
const DOT_MARKER_SIZE: f32 = BAR_HEIGHT as f32 * 0.1875;
|
||||
const EMPTY_MARKER_SIZE: f32 = BAR_HEIGHT as f32 * 0.125;
|
||||
|
||||
fn main() -> cosmic::iced::Result {
|
||||
let settings = Settings::default()
|
||||
@@ -206,13 +214,13 @@ impl FereseShell {
|
||||
.or_else(|| self.snapshot.outputs.first());
|
||||
let focused_output_id = focused_output.map(|output| output.id);
|
||||
let mut workspace_row = row::with_capacity(self.snapshot.workspaces.len() + 1)
|
||||
.spacing(2)
|
||||
.spacing(1)
|
||||
.align_y(cosmic::iced::Alignment::Center);
|
||||
|
||||
workspace_row = workspace_row.push(
|
||||
button::suggested("F")
|
||||
.font_size(12)
|
||||
.height(24)
|
||||
.font_size(BAR_TEXT_SIZE)
|
||||
.height(CONTROL_HEIGHT)
|
||||
.padding([2, 9])
|
||||
.on_press(cosmic::Action::App(Message::EnterOverview)),
|
||||
);
|
||||
@@ -222,16 +230,21 @@ impl FereseShell {
|
||||
.iter()
|
||||
.filter(|workspace| workspace.output == focused_output_id)
|
||||
{
|
||||
let button = if workspace.active {
|
||||
button::suggested(workspace.name.clone())
|
||||
} else {
|
||||
button::text(workspace.name.clone())
|
||||
};
|
||||
let occupied = self
|
||||
.snapshot
|
||||
.windows
|
||||
.iter()
|
||||
.any(|window| window.workspace == workspace.id);
|
||||
let indicator = workspace_indicator(workspace.active, occupied);
|
||||
let workspace_button = button::custom(indicator)
|
||||
.height(CONTROL_HEIGHT)
|
||||
.padding(0)
|
||||
.class(theme::Button::Transparent)
|
||||
.on_press(cosmic::Action::App(Message::ActivateWorkspace(
|
||||
workspace.id,
|
||||
)));
|
||||
|
||||
workspace_row =
|
||||
workspace_row.push(button.font_size(12).height(24).padding([2, 8]).on_press(
|
||||
cosmic::Action::App(Message::ActivateWorkspace(workspace.id)),
|
||||
));
|
||||
workspace_row = workspace_row.push(workspace_button);
|
||||
}
|
||||
|
||||
let app_name = self
|
||||
@@ -245,18 +258,14 @@ impl FereseShell {
|
||||
})
|
||||
.map(display_app_name)
|
||||
.unwrap_or_else(|| "Desktop".to_owned());
|
||||
let left = row![workspace_row, text(app_name).size(12)]
|
||||
let left = row![workspace_row, text(app_name).size(BAR_TEXT_SIZE)]
|
||||
.spacing(12)
|
||||
.align_y(cosmic::iced::Alignment::Center);
|
||||
let center = text(&self.clock).size(13);
|
||||
let output_hint = focused_output
|
||||
.map(|output| output.name.as_str())
|
||||
.unwrap_or("No display");
|
||||
let center = text(&self.clock).size(BAR_TEXT_SIZE);
|
||||
let right = row![
|
||||
text("◌").size(16),
|
||||
text("♪").size(15),
|
||||
text(output_hint).size(11),
|
||||
text("●").size(10),
|
||||
text("◌").size(BAR_ICON_SIZE),
|
||||
text("♪").size(BAR_ICON_SIZE),
|
||||
text("●").size(BAR_ICON_SIZE),
|
||||
]
|
||||
.spacing(10)
|
||||
.align_y(cosmic::iced::Alignment::Center);
|
||||
@@ -283,6 +292,63 @@ impl FereseShell {
|
||||
}
|
||||
}
|
||||
|
||||
fn workspace_indicator(active: bool, occupied: bool) -> Element<'static, cosmic::Action<Message>> {
|
||||
let (width, height, style) = if active {
|
||||
(
|
||||
ACTIVE_MARKER_WIDTH,
|
||||
ACTIVE_MARKER_HEIGHT,
|
||||
active_workspace_style as fn(&cosmic::Theme) -> container::Style,
|
||||
)
|
||||
} else if occupied {
|
||||
(
|
||||
DOT_MARKER_SIZE,
|
||||
DOT_MARKER_SIZE,
|
||||
occupied_workspace_style as fn(&cosmic::Theme) -> container::Style,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
EMPTY_MARKER_SIZE,
|
||||
EMPTY_MARKER_SIZE,
|
||||
empty_workspace_style as fn(&cosmic::Theme) -> container::Style,
|
||||
)
|
||||
};
|
||||
let marker = container(text(""))
|
||||
.width(width)
|
||||
.height(height)
|
||||
.class(theme::Container::custom(style));
|
||||
|
||||
container(marker)
|
||||
.width(WORKSPACE_HIT_WIDTH)
|
||||
.height(CONTROL_HEIGHT)
|
||||
.align_x(alignment::Horizontal::Center)
|
||||
.align_y(alignment::Vertical::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn active_workspace_style(_theme: &cosmic::Theme) -> container::Style {
|
||||
workspace_marker_style(Color::from_rgb8(91, 140, 255), 2.0)
|
||||
}
|
||||
|
||||
fn occupied_workspace_style(_theme: &cosmic::Theme) -> container::Style {
|
||||
workspace_marker_style(Color::from_rgba8(221, 228, 240, 0.68), 3.0)
|
||||
}
|
||||
|
||||
fn empty_workspace_style(_theme: &cosmic::Theme) -> container::Style {
|
||||
workspace_marker_style(Color::from_rgba8(221, 228, 240, 0.25), 2.0)
|
||||
}
|
||||
|
||||
fn workspace_marker_style(color: Color, radius: f32) -> container::Style {
|
||||
container::Style {
|
||||
background: Some(Background::Color(color)),
|
||||
border: Border {
|
||||
radius: radius.into(),
|
||||
..Border::default()
|
||||
},
|
||||
snap: true,
|
||||
..container::Style::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn display_app_name(window: &control::WindowSnapshot) -> String {
|
||||
let identity = window
|
||||
.app_id
|
||||
|
||||
Reference in new issue
Block a user