Skip to content

Commit

Permalink
x11: refactor x11 dnd a little
Browse files Browse the repository at this point in the history
Reduce some nesting and make it a little easier to follow.

refs: #5316
  • Loading branch information
wez committed May 5, 2024
1 parent 3d511bb commit 1598579
Showing 1 changed file with 67 additions and 72 deletions.
139 changes: 67 additions & 72 deletions window/src/os/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 1598579

Please sign in to comment.