mirror of
https://github.com/wez/wezterm.git
synced 2024-10-26 15:52:29 +03:00
x11: refactor x11 dnd a little
Reduce some nesting and make it a little easier to follow. refs: https://github.com/wez/wezterm/pull/5316
This commit is contained in:
parent
3d511bbd67
commit
1598579551
@ -18,8 +18,10 @@ use raw_window_handle::{
|
|||||||
};
|
};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use url::Url;
|
||||||
use wezterm_font::FontConfiguration;
|
use wezterm_font::FontConfiguration;
|
||||||
use wezterm_input_types::{KeyCode, KeyEvent, KeyboardLedStatus, Modifiers};
|
use wezterm_input_types::{KeyCode, KeyEvent, KeyboardLedStatus, Modifiers};
|
||||||
use xcb::x::{Atom, PropMode};
|
use xcb::x::{Atom, PropMode};
|
||||||
@ -1116,84 +1118,16 @@ impl XWindowInner {
|
|||||||
let text = String::from_utf8_lossy(prop.value()).to_string();
|
let text = String::from_utf8_lossy(prop.value()).to_string();
|
||||||
self.events.dispatch(WindowEvent::DroppedString(text));
|
self.events.dispatch(WindowEvent::DroppedString(text));
|
||||||
} else if selection.target() == conn.atom_xmozurl {
|
} else if selection.target() == conn.atom_xmozurl {
|
||||||
let raw = prop.value();
|
let data = decode_dropped_url_string(prop.value());
|
||||||
let data;
|
let urls = parse_xmozurl_list(&data);
|
||||||
if raw.len() >= 2
|
|
||||||
&& ((raw[0], raw[1]) == (0xfe, 0xff)
|
|
||||||
|| (raw[0] != 0x00 && raw[1] == 0x00))
|
|
||||||
{
|
|
||||||
data = String::from_utf16_lossy(
|
|
||||||
raw.chunks_exact(2)
|
|
||||||
.map(|x: &[u8]| u16::from(x[1]) << 8 | u16::from(x[0]))
|
|
||||||
.collect::<Vec<u16>>()
|
|
||||||
.as_slice(),
|
|
||||||
);
|
|
||||||
} else if raw.len() >= 2
|
|
||||||
&& ((raw[0], raw[1]) == (0xff, 0xfe)
|
|
||||||
|| (raw[0] == 0x00 && raw[1] != 0x00))
|
|
||||||
{
|
|
||||||
data = String::from_utf16_lossy(
|
|
||||||
raw.chunks_exact(2)
|
|
||||||
.map(|x: &[u8]| u16::from(x[0]) << 8 | u16::from(x[1]))
|
|
||||||
.collect::<Vec<u16>>()
|
|
||||||
.as_slice(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
data = String::from_utf8_lossy(prop.value()).to_string();
|
|
||||||
}
|
|
||||||
use url::Url;
|
|
||||||
let urls = data
|
|
||||||
.lines()
|
|
||||||
.step_by(2)
|
|
||||||
.filter_map(|line| {
|
|
||||||
// the lines alternate between the urls and their titles
|
|
||||||
Url::parse(line)
|
|
||||||
.map_err(|err| {
|
|
||||||
log::error!(
|
|
||||||
"Error parsing dropped file line {} as url: {:#}",
|
|
||||||
line,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
self.events.dispatch(WindowEvent::DroppedUrl(urls));
|
self.events.dispatch(WindowEvent::DroppedUrl(urls));
|
||||||
} else if selection.target() == conn.atom_texturilist {
|
} else if selection.target() == conn.atom_texturilist {
|
||||||
let paths = String::from_utf8_lossy(prop.value())
|
let paths = parse_texturi_list(prop.value());
|
||||||
.lines()
|
|
||||||
.filter_map(|line| {
|
|
||||||
if line.starts_with('#') || line.trim().is_empty() {
|
|
||||||
// text/uri-list: Any lines beginning with the '#' character
|
|
||||||
// are comment lines and are ignored during processing
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
use url::Url;
|
|
||||||
let url = Url::parse(line)
|
|
||||||
.map_err(|err| {
|
|
||||||
log::error!(
|
|
||||||
"Error parsing dropped file line {} as url: {:#}",
|
|
||||||
line,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.ok()?;
|
|
||||||
url.to_file_path()
|
|
||||||
.map_err(|_| {
|
|
||||||
log::error!(
|
|
||||||
"Error converting url {} from line {} to pathbuf",
|
|
||||||
url,
|
|
||||||
line
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
self.events.dispatch(WindowEvent::DroppedFile(paths));
|
self.events.dispatch(WindowEvent::DroppedFile(paths));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("clipboard: err while getting clipboard property: {:?}", err);
|
log::error!("clipboard: err while getting clipboard property: {err:#}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.send_request_no_reply_log(&xcb::x::SendEvent {
|
conn.send_request_no_reply_log(&xcb::x::SendEvent {
|
||||||
@ -2163,6 +2097,67 @@ impl WindowOps for XWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_texturi_list(url_list: &[u8]) -> Vec<PathBuf> {
|
||||||
|
String::from_utf8_lossy(url_list)
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
if line.starts_with('#') || line.trim().is_empty() {
|
||||||
|
// text/uri-list: Any lines beginning with the '#' character
|
||||||
|
// are comment lines and are ignored during processing
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let url = Url::parse(line)
|
||||||
|
.map_err(|err| {
|
||||||
|
log::error!("Error parsing dropped file line {line} as url: {err:#}");
|
||||||
|
})
|
||||||
|
.ok()?;
|
||||||
|
url.to_file_path()
|
||||||
|
.map_err(|_| {
|
||||||
|
log::error!("Error converting url {url:?} from line {line} to pathbuf");
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_xmozurl_list(url_list: &str) -> Vec<Url> {
|
||||||
|
url_list
|
||||||
|
.lines()
|
||||||
|
.step_by(2)
|
||||||
|
.filter_map(|line| {
|
||||||
|
// the lines alternate between the urls and their titles
|
||||||
|
Url::parse(line)
|
||||||
|
.map_err(|err| {
|
||||||
|
log::error!("Error parsing dropped file line {line} as url: {err:#}");
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data may be UTF16 in either byte order, or UTF8
|
||||||
|
fn decode_dropped_url_string(raw: &[u8]) -> String {
|
||||||
|
if raw.len() >= 2 && ((raw[0], raw[1]) == (0xfe, 0xff) || (raw[0] != 0x00 && raw[1] == 0x00)) {
|
||||||
|
String::from_utf16_lossy(
|
||||||
|
raw.chunks_exact(2)
|
||||||
|
.map(|x: &[u8]| u16::from(x[1]) << 8 | u16::from(x[0]))
|
||||||
|
.collect::<Vec<u16>>()
|
||||||
|
.as_slice(),
|
||||||
|
)
|
||||||
|
} else if raw.len() >= 2
|
||||||
|
&& ((raw[0], raw[1]) == (0xff, 0xfe) || (raw[0] == 0x00 && raw[1] != 0x00))
|
||||||
|
{
|
||||||
|
String::from_utf16_lossy(
|
||||||
|
raw.chunks_exact(2)
|
||||||
|
.map(|x: &[u8]| u16::from(x[0]) << 8 | u16::from(x[1]))
|
||||||
|
.collect::<Vec<u16>>()
|
||||||
|
.as_slice(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
String::from_utf8_lossy(raw).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
enum NetWmStateAction {
|
enum NetWmStateAction {
|
||||||
|
Loading…
Reference in New Issue
Block a user