Improve command logging and log_err module paths (#39674)

Prior we only logged the crate in `log_err`, which is not too helpful.
We now assemble the module path from the file system path.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-10-07 12:11:15 +00:00
committed by GitHub
parent 64eec67a81
commit 9a5034ea6d
10 changed files with 114 additions and 139 deletions
+46 -40
View File
@@ -3,7 +3,6 @@ use std::sync::LazyLock;
use anyhow::Result;
use collections::{FxHashMap, FxHashSet};
use itertools::Itertools;
use util::ResultExt;
use windows::Win32::{
Foundation::{HANDLE, HGLOBAL},
System::{
@@ -76,14 +75,18 @@ enum ClipboardFormatType {
}
pub(crate) fn write_to_clipboard(item: ClipboardItem) {
write_to_clipboard_inner(item).log_err();
unsafe { CloseClipboard().log_err() };
with_clipboard(|| write_to_clipboard_inner(item));
}
pub(crate) fn read_from_clipboard() -> Option<ClipboardItem> {
let result = read_from_clipboard_inner();
unsafe { CloseClipboard().log_err() };
result
with_clipboard(|| {
with_best_match_format(|item_format| match format_to_type(item_format) {
ClipboardFormatType::Text => read_string_from_clipboard(),
ClipboardFormatType::Image => read_image_from_clipboard(item_format),
ClipboardFormatType::Files => read_files_from_clipboard(),
})
})
.flatten()
}
pub(crate) fn with_file_names<F>(hdrop: HDROP, mut f: F)
@@ -96,11 +99,33 @@ where
let mut buffer = vec![0u16; filename_length + 1];
let ret = unsafe { DragQueryFileW(hdrop, file_index, Some(buffer.as_mut_slice())) };
if ret == 0 {
log::error!("unable to read file name");
log::error!("unable to read file name of dragged file");
continue;
}
if let Some(file_name) = String::from_utf16(&buffer[0..filename_length]).log_err() {
f(file_name);
match String::from_utf16(&buffer[0..filename_length]) {
Ok(file_name) => f(file_name),
Err(e) => {
log::error!("dragged file name is not UTF-16: {}", e)
}
}
}
}
fn with_clipboard<F, T>(f: F) -> Option<T>
where
F: FnOnce() -> T,
{
match unsafe { OpenClipboard(None) } {
Ok(()) => {
let result = f();
if let Err(e) = unsafe { CloseClipboard() } {
log::error!("Failed to close clipboard: {e}",);
}
Some(result)
}
Err(e) => {
log::error!("Failed to open clipboard: {e}",);
None
}
}
}
@@ -124,7 +149,6 @@ fn format_to_type(item_format: u32) -> &'static ClipboardFormatType {
// Currently, we only write the first item.
fn write_to_clipboard_inner(item: ClipboardItem) -> Result<()> {
unsafe {
OpenClipboard(None)?;
EmptyClipboard()?;
}
match item.entries().first() {
@@ -215,15 +239,6 @@ fn convert_image_to_png_format(bytes: &[u8], image_format: ImageFormat) -> Resul
Ok(output_buf)
}
fn read_from_clipboard_inner() -> Option<ClipboardItem> {
unsafe { OpenClipboard(None) }.log_err()?;
with_best_match_format(|item_format| match format_to_type(item_format) {
ClipboardFormatType::Text => read_string_from_clipboard(),
ClipboardFormatType::Image => read_image_from_clipboard(item_format),
ClipboardFormatType::Files => read_files_from_clipboard(),
})
}
// Here, we enumerate all formats on the clipboard and find the first one that we can process.
// The reason we don't use `GetPriorityClipboardFormat` is that it sometimes returns the
// wrong format.
@@ -266,7 +281,7 @@ where
}
fn read_string_from_clipboard() -> Option<ClipboardEntry> {
let text = with_clipboard_data(CF_UNICODETEXT.0 as u32, |data_ptr| {
let text = with_clipboard_data(CF_UNICODETEXT.0 as u32, |data_ptr, _| {
let pcwstr = PCWSTR(data_ptr as *const u16);
String::from_utf16_lossy(unsafe { pcwstr.as_wide() })
})?;
@@ -290,20 +305,22 @@ fn read_hash_from_clipboard() -> Option<u64> {
if unsafe { IsClipboardFormatAvailable(*CLIPBOARD_HASH_FORMAT).is_err() } {
return None;
}
with_clipboard_data(*CLIPBOARD_HASH_FORMAT, |data_ptr| {
with_clipboard_data(*CLIPBOARD_HASH_FORMAT, |data_ptr, size| {
if size < 8 {
return None;
}
let hash_bytes: [u8; 8] = unsafe {
std::slice::from_raw_parts(data_ptr.cast::<u8>(), 8)
.to_vec()
.try_into()
.log_err()
.ok()
}?;
Some(u64::from_ne_bytes(hash_bytes))
})?
}
fn read_metadata_from_clipboard() -> Option<String> {
unsafe { IsClipboardFormatAvailable(*CLIPBOARD_METADATA_FORMAT).log_err()? };
with_clipboard_data(*CLIPBOARD_METADATA_FORMAT, |data_ptr| {
unsafe { IsClipboardFormatAvailable(*CLIPBOARD_METADATA_FORMAT).ok()? };
with_clipboard_data(*CLIPBOARD_METADATA_FORMAT, |data_ptr, _size| {
let pcwstr = PCWSTR(data_ptr as *const u16);
String::from_utf16_lossy(unsafe { pcwstr.as_wide() })
})
@@ -320,7 +337,7 @@ fn format_number_to_image_format(format_number: u32) -> Option<&'static ImageFor
}
fn read_image_for_type(format_number: u32, format: ImageFormat) -> Option<ClipboardEntry> {
let (bytes, id) = with_clipboard_data_and_size(format_number, |data_ptr, size| {
let (bytes, id) = with_clipboard_data(format_number, |data_ptr, size| {
let bytes = unsafe { std::slice::from_raw_parts(data_ptr as *mut u8 as _, size).to_vec() };
let id = hash(&bytes);
(bytes, id)
@@ -329,7 +346,7 @@ fn read_image_for_type(format_number: u32, format: ImageFormat) -> Option<Clipbo
}
fn read_files_from_clipboard() -> Option<ClipboardEntry> {
let text = with_clipboard_data(CF_HDROP.0 as u32, |data_ptr| {
let text = with_clipboard_data(CF_HDROP.0 as u32, |data_ptr, _size| {
let hdrop = HDROP(data_ptr);
let mut filenames = String::new();
with_file_names(hdrop, |file_name| {
@@ -344,25 +361,14 @@ fn read_files_from_clipboard() -> Option<ClipboardEntry> {
}
fn with_clipboard_data<F, R>(format: u32, f: F) -> Option<R>
where
F: FnOnce(*mut std::ffi::c_void) -> R,
{
let global = HGLOBAL(unsafe { GetClipboardData(format).log_err() }?.0);
let data_ptr = unsafe { GlobalLock(global) };
let result = f(data_ptr);
unsafe { GlobalUnlock(global).log_err() };
Some(result)
}
fn with_clipboard_data_and_size<F, R>(format: u32, f: F) -> Option<R>
where
F: FnOnce(*mut std::ffi::c_void, usize) -> R,
{
let global = HGLOBAL(unsafe { GetClipboardData(format).log_err() }?.0);
let global = HGLOBAL(unsafe { GetClipboardData(format).ok() }?.0);
let size = unsafe { GlobalSize(global) };
let data_ptr = unsafe { GlobalLock(global) };
let result = f(data_ptr, size);
unsafe { GlobalUnlock(global).log_err() };
unsafe { GlobalUnlock(global).ok() };
Some(result)
}