1
1
mirror of https://github.com/wez/wezterm.git synced 2024-08-17 10:10:23 +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:
Wez Furlong 2024-05-05 13:02:40 -07:00
parent 3d511bbd67
commit 1598579551
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387

View File

@ -18,8 +18,10 @@ use raw_window_handle::{
};
use std::any::Any;
use std::convert::TryInto;
use std::path::PathBuf;
use std::rc::{Rc, Weak};
use std::sync::{Arc, Mutex};
use url::Url;
use wezterm_font::FontConfiguration;
use wezterm_input_types::{KeyCode, KeyEvent, KeyboardLedStatus, Modifiers};
use xcb::x::{Atom, PropMode};
@ -1116,84 +1118,16 @@ impl XWindowInner {
let text = String::from_utf8_lossy(prop.value()).to_string();
self.events.dispatch(WindowEvent::DroppedString(text));
} else if selection.target() == conn.atom_xmozurl {
let raw = prop.value();
let 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<_>>();
let data = decode_dropped_url_string(prop.value());
let urls = parse_xmozurl_list(&data);
self.events.dispatch(WindowEvent::DroppedUrl(urls));
} else if selection.target() == conn.atom_texturilist {
let paths = String::from_utf8_lossy(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<_>>();
let paths = parse_texturi_list(prop.value());
self.events.dispatch(WindowEvent::DroppedFile(paths));
}
}
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 {
@ -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)]
#[repr(u32)]
enum NetWmStateAction {