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)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct OutputSnapshot {
|
pub(crate) struct OutputSnapshot {
|
||||||
pub(crate) id: u64,
|
pub(crate) id: u64,
|
||||||
pub(crate) name: String,
|
|
||||||
pub(crate) active_workspace: u64,
|
pub(crate) active_workspace: u64,
|
||||||
pub(crate) focused: bool,
|
pub(crate) focused: bool,
|
||||||
}
|
}
|
||||||
@@ -37,7 +36,6 @@ pub(crate) struct OutputSnapshot {
|
|||||||
pub(crate) struct WorkspaceSnapshot {
|
pub(crate) struct WorkspaceSnapshot {
|
||||||
pub(crate) id: u64,
|
pub(crate) id: u64,
|
||||||
pub(crate) output: Option<u64>,
|
pub(crate) output: Option<u64>,
|
||||||
pub(crate) name: String,
|
|
||||||
pub(crate) active: bool,
|
pub(crate) active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,13 +180,12 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
|||||||
ferese_shell_v1::Event::Output {
|
ferese_shell_v1::Event::Output {
|
||||||
output_hi,
|
output_hi,
|
||||||
output_lo,
|
output_lo,
|
||||||
name,
|
name: _,
|
||||||
active_workspace_hi,
|
active_workspace_hi,
|
||||||
active_workspace_lo,
|
active_workspace_lo,
|
||||||
focused,
|
focused,
|
||||||
} => state.pending.outputs.push(OutputSnapshot {
|
} => state.pending.outputs.push(OutputSnapshot {
|
||||||
id: join_id(output_hi, output_lo),
|
id: join_id(output_hi, output_lo),
|
||||||
name,
|
|
||||||
active_workspace: join_id(active_workspace_hi, active_workspace_lo),
|
active_workspace: join_id(active_workspace_hi, active_workspace_lo),
|
||||||
focused: focused != 0,
|
focused: focused != 0,
|
||||||
}),
|
}),
|
||||||
@@ -197,7 +194,7 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
|||||||
workspace_lo,
|
workspace_lo,
|
||||||
output_hi,
|
output_hi,
|
||||||
output_lo,
|
output_lo,
|
||||||
name,
|
name: _,
|
||||||
active,
|
active,
|
||||||
} => {
|
} => {
|
||||||
let output = join_id(output_hi, output_lo);
|
let output = join_id(output_hi, output_lo);
|
||||||
@@ -205,7 +202,6 @@ impl Dispatch<FereseShellV1, ()> for ControlState {
|
|||||||
state.pending.workspaces.push(WorkspaceSnapshot {
|
state.pending.workspaces.push(WorkspaceSnapshot {
|
||||||
id: join_id(workspace_hi, workspace_lo),
|
id: join_id(workspace_hi, workspace_lo),
|
||||||
output: (output != 0).then_some(output),
|
output: (output != 0).then_some(output),
|
||||||
name,
|
|
||||||
active: active != 0,
|
active: active != 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,14 @@ const APP_ID: &str = "dev.ferese.Shell";
|
|||||||
const BAR_HEIGHT: u32 = 32;
|
const BAR_HEIGHT: u32 = 32;
|
||||||
const BAR_MARGIN: i32 = 8;
|
const BAR_MARGIN: i32 = 8;
|
||||||
const EXCLUSIVE_ZONE: i32 = BAR_HEIGHT as i32;
|
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 {
|
fn main() -> cosmic::iced::Result {
|
||||||
let settings = Settings::default()
|
let settings = Settings::default()
|
||||||
@@ -206,13 +214,13 @@ impl FereseShell {
|
|||||||
.or_else(|| self.snapshot.outputs.first());
|
.or_else(|| self.snapshot.outputs.first());
|
||||||
let focused_output_id = focused_output.map(|output| output.id);
|
let focused_output_id = focused_output.map(|output| output.id);
|
||||||
let mut workspace_row = row::with_capacity(self.snapshot.workspaces.len() + 1)
|
let mut workspace_row = row::with_capacity(self.snapshot.workspaces.len() + 1)
|
||||||
.spacing(2)
|
.spacing(1)
|
||||||
.align_y(cosmic::iced::Alignment::Center);
|
.align_y(cosmic::iced::Alignment::Center);
|
||||||
|
|
||||||
workspace_row = workspace_row.push(
|
workspace_row = workspace_row.push(
|
||||||
button::suggested("F")
|
button::suggested("F")
|
||||||
.font_size(12)
|
.font_size(BAR_TEXT_SIZE)
|
||||||
.height(24)
|
.height(CONTROL_HEIGHT)
|
||||||
.padding([2, 9])
|
.padding([2, 9])
|
||||||
.on_press(cosmic::Action::App(Message::EnterOverview)),
|
.on_press(cosmic::Action::App(Message::EnterOverview)),
|
||||||
);
|
);
|
||||||
@@ -222,16 +230,21 @@ impl FereseShell {
|
|||||||
.iter()
|
.iter()
|
||||||
.filter(|workspace| workspace.output == focused_output_id)
|
.filter(|workspace| workspace.output == focused_output_id)
|
||||||
{
|
{
|
||||||
let button = if workspace.active {
|
let occupied = self
|
||||||
button::suggested(workspace.name.clone())
|
.snapshot
|
||||||
} else {
|
.windows
|
||||||
button::text(workspace.name.clone())
|
.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 = workspace_row.push(workspace_button);
|
||||||
workspace_row.push(button.font_size(12).height(24).padding([2, 8]).on_press(
|
|
||||||
cosmic::Action::App(Message::ActivateWorkspace(workspace.id)),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let app_name = self
|
let app_name = self
|
||||||
@@ -245,18 +258,14 @@ impl FereseShell {
|
|||||||
})
|
})
|
||||||
.map(display_app_name)
|
.map(display_app_name)
|
||||||
.unwrap_or_else(|| "Desktop".to_owned());
|
.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)
|
.spacing(12)
|
||||||
.align_y(cosmic::iced::Alignment::Center);
|
.align_y(cosmic::iced::Alignment::Center);
|
||||||
let center = text(&self.clock).size(13);
|
let center = text(&self.clock).size(BAR_TEXT_SIZE);
|
||||||
let output_hint = focused_output
|
|
||||||
.map(|output| output.name.as_str())
|
|
||||||
.unwrap_or("No display");
|
|
||||||
let right = row![
|
let right = row![
|
||||||
text("◌").size(16),
|
text("◌").size(BAR_ICON_SIZE),
|
||||||
text("♪").size(15),
|
text("♪").size(BAR_ICON_SIZE),
|
||||||
text(output_hint).size(11),
|
text("●").size(BAR_ICON_SIZE),
|
||||||
text("●").size(10),
|
|
||||||
]
|
]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.align_y(cosmic::iced::Alignment::Center);
|
.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 {
|
fn display_app_name(window: &control::WindowSnapshot) -> String {
|
||||||
let identity = window
|
let identity = window
|
||||||
.app_id
|
.app_id
|
||||||
|
|||||||
Reference in new issue
Block a user