Store cctk::workspace::Workspace in struct Workspace
Instead of adding more fields to this struct that need to be copied from the cctk type, just wrap it. Can add methods where that's convenient.
This commit is contained in:
parent
bcb68ab054
commit
62fbd056bf
2 changed files with 31 additions and 27 deletions
40
src/main.rs
40
src/main.rs
|
|
@ -115,12 +115,22 @@ enum Msg {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Workspace {
|
struct Workspace {
|
||||||
name: String,
|
info: cctk::workspace::Workspace,
|
||||||
// img_for_output: HashMap<wl_output::WlOutput, backend::CaptureImage>,
|
// img_for_output: HashMap<wl_output::WlOutput, backend::CaptureImage>,
|
||||||
img: Option<backend::CaptureImage>,
|
img: Option<backend::CaptureImage>,
|
||||||
handle: ExtWorkspaceHandleV1,
|
|
||||||
outputs: HashSet<wl_output::WlOutput>,
|
outputs: HashSet<wl_output::WlOutput>,
|
||||||
is_active: bool,
|
}
|
||||||
|
|
||||||
|
impl Workspace {
|
||||||
|
fn handle(&self) -> &ExtWorkspaceHandleV1 {
|
||||||
|
&self.info.handle
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_active(&self) -> bool {
|
||||||
|
self.info
|
||||||
|
.state
|
||||||
|
.contains(ext_workspace_handle_v1::State::Active)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -171,14 +181,14 @@ struct App {
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn workspace_for_handle(&self, handle: &ExtWorkspaceHandleV1) -> Option<&Workspace> {
|
fn workspace_for_handle(&self, handle: &ExtWorkspaceHandleV1) -> Option<&Workspace> {
|
||||||
self.workspaces.iter().find(|i| &i.handle == handle)
|
self.workspaces.iter().find(|i| i.handle() == handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspace_for_handle_mut(
|
fn workspace_for_handle_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: &ExtWorkspaceHandleV1,
|
handle: &ExtWorkspaceHandleV1,
|
||||||
) -> Option<&mut Workspace> {
|
) -> Option<&mut Workspace> {
|
||||||
self.workspaces.iter_mut().find(|i| &i.handle == handle)
|
self.workspaces.iter_mut().find(|i| i.handle() == handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO iterate in order based on `coordinates`
|
// TODO iterate in order based on `coordinates`
|
||||||
|
|
@ -284,8 +294,8 @@ impl App {
|
||||||
capture_filter.toplevels_on_workspaces = self
|
capture_filter.toplevels_on_workspaces = self
|
||||||
.workspaces
|
.workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.is_active)
|
.filter(|x| x.is_active())
|
||||||
.map(|x| x.handle.clone())
|
.map(|x| x.handle().clone())
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
self.send_wayland_cmd(backend::Cmd::CaptureFilter(capture_filter));
|
self.send_wayland_cmd(backend::Cmd::CaptureFilter(capture_filter));
|
||||||
|
|
@ -382,24 +392,18 @@ impl Application for App {
|
||||||
let old_workspaces = mem::take(&mut self.workspaces);
|
let old_workspaces = mem::take(&mut self.workspaces);
|
||||||
self.workspaces = Vec::new();
|
self.workspaces = Vec::new();
|
||||||
for (outputs, workspace) in workspaces {
|
for (outputs, workspace) in workspaces {
|
||||||
let is_active = workspace
|
|
||||||
.state
|
|
||||||
.contains(ext_workspace_handle_v1::State::Active);
|
|
||||||
|
|
||||||
// XXX efficiency
|
// XXX efficiency
|
||||||
#[allow(clippy::mutable_key_type)]
|
#[allow(clippy::mutable_key_type)]
|
||||||
let img = old_workspaces
|
let img = old_workspaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|i| i.handle == workspace.handle)
|
.find(|i| *i.handle() == workspace.handle)
|
||||||
.map(|i| i.img.clone())
|
.map(|i| i.img.clone())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
self.workspaces.push(Workspace {
|
self.workspaces.push(Workspace {
|
||||||
name: workspace.name,
|
info: workspace,
|
||||||
handle: workspace.handle,
|
|
||||||
outputs,
|
outputs,
|
||||||
img,
|
img,
|
||||||
is_active,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.update_capture_filter();
|
self.update_capture_filter();
|
||||||
|
|
@ -466,7 +470,7 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
Msg::ActivateWorkspace(workspace_handle) => {
|
Msg::ActivateWorkspace(workspace_handle) => {
|
||||||
if let Some(workspace) = self.workspace_for_handle(&workspace_handle) {
|
if let Some(workspace) = self.workspace_for_handle(&workspace_handle) {
|
||||||
if workspace.is_active {
|
if workspace.is_active() {
|
||||||
return self.hide();
|
return self.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -601,7 +605,7 @@ impl Application for App {
|
||||||
|
|
||||||
// TODO assumes only one active workspace per output
|
// TODO assumes only one active workspace per output
|
||||||
let workspaces = self.workspaces_for_output(&output).collect::<Vec<_>>();
|
let workspaces = self.workspaces_for_output(&output).collect::<Vec<_>>();
|
||||||
if let Some(workspace_idx) = workspaces.iter().position(|i| i.is_active) {
|
if let Some(workspace_idx) = workspaces.iter().position(|i| i.is_active()) {
|
||||||
let workspace = match direction {
|
let workspace = match direction {
|
||||||
// Next workspace on output
|
// Next workspace on output
|
||||||
ScrollDirection::Next => workspaces[workspace_idx + 1..].iter().next(),
|
ScrollDirection::Next => workspaces[workspace_idx + 1..].iter().next(),
|
||||||
|
|
@ -610,7 +614,7 @@ impl Application for App {
|
||||||
};
|
};
|
||||||
if let Some(workspace) = workspace {
|
if let Some(workspace) = workspace {
|
||||||
self.send_wayland_cmd(backend::Cmd::ActivateWorkspace(
|
self.send_wayland_cmd(backend::Cmd::ActivateWorkspace(
|
||||||
workspace.handle.clone(),
|
workspace.handle().clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ pub(crate) fn layer_surface<'a>(
|
||||||
|
|
||||||
i.info.workspace.iter().any(|workspace| {
|
i.info.workspace.iter().any(|workspace| {
|
||||||
app.workspace_for_handle(workspace)
|
app.workspace_for_handle(workspace)
|
||||||
.map_or(false, |x| x.is_active)
|
.map_or(false, |x| x.is_active())
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
layout,
|
layout,
|
||||||
|
|
@ -83,10 +83,10 @@ pub(crate) fn layer_surface<'a>(
|
||||||
// TODO multiple active workspaces? Not currently supported by cosmic.
|
// TODO multiple active workspaces? Not currently supported by cosmic.
|
||||||
let first_active_workspace = app
|
let first_active_workspace = app
|
||||||
.workspaces_for_output(&surface.output)
|
.workspaces_for_output(&surface.output)
|
||||||
.find(|w| w.is_active);
|
.find(|w| w.is_active());
|
||||||
let toplevels = if let Some(workspace) = first_active_workspace {
|
let toplevels = if let Some(workspace) = first_active_workspace {
|
||||||
dnd_destination_for_target(
|
dnd_destination_for_target(
|
||||||
DropTarget::OutputToplevels(workspace.handle.clone(), surface.output.clone()),
|
DropTarget::OutputToplevels(workspace.handle().clone(), surface.output.clone()),
|
||||||
toplevels,
|
toplevels,
|
||||||
Msg::DndToplevelDrop,
|
Msg::DndToplevelDrop,
|
||||||
)
|
)
|
||||||
|
|
@ -189,7 +189,7 @@ fn workspace_item<'a>(
|
||||||
|
|
||||||
let workspace_name = widget::text::body(fl!(
|
let workspace_name = widget::text::body(fl!(
|
||||||
"workspace",
|
"workspace",
|
||||||
HashMap::from([("number", &workspace.name)])
|
HashMap::from([("number", &workspace.info.name)])
|
||||||
));
|
));
|
||||||
|
|
||||||
// Needed to prevent text getting pushed out when scaling on Vertical layout
|
// Needed to prevent text getting pushed out when scaling on Vertical layout
|
||||||
|
|
@ -205,10 +205,10 @@ fn workspace_item<'a>(
|
||||||
.max_height(image_height + 21.0 + 4.0), // text height + spacing
|
.max_height(image_height + 21.0 + 4.0), // text height + spacing
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_active = workspace.is_active;
|
let is_active = workspace.is_active();
|
||||||
// TODO editable name?
|
// TODO editable name?
|
||||||
widget::button::custom(content)
|
widget::button::custom(content)
|
||||||
.selected(workspace.is_active)
|
.selected(workspace.is_active())
|
||||||
.class(cosmic::theme::Button::Custom {
|
.class(cosmic::theme::Button::Custom {
|
||||||
active: Box::new(move |_focused, theme| {
|
active: Box::new(move |_focused, theme| {
|
||||||
workspace_item_appearance(theme, is_active, is_drop_target)
|
workspace_item_appearance(theme, is_active, is_drop_target)
|
||||||
|
|
@ -221,7 +221,7 @@ fn workspace_item<'a>(
|
||||||
workspace_item_appearance(theme, is_active, true)
|
workspace_item_appearance(theme, is_active, true)
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.on_press(Msg::ActivateWorkspace(workspace.handle.clone()))
|
.on_press(Msg::ActivateWorkspace(workspace.handle().clone()))
|
||||||
.padding(8)
|
.padding(8)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
@ -263,7 +263,7 @@ fn workspace_sidebar_entry<'a>(
|
||||||
//crate::widgets::mouse_interaction_wrapper(
|
//crate::widgets::mouse_interaction_wrapper(
|
||||||
// mouse_interaction,
|
// mouse_interaction,
|
||||||
dnd_destination_for_target(
|
dnd_destination_for_target(
|
||||||
DropTarget::WorkspaceSidebarEntry(workspace.handle.clone(), output.clone()),
|
DropTarget::WorkspaceSidebarEntry(workspace.handle().clone(), output.clone()),
|
||||||
item,
|
item,
|
||||||
Msg::DndToplevelDrop,
|
Msg::DndToplevelDrop,
|
||||||
)
|
)
|
||||||
|
|
@ -276,7 +276,7 @@ fn workspaces_sidebar<'a>(
|
||||||
drop_target: Option<&backend::ExtWorkspaceHandleV1>,
|
drop_target: Option<&backend::ExtWorkspaceHandleV1>,
|
||||||
) -> cosmic::Element<'a, Msg> {
|
) -> cosmic::Element<'a, Msg> {
|
||||||
let sidebar_entries = workspaces
|
let sidebar_entries = workspaces
|
||||||
.map(|w| workspace_sidebar_entry(w, output, layout, drop_target == Some(&w.handle)))
|
.map(|w| workspace_sidebar_entry(w, output, layout, drop_target == Some(w.handle())))
|
||||||
.collect();
|
.collect();
|
||||||
let (axis, width, height) = match layout {
|
let (axis, width, height) = match layout {
|
||||||
WorkspaceLayout::Vertical => (Axis::Vertical, Length::Shrink, Length::Fill),
|
WorkspaceLayout::Vertical => (Axis::Vertical, Length::Shrink, Length::Fill),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue