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:
parent
3d511bbd67
commit
1598579551
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user