1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-22 21:01:36 +03:00

support drag and drop files for macos

Signed-off-by: Ye Sijun <junnplus@gmail.com>
This commit is contained in:
Ye Sijun 2022-04-13 01:35:48 +08:00 committed by Wez Furlong
parent 3246651c63
commit 8f6facd584
4 changed files with 78 additions and 2 deletions

View File

@ -943,6 +943,20 @@ impl TermWindow {
}
Ok(true)
}
WindowEvent::DroppedFile(paths) => {
let pane = match self.get_active_pane_or_overlay() {
Some(pane) => pane,
None => return Ok(true),
};
let paths = paths
.iter()
.map(|path| format!("{:?}", path.to_string_lossy().to_string()))
.collect::<Vec<_>>()
.join(" ");
pane.trickle_paste(paths)?;
Ok(true)
}
WindowEvent::DraggedFile(_) => Ok(true),
}
}

View File

@ -82,6 +82,8 @@ impl MyWindow {
| WindowEvent::AdviseDeadKeyStatus(_)
| WindowEvent::Notification(_)
| WindowEvent::FocusChanged(_)
| WindowEvent::DraggedFile(_)
| WindowEvent::DroppedFile(_)
| WindowEvent::MouseLeave => {}
}
}

View File

@ -3,6 +3,7 @@ use bitflags::bitflags;
use config::{ConfigHandle, Dimension, GeometryOrigin};
use promise::Future;
use std::any::Any;
use std::path::PathBuf;
use std::rc::Rc;
use thiserror::Error;
pub mod bitmaps;
@ -175,6 +176,12 @@ pub enum WindowEvent {
AppearanceChanged(Appearance),
Notification(Box<dyn Any + Send + Sync>),
// Called when the files is being dragged into the window
DraggedFile(Vec<PathBuf>),
// Called when the files is been dropped into the window
DroppedFile(Vec<PathBuf>),
}
pub struct WindowEventSender {

View File

@ -16,12 +16,13 @@ use async_trait::async_trait;
use cocoa::appkit::{
self, CGFloat, NSApplication, NSApplicationActivateIgnoringOtherApps,
NSApplicationPresentationOptions, NSBackingStoreBuffered, NSEvent, NSEventModifierFlags,
NSOpenGLContext, NSOpenGLPixelFormat, NSRunningApplication, NSScreen, NSView,
NSOpenGLContext, NSOpenGLPixelFormat, NSPasteboard, NSRunningApplication, NSScreen, NSView,
NSViewHeightSizable, NSViewWidthSizable, NSWindow, NSWindowStyleMask,
};
use cocoa::base::*;
use cocoa::foundation::{
NSArray, NSAutoreleasePool, NSInteger, NSNotFound, NSPoint, NSRect, NSSize, NSUInteger,
NSArray, NSAutoreleasePool, NSFastEnumeration, NSInteger, NSNotFound, NSPoint, NSRect, NSSize,
NSUInteger,
};
use config::{ConfigHandle, DimensionContext, GeometryOrigin};
use core_foundation::base::{CFTypeID, TCFType};
@ -39,6 +40,7 @@ use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use std::any::Any;
use std::cell::RefCell;
use std::ffi::c_void;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use std::time::Instant;
@ -492,6 +494,13 @@ impl Window {
window.setContentView_(*view);
window.setDelegate_(*view);
// register for drag and drop operations.
let () = msg_send![
*window,
registerForDraggedTypes:
NSArray::arrayWithObject(nil, appkit::NSFilenamesPboardType)
];
let frame = NSView::frame(*view);
let backing_frame = NSView::convertRectToBacking(*view, frame);
let width = backing_frame.size.width;
@ -2475,6 +2484,42 @@ impl WindowView {
}
}
extern "C" fn dragging_entered(this: &mut Object, _: Sel, sender: id) -> BOOL {
if let Some(this) = Self::get_this(this) {
let mut inner = this.inner.borrow_mut();
let pb: id = unsafe { msg_send![sender, draggingPasteboard] };
let filenames =
unsafe { NSPasteboard::propertyListForType(pb, appkit::NSFilenamesPboardType) };
let paths = unsafe { filenames.iter() }
.map(|file| unsafe {
let path = nsstring_to_str(file);
PathBuf::from(path)
})
.collect::<Vec<_>>();
inner.events.dispatch(WindowEvent::DraggedFile(paths));
}
YES
}
extern "C" fn perform_drag_operation(this: &mut Object, _: Sel, sender: id) -> BOOL {
if let Some(this) = Self::get_this(this) {
let mut inner = this.inner.borrow_mut();
let pb: id = unsafe { msg_send![sender, draggingPasteboard] };
let filenames =
unsafe { NSPasteboard::propertyListForType(pb, appkit::NSFilenamesPboardType) };
let paths = unsafe { filenames.iter() }
.map(|file| unsafe {
let path = nsstring_to_str(file);
PathBuf::from(path)
})
.collect::<Vec<_>>();
inner.events.dispatch(WindowEvent::DroppedFile(paths));
}
YES
}
fn get_this(this: &Object) -> Option<&mut Self> {
unsafe {
let myself: *mut c_void = *this.get_ivar(VIEW_CLS_NAME);
@ -2710,6 +2755,14 @@ impl WindowView {
Self::first_rect_for_character_range
as extern "C" fn(&mut Object, Sel, NSRange, NSRangePointer) -> NSRect,
);
cls.add_method(
sel!(draggingEntered:),
Self::dragging_entered as extern "C" fn(&mut Object, Sel, id) -> BOOL,
);
cls.add_method(
sel!(performDragOperation:),
Self::perform_drag_operation as extern "C" fn(&mut Object, Sel, id) -> BOOL,
);
}
cls.register()