From f8a3c4ba5588c70eac54d0e7087155da4a62b8ed Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 10 Jul 2023 13:55:32 -0700 Subject: [PATCH] WIP drag-and-drop --- Cargo.lock | 65 ++++++++++------------------- src/main.rs | 117 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 133 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bbcc2d..d1a70c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -586,7 +586,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -600,7 +600,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "quote", "syn 1.0.109", @@ -641,7 +641,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "anyhow", "cosmic-config", @@ -1506,7 +1506,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iced" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "iced_accessibility", "iced_core", @@ -1521,7 +1521,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "accesskit", "accesskit_unix", @@ -1530,7 +1530,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "bitflags 1.3.2", "iced_accessibility", @@ -1545,7 +1545,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "futures", "iced_core", @@ -1558,7 +1558,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1575,7 +1575,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -1587,7 +1587,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "iced_accessibility", "iced_core", @@ -1599,7 +1599,7 @@ dependencies = [ [[package]] name = "iced_sctk" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "enum-repr", "float-cmp", @@ -1621,7 +1621,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "iced_core", "once_cell", @@ -1631,7 +1631,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "bytemuck", "cosmic-text", @@ -1649,7 +1649,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1670,7 +1670,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "iced_renderer", "iced_runtime", @@ -1881,7 +1881,7 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#598bfaa6111c38633cbcd9d875ef8384108fb40d" +source = "git+https://github.com/pop-os/libcosmic#56d24b2372ed699115fee777b4811c60419e2f66" dependencies = [ "apply", "cosmic-config", @@ -2395,17 +2395,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.6", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core", ] [[package]] @@ -2422,19 +2412,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "parking_lot_core" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.3.5", - "smallvec", - "windows-targets 0.48.1", -] - [[package]] name = "phf" version = "0.11.2" @@ -3647,7 +3624,7 @@ checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ "futures", "js-sys", - "parking_lot 0.11.2", + "parking_lot", "pin-utils", "wasm-bindgen", "wasm-bindgen-futures", @@ -3856,7 +3833,7 @@ dependencies = [ "js-sys", "log", "naga", - "parking_lot 0.12.1", + "parking_lot", "profiling", "raw-window-handle", "smallvec", @@ -3881,7 +3858,7 @@ dependencies = [ "codespan-reporting", "log", "naga", - "parking_lot 0.12.1", + "parking_lot", "profiling", "raw-window-handle", "rustc-hash", @@ -3920,7 +3897,7 @@ dependencies = [ "metal", "naga", "objc", - "parking_lot 0.12.1", + "parking_lot", "profiling", "range-alloc", "raw-window-handle", diff --git a/src/main.rs b/src/main.rs index d3fbb3b..cb9a8d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use cctk::{ sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer}, toplevel_info::ToplevelInfo, wayland_client::{ - protocol::{wl_output, wl_seat}, + protocol::{wl_data_device_manager::DndAction, wl_output, wl_seat}, Connection, WEnum, }, }; @@ -18,6 +18,10 @@ use cosmic::{ self, event::wayland::{Event as WaylandEvent, OutputEvent}, keyboard::KeyCode, + wayland::{ + actions::data_device::{DataFromMimeType, DndIcon}, + data_device::start_drag, + }, widget, Application, Command, Subscription, }, iced_runtime::{ @@ -36,6 +40,20 @@ use std::{collections::HashMap, mem}; mod toggle_dbus; mod wayland; +static WORKSPACE_MIME: &str = "text/x.cosmic-workspace-id"; + +struct WorkspaceDndId(String); + +impl DataFromMimeType for WorkspaceDndId { + fn from_mime_type(&self, mime_type: &str) -> Option> { + if mime_type == WORKSPACE_MIME { + Some(self.0.as_bytes().to_vec()) + } else { + None + } + } +} + #[derive(Clone, Debug)] enum Msg { WaylandEvent(WaylandEvent), @@ -47,6 +65,8 @@ enum Msg { ActivateToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1), CloseToplevel(zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1), DBus(toggle_dbus::Event), + StartDrag(DragSurface), + SourceFinished, } #[derive(Debug)] @@ -83,6 +103,11 @@ struct LayerSurface { // them all the time every frame. } +#[derive(Clone, Debug)] +enum DragSurface { + Workspace { name: String, output_name: String }, +} + #[derive(Default)] struct App { max_surface_id: u128, @@ -96,6 +121,7 @@ struct App { seats: Vec, visible: bool, wayland_cmd_sender: Option>, + drag_surface: Option<(SurfaceId, DragSurface)>, } impl App { @@ -391,6 +417,34 @@ impl Application for App { Msg::DBus(toggle_dbus::Event::Toggle) => { return self.toggle(); } + Msg::StartDrag(drag_surface) => { + match &drag_surface { + DragSurface::Workspace { + output_name, + name: _, + } => { + let id = self.next_surface_id(); + if let Some((parent_id, _)) = self + .layer_surfaces + .iter() + .find(|(_, x)| &x.output_name == output_name) + { + println!("\n\n\nSTART DRAG"); + self.drag_surface = Some((id, drag_surface)); + return start_drag( + vec![WORKSPACE_MIME.to_string()], + DndAction::Move, + *parent_id, + Some(DndIcon::Custom(id)), // TODO store + Box::new(WorkspaceDndId(String::new())), + ); + } + } + } + } + Msg::SourceFinished => { + println!("finish"); + } } Command::none() @@ -423,7 +477,23 @@ impl Application for App { if let Some(surface) = self.layer_surfaces.get(&id) { return layer_surface(self, surface); } + if let Some((drag_id, drag_surface)) = &self.drag_surface { + if drag_id == &id { + println!("DRAG VIEW"); + match drag_surface { + DragSurface::Workspace { output_name, name } => { + if let Some(workspace) = self.workspaces.iter().find(|x| &x.name == name) { + return workspace_item2(workspace, &output_name); + } + } + } + } + } + println!("NO VIEW"); text("workspaces").into() + // + // workspace_sidebar_entry(&self.workspaces[0], "eDP-1").into() + //text("FOO BAR BAZ FOO BAR BAZ").into() } fn close_requested(&self, id: SurfaceId) -> Msg { @@ -465,10 +535,7 @@ fn close_button(on_press: Msg) -> cosmic::Element<'static, Msg> { .into() } -fn workspace_sidebar_entry<'a>( - workspace: &'a Workspace, - output_name: &'a str, -) -> cosmic::Element<'a, Msg> { +fn workspace_item<'a>(workspace: &'a Workspace, output_name: &'a str) -> cosmic::Element<'a, Msg> { // TODO style let theme = if workspace.is_active { cosmic::theme::Button::Primary @@ -498,6 +565,46 @@ fn workspace_sidebar_entry<'a>( .into() } +fn workspace_item2<'a>(workspace: &'a Workspace, output_name: &'a str) -> cosmic::Element<'a, Msg> { + println!("{:?}", workspace); + println!("{:?}", output_name); + /* + widget::column![ + widget::Image::new( + workspace + .img_for_output + .get(output_name) + .cloned() + .unwrap_or_else(|| widget::image::Handle::from_pixels( + 1, + 1, + vec![0, 0, 0, 255] + )) + ), + widget::text(&workspace.name) + ] + .into() + */ + //widget::text(&workspace.name).into() + widget::Image::new(workspace.img_for_output.get(output_name).cloned().unwrap()).into() + //widget::text(&format!("WORKSPACE: {}", workspace.name)).into() + //widget::text("ABC").into() +} + +fn workspace_sidebar_entry<'a>( + workspace: &'a Workspace, + output_name: &'a str, +) -> cosmic::Element<'a, Msg> { + widget::dnd_source(workspace_item(workspace, output_name)) + .on_drag(Msg::StartDrag(DragSurface::Workspace { + name: workspace.name.to_string(), + output_name: output_name.to_string(), + })) + .on_finished(Msg::SourceFinished) + .on_cancelled(Msg::SourceFinished) + .into() +} + fn workspaces_sidebar<'a>( workspaces: impl Iterator, output_name: &'a str,