Drag toplevel to workspace; recognize what toplevel was dragged
This commit is contained in:
parent
e5aca0a6b5
commit
f2c77d035c
2 changed files with 55 additions and 74 deletions
105
src/main.rs
105
src/main.rs
|
|
@ -41,6 +41,7 @@ use once_cell::sync::Lazy;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
mem,
|
mem,
|
||||||
|
str::{self, FromStr},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod view;
|
mod view;
|
||||||
|
|
@ -92,18 +93,6 @@ impl DataFromMimeType for WlDndId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorkspaceDndId(String);
|
|
||||||
|
|
||||||
impl DataFromMimeType for WorkspaceDndId {
|
|
||||||
fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> {
|
|
||||||
if mime_type == *WORKSPACE_MIME {
|
|
||||||
Some(self.0.as_bytes().to_vec())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum Msg {
|
enum Msg {
|
||||||
WaylandEvent(WaylandEvent),
|
WaylandEvent(WaylandEvent),
|
||||||
|
|
@ -115,7 +104,6 @@ enum Msg {
|
||||||
ActivateToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
ActivateToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
||||||
CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1),
|
||||||
StartDrag(Size, DragSurface),
|
StartDrag(Size, DragSurface),
|
||||||
SourceFinished,
|
|
||||||
DndWorkspaceEnter(DndAction, Vec<String>, (f32, f32)),
|
DndWorkspaceEnter(DndAction, Vec<String>, (f32, f32)),
|
||||||
DndWorkspaceLeave,
|
DndWorkspaceLeave,
|
||||||
DndWorkspaceDrop,
|
DndWorkspaceDrop,
|
||||||
|
|
@ -154,8 +142,9 @@ struct LayerSurface {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
enum DragSurface {
|
enum DragSurface {
|
||||||
|
#[allow(dead_code)]
|
||||||
Workspace {
|
Workspace {
|
||||||
name: String,
|
handle: zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||||
output: wl_output::WlOutput,
|
output: wl_output::WlOutput,
|
||||||
},
|
},
|
||||||
Toplevel {
|
Toplevel {
|
||||||
|
|
@ -164,15 +153,6 @@ enum DragSurface {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DragSurface {
|
|
||||||
fn output(&self) -> &wl_output::WlOutput {
|
|
||||||
match self {
|
|
||||||
Self::Workspace { output, .. } => output,
|
|
||||||
Self::Toplevel { output, .. } => output,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Conf {
|
struct Conf {
|
||||||
_cosmic_comp_config: cosmic_config::Config,
|
_cosmic_comp_config: cosmic_config::Config,
|
||||||
workspace_config: cosmic_comp_config::workspace::WorkspaceConfig,
|
workspace_config: cosmic_comp_config::workspace::WorkspaceConfig,
|
||||||
|
|
@ -509,65 +489,62 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::StartDrag(size, drag_surface) => {
|
Msg::StartDrag(size, drag_surface) => {
|
||||||
let output = drag_surface.output();
|
let (wl_id, output, mime_type) = match &drag_surface {
|
||||||
|
DragSurface::Workspace { handle, output } => {
|
||||||
|
(handle.clone().id(), output, &*WORKSPACE_MIME)
|
||||||
|
}
|
||||||
|
DragSurface::Toplevel { handle, output } => {
|
||||||
|
(handle.clone().id(), output, &*TOPLEVEL_MIME)
|
||||||
|
}
|
||||||
|
};
|
||||||
let id = self.next_surface_id();
|
let id = self.next_surface_id();
|
||||||
if let Some((parent_id, _)) = self
|
if let Some((parent_id, _)) = self
|
||||||
.layer_surfaces
|
.layer_surfaces
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, x)| &x.output == output)
|
.find(|(_, x)| &x.output == output)
|
||||||
{
|
{
|
||||||
match &drag_surface {
|
self.drag_surface = Some((id, drag_surface, size));
|
||||||
DragSurface::Workspace { output, name: _ } => {
|
return start_drag(
|
||||||
self.drag_surface = Some((id, drag_surface, size));
|
vec![mime_type.to_string()],
|
||||||
return start_drag(
|
DndAction::Move,
|
||||||
vec![WORKSPACE_MIME.to_string()],
|
*parent_id,
|
||||||
DndAction::Move,
|
Some(DndIcon::Custom(id)),
|
||||||
*parent_id,
|
Box::new(WlDndId {
|
||||||
Some(DndIcon::Custom(id)),
|
id: wl_id,
|
||||||
Box::new(WorkspaceDndId(String::new())),
|
mime_type,
|
||||||
);
|
}),
|
||||||
}
|
);
|
||||||
DragSurface::Toplevel { handle, .. } => {
|
|
||||||
let handle = handle.clone();
|
|
||||||
self.drag_surface = Some((id, drag_surface, size));
|
|
||||||
return start_drag(
|
|
||||||
vec![TOPLEVEL_MIME.to_string()],
|
|
||||||
DndAction::Move,
|
|
||||||
*parent_id,
|
|
||||||
Some(DndIcon::Custom(id)),
|
|
||||||
Box::new(WlDndId {
|
|
||||||
id: handle.id(),
|
|
||||||
mime_type: &*TOPLEVEL_MIME,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::SourceFinished => {
|
|
||||||
println!("finish");
|
|
||||||
}
|
|
||||||
Msg::DndWorkspaceEnter(action, mimes, (_x, _y)) => {
|
Msg::DndWorkspaceEnter(action, mimes, (_x, _y)) => {
|
||||||
println!("Workspace enter: {:?}", (action, &mimes));
|
|
||||||
// XXX
|
// XXX
|
||||||
// if mimes.iter().any(|x| x == WORKSPACE_MIME) && action == DndAction::Move {
|
// if mimes.iter().any(|x| x == WORKSPACE_MIME) && action == DndAction::Move {
|
||||||
if mimes.iter().any(|x| x == &*WORKSPACE_MIME) {
|
if mimes.iter().any(|x| x == &*TOPLEVEL_MIME) {
|
||||||
return Command::batch(vec![
|
return Command::batch(vec![
|
||||||
set_actions(DndAction::Move, DndAction::Move),
|
set_actions(DndAction::Move, DndAction::Move),
|
||||||
accept_mime_type(Some(WORKSPACE_MIME.to_string())),
|
accept_mime_type(Some(TOPLEVEL_MIME.to_string())),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Msg::DndWorkspaceLeave => {
|
Msg::DndWorkspaceLeave => {
|
||||||
println!("Workspace leave");
|
|
||||||
return accept_mime_type(None);
|
return accept_mime_type(None);
|
||||||
}
|
}
|
||||||
Msg::DndWorkspaceDrop => {
|
Msg::DndWorkspaceDrop => {
|
||||||
println!("Workspace drop");
|
return request_dnd_data(TOPLEVEL_MIME.to_string());
|
||||||
return request_dnd_data(WORKSPACE_MIME.to_string());
|
|
||||||
}
|
}
|
||||||
Msg::DndWorkspaceData(mime, data) => {
|
Msg::DndWorkspaceData(mime_type, data) => {
|
||||||
println!("Workspace data: {:?}", (mime, &data));
|
if mime_type == *TOPLEVEL_MIME {
|
||||||
|
// XXX getting empty data?
|
||||||
|
let _protocol_id = str::from_utf8(&data)
|
||||||
|
.ok()
|
||||||
|
.and_then(|s| u32::from_str(s).ok());
|
||||||
|
if let Some((_, DragSurface::Toplevel { handle, .. }, _)) = &self.drag_surface {
|
||||||
|
if let Some(toplevel) = self.toplevels.iter().find(|t| &t.handle == handle)
|
||||||
|
{
|
||||||
|
dbg!(toplevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -618,8 +595,10 @@ impl Application for App {
|
||||||
if let Some((drag_id, drag_surface, size)) = &self.drag_surface {
|
if let Some((drag_id, drag_surface, size)) = &self.drag_surface {
|
||||||
if drag_id == &id {
|
if drag_id == &id {
|
||||||
match drag_surface {
|
match drag_surface {
|
||||||
DragSurface::Workspace { output, name } => {
|
DragSurface::Workspace { handle, output } => {
|
||||||
if let Some(workspace) = self.workspaces.iter().find(|x| &x.name == name) {
|
if let Some(workspace) =
|
||||||
|
self.workspaces.iter().find(|x| &x.handle == handle)
|
||||||
|
{
|
||||||
let item = view::workspace_item(workspace, output);
|
let item = view::workspace_item(workspace, output);
|
||||||
return widget::container(item)
|
return widget::container(item)
|
||||||
.height(iced::Length::Fixed(size.height))
|
.height(iced::Length::Fixed(size.height))
|
||||||
|
|
|
||||||
|
|
@ -85,12 +85,13 @@ fn workspace_sidebar_entry<'a>(
|
||||||
workspace: &'a Workspace,
|
workspace: &'a Workspace,
|
||||||
output: &'a wl_output::WlOutput,
|
output: &'a wl_output::WlOutput,
|
||||||
) -> cosmic::Element<'a, Msg> {
|
) -> cosmic::Element<'a, Msg> {
|
||||||
|
/* TODO allow moving workspaces (needs compositor support)
|
||||||
iced::widget::dnd_source(workspace_item(workspace, output))
|
iced::widget::dnd_source(workspace_item(workspace, output))
|
||||||
.on_drag(|size| {
|
.on_drag(|size| {
|
||||||
Msg::StartDrag(
|
Msg::StartDrag(
|
||||||
size,
|
size,
|
||||||
DragSurface::Workspace {
|
DragSurface::Workspace {
|
||||||
name: workspace.name.to_string(),
|
handle: workspace.handle.clone(),
|
||||||
output: output.clone(),
|
output: output.clone(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -98,6 +99,13 @@ fn workspace_sidebar_entry<'a>(
|
||||||
.on_finished(Msg::SourceFinished)
|
.on_finished(Msg::SourceFinished)
|
||||||
.on_cancelled(Msg::SourceFinished)
|
.on_cancelled(Msg::SourceFinished)
|
||||||
.into()
|
.into()
|
||||||
|
*/
|
||||||
|
iced::widget::dnd_listener(workspace_item(workspace, output))
|
||||||
|
.on_enter(Msg::DndWorkspaceEnter)
|
||||||
|
.on_exit(Msg::DndWorkspaceLeave)
|
||||||
|
.on_drop(Msg::DndWorkspaceDrop)
|
||||||
|
.on_data(Msg::DndWorkspaceData)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn workspaces_sidebar<'a>(
|
fn workspaces_sidebar<'a>(
|
||||||
|
|
@ -117,16 +125,10 @@ fn workspaces_sidebar<'a>(
|
||||||
WorkspaceLayout::Vertical => column(sidebar_entries).into(),
|
WorkspaceLayout::Vertical => column(sidebar_entries).into(),
|
||||||
WorkspaceLayout::Horizontal => row(sidebar_entries).into(),
|
WorkspaceLayout::Horizontal => row(sidebar_entries).into(),
|
||||||
};
|
};
|
||||||
widget::container(
|
widget::container(sidebar_entries_container)
|
||||||
iced::widget::dnd_listener(sidebar_entries_container)
|
.width(iced::Length::Fill)
|
||||||
.on_enter(Msg::DndWorkspaceEnter)
|
.height(iced::Length::Fill)
|
||||||
.on_exit(Msg::DndWorkspaceLeave)
|
.into()
|
||||||
.on_drop(Msg::DndWorkspaceDrop)
|
|
||||||
.on_data(Msg::DndWorkspaceData),
|
|
||||||
)
|
|
||||||
.width(iced::Length::Fill)
|
|
||||||
.height(iced::Length::Fill)
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn toplevel_preview(toplevel: &Toplevel) -> cosmic::Element<Msg> {
|
pub(crate) fn toplevel_preview(toplevel: &Toplevel) -> cosmic::Element<Msg> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue