Skip to content

Commit

Permalink
Merge pull request #13 from tekai-crabnebula/fix/windows-forward-slas…
Browse files Browse the repository at this point in the history
…h-handling

fix: Handle forward slash path in Windows
  • Loading branch information
lucasfernog-crabnebula authored Dec 7, 2023
2 parents 935b34f + 20de75d commit 0e18b08
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 29 deletions.
3 changes: 3 additions & 0 deletions crates/drag/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ objc = "0.2"
gtk = "0.15"
gdkx11 = "0.15"

[target."cfg(target_os = \"windows\")".dependencies]
dunce = "1"

[target."cfg(target_os = \"windows\")".dependencies.windows]
version = "0.51"
features = [
Expand Down
8 changes: 5 additions & 3 deletions crates/drag/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
//! let window = tao::window::WindowBuilder::new().build(&event_loop).unwrap();
//!
//! let item = drag::DragItem::Files(vec![std::fs::canonicalize("./examples/icon.png").unwrap()]);
//! let preview_icon = drag::Image::File("../../icon.png".into());
//! let preview_icon = drag::Image::File("./examples/icon.png".into());
//!
//! drag::start_drag(
//! #[cfg(target_os = "linux")]
Expand All @@ -45,7 +45,7 @@
//! let webview = wry::webview::WebViewBuilder::new(window).unwrap().build().unwrap();
//!
//! let item = drag::DragItem::Files(vec![std::fs::canonicalize("./examples/icon.png").unwrap()]);
//! let preview_icon = drag::Image::File("../../icon.png".into());
//! let preview_icon = drag::Image::File("./examples/icon.png".into());
//!
//! drag::start_drag(
//! #[cfg(target_os = "linux")]
Expand All @@ -66,7 +66,7 @@
//! let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
//!
//! let item = drag::DragItem::Files(vec![std::fs::canonicalize("./examples/icon.png").unwrap()]);
//! let preview_icon = drag::Image::File("../../icon.png".into());
//! let preview_icon = drag::Image::File("./examples/icon.png".into());
//!
//! # #[cfg(not(target_os = "linux"))]
//! let _ = drag::start_drag(&window, item, preview_icon);
Expand All @@ -89,6 +89,8 @@ pub enum Error {
#[cfg(windows)]
#[error("{0}")]
WindowsError(#[from] windows::core::Error),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("unsupported window handle")]
UnsupportedWindowHandle,
#[error("failed to start drag")]
Expand Down
7 changes: 4 additions & 3 deletions crates/drag/src/platform_impl/windows/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use std::os::windows::ffi::OsStrExt;
use std::{ffi::c_void, iter::once, path::Path};
use windows::core::PCWSTR;
use windows::Win32::Foundation::*;
use windows::Win32::{
Graphics::{
Gdi::{CreateBitmap, HBITMAP},
Expand All @@ -14,9 +16,8 @@ use windows::Win32::{
},
System::Com::{CoCreateInstance, CLSCTX_INPROC_SERVER},
};
use windows::{core::*, Win32::Foundation::*};

use super::utils::adjust_canonicalization;
use crate::Result;

pub(crate) fn read_bytes_to_hbitmap(bytes: &[u8]) -> Result<HBITMAP> {
unsafe {
Expand All @@ -41,7 +42,7 @@ pub(crate) fn read_path_to_hbitmap(path: &Path) -> Result<HBITMAP> {
let factory: IWICImagingFactory =
CoCreateInstance(&CLSID_WICImagingFactory, None, CLSCTX_INPROC_SERVER)?;

let path = adjust_canonicalization(path);
let path = dunce::canonicalize(path)?;
let wide_path: Vec<u16> = path.as_os_str().encode_wide().chain(once(0)).collect();

let decoder = factory.CreateDecoderFromFilename(
Expand Down
12 changes: 8 additions & 4 deletions crates/drag/src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use windows::{
};

mod image;
mod utils;

static mut OLE_RESULT: Result<()> = Ok(());
static OLE_UNINITIALIZE: Once = Once::new();
Expand Down Expand Up @@ -199,7 +198,13 @@ pub fn start_drag<W: HasRawWindowHandle>(
return Err(e.clone().into());
}
}
let data_object: IDataObject = get_file_data_object(&files).unwrap();

let mut paths = Vec::new();
for f in files {
paths.push(dunce::canonicalize(f)?);
}

let data_object: IDataObject = get_file_data_object(&paths).unwrap();
let drop_source: IDropSource = DropSource::new().into();

unsafe {
Expand Down Expand Up @@ -276,7 +281,7 @@ fn get_hglobal(size: usize, buffer: Vec<u16>) -> Result<HGLOBAL> {
Ok(handle)
}

pub fn create_instance<T: Interface + ComInterface>(clsid: &GUID) -> windows::core::Result<T> {
pub fn create_instance<T: Interface + ComInterface>(clsid: &GUID) -> Result<T> {
unsafe { CoCreateInstance(clsid, None, CLSCTX_ALL) }
}

Expand All @@ -299,7 +304,6 @@ fn get_shell_item_array(paths: &[PathBuf]) -> Option<IShellItemArray> {

fn get_file_item_id(path: &Path) -> *mut Common::ITEMIDLIST {
unsafe {
let path = utils::adjust_canonicalization(path);
let wide_path: Vec<u16> = path.as_os_str().encode_wide().chain(once(0)).collect();
windows::Win32::UI::Shell::ILCreateFromPathW(PCWSTR::from_raw(wide_path.as_ptr()))
}
Expand Down
16 changes: 0 additions & 16 deletions crates/drag/src/platform_impl/windows/utils.rs

This file was deleted.

2 changes: 1 addition & 1 deletion examples/tao/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn main() {
&window,
DragItem::Files(vec![std::fs::canonicalize("./examples/icon.png").unwrap()]),
Image::Raw(include_bytes!("../../icon.png").to_vec()),
// Image::File("../../icon.png".into()),
// Image::File("./examples/icon.png".into()),
)
.unwrap();
}
Expand Down
2 changes: 1 addition & 1 deletion examples/winit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn main() {
vec![std::fs::canonicalize("./examples/icon.png").unwrap()],
),
Image::Raw(include_bytes!("../../icon.png").to_vec()),
// Image::File("../../icon.png".into()),
// Image::File("./examples/icon.png".into()),
)
.unwrap();
}
Expand Down
2 changes: 1 addition & 1 deletion examples/wry/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn main() -> wry::Result<()> {
std::fs::canonicalize("./examples/icon.bmp").unwrap(),
]),
Image::Raw(include_bytes!("../../icon.png").to_vec()),
// Image::File("../../icon.png".into()),
// Image::File("./examples/icon.png".into()),
)
.unwrap();
}
Expand Down

0 comments on commit 0e18b08

Please sign in to comment.