Initial support for horizontal workspaces

This commit is contained in:
Ian Douglas Scott 2023-11-17 14:56:37 -08:00
parent 94561b9ed1
commit fccc5f26e5
4 changed files with 121 additions and 30 deletions

View file

@ -35,6 +35,7 @@ use cosmic::{
settings::InitialSurface,
},
};
use cosmic_config::ConfigGet;
use std::{
collections::{HashMap, HashSet},
mem,
@ -117,6 +118,25 @@ enum DragSurface {
},
}
struct Conf {
_cosmic_comp_config: cosmic_config::Config,
workspace_config: cosmic_comp_config::workspace::WorkspaceConfig,
}
impl Default for Conf {
fn default() -> Self {
let cosmic_comp_config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap();
let workspace_config = cosmic_comp_config.get("workspaces").unwrap_or_else(|err| {
eprintln!("Failed to read config 'worspaces': {}", err);
cosmic_comp_config::workspace::WorkspaceConfig::default()
});
Self {
_cosmic_comp_config: cosmic_comp_config,
workspace_config,
}
}
}
#[derive(Default)]
struct App {
max_surface_id: u128,
@ -131,6 +151,7 @@ struct App {
visible: bool,
wayland_cmd_sender: Option<calloop::channel::Sender<wayland::Cmd>>,
drag_surface: Option<(SurfaceId, DragSurface, Size)>,
conf: Conf,
}
impl App {

View file

@ -6,6 +6,7 @@ use cosmic::{
},
widget,
};
use cosmic_comp_config::workspace::WorkspaceLayout;
use crate::{wayland::CaptureImage, App, DragSurface, LayerSurface, Msg, Toplevel, Workspace};
@ -13,28 +14,36 @@ pub(crate) fn layer_surface<'a>(
app: &'a App,
surface: &'a LayerSurface,
) -> cosmic::Element<'a, Msg> {
row![
workspaces_sidebar(
app.workspaces
.iter()
.filter(|i| i.outputs.contains(&surface.output)),
&surface.output
),
toplevel_previews(app.toplevels.iter().filter(|i| {
if !i.info.output.contains(&surface.output) {
return false;
}
let layout = app.conf.workspace_config.workspace_layout;
let sidebar = workspaces_sidebar(
app.workspaces
.iter()
.filter(|i| i.outputs.contains(&surface.output)),
&surface.output,
layout,
);
let toplevels = toplevel_previews(app.toplevels.iter().filter(|i| {
if !i.info.output.contains(&surface.output) {
return false;
}
i.info.workspace.iter().any(|workspace| {
app.workspace_for_handle(workspace)
.map_or(false, |x| x.is_active)
})
}))
]
.spacing(12)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.into()
i.info.workspace.iter().any(|workspace| {
app.workspace_for_handle(workspace)
.map_or(false, |x| x.is_active)
})
}));
match layout {
WorkspaceLayout::Vertical => row![sidebar, toplevels]
.spacing(12)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.into(),
WorkspaceLayout::Horizontal => column![sidebar, toplevels]
.spacing(12)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.into(),
}
}
fn close_button(on_press: Msg) -> cosmic::Element<'static, Msg> {
@ -89,17 +98,21 @@ fn workspace_sidebar_entry<'a>(
fn workspaces_sidebar<'a>(
workspaces: impl Iterator<Item = &'a Workspace>,
output: &'a wl_output::WlOutput,
layout: WorkspaceLayout,
) -> cosmic::Element<'a, Msg> {
let sidebar_entries = workspaces
.map(|w| workspace_sidebar_entry(w, output))
.collect();
let sidebar_entries_container: cosmic::Element<'_, _> = match layout {
WorkspaceLayout::Vertical => column(sidebar_entries).into(),
WorkspaceLayout::Horizontal => row(sidebar_entries).into(),
};
widget::container(
iced::widget::dnd_listener(column(
workspaces
.map(|w| workspace_sidebar_entry(w, output))
.collect(),
))
.on_enter(Msg::DndWorkspaceEnter)
.on_exit(Msg::DndWorkspaceLeave)
.on_drop(Msg::DndWorkspaceDrop)
.on_data(Msg::DndWorkspaceData),
iced::widget::dnd_listener(sidebar_entries_container)
.on_enter(Msg::DndWorkspaceEnter)
.on_exit(Msg::DndWorkspaceLeave)
.on_drop(Msg::DndWorkspaceDrop)
.on_data(Msg::DndWorkspaceData),
)
.width(iced::Length::Fill)
.height(iced::Length::Fill)