UI code for supporting workspace drags
Not used yet.
This commit is contained in:
parent
9b12e76765
commit
ca5db9cc8e
3 changed files with 88 additions and 18 deletions
41
src/dnd.rs
41
src/dnd.rs
|
|
@ -10,7 +10,6 @@ use crate::backend::{ZcosmicToplevelHandleV1, ZcosmicWorkspaceHandleV1};
|
||||||
|
|
||||||
// Include `pid` in mime. Want to drag between our surfaces, but not another
|
// Include `pid` in mime. Want to drag between our surfaces, but not another
|
||||||
// process, if we use Wayland object ids.
|
// process, if we use Wayland object ids.
|
||||||
#[allow(dead_code)]
|
|
||||||
static WORKSPACE_MIME: LazyLock<String> =
|
static WORKSPACE_MIME: LazyLock<String> =
|
||||||
LazyLock::new(|| format!("text/x.cosmic-workspace-id-{}", std::process::id()));
|
LazyLock::new(|| format!("text/x.cosmic-workspace-id-{}", std::process::id()));
|
||||||
|
|
||||||
|
|
@ -59,11 +58,47 @@ impl TryFrom<(Vec<u8>, std::string::String)> for DragToplevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DragWorkspace {}
|
||||||
|
|
||||||
|
impl AsMimeTypes for DragWorkspace {
|
||||||
|
fn available(&self) -> Cow<'static, [String]> {
|
||||||
|
vec![WORKSPACE_MIME.clone()].into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_bytes(&self, mime_type: &str) -> Option<Cow<'static, [u8]>> {
|
||||||
|
if mime_type == *WORKSPACE_MIME {
|
||||||
|
Some(Vec::new().into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl cosmic::iced::clipboard::mime::AllowedMimeTypes for DragWorkspace {
|
||||||
|
fn allowed() -> Cow<'static, [String]> {
|
||||||
|
vec![WORKSPACE_MIME.clone()].into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<(Vec<u8>, std::string::String)> for DragWorkspace {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from((_bytes, mime_type): (Vec<u8>, String)) -> Result<Self, ()> {
|
||||||
|
if mime_type == *WORKSPACE_MIME {
|
||||||
|
Ok(Self {})
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[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),
|
OutputToplevels(ZcosmicWorkspaceHandleV1, wl_output::WlOutput),
|
||||||
|
#[allow(dead_code)]
|
||||||
|
WorkspacesBar(wl_output::WlOutput),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DropTarget {
|
impl DropTarget {
|
||||||
|
|
@ -81,6 +116,10 @@ impl DropTarget {
|
||||||
let id = output.id().protocol_id();
|
let id = output.id().protocol_id();
|
||||||
(u64::from(discriminant) << 32) | u64::from(id)
|
(u64::from(discriminant) << 32) | u64::from(id)
|
||||||
}
|
}
|
||||||
|
Self::WorkspacesBar(output) => {
|
||||||
|
let id = output.id().protocol_id();
|
||||||
|
(u64::from(discriminant) << 32) | u64::from(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
src/main.rs
12
src/main.rs
|
|
@ -47,7 +47,7 @@ use backend::{ToplevelInfo, ZcosmicToplevelHandleV1, ZcosmicWorkspaceHandleV1};
|
||||||
mod dnd;
|
mod dnd;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
use dnd::{DragSurface, DragToplevel, DropTarget};
|
use dnd::{DragSurface, DragToplevel, DragWorkspace, DropTarget};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, CosmicConfigEntry)]
|
#[derive(Clone, Debug, Default, PartialEq, CosmicConfigEntry)]
|
||||||
struct CosmicWorkspacesConfig {
|
struct CosmicWorkspacesConfig {
|
||||||
|
|
@ -98,6 +98,10 @@ enum Msg {
|
||||||
DndEnter(DropTarget, f64, f64, Vec<String>),
|
DndEnter(DropTarget, f64, f64, Vec<String>),
|
||||||
DndLeave(DropTarget),
|
DndLeave(DropTarget),
|
||||||
DndToplevelDrop(DragToplevel),
|
DndToplevelDrop(DragToplevel),
|
||||||
|
#[allow(dead_code)]
|
||||||
|
DndWorkspaceDrag,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
DndWorkspaceDrop(DragWorkspace),
|
||||||
SourceFinished,
|
SourceFinished,
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
NewWorkspace,
|
NewWorkspace,
|
||||||
|
|
@ -109,7 +113,7 @@ enum Msg {
|
||||||
Ignore,
|
Ignore,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Workspace {
|
struct Workspace {
|
||||||
name: String,
|
name: String,
|
||||||
// img_for_output: HashMap<wl_output::WlOutput, backend::CaptureImage>,
|
// img_for_output: HashMap<wl_output::WlOutput, backend::CaptureImage>,
|
||||||
|
|
@ -515,7 +519,7 @@ impl Application for App {
|
||||||
output,
|
output,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
None => {}
|
Some(DropTarget::WorkspacesBar(_)) | None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -608,6 +612,8 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Msg::DndWorkspaceDrag => {}
|
||||||
|
Msg::DndWorkspaceDrop(_workspace) => {}
|
||||||
Msg::Ignore => {}
|
Msg::Ignore => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{self, CaptureImage},
|
backend::{self, CaptureImage},
|
||||||
dnd::{DragSurface, DragToplevel, DropTarget},
|
dnd::{DragSurface, DragToplevel, DragWorkspace, DropTarget},
|
||||||
App, LayerSurface, Msg, Toplevel, Workspace,
|
App, LayerSurface, Msg, Toplevel, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -41,6 +41,25 @@ fn toplevel_dnd_destination<'a>(
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn workspace_dnd_destination<'a>(
|
||||||
|
target: DropTarget,
|
||||||
|
child: cosmic::Element<'a, Msg>,
|
||||||
|
) -> cosmic::Element<'a, Msg> {
|
||||||
|
let target2 = target.clone();
|
||||||
|
cosmic::widget::dnd_destination::dnd_destination_for_data(
|
||||||
|
child,
|
||||||
|
|data: Option<DragWorkspace>, _action| match data {
|
||||||
|
Some(workspace) => Msg::DndWorkspaceDrop(workspace),
|
||||||
|
None => Msg::Ignore,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.drag_id(target.drag_id())
|
||||||
|
.on_enter(move |actions, mime, pos| Msg::DndEnter(target.clone(), actions, mime, pos))
|
||||||
|
.on_leave(move || Msg::DndLeave(target2.clone()))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn layer_surface<'a>(
|
pub(crate) fn layer_surface<'a>(
|
||||||
app: &'a App,
|
app: &'a App,
|
||||||
surface: &'a LayerSurface,
|
surface: &'a LayerSurface,
|
||||||
|
|
@ -142,7 +161,7 @@ fn workspace_item<'a>(
|
||||||
workspace: &'a Workspace,
|
workspace: &'a Workspace,
|
||||||
_output: &wl_output::WlOutput,
|
_output: &wl_output::WlOutput,
|
||||||
is_drop_target: bool,
|
is_drop_target: bool,
|
||||||
) -> cosmic::Element<'a, Msg> {
|
) -> cosmic::Element<'static, Msg> {
|
||||||
let image = capture_image(workspace.img.as_ref(), 1.0);
|
let image = capture_image(workspace.img.as_ref(), 1.0);
|
||||||
let is_active = workspace.is_active;
|
let is_active = workspace.is_active;
|
||||||
// TODO editable name?
|
// TODO editable name?
|
||||||
|
|
@ -184,26 +203,32 @@ fn workspace_sidebar_entry<'a>(
|
||||||
iced::mouse::Interaction::Idle
|
iced::mouse::Interaction::Idle
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
let item = workspace_item(workspace, output, is_drop_target);
|
||||||
/* TODO allow moving workspaces (needs compositor support)
|
/* TODO allow moving workspaces (needs compositor support)
|
||||||
iced::widget::dnd_source(workspace_item(workspace, output))
|
let workspace_clone = workspace.clone(); // TODO avoid clone
|
||||||
.on_drag(|size| {
|
let output_clone = output.clone();
|
||||||
Msg::StartDrag(
|
let source = cosmic::widget::dnd_source(item)
|
||||||
size,
|
.drag_threshold(5.)
|
||||||
DragSurface::Workspace {
|
.drag_content(|| DragWorkspace {})
|
||||||
handle: workspace.handle.clone(),
|
.drag_icon(move |offset| {
|
||||||
output: output.clone(),
|
(
|
||||||
},
|
workspace_item(&workspace_clone, &output_clone, false).map(|_| ()),
|
||||||
|
cosmic::iced_core::widget::tree::State::None,
|
||||||
|
-offset,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.on_finished(Msg::SourceFinished)
|
.on_start(Some(Msg::StartDrag(DragSurface::Workspace(
|
||||||
.on_cancelled(Msg::SourceFinished)
|
workspace.handle.clone(),
|
||||||
.into()
|
))))
|
||||||
|
.on_finish(Some(Msg::SourceFinished))
|
||||||
|
.on_cancel(Some(Msg::SourceFinished))
|
||||||
|
.into();
|
||||||
*/
|
*/
|
||||||
//crate::widgets::mouse_interaction_wrapper(
|
//crate::widgets::mouse_interaction_wrapper(
|
||||||
// mouse_interaction,
|
// mouse_interaction,
|
||||||
toplevel_dnd_destination(
|
toplevel_dnd_destination(
|
||||||
DropTarget::WorkspaceSidebarEntry(workspace.handle.clone(), output.clone()),
|
DropTarget::WorkspaceSidebarEntry(workspace.handle.clone(), output.clone()),
|
||||||
workspace_item(workspace, output, is_drop_target),
|
item,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue