Move drag-and-drop related types to a dnd module
This commit is contained in:
parent
efdfaed6c8
commit
3dc82789f5
3 changed files with 102 additions and 92 deletions
93
src/dnd.rs
Normal file
93
src/dnd.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
//! Types related to drag-and-drop
|
||||
|
||||
use cosmic::{
|
||||
cctk::{
|
||||
cosmic_protocols::workspace::v1::client::zcosmic_workspace_handle_v1,
|
||||
wayland_client::{protocol::wl_output, Proxy},
|
||||
},
|
||||
iced::clipboard::mime::AsMimeTypes,
|
||||
};
|
||||
use std::{borrow::Cow, sync::LazyLock};
|
||||
|
||||
use crate::backend::{ZcosmicToplevelHandleV1, ZcosmicWorkspaceHandleV1};
|
||||
|
||||
// Include `pid` in mime. Want to drag between our surfaces, but not another
|
||||
// process, if we use Wayland object ids.
|
||||
#[allow(dead_code)]
|
||||
static WORKSPACE_MIME: LazyLock<String> =
|
||||
LazyLock::new(|| format!("text/x.cosmic-workspace-id-{}", std::process::id()));
|
||||
|
||||
static TOPLEVEL_MIME: LazyLock<String> =
|
||||
LazyLock::new(|| format!("text/x.cosmic-toplevel-id-{}", std::process::id()));
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum DragSurface {
|
||||
#[allow(dead_code)]
|
||||
Workspace {
|
||||
handle: ZcosmicWorkspaceHandleV1,
|
||||
output: wl_output::WlOutput,
|
||||
},
|
||||
Toplevel {
|
||||
handle: ZcosmicToplevelHandleV1,
|
||||
output: wl_output::WlOutput,
|
||||
},
|
||||
}
|
||||
|
||||
// TODO store protocol object id?
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DragToplevel {}
|
||||
|
||||
impl AsMimeTypes for DragToplevel {
|
||||
fn available(&self) -> Cow<'static, [String]> {
|
||||
vec![TOPLEVEL_MIME.clone()].into()
|
||||
}
|
||||
|
||||
fn as_bytes(&self, mime_type: &str) -> Option<Cow<'static, [u8]>> {
|
||||
if mime_type == *TOPLEVEL_MIME {
|
||||
Some(Vec::new().into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl cosmic::iced::clipboard::mime::AllowedMimeTypes for DragToplevel {
|
||||
fn allowed() -> Cow<'static, [String]> {
|
||||
vec![TOPLEVEL_MIME.clone()].into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(Vec<u8>, std::string::String)> for DragToplevel {
|
||||
type Error = ();
|
||||
fn try_from((_bytes, mime_type): (Vec<u8>, String)) -> Result<Self, ()> {
|
||||
if mime_type == *TOPLEVEL_MIME {
|
||||
Ok(Self {})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum DropTarget {
|
||||
WorkspaceSidebarEntry(
|
||||
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||
wl_output::WlOutput,
|
||||
),
|
||||
}
|
||||
|
||||
impl DropTarget {
|
||||
/// Encode as a u64 for iced/smithay_sctk to associate drag destination area with widget.
|
||||
pub fn drag_id(&self) -> u64 {
|
||||
// https://doc.rust-lang.org/std/mem/fn.discriminant.html#accessing-the-numeric-value-of-the-discriminant
|
||||
let discriminant = unsafe { *<*const _>::from(self).cast::<u8>() };
|
||||
match self {
|
||||
Self::WorkspaceSidebarEntry(workspace, _output) => {
|
||||
// TODO consider workspace that span multiple outputs?
|
||||
let id = workspace.id().protocol_id();
|
||||
(u64::from(discriminant) << 32) | u64::from(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/main.rs
86
src/main.rs
|
|
@ -14,7 +14,6 @@ use cosmic::{
|
|||
cctk,
|
||||
iced::{
|
||||
self,
|
||||
clipboard::mime::AsMimeTypes,
|
||||
event::wayland::{Event as WaylandEvent, LayerEvent, OutputEvent},
|
||||
keyboard::key::{Key, Named},
|
||||
Size, Subscription, Task,
|
||||
|
|
@ -31,12 +30,10 @@ use cosmic_comp_config::CosmicCompConfig;
|
|||
use cosmic_config::{cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry};
|
||||
use i18n_embed::DesktopLanguageRequester;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{HashMap, HashSet},
|
||||
mem,
|
||||
path::PathBuf,
|
||||
str,
|
||||
sync::LazyLock,
|
||||
};
|
||||
|
||||
mod desktop_info;
|
||||
|
|
@ -45,8 +42,10 @@ mod localize;
|
|||
mod backend;
|
||||
mod view;
|
||||
use backend::{ToplevelInfo, ZcosmicToplevelHandleV1, ZcosmicWorkspaceHandleV1};
|
||||
mod dnd;
|
||||
mod utils;
|
||||
mod widgets;
|
||||
use dnd::{DragSurface, DragToplevel, DropTarget};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, CosmicConfigEntry)]
|
||||
struct CosmicWorkspacesConfig {
|
||||
|
|
@ -54,15 +53,6 @@ struct CosmicWorkspacesConfig {
|
|||
show_workspace_name: bool,
|
||||
}
|
||||
|
||||
// Include `pid` in mime. Want to drag between our surfaces, but not another
|
||||
// process, if we use Wayland object ids.
|
||||
#[allow(dead_code)]
|
||||
static WORKSPACE_MIME: LazyLock<String> =
|
||||
LazyLock::new(|| format!("text/x.cosmic-workspace-id-{}", std::process::id()));
|
||||
|
||||
static TOPLEVEL_MIME: LazyLock<String> =
|
||||
LazyLock::new(|| format!("text/x.cosmic-toplevel-id-{}", std::process::id()));
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[command(propagate_version = true)]
|
||||
|
|
@ -87,65 +77,6 @@ impl CosmicFlags for Args {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO store protocol object id?
|
||||
#[derive(Clone, Debug)]
|
||||
struct DragToplevel {}
|
||||
|
||||
impl AsMimeTypes for DragToplevel {
|
||||
fn available(&self) -> Cow<'static, [String]> {
|
||||
vec![TOPLEVEL_MIME.clone()].into()
|
||||
}
|
||||
|
||||
fn as_bytes(&self, mime_type: &str) -> Option<Cow<'static, [u8]>> {
|
||||
if mime_type == *TOPLEVEL_MIME {
|
||||
Some(Vec::new().into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl cosmic::iced::clipboard::mime::AllowedMimeTypes for DragToplevel {
|
||||
fn allowed() -> Cow<'static, [String]> {
|
||||
vec![crate::TOPLEVEL_MIME.clone()].into()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(Vec<u8>, std::string::String)> for DragToplevel {
|
||||
type Error = ();
|
||||
fn try_from((_bytes, mime_type): (Vec<u8>, String)) -> Result<Self, ()> {
|
||||
if mime_type == *TOPLEVEL_MIME {
|
||||
Ok(Self {})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum DropTarget {
|
||||
WorkspaceSidebarEntry(
|
||||
zcosmic_workspace_handle_v1::ZcosmicWorkspaceHandleV1,
|
||||
wl_output::WlOutput,
|
||||
),
|
||||
}
|
||||
|
||||
impl DropTarget {
|
||||
/// Encode as a u64 for iced/smithay_sctk to associate drag destination area with widget.
|
||||
fn drag_id(&self) -> u64 {
|
||||
// https://doc.rust-lang.org/std/mem/fn.discriminant.html#accessing-the-numeric-value-of-the-discriminant
|
||||
let discriminant = unsafe { *<*const _>::from(self).cast::<u8>() };
|
||||
match self {
|
||||
Self::WorkspaceSidebarEntry(workspace, _output) => {
|
||||
// TODO consider workspace that span multiple outputs?
|
||||
let id = workspace.id().protocol_id();
|
||||
(u64::from(discriminant) << 32) | u64::from(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Msg {
|
||||
WaylandEvent(WaylandEvent),
|
||||
|
|
@ -202,19 +133,6 @@ struct LayerSurface {
|
|||
// them all the time every frame.
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum DragSurface {
|
||||
#[allow(dead_code)]
|
||||
Workspace {
|
||||
handle: ZcosmicWorkspaceHandleV1,
|
||||
output: wl_output::WlOutput,
|
||||
},
|
||||
Toplevel {
|
||||
handle: ZcosmicToplevelHandleV1,
|
||||
output: wl_output::WlOutput,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Conf {
|
||||
workspace_config: cosmic_comp_config::workspace::WorkspaceConfig,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use cctk::{
|
||||
cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||
wayland_client::protocol::wl_output,
|
||||
};
|
||||
use cosmic::{
|
||||
cctk,
|
||||
cctk::{
|
||||
cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1,
|
||||
wayland_client::protocol::wl_output,
|
||||
},
|
||||
iced::{
|
||||
self,
|
||||
advanced::layout::flex::Axis,
|
||||
|
|
@ -18,10 +15,12 @@ use cosmic::{
|
|||
};
|
||||
use cosmic_bg_config::Source;
|
||||
use cosmic_comp_config::workspace::WorkspaceLayout;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
backend::{self, CaptureImage},
|
||||
App, DragSurface, DragToplevel, DropTarget, LayerSurface, Msg, Toplevel, Workspace,
|
||||
dnd::{DragSurface, DragToplevel, DropTarget},
|
||||
App, LayerSurface, Msg, Toplevel, Workspace,
|
||||
};
|
||||
|
||||
fn toplevel_dnd_destination<'a>(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue