Allow dropping window onto toplevel list area

Fixes https://github.com/pop-os/cosmic-workspaces-epoch/issues/53.
This commit is contained in:
Ian Douglas Scott 2025-01-24 14:54:29 -08:00
parent 6838bd60be
commit 88b35e3027
3 changed files with 31 additions and 8 deletions

View file

@ -63,6 +63,7 @@ impl TryFrom<(Vec<u8>, std::string::String)> for DragToplevel {
#[repr(u8)] #[repr(u8)]
pub enum DropTarget { pub enum DropTarget {
WorkspaceSidebarEntry(ZcosmicWorkspaceHandleV1, wl_output::WlOutput), WorkspaceSidebarEntry(ZcosmicWorkspaceHandleV1, wl_output::WlOutput),
OutputToplevels(ZcosmicWorkspaceHandleV1, wl_output::WlOutput),
} }
impl DropTarget { impl DropTarget {
@ -76,6 +77,10 @@ impl DropTarget {
let id = workspace.id().protocol_id(); let id = workspace.id().protocol_id();
(u64::from(discriminant) << 32) | u64::from(id) (u64::from(discriminant) << 32) | u64::from(id)
} }
Self::OutputToplevels(_workspace, output) => {
let id = output.id().protocol_id();
(u64::from(discriminant) << 32) | u64::from(id)
}
} }
} }
} }

View file

@ -484,14 +484,18 @@ impl Application for App {
} }
Msg::DndWorkspaceDrop(_toplevel) => { Msg::DndWorkspaceDrop(_toplevel) => {
if let Some((DragSurface::Toplevel(handle), _)) = &self.drag_surface { if let Some((DragSurface::Toplevel(handle), _)) = &self.drag_surface {
if let Some(DropTarget::WorkspaceSidebarEntry(workspace, output)) = match self.drop_target.take() {
self.drop_target.take() Some(
{ DropTarget::WorkspaceSidebarEntry(workspace, output)
self.send_wayland_cmd(backend::Cmd::MoveToplevelToWorkspace( | DropTarget::OutputToplevels(workspace, output),
handle.clone(), ) => {
workspace, self.send_wayland_cmd(backend::Cmd::MoveToplevelToWorkspace(
output, handle.clone(),
)); workspace,
output,
));
}
None => {}
} }
} }
} }

View file

@ -78,6 +78,20 @@ pub(crate) fn layer_surface<'a>(
layout, layout,
drag_toplevel, drag_toplevel,
); );
// TODO multiple active workspaces? Not currently supported by cosmic.
let first_active_workspace = app
.workspaces
.iter()
.find(|i| i.outputs.contains(&surface.output) && i.is_active);
let toplevels = if let Some(workspace) = first_active_workspace {
toplevel_dnd_destination(
DropTarget::OutputToplevels(workspace.handle.clone(), surface.output.clone()),
toplevels,
)
} else {
// Shouldn't happen, but no drag destination if no active workspace found for output
cosmic::Element::from(toplevels)
};
let container = match layout { let container = match layout {
WorkspaceLayout::Vertical => widget::layer_container( WorkspaceLayout::Vertical => widget::layer_container(
row![sidebar, toplevels] row![sidebar, toplevels]